目录
(1) 类型安全
(2)C语言的类型
(3) 类型有何不同
1)sizeof
2 整数
(1)整数的内部表达
1)如何表示负数
(2)数的范围
1)unsigned
2)整数越界
(3) 整数的输入输出
1)8进制和16进制
(4)选择整数类型
3 浮点数
(1)浮点类型
1)科学计数法
2)输出精度
(2)浮点的范围与精度
1) 超过范围的浮点数
(3)浮点运算的精度
(4)浮点数的内部表达
1)选择浮点类型
4 字符
(1)字符类型
(2)字符的输入输出
1)混合输入
(3)字符计算
1)大小写的转换
(4)逃逸字符
5 类型转换
(1)自动类型转换
(2)强制类型转换
1 c语言是有类型的语言
- C语言的变量必须在使用前定义,并且确定类型。
- C语言以后的语言向两个方向发展
- c++/java更强调类型,对类型的检查更严格
- JavaScript、Python、PHP不看重类型,甚至不需要事先定义
类型安全
- 支持强类型的观点认为明确的类型有助于尽早发现程序中的简单错误
- 反对强类型的观点认为过于强调类型迫使程序员面对底层、实现而非事务逻辑
- 总的来说,早期语言强调类型,面向底层的语言强调类型
- C语言需要类型,但是对于类型的安全检查并不足够
C语言的类型
- 整数
- char、short、int、long、longlong、
- 浮点数
- float、double、longdouble
- 逻辑
- bool
- 指针
- 自定义类型
类型有何不同
- 类型名称:int、long、double
- 输入输出时的格式化:%d、%ld、%lf
- 所表达的数的范围:char<short<int<fioat<double
- 内存中所占据的大小:1~16字节
- 内存中的表达形式:二进制(补码)、编码
sizeof
- 是一个运算符,给出某个类型或变量在内存中所占据的字节数
- sizeof()
- 可以用来了解各个变量所占内存大小 ()内放入变量类型
- 是静态运算符,它的结果在编译时刻就决定了
- 不要在sizeof的括号里做运算,这些运算不会做
整数
- char:1字节
- short:2字节
- int:取决于编译器(cpu),通常的意义是“一个字”
- long:取决于编译器(cpu),通常的意义是“一个字”
- longlong:8个字节
整数的内部表达
- 计算机内部的一切都是二进制
- 18--->00010010
- 0--->00000000
- -18--->?
如何表示负数
-
十进制用“-”来表示负数,在做计算的时候
二进制负数----补码
- 考虑-1,我们希望-1+1--->0.如何能做到?
- 0--->00000000
- 1--->00000001
- 11111111+00000001--->(1)00000000
- 因为0-1--->-1,所以,-1=
- (1)00000000-00000001--->11111111
- 11111111被当做纯二进制看待是255,被当做补码看待时为-1
- 同理,对于-a,其补码就是0-a,实际是2的n次方减a,n是这中类型的位数
补码的意义在于拿补码和原码可以加出一个溢出的“零”
数的范围
- 对于一个字节(8位),可以表达的是:
- 00000000-11111111
- 其中
- 00000000--->0
- 11111111~10000000--->-1~-128
- 00000001~01111111--->1~127
unsigned
- 如果一个字面量常数想要表达自己是unsigned,可以在后面加u或U
- 255U
- 用l或L表示long(long)
- *unsigned的初衷并非扩展数能表达的范围,而是为了做纯二进制运算,主要是为了移位
整数越界
- 整数是以纯二进制方式运算的,所以:
- 11111111+1--->100000000--->0
- 01111111+1--->10000000--->-128
- 10000000-1--->01111111--->127
整数的输入输出
- 只有两种形式:int或long long
- %d:int
- %u:unsigned
- %ld:long long
- %lu:unsigned long long
8进制和16进制
- 一个以0开始的数字字面量是8进制
- 一个以0x开始的数字字面量是16进制
- %o用于8进制的输出,%x用于16进制的输出
- 8进制和16进制只是如何把数字表达为字符串,与内部如何表达数字无关
选择整数类型
- 为什么整数要有那么多种?
- 为了准确表达内存,做底层程序需要
- 没有特殊要求,就选择int
- 现在的cpu的字长普遍是32位或64位,一次内存读写就是一个int,一次计算也是一个int,选择更短的类型不会更快,甚至可能更慢
- *现代的编译器一般会设计内存对齐,所以更短的类型实际在内存中有可能也占据一个int的大小
- unsigned与否只是输出的不同,内部计算是一样的
浮点数
浮点类型
类型 | 字长 | 范围 | 有效数字 |
---|---|---|---|
float | 32 | +-(1.2*10^-38~3.40*10^38),0,+-inf,nan | 7 |
double | 64 | +-(2.2*10^-308~1.79*10^308),0,A+-inf,nan | 15 |
无论是float还是double,它们的范围都不能包含无限趋近于0的值
科学计数法
-8.67E+12
- 数字前可用+-号表示数的正负
- eE大小写都可以
- 小数点也可选
- 中间的正负号也是可以选择的(+可以省略)
- 整个数字中间不能有空格
- 中间的+-号后表示的为指数如eg中的12代表的10的12次方
- %e为科学计数法的输出方式
输出精度
- 在%和f之间加上.n可以指定输出小数点后几位,这样的输出是做四舍五入的。
- printf("%.3f\n",-0.0049)——输出结果-0.005
- printf("%.3f\n",-0.00049)——输出结果-0.000
浮点的范围与精度
超过范围的浮点数
- printf输出inf表示超过范围的浮点数:+-无穷
- printf输出nan表示不存在的浮点数
浮点运算的精度
- 计算机中的浮点数精度不是特别高
- a=1.345f
- b=1.123f
- c=2.468
- 在计算机当中c!==a+b
- 带小数点的字面量是double而非float
- float需要用f或F后缀来表明身份
- 在判断两个浮点数是否相等 f1==f2可能失败 应利用fabs(f1-f2)<le-12
浮点数的内部表达
- 浮点数的计算时是由专用的硬件部件实现的
- 计算double和float所用的部件是一样的
选择浮点类型
- 如果没有特殊需要,只使用double
- 现代cpu能直接对double做硬件计算,性能不会比float差,在64位的机器上,数据储存的速度也不比float慢
字符
字符类型
- char是一种整数,也是一种特殊类型:字符。这是因为:
- 用单引号表示的字符字面常量:'a','1'
- "也是一个字符
- printf和scanf里用%o来输入输出字符
字符的输入输出
- 如何输出'1'这个字符给char c
- scanf("%c",&c);——>1
- scanf ("%d",&i);c=i;——>49
- '1'的ascll编码是49,所以当c==49时,它代表'1'
- printf("%i%c\n"c,c);
混合输入
- scanf(“”%d %c“,&i,&c”);
- 其中的空格不可以省略
- %d后的空格表示读入数字的话会把后面的空格也读完
字符计算
-
一个字符加一个数字得到ascll码表中那个数之后的字符
-
两个字符的减,得到他们在表中的距离
大小写的转换
- 字母在ascll表中是顺序排列的
- 大写字母和小写字母是分开排列的,并不在一起
- 'a'-'A'可以得到两段之间的距离,于是
- A+'a'-'A'可以把一个大写字母变成小写字母
- a+'A'-'a'可以把一个小写字母变成大写字母
逃逸字符
- 用来表达无法印出来的控制字符或特殊字符,它由一个反斜杠“\”开头,后面跟上另一个字符,这两个字符合起来,组成了一个字符
字符 | 意义 | 字符 | 意义 |
\b | 回退一格 | \" | 双引号 |
\t | 到下一个表格位 | \' | 单引号 |
\n | 换行 | \\ | 反斜杠本身 |
\r | 回车 |
类型转换
自动类型转换
- 当运算符的两边出现不一致的类型时,会自动转换成较大的类型
- 大的意思是能表达的数的范围更大
- char—>short—>int—>long—>long long
- int—>float—>double
- 对于printf,任何小于int的类型会被转换成int;float会被转换成double
- 但是scanf不会,要输入short,需要%hd。
强制类型转换
- 要把一个量强制转换成另一个类型(通常是较小的类型)
- 比如:
- (int)10.2
- (short)32
- 注意这时的安全性,小的变量不总能表达大的量
- (short)32768——这个就不能正确表示
- 强制类型转换只是从那个变量计算出了一个新的类型的值,它并不改变那个变量,无论是值还是类型都不改变
- 强制类型转换的优先级高于四则运算