C语言学习(1):C语言变量和数据类型,数字与字符串
Author:zhoulujun Date:
小学数学中,变数或变量,是指没有固定的值,可以改变的数。变量以非数字的符号来表达,一般用拉丁字母。比如设 x=1,y=2
变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。变量可以通过变量名访问。在指令式语言中,变量通常是可变的;但在纯函数式语言(如Haskell)中,变量可能是不可变的。在一些语言中,变量可能被明确为是能表示可变状态、具有存储空间的抽象(如在Java和Visual Basic中);
变量(Variable)
int a; //仅仅是在内存中找了一块可以保存整数的区域——创造了一个变量 a,我们把这个过程叫做变量定义
a=123; //赋值(Assign)是指把数据放到内存的过程——我们把这个过程叫做给变量赋值;第一次赋值称为变量的初始化,或者赋初值。
把上面的两个语句连起来:int a=123;
内存中的数据有多种解释方式,使用之前必须要确定;上面的int a;就表明,这份数据是整数。
int 有一个专业的称呼,叫做数据类型(Data Type)。
数据类型(Data Type)
数据是放在内存中的,变量是给这块内存起的名字,有了变量就可以找到并使用这份数据。
数据类型用来说明数据的类型,确定了数据的解释方式,让计算机和程序员不会产生歧义。在C语言中,有多种数据类型,例如:
说 明 | 字符型 | 短整型 | 整型 | 长整型 | 单精度浮点型 | 双精度浮点型 |
---|---|---|---|---|---|---|
数据类型 | char | short | int | long | float | double |
长 度 | 1 | 2 | 4 | 4 | 4 | 8 |
数据的长度(Length)
所谓数据长度(Length),是指数据占用多少个字节。占用的字节越多,能存储的数据就越多,对于数字来说,值就会更大,反之能存储的数据就有限。
多个数据在内存中是连续存储的,彼此之间没有明显的界限,如果不明确指明数据的长度,计算机就不知道何时存取结束。例如我们保存了一个整数 1000,它占用4个字节的内存,而读取时却认为它占用3个字节或5个字节,这显然是不正确的。
所以,在定义变量时还要指明数据的长度。而这恰恰是数据类型的另外一个作用。因为在C语言中,每一种数据类型所占用的字节数都是固定的,知道了数据类型,也就知道了数据的长度。
数值的正负
在数学中,数字有正负之分。在C语言中也是一样,short、int、long 都可以带上正负号。如果不带正负号,默认就是正数。
符号也是数字的一部分,也要在内存中体现出来。符号只有正负两种情况,用1位(Bit)就足以表示;C语言规定,把内存的最高位作为符号位。以 int 为例,它占用 32 位的内存,0~30 位表示数值,31 位表示正负号。如下图所示:
但是在很多情况下,我们非常确定某个数字只能是正数,比如班级学生的人数、字符串的长度、内存地址等,这个时候符号位就是多余的了,就不如删掉符号位,把所有的位都用来存储数值,这样能表示的数值范围更大(大一倍)。
C语言允许我们这样做,如果不希望设置符号位,可以在数据类型前面加上 unsigned 关键字,例如:
unsigned short a = 12; short a = -12;
下表全面地总结了不同类型的整数,以不同进制的形式输出时对应的格式控制符
short | int | long | unsigned short | unsigned int | unsigned long | |
---|---|---|---|---|---|---|
八进制 | -- | -- | -- | %ho | %o | %lo |
十进制 | %hd | %d | %ld | %hu | %u | %lu |
十六进制 | -- | -- | -- | %hx 或者 %hX | %x 或者 %X | %lx 或者 %lX |
使用 %o 和 %x 来输出有符号数了,为什么没有发生错误呢?这是因为:
当以有符号数的形式输出时,printf 会读取数字所占用的内存,并把最高位作为符号位,把剩下的内存作为数值位;
当以无符号数的形式输出时,printf 也会读取数字所占用的内存,并把所有的内存都作为数值位对待。
对于一个有符号的正数,它的符号位是 0,当按照无符号数的形式读取时,符号位就变成了数值位,但是该位恰好是 0 而不是 1,所以对数值不会产生影响,这就好比在一个数字前面加 0,有多少个 0 都不会影响数字的值。
如果对一个有符号的负数使用 %o 或者 %x 输出,那么结果就会大相径庭,读者可以亲试。
可以说,“有符号正数的最高位是 0”这个巧合才使得 %o 和 %x 输出有符号数时不会出错。
再次强调,不管是以 %o、%u、%x 输出有符号数,还是以 %d 输出无符号数,编译器都不会报错,只是对内存的解释不同了。%o、%d、%u、%x 这些格式控制符不会关心数字在定义时到底是有符号的还是无符号的:
你让我输出无符号数,那我在读取内存时就不区分符号位和数值位了,我会把所有的内存都看做数值位;
你让我输出有符号数,那我在读取内存时会把最高位作为符号位,把剩下的内存作为数值位。
说得再直接一些,我管你在定义时是有符号数还是无符号数呢,我只关心内存,有符号数也可以按照无符号数输出,无符号数也可以按照有符号数输出,至于输出结果对不对,那我就不管了,你自己承担风险。
浮点数
浮点数问题,推荐阅读《浮点数精度问题透析:小数计算不准确+浮点数精度丢失根源》
字符与字符串
计算机在存储字符时并不是真的要存储字符实体,而是存储该字符在字符集中的编号(也可以叫编码值)。对于 char 类型来说,它实际上存储的就是字符的 ASCII 码。
无论在哪个字符集中,字符编号都是一个整数;从这个角度考虑,字符类型和整数类型本质上没有什么区别。
字符串
字符串在java里面字符串类型是String
在C语言中没有专门的字符串类型,我们只能使用数组或者指针来间接地存储字符串。
char str1[] = "http://c.biancheng.net"; char *str2 = "C语言中文网";
字符集(Character Set)为每个字符分配了唯一的编号,我们不妨将它称为编码值。在C语言中,一个字符除了可以用它的实体(也就是真正的字符)表示,还可以用编码值表示。这种使用编码值来间接地表示字符的方式称为转义字符(Escape Character)。
转义字符(Escape Character)
转义字符以\或者\x开头,以\开头表示后跟八进制形式的编码值,以\x开头表示后跟十六进制形式的编码值。对于转义字符来说,只能使用八进制或者十六进制。
超出范围的转义字符的行为是未定义的,有的编译器会将编码值直接输出,有的编译器会报错。
控制字符
对于 ASCII 编码,0~31(十进制)范围内的字符为控制字符,它们都是看不见的,不能在显示器上显示,甚至无法从键盘输入,只能用转义字符的形式来表示。不过,直接使用 ASCII 码记忆不方便,也不容易理解,所以,针对常用的控制字符,C语言又定义了简写方式,完整的列表如下:
转义字符 | 意义 | ASCII码值(十进制) |
---|---|---|
\a | 响铃(BEL) | 007 |
\b | 退格(BS) ,将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下页开头 | 012 |
\n | 换行(LF) ,将当前位置移到下一行开头 | 010 |
\r | 回车(CR) ,将当前位置移到本行开头 | 013 |
\t | 水平制表(HT) | 009 |
\v | 垂直制表(VT) | 011 |
\' | 单引号 | 039 |
\" | 双引号 | 034 |
\\ | 反斜杠 | 092 |
以上内容摘自:C语言中文网
转载本站文章《C语言学习(1):C语言变量和数据类型,数字与字符串》,
请注明出处:https://www.zhoulujun.cn/html/theory/C/elementary/8448.html