数据类型

C是有类型的语言

  • C语言的变量,必须:

    • 在使用前定义,并且 确定类型
  • C以后的语言向两个方向发展:

    • C++/Java更强调类型,对类型的检查更严格
    • JavaScript、Python、PHP不看重类型,甚至不需 要事先定义

类型安全

  • 支持强类型的观点认为明确的类型有助于尽早发现程| 序中的简单错误
  • 反对强类型的观点认为过于强调类型迫使程序员面对 底层、实现而非事务逻辑
  • 总的来说,早期语言强调类型,面向底层的语言强调 类型
  • C语言需要类型,但是对类型的安全检查并不足够

c语言类型

  • 整数 •・char、short、int、long、long long
  • 浮点数 • float、double、long double
  • 逻辑 bool
  • 指针
  • 自定义类型

类型有何不同

  • 类型名称:int、long、double
  • 输入输出时的格式化:%d、%ld、%lf
  • 所表达的数的范围:char < short < int < float < double
  • 内存中所占据的大小:1个字节到16个字节
  • 内存中的表达形式:二进制数(补码)、编码

sizeof

  • 是一个运算符,给出某个类型或变量在内存中所占据 的字节数|
  • sizeof(int)
  • sizeof(i)
  • 是静态运算符,它的结果在编译时刻就决定了
  • 不要在sizeof的括号里做运算,这些运算不会做的

整数

  • char:1字节(8比特) •
  • short:2字节 •
  • int:取决于编译器(CPU),通常的意义是“1个字”
  • long:取决于编译器(CPU),通常的意义是“1个字”
  • long long:8字节

二进制负数

  • 1个字节可以表达的数:

    • 00000000 — 11111111 (0-255)
  • 三种方案:

    1. 仿照十进制,有一个特殊的标志表示负数
    2. 取中间的数为0,如1000000表示0,比它小的是 负数,比它大的是正数
    3. 补码

补码

  • 考虑-1,我们希望-1+ 1 —> 0。如何能做到?

    • O—> 00000000 •
    • 1—> 00000001 • 11111111 + 00000001 —> 100000000
  • 因为0-1 —>-1,所以,-1 =

    • (1)00000000,- 00000001 —>11111111
    • 11111111被当作纯二进制看待时,是255,被当作补码看待时是 •同理,对于-a,其补码就是0-a,实际是2"-a,n是这种类型的位数
  • 同理,对于-a,其补码就是0-a,实际是2"-a,n是这种类型的位数

补码的意义就是拿补码和原码可以出一个溢出的“零”

数的范围

  • 对于一个字节(8位),可以表达的是:

    • 0000000- 11111111
  • 其中

    • 00000000 —>0
    • 11111111~ 10000000 —>-1~-128
    • 00000001~ 01111111—> 1~ 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进制只是如何把数字表达为字符串,与内部如何表达数字无关
  • 16进制很适合表达二进制数据,因为4位二进制正好 是一个16进制位
  • 8进制的一位数字正好表达3位二进制

    • 因为早期计算机的字长是12的倍数,而非8

选择整数的类型

  • 为什么整数要有那么多种?

    • 为了准确表达内存,做底层程序的需要
  • 没有特殊需要,就选择int

    • 现在的CPU的字长普遍是32位或64位,一次内存读写就是 一个int,一次计算也是一个int,选择更短的类型不会更 快,甚至可能更慢
    • 现代的编译器一般会设计内存对齐,所以更短的类型实 际在内存中有可能也占据一个int的大小(虽然sizeof告诉 你更小)
  • unsigned与否只是输出的不同,内部计算是一样的

浮点类型

浮点的输入输出

科学计数法

浮点数的范围和精度

输出精度

  • 在%和f之间加上.n可以指定输出小数点后几位,这样 的输出是做4舍5人的 •
  • printf("%.3fin",-0.0049);
  • printf("%.30fn",-0.0049);
  • printf("%.3fin",-0.00049);

超过范围的浮点数

  • printf输出inf表示超过范围的浮点数:±0
  • printf输出nan表示不存在的浮点数

浮点运算的精度

浮点数的内部表达

选择浮点类型

  • 如果没有特殊需要,只使用double
  • 现代CPU能直接对double做硬件运算,性能不会比 float差,在64位的机器上,数据存储的速度也不比 float慢

字符类型

  • char是一种整数,也是一种特殊的类型:字符。这是 因为:

    • 用单引号表示的字符字面量:'a','1'
    • ‘ ’也是一个字符
    • printf和scanf里用%c来输入输出字符

字符的输入输出

  • 如何输入'1'这个字符给char c?

    • scanf("%c",&c);—>1
    • scanf("%d",&i); c=i;—->49
  • ‘1'的ASCII编码是49,所以当c==49时,它代表‘1’

大小写转换

  • 字母在ASCII表中是顺序排列的
  • 大写字母和小写字母是分开排列的,并不在一起
  • 'a’-'A’可以得到两段之间的距离,于是

    • a+'a-'A”可以把一个大写字母变成小写字母,而
    • a+'A-'a'可以把| 个小写字母变成大写字母

逃逸字符

  • 用来表达无法印出来的控制字符或特殊字 符,它由一个反斜杠“\”开头,后面跟上另 一个字符,这两个字符合起来,组成了一 个字符

printf("请分别输入身高的英尺和英寸,” "如输入\"5 7\"表示5英尺7英寸:");

制表位

  • 每行的固定位置
  • 一个\t使得输出从下一个制表位开始
  • 用\t才能使得上下两行对齐

类型转换

自动类型转换

  • 当运算符的两边出现不一致的类型时,会自动转换成 较大的类型

    • 大的意思是能表达的数的范围更大
    • char—> short —>int —> long —> long long
    • int —> float —> double
  • 对于printf,任何小于int的类型会被转换成int;float会 被转换成double
  • 但是scanf不会,要输入short,需要%hd

强制类型转换

  • 要把一个量强制转换成另一个类型(通常是较小的类 型),需要:

    • (类型)值
  • 比如:

    • (int)10.2
    • (short)32
  • 注意这时候的安全性,小的变量不总能表达大的量

    • (short)32768

只是从那个变量计算出了一个新的类型 的值,它并不改变那不变量,无论是值 还是类型都不改变

逻辑类型

bool

  • include <stdbool.h>
  • 之后就可以使用bool和true、false

逻辑运算

  • 逻辑运算是对逻辑量进行的运算,结果只 有0或1
  • 逻辑量是关系运算或逻辑运算的结果

注意

优先级

短路

  • 逻辑运算是自左向右进行的,如果左边的结果已经能 够决定结果了,就不会做右边的计算
  • a==6 && b==1
  • a==6&& b+=1
  • 对于&&,左边是false时就不做右边了
  • 对于l,左边是true时就不做右边了

不要把赋值,包括复合赋值组合进表达式!

条件运算符与逗号运算

条件运算符

  • count =(count>20)?count -10 :count +10;
  • 条件、条件满足时的值和条件不满足时的值
if ( count >20) 
  count= count-10; 
else 
  count = count+10;

优先级

  • 条件运算符的优先级高于赋值运算符,但是低于其他运算符

    • m<n? x : a+5
    • a++>= 1 && b--> 2 ? a : b
    • x=3 * a > 5? 5 : 20

嵌套条件表达式

  • count =(count> 20)?(cout < 50)? count - 10:count - 5 :(count < 10)? count + 10: count + 5;
  • 条件运算符是自右向左结合的 •x<x?×+w:x<y?×:Y

我们不希望你使用嵌套的条件表达式

逗号运算符

  • 逗号用来连接两个表达式,并以其右边的 表达式的值作为它的结果。逗号的优先级 是所有的运算符中最低的,所以它两边的 表达式会先计算;逗号的组合关系是自左 向右,所以左边的表达式会先计算,而右 边的表达式的值就留下来作为逗号运算的 结果。
  • 在for中使用, for (i=0,j=10;i<j;i++,j--)…....

参考资料

程序设计入门——C语言\_浙江大学\_中国大学MOOC(慕课) (icourse163.org)

最后修改:2023 年 10 月 21 日
如果觉得我的文章对你有用,请随意赞赏