本人0基础开始学编程,我能学会的,你也一定可以,学会多少写多少。
下载安装请从官网入手,社区版本即可,这里主要使用的软件是VS2019,图标如下。
上一篇:从0开始学c语言-18-操作符详解_阿秋的阿秋不是阿秋的博客-CSDN博客
目录
建议看之前,把上一篇看了,这俩属于同一范畴的,链接在最上面。
表达式求值
1·隐式类型转换
整型提升的意义:
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转 换为int或unsigned int,然后才能送入CPU去执行运算。
简单点就是说:char和short在运算的时候因为达不到int类型的大小才进行提升的,达到int大小的就不用提升。
例子1-怎么整型提升
int main()
{
char a = 3;
char b = 127;
char c = a + b;
printf("%d\n", c);
//-126
return 0;
}
int main()
{
char a = 3;
//00000000 00000000 00000000 00000011 -3
//char只能存放一个字节也就是八个bit位的二进制序列
//00000011 - a -截断
这是char a变量的整型提升过程,因为后续要执行和char b变量的相加,所以在使用之前需要进行整型提升,然后再执行加法运算,加法结果截断后存储于char c变量中。
-1上面这段整型提升的原理是?
//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:
11111111
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111
//正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001
-2细化例子过程
1-a和b的存放 把3和127的二进制序列存放到char a和b,在存放时候进行截断。
2-a和b的相加 在运算时候进行整型提升后相加,又因为char c只能储存8bit位,所以对相加结果进行截断并存放。
3-打印结果 打印的时候因为c是char 类型,而我们进行的是整型打印,所以需要进行整型提升,在整型提升过程中发现最高位的符号位是1(负数),所以我们需要对补码进行转换,进行原码输出。
int main()
{
//char就意味着是有符号char,最高位是符号位
char a = 3;
//00000000 00000000 00000000 00000011 -3
//char只能存放一个字节也就是八个bit位的二进制序列
//00000011 - a的存放(补码) -截断
char b = 127;
//00000000 00000000 00000000 01111111 -127
//01111111 - b的存放(补码) -截断
// 整型提升按照变量数据类型的符号位来提升
// 无符号高位就补0
char c = a + b;
//a和b都是char类型的,没有达到int大小
//就会发生整型提升
//00000000 00000000 00000000 00000011 -a的整型提升
//00000000 00000000 00000000 01111111 -b的整型提升
//00000000 00000000 00000000 10000010 -c=a+b的结果
//10000010 - c的存放(补码) -截断
printf("%d\n", c);
//打印是以整型方式打印的,所以c要整型提升
//11111111 11111111 11111111 10000010 -c(补码)的整型提升
//11111111 11111111 11111111 10000001 -c的反码
//10000000 00000000 00000000 01111110 -c的原码
//-126
return 0;
}
-3 %u输出结果是?
猜一猜,如果我们换成%u --- 也就是无符号整型的方式进行打印,结果会是?
提示:整型提升是看变量的数据类型的符号位来提升的 ,无符号则高位补0。
//10000010 - c的存放(补码) -截断
printf("%u\n", c);
//打印是以无符号整型方式打印的,所以c要整型提升
//整型提升是看变量的数据类型的符号位来提升的 ,无符号则高位补0
//变量c的类型是char,我们默认char是有符号的类型
//那么在提升的时候,按照c变量数据类型的符号位来提升,补1
//11111111 11111111 11111111 10000010 -c(补码)的整型提升
最后这补码转换成十进制的结果就是输出的结果,不用进行反码和原码的转换,因为我们是以无符号整型的方式进行输出,所以第一个1不是符号位。
也就是说,整型提升的时候要看变量数据类型是否有符号,不用看输出形式有无符号,输出形式只会影响输出结果,对于整型提升没有作用的。
例子2-数据的储存、运算、输出对比
0x代表后面的数字是16进制数字。
int main()
{
char a = 0xb6;
short b = 0xb600;
int c = 0xb6000000;
if(a==0xb6)
printf("a");
if(b==0xb600)
printf("b");
if(c==0xb6000000)
printf("c");
return 0;
}
因为运算的时候,char和short不够int的大小,所以我们对a和b进行整型提升。
char a = 0xb6;
//00000000 00000000 00000000 10110110 -0xb6
//10110110 - a截断并储存
if(a==0xb6)
printf("a");
//因为a要和0xb6进行比较,而a是char类型
//所以a要进行整型提升
//10110110 - a
//11111111 11111111 11111111 10110110 -a的整型提升
//00000000 00000000 00000000 10110110 -0xb6
//因此不成立
同理,大家试试自己梳理一下b和c变量的能否进行输出。
这里直接说结果了
输出结果是c。(c不需要进行整型提升,c是int类型。)
这里放一下监视细节,重点观察好变量对应的类型和值。

数据在储存的时候,会受到数据类型的影响,进行截断。
数据在对比、运算的时候,会受到整型提升的影响(尤其是有符号的数据类型)。
数据在输出的时候,以补码为起点,进行不同形式的原码输出。
例子3-和sizeof的结合
int main()
{
char c = 1;
printf("%u\n", sizeof(c));
printf("%u\n", sizeof(+c));
printf("%u\n", sizeof(-c));
return 0;
}
输出结果是1 4 4 。
int main()
{
char c = 1;
printf("%u\n\n", sizeof(c));//sizeof - %u无符号整型
printf("%u\n", sizeof(+c));
printf("%d\n\n", c);
printf("%u\n", sizeof(-c));
printf("%d\n\n", c);
return 0;
}
可以看到,-c后并没有输出-1。
可见sizeof中的表达式确实没有进行运算,那么+c、-c为什么size会变为4呢?
sizeof中的表达式不会影响c本身,c不会变化,只是sizeof输出的结果是运算后的。
一个数据有值属性和类型属性,sizeof中的表达式不参与运算,但是它打印的是这个表达式如果参与运算之后产生的类型大小。
2·算术转换
long doubledoublefloatunsigned long intlong intunsigned intint
float f = 3.14;
int num = f;//隐式转换,会有精度丢失
3·操作符的属性
简单一些记:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符
例子1:
a*b + c*d + e*f
也就是说会有两种运算顺序,先算加法的两个操作符
a*b
c*d
a*b + c*d
e*f
a*b + c*d + e*f
或者先算所有乘法
a*b
c*d
e*f
a*b + c*d
a*b + c*d + e*f
例子2:
c + --c;
例子3:非法表达
int main()
{
int i = 10;
i = i-- - --i * ( i = -3 ) * i++ + ++i;
printf("i = %d\n", i);
return 0;
}
例子4:
int fun()
{
static int count = 1;
return ++count; }
int main()
{
int answer;
answer = fun() - fun() * fun();
printf( "%d\n", answer);//输出多少?
return 0; }
例子5:
int main()
{
int i = 1;
int ret = (++i) + (++i) + (++i);
printf("%d\n", ret);
printf("%d\n", i);
return 0; }