1.为什么c语言中int的取值范围是-32768~~~~32767?
这得从二进制的原码说起: 如果以最高位为符号位,二进制原码最大为0111111111111111=215-1=32767 最小为1111111111111111=-(215-1)=-32767 此时0有两种表示方法,即正0和负0:0000000000000000=1000000000000000=0 所以,二进制原码表示时,范围是-32767~-0和0~32767,因为有两个零的存在,所以不同的数值个数一共只有2的16次方-1个,比16位二进制能够提供的2的16次方个编码少1个。 但是计算机中采用二进制补码存储数据,即正数编码不变,从0000000000000000到0111111111111111依旧表示0到32767,而负数需要把除符号位以后的部分取反加1,即-32767的补码为1000000000000001。 到此,再来看原码的正0和负0:0000000000000000和1000000000000000,补码表示中,前者的补码还是0000000000000000,后者经过非符号位取反加1后,同样变成了0000000000000000,也就是正0和负0在补码系统中的编码是一样的。但是,我们知道,16位二进制数可以表示2的16次方个编码,而在补码中零的编码只有一个,也就是补码中会比原码多一个编码出来,这个编码就是1000000000000000,因为任何一个原码都不可能在转成补码时变成1000000000000000。所以,人为规定1000000000000000这个补码编码为-32768。 所以,补码系统中范围是-32768~32767。 因此,实际上,二进制的最小数确实是1111111111111111,只是二进制补码的最小值才是1000000000000000,而补码的1111111111111111是二进制值的-1.
2.由于实型变量是由有限的存储单元组成的,因此能提供的有效数字总是有限的.
类型说明符 |
比特数(字节数) |
有效数字 |
数的范围 |
float |
32(4) |
6~7 |
10-37~1038 |
double |
64(8) |
15~16 |
10-307~10308 |
long double |
128(16) |
18~19 |
10-4931~104932 |
eg:
- main()
- {
- float a;
- double b;
- a=33333.33333;
- b=33333.33333333333333;
- printf("%f\\n%f\\n",a,b);
- //输出结果为a=33333.332031 b=33333.333333
- //float 有效数字最大7位,故2位小数之后为无效数字;大部分编译器规定小数最多保留6位,其余四舍五入
- }
3.每个字符变量被分配一个字节的内存空间,因此只能存放一个字符。字符值是以ASCII码的形式存放在变量的内存单元之中的。
如x的十进制ASCII码是120,y的十进制ASCII码是121。对字符变量a,b赋予\'x\'和\'y\'值:
a='x'; b='y';
实际上是在a,b两个单元内存放120和121的二进制代码:
a:
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
b:
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
4.常用的转义字符及其含义
转义字符 |
转义字符的意义 |
ASCII代码 |
\n |
回车换行 |
10 |
\t |
横向跳到下一制表位置 |
9 |
\b |
退格 |
8 |
\r |
回车 |
13 |
\f |
走纸换页 |
12 |
\\ |
反斜线符"\" |
92 |
\' |
单引号符 |
39 |
\” |
双引号符 |
34 |
\a |
鸣铃 |
7 |
\ddd |
1~3位八进制数所代表的字符 |
|
\xhh |
1~2位十六进制数所代表的字符 |
|
广义地讲,C语言字符集中的任何一个字符均可用转义字符来表示。表中的\ddd和\xhh正是为此而提出的。ddd和hh分别为八进制和十六进制的ASCII代码。如\101表示字母"A" ,\102表示字母"B",\134表示反斜线,\XOA表示换行等。
5.字符串常量和字符常量是不同的量。它们之间主要有以下区别:
1) 字符常量由单引号括起来,字符串常量由双引号括起来。
2) 字符常量只能是单个字符,字符串常量则可以含一个或多个字符。
3) 可以把一个字符常量赋予一个字符变量,但不能把一个字符串常量赋予一个字符变量。在C语言中没有相应的字符串变量。这是与BASIC 语言不同的。但是可以用一个字符数组来存放一个字符串常量。
4) 字符常量占一个字节的内存空间。字符串常量占的内存字节数等于字符串中字节数加1。增加的一个字节中存放字符"\0" (ASCII码为0)。这是字符串结束的标志。
例如:
字符串 "C program" 在内存中所占的字节为:
C |
|
p |
r |
o |
g |
r |
a |
m |
\0 |
字符常量'a'和字符串常量"a"虽然都只有一个字符,但在内存中的情况是不同的。
'a'在内存中占一个字节,可表示为:
a |
"a"在内存中占二个字节,可表示为:
a |
\0 |
6.变量的数据类型是可以转换的。转换的方法有两种,一种是自动转换,一种是强制转换。自动转换发生在不同数据类型的量混合运算时,由编译系统自动完成。
1>.自动转换遵循以下规则:
1) 若参与运算量的类型不同,则先转换成同一类型,然后进行运算。
2) 转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。
3) 所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。
4) char型和short型参与运算时,必须先转换成int型。
5) 在赋值运算中的类型转换
<1>. 浮点型与整型
将浮点数(单双精度)转换为整数时,将舍弃浮点数的小数部分, 只保留整数部分。将整型值赋给浮点型变量,数值不变,只将形式改为浮点形式, 即小数点后带若干个0。注意:赋值时的类型转换实际上是强制的。
<2>. 单、双精度浮点型
由于C语言中的浮点值总是用双精度表示的,所以float 型数据只是在尾部加0延长为double型数据参加运算,然后直接赋值。double型数据转换为float型时,通过截尾数来实现,截断前要进行四舍五入操作。
<3>.long型数据赋给int型变量时将低16位值送给int型变量而将高16位截断舍弃。这里假定int型占两个字节。 将int型数据送给long型变量时其外部值保持不变而内部形式有所改变。
<4>无符号整数 将一个unsigned型数据赋给一个占据同样长度存储单元的整型变量时如unsigned→int、unsigned long→longunsigned short→short原值照赋内部的存储方式不变但外部值却可能改变。
<5>将一个非unsigned整型数据赋给长度相同的unsigned型变量时内部存储形式不变但外部表示时总是无符号的。 例赋值运算符举例/ main unsigned ab int ij a65535 i-1 ja bi printfunsignedu→intdnaj printfintd→unsignedunib 运行结果为 unsigned65535→int-1 int-1→unsigned65535
<6>计算机中数据用补码表示int型量最高位是符号位为1时表示负值为0时表示正值。如果一个无符号数的值小于32768则最高位为0赋给int型变量后、得到正值。如果无符号数大于等于32768则最高位为1赋给整型变量后就得到一个负整数值。反之当一个负整数赋给unsigned型变量时得到的无符号值是一个大于32768的值。
2.>强制转换:(类型说明符)(表达式),其功能是把表达式的运算结果强制转换成类型说明符所表示的类型
在使用强制转换时应注意以下问题:
1) 类型说明符和表达式都必须加括号(单个变量可以不加括号),如把(int)(x+y)写成(int)x+y则成了把x转换成int型之后再与y相加了。
2).无论是强制转换或是自动转换,都只是为了本次运算的需要而对变量的数据长度进行的临时性转换,而不改变数据说明时对该变量定义的类型