2.2、变量类型

By | 2014年12月21日

c语言中的基本数据类型有

  • int                定义整形变量
  • float            定义浮点型变量(浮点型就是保存小数的)
  • double       定义双精度浮点型变量
  • char            定义字符型变量

整形变量

整形变量自然就是保存整数的变量。为什么要把整数和小数分开呢?

这是因为,在二进制中,只有0和1,没有小数点,因此整数和小数在计算机看来,都是1和0的组合,没有什么区别。

而我们把某一块数据看作小数,那么他就是小数,把它看作整数,他就变成了整数。

因此一个数据是什么类型都是看你用什么标准去看他。

整形变量只能保存整数,如果你让他保存一个小数会怎么样呢。让我们将他作为一个问题,稍后我们会做相关的实验来进行探究。

浮点型

浮点型就是保存小数的类型,那么为什么有float和double之分呢?

前面说到过,变量的本质就是内存上的一小块储存空间。

而空间的容量是有限的,就像一个瓶子,当你装满了水后就放不下其他东西了。(别告诉我水里面还能继续溶解气体。。。)

想要装更多东西?没关系,方法就是增大容积(增加内存上储存空间的大小)。

但是很不幸,c语言中,一个类型所占用的空间是固定的(尽管不同的环境下变量的空间确实有可能不同,但是在一个确定的环境下各种类型的空间大小就是一个常 数!)。这意味着我们不能像往气球里面灌水一样(我打赌你玩过),气球的体积会自动增大。我们只能换一个更大的杯子来装水。

float和double就是两个不同的杯子。

double有双的意思,而在编程中,double的储存空间便是float的两倍。空间更大他的精度自然更大。

那么你可能又会问了,既然double精度更高,那么留着float干啥呢?

当然是省空间了,在早期,计算机的内存是很少的,现在早已淘汰的512M内存在当时是不敢想象的。

现在计算机的内存变大了,我们当然不用再去挖空心思的去想如何省内存。不过现在某些单片机上硬件内存仍然很紧张。例如很常用的51单片机上,只有218B的RAM,请注意是B不是MB也不是KB,在这种环境下省内存的意义便体现出来了。

字符型

字符型就是用来保存字符的了。

这里有一点需要注意,那就是字符是如何保存的?

前文中已经说过很多遍,计算机内只有1和0两个符号,那么如何表示各种各样的字符呢。

把某个数据看作是字符就行了。

我们可以规定,1代表a,2代表b,自然3就是c,4就是d

现在就好办了,只要一个专门负责显示的程序,遇到1就将a显示出来,遇到2则显示b,依次类推。此时,我们其实已经自己创造了一种数与字符的对应关系,也就是编码。

很不幸的是,我们现实中的计算机中并不是使用上面的字符和数字映射的关系,尽管它看起来比较简单。

我们使用的是一种叫做ASCII的编码方案(American Standard Code for Information Interchange,美国信息互换标准代码)。如果你要问为什么前面有个American?答案很简单,因为计算机一开始就是美国人发明的。

注意ASCII的最后是两个大写的“i”而不是两个小写的“L”

关于ASCII的更多内容,我们将在专门的一节说道。

有符号和无符号

一般来说,数值可以分为有符号和无符号两种,有符号就是要区分数据的正负,而无符号则不需要考虑数据的正负,它通常用在那些不关心正负或者根本就没有负数情况的场合。比如计算圆的面积,你总不可能找个面积为负数的圆吧!

我们使用unsigned来修饰无符号类型,而用signed来修饰有符号的变量。

如 unsigned int, signed double等

其实int,float和double已经被规定了是默认有符号的,即int=signed int,double=signed double。

你可能已经意识到,上面遗漏了一个char,这当然不是不小心写漏了。而是人们并没有专门的去规定它是不是有符号的,即char 可能等于signed char,也可能等于unsigned char,具体要看编译器的心情。不同的环境是有不同的结果的。

有符号和无符号的区别不仅仅在于无符号不能保存负数。要讨论这个问题我们需要先从数据在内存中保存的方法说起。

任何数据在电子计算机中都是使用二进制保存的,而保存数据的空间是有限制的,以char为例,他是一个字节。也就是8位。

比如 0111 1111

因为二进制中没有负号这个东西,如果需要保存数据的正负呢,你可能已经想到,我们可以用一位的0和1来表示这个数的正负。恭喜你,你猜对了!人们规定将最高位用来说明数据的正负(也就是上面的0),用1代表负数,而0则表示正数。这样看来,我们只有剩下的7位来保存数值了。

但是有时候我们不需要考虑数据的正负,这样最高位就没有意义了,我们总不能空着它不用吧!为了节约空间,在不考虑正负的情况下,我们便将最高位也用来保存数据。这样一来,无符号保存数据用了8位,而有符号则只有7位。空间不同它们所能保存数据的范围自然不同。

signed char是-128~127,你可能会问,为什么正数只到127,因为还有一个0呀!

unsigned char则是0~255.


int在32位环境下一般是4字节,所能表示的数据范围是-2147483648 ~ +2147483647,这个范围有时候稍微大了一点,比如我的某个数据只会在0-10000中变化,还用4字节来保存就显得有些浪费了。

于是在基本数据类型之下,我们还定义了一些修饰符。它们是:

short和long,取字面意思,short就是短,long就是长。

它们可以这样写:
short int, long int, long double

short int顾名思义就是短整型了。至于short double?那不就是float嘛

然后int在这个时候可以省略,也就是说short=short int,long=long int

不过double就不能省略了。

人们并没有规定short一定是多长,只要不比int大就行,long也是这样,不能比int小。

我们可以用下面这个程序来测试一下,各个数据类型的大小和范围

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <float.h>
int main()
{
    printf("char>%d Byte %d ~ %d\n\n", sizeof(char), CHAR_MIN, CHAR_MIN);
    printf("unsigned char>%d Byte %d ~ %d\n\n", sizeof(unsigned char), 0, UCHAR_MAX);
    printf("int>%d Byte %d ~ %d\n\n", sizeof(int), INT_MIN, INT_MAX);
    printf("unsigned int>%d Byte %d ~ %u\n\n", sizeof(unsigned int), 0, UINT_MAX);

    printf("short>%d Byte %d ~ %d\n\n", sizeof(short), SHRT_MIN, SHRT_MAX);
    printf("long>%d Byte %ld ~ %ld\n\n", sizeof(long), LONG_MIN, LONG_MAX);

    printf("float>%d Byte %e ~ %e\n\n", sizeof(float), FLT_MIN, FLT_MAX);
    printf("double>%d Byte %e ~ %e\n\n", sizeof(double), DBL_MIN, DBL_MAX);
    return 0;

}

请自己编译并运行程序

可以看到在gcc环境下,char默认是有符号的!

发表评论

邮箱地址不会被公开。 必填项已用*标注