第三章总结

3.1

如果程序的输出结果在屏幕上一闪而过

可以在程序中添加一行代码:
getchar();
如果仍然是一闪而过那么就试试再添加一行
getchar();
getchar();
第一行读取换行符(\n)
第二行让程序暂停,等待输入。

getchar()函数用来读取下一个字符,因此程序会等待用户输入。

3.2

不常见的数据类型

  • _Bool 布尔类型 表示true和false,常见为bool
  • _Complex 复数
  • _Imaginary 虚数
    按照计算机存储的方式可以分为两大类:整数类型和浮点数类型

字的定义

  • word 是设计计算机时给定的自然存储单位

整数与浮点数

整数是没有小数部分的数。
![[Pasted image 20230719223913.png]]
浮点数与数学中实数的概念差不多。
![[Pasted image 20230719224010.png]]

  • 7是整数,而7.00是浮点数
  • 浮点数通常只是实际值的近似值。例如,7.0可能被储存为浮点值6.99999
  • 浮点数运算更慢些,

理解浮点数和整数的储存方案不同

计算机把浮点数分成小数部分和指数部分来表示,而且分开储存这两部分。因此,虽然7.00和7在数值上相同,但是它们的储存方式不同。
在十进制下,可以把7.0写成0.7E1。这里,0.7是小数部分,1是指数部分。

3.4

int

  • int类型要占用一个机器字长,早期的机器系统使用16位来存储一个int类型,所以占用2字节;现在大多数个人计算机用32位存储一个int类型,所以占用4字节。
  • 根据系统和机器的不同,int类型占用的存储空间也会不同。
  • 现在,个人计算机产业正逐步向着64位处理器发展,自然能储存更大的整数。
  • ISO C规定int的取值范围最小为-32768~32767。一般而言,系统用一个特殊位的值表示有符号整数的正负号。

注意初始化和赋值的区别

  • 初始化是为变量赋一个初始值
    • 可以在声明中完成
    • 声明为变量创建和标记存储空间,并为其指定初始值
    • ![[Pasted image 20230719225416.png]]
  • 赋值是将一个值或者另一个变量的值赋给变量

printf("%d minus %d is %d\n", ten); // 遗漏2个参数

  • 第1个%d对应ten的值,但是由于没有给后两个%d提供任何值,所以打印出的值是内存中的任意值
    这是一种明显的错误
    但是编译器并不会报错
    printf()函数中的内容称为参数,对应转换说明应该给出三个变量或者内存地址,但是并没有。

你可能会抱怨编译器为何不能捕获这种明显的错误,但实际上问题出在 printf()不寻常的设计。大部分函数都需要指定数目的参数,编译器会检查参数的数目是否正确。但是,printf()函数的参数数目不定,可以有1个、2个、3个或更多,编译器也爱莫能助。记住,使用printf()函数时,要确保转换说明的数量与待打印值的数量相等。

八进制和十六进制

printf("dec = %d; octal = %o; hex = %x\n", x, x, x);
printf("dec = %d; octal = %#o; hex = %#x\n", x, x, x);

dec = 100; octal = 144; hex = 64
dec = 100; octal = 0144; hex = 0x64
  • 0X或0x前缀表示十六进制
  • 0前缀表示八进制

进制与转换说明

  • %d 十进制整形
  • %o 八进制
    • %#0 在显示数值中显示八进制前缀 0
  • %x 十六进制
    • %#x和%#X 在显示数值中显示十六进制 0x和0X

为什么说short类型“可能”比int类型占用的空间少,long类型“可能”比int类型占用的空间多?

因为C语言只规定了short占用的存储空间不能多于int,long占用的存储空间不能少于int。这样规定是为了适应不同的机器。
现在,个人计算机上最常见的设置是,long long占64位,long占32位,short占16位,int占16位或32位(依计算机的自然字长而定)。

int类型那么多,应该如何选择?

首先,考虑unsigned类型。这种类型的数常用于计数,因为计数不用负数。而且,unsigned类型可以表示更大的正数。
如果一个数超出了int类型的取值范围,且在long类型的取值范围内时,使用long类型。然而,对于那些long占用的空间比int大的系统,使用long类型会减慢运算速度。因此,如非必要,请不要使用long类型
另外要注意一点:如果在long类型和int类型占用空间相同的机器上编写代码,当确实需要32位的整数时,应使用long类型而不是int类型,以便把程序移植到16位机后仍然可以正常工作。
类似地,如果确实需要64位的整数,应使用long long类型
如果在int设置为32位的系统中要使用16位的值,应使用short类型以节省存储空间。
使用short类型的另一个原因是,计算机中某些组件使用的硬件寄存器是16位。

long常量和long long常量

八进制和十六进制常量被视为int类型。如果值太大,编译器会尝试使用unsigned int。如果还不够大,编译器会依次使用long、unsigned long、long long和unsigned long long类型。

要把一个较小的常量作为long类型对待,可以在值的末尾加上l(小写的L)或L后缀。使用L后缀更好,因为l看上去和数字1很像。

类似地,在支持long long类型的系统中,也可以使用ll或LL后缀来表示long long类型的值,如3LL。另外,u或U后缀表示unsigned long long,如5ull、10LLU、6LLU或9Ull。

整数溢出

另外,要注意整数的溢出这个很好理解,
当一个变量所占用的内存空间,达到了所能表示的最大值时,会重新从起点开始

  • 注意有符号和无符号类型的起点不同,
    注意,当i超出(溢出)其相应类型所能表示的最大值时,系统并未通知用户。因此,在编程时必须自己注意这类问题。
    溢出行为是未定义的行为,C 标准并未定义有符号类型的溢出规则。

提示 匹配printf()说明符的类型

在使用 printf()函数时,切记检查每个待打印值都有对应的转换说明,还要检查转换说明的类型是否与待打印值的类型相匹配。

使用字符:char类型

  • 从技术层面看,char 是整数类型,因为char 类型存储的是整数而不是字符。
  • 计算机使用数字编码来处理字符,即用特定的整数表示特定的字符。(常用的编码是ASCII编码)
  • 利用字符常量的这种特性,可以定义一个字符常量’FATE’,即把4个独立的8位ASCII码储存在一个32位存储单元中。如果把这样的字符常量赋给char类型变量grade,只有最后8位有效。因此,grade的值是’E’

非打印字符

单引号只适用于字符、数字和标点符号,浏览ASCII表会发现,有些ASCII字符打印不出来。
![[Pasted image 20230720135116.png]]
换页符(\f)把活跃位置移至下一页的开始处;
换行符(\n)把活跃位置移至下一行的开始处;
回车符(\r)把活跃位置移动到当前行的开始处;
水平制表符(\t)将活跃位置移至下一个水平制表点(通常是第1个、第9个、第17个、第25个等字符位置);
垂直制表符(\v)把活跃位置移至下一个垂直制表点。
换页符和垂直制表符在PC屏幕上会生成奇怪的符号,光标并不会移动。只有将其输出到打印机上时才会产生前面描述的效果。

\0oo和\xhh

是对ASCII码的特殊表示,

  • 八进制表示ASCII码
    可以在编码值前面加一个反斜杠(\)并用单引号括起来。
    beep = ‘\7’;

  • 十六进制表示ASCII码
    反斜杠后面跟一个x或X,再加上1~3位十六进制数字。
    Ctrl+P字符的ASCII十六进制码是10(相当于十进制的16),可表示为’\x10’或’\x010’。

整数类型的不同进制形式。

![[Pasted image 20230720135827.png]]

3.4.6 float、double和long double

面向金融和数学的程序经常使用浮点数
![[Pasted image 20230720140307.png]]
第1列是一般记数法;第2列是科学记数法;第3列是指数记数法(或称为e记数法),这是科学记数法在计算机中的写法,e后面的数字代表10的指数。

  • C标准规定,float类型必须至少能表示6位有效数字,且取值范围至少是10-37~10+37。
    • 通常,系统储存一个浮点数要占用32位。其中8位用于表示指数的值和符号,剩下24位用于表示非指数部分(也叫作尾数或有效数)及其符号
  • double类型和float类型的最小取值范围相同,但至少必须能表示10位有效数字。一般情况下,double占用64位而不是32位。一些系统将多出的 32 位全部用来表示非指数部分,这不仅增加了有效数字的位数(即提高了精度),而且还减少了舍入误差。
  • 语言的第3种浮点类型是long double,以满足比double类型更高的精度要求。不过,C只保证long double类型至少与double类型的精度相同。

浮点型常量

-1.56E+12
2.87e-3
  • 正号可以省略。可以没有小数点(如,2E5)或指数部分(如,19.28),但是不能同时省略两者。
  • 可以省略小数部分(如,3.E16)或整数部分(如,.45E-6),但是不能同时省略两者。
    3.14159
    .2
    4e16
    .8E-5

不要在浮点型常量中间加空格:1.56 E+12(错误!)

浮点型常量默认为double类型的,可以在浮点数常量后加上F或者f覆盖默认设置,编译器将时作为float类型。
如2.3f和9.11E9F。
使用l或L后缀使得数字成为long double类型,
如54.3l和4.32L
没有后缀的就是double类型的

用十六进制表示浮点型常量,即在十六进制数前加上十六进制前缀(0x或0X),用p和P分别代替e和E,用2的幂代替10的幂(即,p计数法)。
这应该不重要吧😢

浮点值的上溢和下溢

上溢

当计算导致数字过大,超过当前类型能表达的范围时,就会发生上溢。这种行为在过去是未定义的,不过现在C语言规定,在这种情况下会给变量赋一个表示无穷大的特定值,而且printf()显示该值为inf或infinity(或者具有无穷含义的其他内容)。

下溢

所能表示的最小数字除以一个数,将会把最小数向右偏移,为第一位数字空出位置,在计算过程中损失了精度。
以十进制为例,把一个有4位有效数字的数(如,0.1234E-10)除以10,得到的结果是0.0123E-10。虽然得到了结果,但是在计算过程中却损失了原末尾有效位上的数字。这种情况叫作下溢(underflow)。

如果除以一个非常大的值,会导致所有的位都为0。

NaN(not a number)

给asin()函数传递一个值,该函数将返回一个角度,该角度的正弦就是传入函数的值。但是正弦值不能大于1,因此,如果传入的参数大于1,该函数的行为是未定义的。在这种情况下,该函数将返回NaN值,printf()函数可将其显示为nan、NaN或其他类似的内容。

3.7

printf()何时把输出发送到屏幕上?

刷新输出
最初,printf()语句把输出发送到一个叫作缓冲区(buffer)的中间存储区域,然后缓冲区中的内容再不断被发送到屏幕上。

C 标准明确规定了何时把缓冲区中的内容发送到屏幕:

  • 当缓冲区满
  • 遇到换行字符或需要输入的时候(从缓冲区把数据发送到屏幕或文件被称为刷新缓冲区)

printf()函数和scanf()函数中的类型与转换说明

  • 浮点型 float %f
    • %.2f 精确控制输出两位小数
    • %e和%E 显示打印结果为指数计数法的浮点数
    • %a和%A 显示打印结果为十六进制格式的浮点数
  • 整形 int %d
    • unsigned int %u
    • %d指明了在一行中打印整数的位置。%d称为转换说明,它指定了printf()应使用什么格式来显示一个值。
    • %d 十进制
  • 长整形 long %ld
    • 如果系统中int和long的大小相同,使用%d就行。
    • 在x和o前面可以使用l前缀,%lx表示以十六进制格式打印long类型整数,%lo表示以八进制格式打印long类型整数。
    • 注意,虽然C允许使用大写或小写的常量后缀,但是在转换说明中只能用小写。
    • %lu unsigned long 类型
  • short %h
    • %hd 以十进制显示short类型的值
    • %ho 以八进制显示short类型的值
    • %hx 以十六进制显示short类型的值
    • %hu unsigned short类型
  • C99和C11提供%zd转换说明匹配sizeof的返回类型:
  • %zd同样适用于strlen()函数
  • 注意如果系统不支持%zd,可使用%u或者%lu代替%zd。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值