《深入 C 语言和程序运行原理》02 程序基石:数据与量值是如何被组织的?(学习笔记)
仅作为本人学习《深入 C 语言和程序运行原理》的学习笔记,原课程链接:极客时间《深入 C 语言和程序运行原理》——于航
仅作为本人学习《深入 C 语言和程序运行原理》的学习笔记,原课程链接:极客时间《深入 C 语言和程序运行原理》——于航
该讲原作者主要讲述的问题是:一个 C 程序的各种语法结构,是如何映射到机器能识别的指令上的。
C语言中的量值与数据
量值可以被粗略分为变量和常量,变量是指在整个程序生命周期中能被多次改变的量;而常量一经定义就无法修改。
变量
变量主要包括三部分信息,即变量对应的名称、所表示的数据的具体类型,以及当前数据值,如下面这个例子,int 为数据类型,x 为变量名称,10 为变量当前值。int x = 10
C 语言提供了很多关键字,可以用来指定变量的类型,这些类型均以字节为单位,表示变量可容纳数据的最大宽度。例如,char
类型的数据占 1 个字节的空间,short
占用 2 个字节空间等等。
除了常见的数据类型关键字外,C90 与 C99 标准还提供了 void
(空类型)、_Bool
(布尔型)、_Complex
(复数类型)等类型的关键字。
这里专门提一下 int
类型,C 语言函数返回值的默认类型就是 int
,C 标准中规定, int
类型的大小为执行环境架构体系所建议的自然大小,之所以这样规定,是因为硬件体系能够以最高效率对这种大小的数据进行处理。正是因为这一点,不同硬件体系,其 C 变量的类型所占字节可能会存在不同。(例如 C51 中,int 类型所占空间为 2 个字节)
常量
在 C 语言中,通过内联方式直接写到源代码中的字面值一般被称为“常量”。比如 char *tmp = "abc";
,这个tmp就是一个常量。常量在定义后就无法被修改,它们在被拷贝并赋值给相应的变量后便结束了使命。
const
修饰的的变量也是常量吗?上面所说的常量是常量表达式,在程序编译时就能被求值,而 const
修饰的只读变量,只有在程序运行时才能知晓它的值。编译器通常不会对只读变量进行内联处理,所以const
变量不符合常量表达式的特征。
数据的存储形式
在编程时,我们能直观地看到变量和常量是如何定义、变化,但程序一旦编译后被运行,数据的变化我们就不得而知。
对于绝大多数计算器来说,其内部使用补码的格式来存放有符号整数,使用直接的二进制位格式来存放无符号整数,使用 IEEE-754 标准编码格式来存放浮点数(小数)。但是,计算机不会自己区分数据的符号性,而是需要通过计算机指令来进行操作。
二进制
无符号整数在计算机中直接用对应的二进制存储,这个很好理解,因为无需考虑符号位,所以有多少个位,就能表示对应大小的整数。
无符号整数常用于表示地址、索引等正整数,它们可以是8位、16位、32位、64位甚至更多。8个二进制表示的正整数其取值范围是0~255(0~28-1),16位二进制位表示的正整数其取值范围是0~65535(0~216-1),32位二进制位表示的正整数其取值范围是0~232-1。
补码
使用补码来存储有符号整数,CPU 在处理有符号数加减运算时,不需要因为符号的不同而采用多个底层加法电路,这样可以减轻电路设计的负担,甚至还能缩小 CPU 的物理尺寸。
原文提到了一些补码的计算,我这里就直接不记录了(暂时不想关心这些😁)。
计算机不会区分数据的符号性,符号性的差异仅由计算机指令如何使用数据而定。比如 C 语言在对某类型变量进行强制类型转换时,其底层的数据并不会发生实质的变化,而仅是程序对如何解读这部分数据的方式发生了变化。比如下面这个例子:
char x = -10;
unsigned char y = (unsigned char)x;
printf("%d\n", y); // 输出值为246
强转后,y的底层数据依然和x相同(都是1111 0110
),只是因为数据类型改变了,所以表示的值也不同。C 语言变量类型的隐式转换也遵循这一规律。
IEEE-754
大多数计算器体系会选择使用 IEEE-754 标准作为浮点数的编码格式,这个标准解决了浮点数在硬件实现上的很多问题,使其更具可移植性。
和整数一样,C 语言在处理浮点数的类型转换时,不会对底层存放的浮点数据进行改动,而只是改变其解释方式。
数据的存储位置
在 C 语言中,定义在不同位置的变量,可以被划分为局部变量和全局变量。如果加上 static
关键字,还可以将变量标记为静态变量,用来延长变量的生命周期,同时可以限定其可见范围为当前文件。通过添加 register
关键字,还可以将变量值存放到寄存器中,以提升其读写性能。
上面提到的不同种类的变量,其存放位置都是各不相同的,
.data 和 .bss 我好像上学时接触过,不过现在不太清楚它们到底指什么,课程原文说后面会介绍,所以这里我也就不展开记录了。

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐
所有评论(0)