这是皮皮虾整理C语言的知识点
皮皮虾整理的知识点逻辑性非常强,非常清晰明了
什么是隐式转换
数据类型在转换过程中不用写强制转换运算符,由编译器完成就是隐式转换
隐式转换:编译器自动完成,不用写强制类型转换运算符
赋值运算符数据类型规则:
1.赋值运算符涉及类型转换,左边的数据类型永远不变,赋值运算符的数据类型转换逻辑永远是右边转换为左边,只不过前提是这两个数据类型可以进行隐式转换
2.赋值不会修改右边变量自身的类型;只是右边表达式的值被转换为左边变量的类型,再拷贝过去。(强制类型转换也是)
隐式转换分类
1.非指针数据类型赋值隐式转换(都是针对从右往左转)
(1).字节少类型转换为字节多类型:char/short → int → long → long long → float → double → long double
int x; char c=5;x = c; // ✅ char → int,整数提升,但是char不能转换为其他字节多的了
double d = x; // ✅ int → double //多出来的怎么办,大不了多出来的置0
对了,ASCII值都是int类型的
(2).字节多类型转换为字节少类型:也允许隐式,但是会截断、丢失数据
这里字节少的不一定非得是char,short都行,只要左边数据类型字节少于右边就行
char c;int x = 1000;c = x; // ✅语法隐式,但是值截断,结果不可控
2.非指针数据类型算术隐式转换(都是针对从右往左转)
+ - * / % > < == 等双目运算,两个操作数先转成同一个公共类型:
非指针数据类型算术隐式转换遵循两个规则
(1)不同数据类型进行运算遵循少字节向多字节靠齐,精度低的向精度高的靠齐
如int 的a加double的b,会变成double值
(2)遵循整数提升规则:
C 标准:整数提升规则,只要char、short(包括 signed/unsigned)参与运算,就会先提升为 int;之后再做运算
char和short之间进行整数运算,会发生隐式转换把char和short看成int
char和char相加会看成int和int相加,short和short相加也会看成int和int相加
char和short相加看成两个int,就算很多数据类型相加,此时char和short也看成int
只要是运算符的「右操作数 / 运算输入」,char/short 才会整数提升为 int;sizeof 里面裸变量、赋值号左边、取地址,不会提升。
甚至可以是赋值运算符右边,赋值运算符右边是char和short数据类型char和short会转换为int
整数提升,也仅仅改变表达式的值的类型,不会改变原始变量本身的类型
但是sizeof里面不行
sizeof里面不会做整数提升,也不会做数组转指针,它是编译期运算符,不是普通算术表达式。
int 以及以上,不再有整数提升。
10 + 3.5; // int → double,结果double
char a,b;
a + b; // char先提升为int,再相加
那么平时感觉a+b还是char是为什么呢
是因为平时会写c=a+b,这里又发生了数据类型隐式转换
💡解答
char c; sizeof(c + 0); c 会提升为 int。
结果为4
char c; sizeof(c); c 不提升为 int。
解析:只是 sizeof 作用于变量,不做算术运算,不提升。
char c; sizeof(c >1); c 会提升为 int。
结果为1
3.指针数据类型隐式转换(都是针对从右往左转)
指针隐式转换只有 3 条合法情况,除此之外,所有不同指针之间都没有隐式转换,必须强制类型转换
(1)任意对象指针转换为void *
int a;
int *pi = &a;
void *vp = pi; // 只是pi里面得地址变成了void *,本身pi还是int *
(2)void *转换为任意对象指针
void *vp = &a;
int *p1 = vp; // ✅C隐式
char *p2 = vp; // ✅C隐式
(3)空指针常量 0 / NULL / (void*)0 → 任意对象指针、任意函数指针【隐式】
NULL是void *
int *pi = NULL;
void (*pf)(int) = NULL; // ✅空指针常量隐式转换
任意对象指针之间不能进行互相隐式转换
函数指针不能和void *进行隐式转换
不同类型函数指针之间也不行,不同类型函数指针之间不能进行互相赋值
隐式转换和强制数据类型转换做对比
强制转换类型和隐式转换类型都只是修改表达式临时值的类型,完全不改变原来变量本身的类型、内存、内容。
说白了强制转换数据类型也只是转换变量的值,强制类型转换和隐式转换都不会改变原本变量的数据类型
为什么char和short在算术表达式里面会整数提升?(有头文件的bool数据类型也有整数提升)
bool b = true;printf("%zu\n", sizeof(b + 0)); 结果为4,bool处于算术运算会触发整数提升规则,c的值变为int
是因为硬件 CPU 只能用寄存器宽度来运算算术表达式,而寄存器宽度是32位就是4个字节
硬件不会拿 8bit 直接算,必须先拓宽到机器字长,于是 C 语言标准就把这个硬件行为规定成语法规则,叫整数提升。