C语言程序设计CAP——C语言学习笔记(八)上

8.1   数据类型

C是有类型的语⾔

• C语⾔的变量,必须: 

  • 在使⽤前定义,并且

  • 确定类型

• C以后的语⾔向两个⽅向发展:

  • C++/Java更强调类型,对类型的检查更严格

  • JavaScript、Python、PHP不看重类型,甚⾄不需 要事先定义

类型安全

• ⽀持强类型的观点认为明确的类型有助于尽早发现程 序中的简单错误

• 反对强类型的观点认为过于强调类型迫使程序员⾯对 底层、实现⽽⾮事务逻辑

• 总的来说,早期语⾔强调类型,⾯向底层的语⾔强调 类型

• C语⾔需要类型,但是对类型的安全检查并不⾜够

C语⾔的类型

• 整数

   • char、short、int、long、long long

• 浮点数

   • float、double、long double

• 逻辑

   • bool

• 指针

• ⾃定义类型

ps:蓝⾊的是C99的类型

类型有何不同

• 类型名称:int、long、double

• 输⼊输出时的格式化:%d、%ld、%lf

• 所表达的数的范围:char < short < int < float < double

• 内存中所占据的⼤⼩:1个字节到16个字节

• 内存中的表达形式:⼆进制数(补码)、编码

sizeof

• 是⼀个运算符,给出某个类型或变量在内存中所占据 的字节数

• sizeof(int)

• sizeof(i)

sizeof

• 是静态运算符,它的结果在编译时刻就决定了

• 不要在sizeof的括号⾥做运算,这些运算不会做的

整数

整数

• char

• short

• int

• long

• long long

整数

• char:1字节(8⽐特)

• short:2字节

• int:取决于编译器(CPU),通常的意义是“1个字”

• long:取决于编译器(CPU),通常的意义是“1个字”

• long long:8字节

*整数的内部表达

计算机内部⼀切都是⼆进制

• 18 —> 00010010

• 0 —> 00000000 • -18 —> ?

*如何表⽰负数

• ⼗进制⽤“-”来表⽰负数,在做计算的时候

   • 加减是做相反的运算

   • 乘除时当作正数,计算完毕后对结果的符号取反

*⼆进制负数

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

   • 00000000 — 11111111 (0-255)

• 三种⽅案:

   1. 仿照⼗进制,有⼀个特殊的标志表⽰负数

   2. 取中间的数为0,如1000000表⽰0,⽐它⼩的是 负数,⽐它⼤的是正数

   3. 补码

*补码

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

   • 0 —> 00000000

   • 1 —> 00000001

   • 11111111 + 00000001 —> 100000000

• 因为0 - 1 —> -1,所以,-1 =

   • (1)00000000 - 00000001 —> 11111111

   • 11111111被当作纯⼆进制看待时,是255,被当作补码看待时是 -1

• 同理,对于-a,其补码就是0-a,实际是2n - a,n是这种类型的位数

ps:补码的意义就是拿补码和原码可以加出⼀个溢出的“零”

数的范围

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

   • 00000000 - 11111111

• 其中

   • 00000000 —> 0

   • 11111111 ~ 10000000 —> -1 ~ -128

   • 00000001 ~ 01111111 —> 1 ~ 127

整数的范围

• char:1字节:-128 ~ 127

• short:2字节:-32768 ~ 32767

• int:取决于编译器(CPU),通常的意义是“1个字”

• long:4字节

• long long:8字节

unsigned

• 在整形类型前加上unsigned使得它们成为⽆符号的整 数

• 内部的⼆进制表达没变,变的是如何看待它们

   • 如何输出

• 11111111

   • 对于char,是-1

   • 对于unsigned char,是255

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进制只是如何把数字表达为字符串,与内 部如何表达数字⽆关

*8进制和16进制

• 16进制很适合表达⼆进制数据,因为4位⼆进制正好 是⼀个16进制位

   • 8进制的⼀位数字正好表达3位⼆进制

• 因为早期计算机的字⻓是12的倍数,⽽⾮8

选择整数类型

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

   • 为了准确表达内存,做底层程序的需要

• 没有特殊需要,就选择int

   • 现在的CPU的字⻓普遍是32位或64位,⼀次内存读写就是 ⼀个int,⼀次计算也是⼀个int,选择更短的类型不会更 快,甚⾄可能更慢

   • *现代的编译器⼀般会设计内存对⻬,所以更短的类型实 际在内存中有可能也占据⼀个int的⼤⼩(虽然sizeof告诉 你更⼩)

• unsigned与否只是输出的不同,内部计算是⼀样的

浮点数

浮点类型

浮点的输⼊输出

科学计数法

输出精度

• 在%和f之间加上.n可以指定输出⼩数点后⼏位,这样 的输出是做4舍5⼊的

   • printf("%.3f\n", -0.0049);

   • printf("%.30f\n", -0.0049);

   • printf("%.3f\n", -0.00049);

超过范围的浮点数

• printf输出inf表⽰超过范围的浮点数:±∞

• printf输出nan表⽰不存在的浮点数

浮点运算的精度

*浮点数的内部表达

• 浮点数在计算时是由专⽤的硬件部件实现的

• 计算double和float所⽤的部件是⼀样的

选择浮点类型

• 如果没有特殊需要,只使⽤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'

   • printf("%i %c\n", c,c );

• ⼀个49各⾃表述!

混合输⼊

• 有何不同?

   • scanf("%d %c", &i, &c);

   • scanf("%d%c", &i, &c);

字符计算

 • ⼀个字符加⼀个数字得到ASCII码表中那个数之后的 字符

• 两个字符的减,得到它们在表中的距离

⼤⼩写转换

• 字⺟在ASCII表中是顺序排列的

• ⼤写字⺟和⼩写字⺟是分开排列的,并不在⼀起

 • ‘a’-‘A’可以得到两段之间的距离,于是

   • a+’a’-‘A”可以把⼀个⼤写字⺟变成⼩写字⺟,⽽

   • a+’A’-‘a’可以把⼀个⼩写字⺟变成⼤写字⺟

逃逸字符

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

逃逸字符 

回⻋换⾏

• 源⾃打字机的动作 

制表位

 • 每⾏的固定位置

• ⼀个\t使得输出从下⼀个制表位开始

• ⽤\t才能使得上下两⾏对⻬

逻辑类型

bool

• #include

• 之后就可以使⽤bool和true、false

bool的运算

• bool实际上还是以int的⼿段实现的,所以 可以当作int来计算

• 也只能当作int来输⼊输出

类型转换

类型转换⾃动类型转换

• 当运算符的两边出现不⼀致的类型时,会⾃动转换成 较⼤的类型

• ⼤的意思是能表达的数的范围更⼤

• char —> short —> int —> long —> long long

• int —> float —> double

⾃动类型转换

 • 对于printf,任何⼩于int的类型会被转换成int;float会 被转换成double

• 但是scanf不会,要输⼊short,需要%hd

强制类型转换

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

   • (类型)值

• ⽐如:

   • (int)10.2

   • (short)32

• 注意这时候的安全性,⼩的变量不总能表达⼤的量

   • (short)32768

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

强制类型转换

 • 强制类型转换的优先级⾼于四则运算

 思考:

你的计算机上的类型大小

用sizeof探求一下你的计算机上的各种整数的大小吧。把你的计算机的配置、操作系统的版本、编译软件的版本都曝光一下吧。

 整数的类型转换是怎么做的?

char大小是1字节,也就是8位,32768的二进制表示是1000000000000000,系统会只查看最后8位,因此得00000000,相当于将32768%256,得到的余数就是转换后的结果。如果用32769那么就会得到1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值