Snowming04's Blog
一颗红❤
Toggle navigation
Snowming04's Blog
主页
Cobalt Strike
Accelerated C++
区块链安全
友链
关于我
常用工具
代码积累
归档
标签
【C基础】课时2:进制转换、命名规范、内存区域划分、向0取整、浮点数(二进制表示,在内存中的存储)
? C ?
2020-03-06 15:35:39
269
0
0
snowming
? C ?
# 第3章:数据和C **<u>本章要点</u>** - 关键字:`int`、`short`、`long`、`unsigned`、`char`、`float`、`double`、`_Bool`、`_Complex`、`_Imaginary` - 运算符:sizeof() - 函数:scanf() - 整数类型和浮点数类型的区别 - 如何书写整型和浮点型常数,如何声明这些类型的变量 - 如何使用`printf()`和`scanf()`函数读写不同类型的值 **<u>%.2f</u>** `%.2f`中的`%.2`用于精准控制输出,指定输出的浮点数只显示小数点后面两位。 **<u>scanf()</u>** - `scanf()`函数用于读取键盘的输入。`%f`说明`scanf()`要读取用户从键盘输入的浮点数,`&weight`告诉`scanf()`把输入的值赋给名为weight的变量。`scanf()`函数使用`&`符号表明找到weight变量的地点。 - `scanf()`函数读取用户从键盘输入的数据,并把数据传递给程序;`printf()`函数读取程序中的数据,并把数据显示在屏幕上。把两个函数结合起来,就可以建立人机双向通信。 **<u>浮点数</u>** - 在一个值后面加上一个小数点,该值就成为一个浮点数。比如7是整数,7.00是浮点数。 - e计数法:3.16E7表示3.16*10^7。 - 浮点数和整数的储存方案不同。计算机把浮点数分为小数部分和指数部分来表示,而且要分开储存这两部分。比如在十进制下,可以把7.0写成0.7E1,这里0.7是小数部分,1是指数部分。当然,在计算机内部使用二进制和2的幂进行储存,而不是10的幂。 - <u>C语言不把含小数点和指数的数作为整数。因此22和-44都是整型常量,但是22.0和2.2E1则不是。</u> **<u>八进制和十六进制</u>** 计算机如何知道一个数是十进制、十六进制还是二进制?比如10000。在C语言中,用特定的前缀表示使用哪种进制。 - `0x`或`0X`前缀表示十六进制。所以十进制数16表示成十六进制是`0x10`或者`0X10`。 - `0`前缀表示八进制。例如,十进制数16表示成八进制是`020`(2*8^1)。 - <u>要清楚,使用不同的进制数是为了方便,不会影响数被储存的方式。也就是说,无论把数字写成16、020或者0x10,储存该数的方式都相同,因为计算机内部都以二进制进行编码。</u> **<u>显示八进制和十六进制</u>** 不同的进制要使用不同的转换说明。 - 以十进制显示数字,使用`%d`。 - 以八进制显示数字,使用`%o`。 - 以十六进制显示数字,使用`%x`。 - 要显示各进制数的前缀`0`、`0x`和`0X`,必须分别使用`%#o`(小写o表示八进制,不是0)、`%#x`、`%#X`。 - 虽然C允许使用大写或小写的常量后缀(比如`L`),但是在转换说明中只能用小写。 **<u>char类型</u>** 标准ASCII码的范围是0~127,只需7位二进制数即可表示。通常,char类型被定义为8位的存储单元,因此容纳标准ASCII码绰绰有余。 C语言把1字节定义为char类型占用的位(bit)数,因此无论是16还是32位系统,都可以使用char类型。 - 字符常量用单引号。 - 字符串用双引号。 **<u>非打印字符</u>** 如果要使用ASCII码,为何要写成`\032`而不是`032`?首先,`\032`能更清晰地表达程序员使用字符编码的意图。其次,类似`\032`这样的转义序列可以嵌入C的字符串中,如 ``` printf("Hello!\007\n"); ``` 中就嵌入了`\007`。 **<u>&符号</u>** ``` scanf("%c",&ch); ``` - scanf()函数会读取用户输入的字符,`&`符号表示把输入的字符赋给变量`ch`。 - printf()函数中的转换说明(就是%xx)决定了数据的显示方式,而不是数据的储存方式。 **<u>有符号还是无符号</u>** - 有些C编译器把char实现为有符号类型,这意味着char可表示的范围是`-128~127`。 >因为保留一位为符号位,char本身8bit。那么就是2^7=128,整数里面带了一个0。 - 有些C编译器把char实现为无符号类型,那么char可表示的范围是`0~255`。 >也就是一共2^8=256个数。 - 根据C90标准,C语言允许在关键字char前面使用`signed`或`unsigned`。这样,无论编译器默认char是什么类型,`signed char`表示有符号类型,而`unsigned char`表示无符号类型。这在char类型处理小整数时很有用。 **<u>_Bool类型</u>** - C99标准添加了_Bool类型,用于表示布尔值。 - 1表示true,0表示false。 - 所以_Bool类型实际上也是一种整数类型。但原则上它仅占用1位存储空间,因为对0和1而言,1位的存储空间足够了。 - 程序通过布尔值可选择执行哪部分代码。 **<u>float、double和long double</u>** - 浮点数的表示使用指数计数法。该计数系统常用于表示非常大或非常小的数。 |数字|指数计数法| |:--:|:--:| |1000000000|1.0e9| |123000|1.23e5| |322.56|3.2256e2| |0.000056|5.6e-5| - 通常,系统储存一个浮点数要占用32位。其中8位用于表示指数的值和符号,剩下24位用于表示非指数部分(也叫作尾数或有效数)及其符号。 - double(双精度)类型和float类型的最小取值范围相同,但至少必须能表示10位有效数字。一般情况下,double占用64位而不是32位。 **<u>浮点型常量</u>** 在代码中,可以用多种形式书写浮点型常量。浮点型常量的基本形式是: <u>有符号的数字(包括小数点),后面紧跟e或E,最后是一个有符号数表示10的指数。</u> 如: - -1.56E+12 - 2.87e-3 - 注:正号可以省略 可以没有小数点(如,`2E5`)或指数部分(如,`19.28`),但是不能同时省略两者。 可以省略小数部分(如,`3.E16`)或整数部分(如,`.45E-6`),但是不能同时省略两者。 下面是更多的有效浮点型常量示例: - 3.14159 - .2 - 4e16 - .8E-5 - 100. **<u>用十六进制表示浮点型常量</u>** C99标准添加了一种新的浮点型常量格式——用十六进制表示浮点型,即在十六进制数前加上十六进制前缀(0x或0X),用p和P分别代表e和E,用2的幂代替10的幂(即,p计数法)。如下所示: 0xa.1fp10 十六进制a等于十进制10,`.1f`是1/16加上15/256,p10是2^10或1024。0xa.1fp10表示的值是(10+1/16+15/256)*1024,即十进制数10364.0。 注意,并非所有的编译器都支持C99的这一特性。 **<u>浮点数的上溢和下溢</u>** -------------- **<u>类型大小</u>** 如何知道当前系统的指定类型的大小是多少? > Win10 64位  sizeof是C语言的内置运算符,以字节为单位给出指定类型的大小。C99和C11提供`%zd`转换说明匹配sizeof的的返回类型。一些不支持C99和C11的编译器可用`%u`或`%lu`代替`%zd`。 **<u>使用数据类型</u>** 把一个类型的数值初始化给不同类型的变量时,编译器会把值转换成<u>与变量匹配</u>的类型,这将导致部分数据丢失。例如,下面的初始化: ``` int cost = 12.99; //用double类型的值初始化int类型的变量 float pi = 3.1415926536; //用double类型的值初始化float类型的变量 ``` - 第1个声明,cost的值是12。C编译器把浮点数转换成整数时,会直接截断小数部分,<u>而不进行四舍五入</u>。 - 第2个声明会损失一些精度,因为C只保证了float类型前6位的精度。 许多程序员和公司内部都有系统化的命名约定,在变量名中体现其类型。例如,用`i_`前缀表示int类型,`us_`前缀表示unsigned short类型。这样,一眼就能看出来i_smart是int类型的变量,us_versmart是unsigned short类型的变量。 **<u>参数和陷阱</u>** ``` float f = 7.0f; float g = 8.0f; printf("%d %d\n",f,g); /*值的类型不匹配*/ ``` 输出示例: ``` 1606414344 1 或 0 1075576832 ``` 注意,用%d显示float类型的值,其值不会被转换成int类型。在不同的平台下,缺少参数或参数类型不匹配导致的结果不同。 **<u>转义序列示例</u>**  注:图中应该是`int main(void)`而不是`void main(void)`,笔误。 **<u>刷新输出</u>** printf()何时把输出发送到屏幕上?最初,printf()语句把输出发送到一个叫作缓冲区(buffer)的中间存储区域,然后缓冲区中的内容再不断被发送到屏幕上。 C标准明确规定了何时把缓冲区中的内容发送到屏幕: - 当缓冲区满、遇到换行字符或需要输入的时候(从缓冲区把数据发送到屏幕或文件被称为刷新缓冲区) 例如,上图中前两个printf()语句既没有填满缓冲区,也没有换行符,但是下一条scanf()语句要求用户输入,这迫使printf()的输出被发送到屏幕上。 旧式编译器遇到scanf()也不会刷新缓冲区,程序会停在那里不显示任何提示内容,等待用户输入数据。在这种情况下,可以使用换行字符刷新缓冲区。代码应改为: ``` printf("Enter your desired monthly salary:\n"); scanf_s("%f",&salary); ``` 无论接下来的输入是否能刷新缓冲区,代码都会正常运行。这将导致光标移至下一行起始处,用户无法在提示内容同一行输入数据。还有一种刷新缓冲区的方法是使用`fflush()`函数。
上一篇:
【C基础】课时3:字符串和格式化输入/输出
下一篇:
【C基础】课时1:变量、四则运算
0
赞
269 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
提交评论
立即登录
, 发表评论.
没有帐号?
立即注册
0
条评论
More...
文档导航
没有帐号? 立即注册