说到这操作符下篇,各位看官老爷可得认真听听喽。主要就是说说这整型提升和算术转换,对于初学者来说可能学到的内容太过浅显,今天就让我呀来带您好好唠唠。
先接着上篇的内容给大家聊聊吧。
4、单目操作符( ! - + & sizeof ~ -- ++ * )
! : 逻辑反操作
- : 负值
+ : 正值
& : 取地址
sizeof : 操作数的类型长度
~ : 对一个数的二进制按位取反
-- : 前置、后置--
++ :前置、后置++
* : 解引用操作符
对于上面的这些操作符,在这里要提醒大家要注意的就是sizeof,它的返回值类型为unsigned int 类型,也就是无符号整型。还有要注意前置加加和减减(先加减再用),后置加加和减减(先用再加减)。
5、关系操作符 (> >= < <= != ==)
这里要注意的是,在判断两数相等的时候要使用的是==操作符。在编程的过程中要注意在判断时错写成=。
6、逻辑操作符( && ||)
&& : 逻辑与
|| : 逻辑或
这里来看一道例题:
#include <stdio.h>
int main()
{
int i = 0,a=0,b=2,c =3,d=4;
i = a++ && ++b && d++;
//i = a++||++b||d++;
printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);
return 0;
}
//程序输出的结果是什么?
这里有一点需要说明:在逻辑与的时候,当第一个操作数的值为0时,程序不会往下计算第二个操作数的值,因为一旦有0,逻辑与的结果就是0。所以在遇到的第一个操作数为0时,i的值就会被赋为0,且++b和d++不会被执行。相同的道理,在逻辑或的时候,当第一个操作数为1时,程序便不会计算后面的操作数,直接返回1。
7、条件操作符 ( exp1 ? exp2 : exp3 )
exp1 ? exp2 : exp3 ,当表达式1的结果为真时,返回表达式2,否则返回表达式3。条件表达式可以用来简化代码。
if (a > 5)
b = 3;
else
b = -3;
上面的程序可以简化为:
(a>5) ? b=3:b=-3
8、逗号表达式 (exp1, exp2, exp3, …expN )
逗号表达式,就是用逗号隔开的多个表达式。逗号表达式从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗号表达式c是多少?
9、表达式求值
9.1隐式类型转换
终于说到这里了,这部分是操作符部分的难点,同样也是初学者最容易摸不着头脑的地方。废话不多说,现在开讲!
C语言的整型算数运算总是至少以缺少整型类型的精度来进行的。说人话就是:像char short类型的变量在参与运算的过程中会先将数据的长度增长为整型的长度,即需要增长成4个字节。为了获得整型的精度,表达式中的字符和短整型操作数在使用之前会被自动转换成普通整形,这种转换称为整型提升。
整型提升的意义:
表达式的整型运算要在CPU 的相应运算器件内执行, CPU 内整型运算器 (ALU) 的操作数的字节长度一般就是int 的字节长度,同时也是 CPU的通用寄存器的长度。 因此,即使两个 char 类型的相加,在 CPU 执行时实际上也要先转换为 CPU 内整型操作数的标准长度。 通用 CPU ( general-purpose CPU )是难以直接实现两个 8 比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于 int 长度的整型值,都必须先转 换为 int 或 unsigned int ,然后才能送入 CPU 去执行运算。//实例1
char a,b,c;
...
a = b + c;
b和c的值被提升为普通整型,然后再执行加法运算。加法运算完成之后,结果将被截断,然后再存储于a中。
如何进行整体提升呢?(整型提升是按照变量的数据类型的符号位来提升的)
//负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:即 1111 1111 ,因为char是 singed char(有符号),所以再提升的时候,高位补充符号位1,所以提升的结果为0xFFFF(32个1)。
//正数的整型提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:即 0000 0001 ,因为char是 singed char(有符号),所以再提升的时候,高位补充符号位0,所以提升的结果为:0x0001。
讲完了这些,我们可以来看一个例子:
#include <stdio.h>
//实例1
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;
}
在表达式a==0xb6,b==0xb600 执行前都需要对a,b进行整型提升,但是c本身就是int类型所以它不需要进行提升。a,b进行整型提升之后,都变成了负数,所以表达式a==0xb6,b==0xb600的结果为假,而c本身是不动的,所以表达式c==0xb6000000位真,所以程序输出的结果为:
#include <stdio.h>
//实例2
int main()
{
char c = 1;
printf("%u\n", sizeof(c));
printf("%u\n", sizeof(+c));
printf("%u\n", sizeof(-c));
return 0;
}
在实例2中的c只要参与表达式运算,就会发生整型提升,表达式+c时,c就会发生整型提升。表达式-c,也是同样的效果。所以sizeof(+c)和sizeof(-c)就都是4个字节。而sizeof(c)是一个字节。
9.2 算术转换
在运算过程中,如果某个操作数的各个操作数属于不同类型,那么除非其中一个操作数的类型转换位另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。
这里我们引入一个例子:
#include <stdio.h>
int i;
int main()
{
i--;
if (i > sizeof(i))
{
printf(">\n");
}
else
{
printf("<\n");
}
return 0;
}
让我们来分析一下:全局变量i未进行初始化,所以它的默认值为0;进入主函数后i--,i的值变为-1,在内存中存储的值为负数的补码形式(0xFFFF)。sizeof(i)的值为4,初学者认为-1< 4,那么程序的输出应该为 '<';让我们来运行一下:
结果恰恰相反,那么究竟是怎么一回事嘞?原来sizeof(i)返回的数据类型为无符号整形,它的等级高于整形,所以在参与运算前,i进行了算术转换,从原来的整型转换为无符号整型。内存中的(0xFFFF)被当成正数,所以它的值大于4。故输出 '>'。
10、操作符的属性
复杂表达式的求值有三个影响的因素。 1. 操作符的优先级 2. 操作符的结合性 3. 是否控制求值顺序。 两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。 各位看官老爷们,今天要分享的内容到这里就结束了。希望上述的内容对大家有所帮助! 如有帮助请一键三连,万分感谢。标签:操作数,语言,int,操作符,整型,sizeof,表达式 From: https://blog.csdn.net/qq_70199082/article/details/143082861