梦开始的地方——C语言中那些细节
Posted 爱敲代码的三毛
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了梦开始的地方——C语言中那些细节相关的知识,希望对你有一定的参考价值。
文章目录
static关键字
1.static修饰局部变量
- 生命周期延长:该变量不随函数结束而结束,变成了全局变量的生命周期
- 初始化:只在第一次调用该函数时进行初始化(函数中局部变量)
- 记忆性:后序调用时,该变量使用前一次函数调用完成之后保存的值
- 存储位置:不会存储在栈上,放在数据段
- 修饰变量时,没有被初始化时会被自动初始化为0
来看下面这段代码
#include <stdio.h>
void prt()
static int a = 0;
a++;
printf("%d ", a);
int main()
int i = 0;
for (i = 0; i < 10; i++)
prt();
return 0;
输出
1 2 3 4 5 6 7 8 9 10
2. static修饰全局变量
静态全局变量,改变了全局变量的链接属性,使它的外部链接属性变成了内部链接属性只能在当前源文件内使用
3. static修饰函数
静态函数,同样也消除了它的外部链接属性,只能在当前源文件使用
函数的默认返回值
函数在不写放回值的时候默认返回的是整形,返回随机值
#include <stdio.h>
prt()
int main()
printf("%d", prt());
return 0;
隐式类型转换
1.整形提升
C的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升
注意:整形提升是以符号位来进行提升的
来看一段代码
#include <stdio.h>
int main()
char a = 3;
char b = 127;
char tmp = a + b;
printf("%d\\n", tmp);
return 0;
//输出
-126
-
数字3的原反补码:00000000000000000000000000000011
-
把3放到一个字节的char类型中就会发送截断,变成:00000011
-
数字127的原反补码:00000000000000000000000001111111
-
把数字127放到一个字节的char类型中也会发送截断,变成:01111111
-
当字符a和字符b进行相加的时候,就会发送整形提升。会把char类型提升成4个字节的整形再相加,在左边添加上符号位0进行整形提升
-
00000000000000000000000000000011 整形提升后a的补码
-
00000000000000000000000001111111 整形提升后b的补码
-
00000000000000000000000010000010 相加和
-
因为1个字节是8个比特位,存放到tmp里就会发送截断,这个时候tmp里装的就是:10000010,最前面的1是符号位
-
而在pritf(“%d”),以整形的方式来打印的时候又会发生整形提升。(而整形提升是以符号位来进行提升的)
-
10000010 发生整形提升
-
11111111111111111111111110000010(注意这是存在内存中的补码)
-
11111111111111111111111110000001 减一得到反码
-
10000000000000000000000001111110除符号位外取反得到原码
-
最后打印的就是有符号的 10000000000000000000000001111110,也就是 -126
代码示例2
#include <stdio.h>
int main()
char a = 0xB6;//1011 0110 使用时发送整形提升
//00000000 00000000 00000000 10110110
short b = 0xb600;
int c = 0xb6000000;
printf("%d", (int)a);
if (a == 0xb6)
printf("a");
if (b == 0xb600)
printf("b");
if (c == 0xb6000000)
printf("c");
return 0;
//输出c
- a发送整形提升后截断
- 00000000 00000000 00000000 10110110
- 10110110转换为十进制就是-74
- b发生整形提升后截断变成10110110 00000000,变成了-18944
- 它们的第一位都是符号位
代码示例3
#include <stdio.h>
int main()
char a = 1;
printf("%d\\n", sizeof(a));
printf("%d\\n", sizeof(+a));
printf("%d\\n", sizeof(-a));
return 0;
//输出
1
4
4
//发生了整形提升
只要一个数参与了运算这个数不满足整形大小,就会发送整形提升,并且时以符号位进行提升的。
2. 整型提升的意义
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度
一般就是int的字节长度,同时也是CPU的通用寄存器的长度。
因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长
度。
通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令
中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转
换为int或unsigned int,然后才能送入CPU去执行运算
3. 算数转换
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类
型,否则操作就无法进行。下面的层次体系称为寻常算术转换
long double
double
float
unsigned long int
long int
unsigned int
int
如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算
比如 int 和 float进行运算,会先将 int 转换为flaot类型,int 和 long int 进行运算会将 int 先转换为 long int
int是最低的
以上是关于梦开始的地方——C语言中那些细节的主要内容,如果未能解决你的问题,请参考以下文章