C语言操作符---深入补充

本文详细介绍了C语言中的操作符分类,包括算术、移位、位操作、赋值、单目、关系、逻辑、条件、逗号表达式、下标引用、函数调用、结构成员等内容,以及整型提升和算术转换的规则。还讨论了表达式求值的优先级、结合性和控制因素。
摘要由CSDN通过智能技术生成

1. 操作符分类:
算术操作符、移位操作符、位操作符、赋值操作符、单目操作符、关系操作符、逻辑操作符、条件操作符、逗号表达式、下标引用、函数调用和结构成员。

2.算术操作符

+    -    *    /     % 

//当除号两端都是整数的时候,执行的是整数的除法,两端只要有一个是浮点数,执行的就是浮点数的除法。

//取模操作符两端必须是整数。

3.移位操作符     (<< 左移操作符             >>  右移操作符)

这里的位指的是二进制位。

计算机中整数有3种二进制表示形式(原码、反码、补码)

正整数的原码、反码、补码相同。

负整数的原码、反码、补码不同需要计算。

(负整数的反码=原码符号位不变,其他位按位取反;补码=反码的二进制位+1)

 //负整数前面第一个位置为符号位,1表示负号。

//整数在内存中的存储的二进制形式是补码。

//打印或者使用时,用的是原码的值。

3.1 左移操作符                                                                                                                             3.1.1正整数

方法

①将补码进行左移,将前面移出去的部分去掉,后面空出来的空间补0;

②正整数的原、反、补码相同,直接读取移位后补码的值,就得出正整数移位后的值。

                                                                                                                 

3.1.2负整数

因为负整数原码、反码、补码不相同,所以负整数进行左移操作时与正整数有区别

① 先将补码进行左移,将前面移出去的部分去掉,后面空出来的空间补0;

②  将移位后的补码减1,求移位后的反码;

③ 符号位不变,其他位按位取反求出原码,通过原码可以算出 -5左移2位的值位-20,通过编译器编译得到认证。也说明在进行位操作符过程中,打印或者使用的时候。用的说原码的值。

                                                                                                                                                                                                                                           

 3.2右移操作符

右移有两种形式

1.算术右移(规则:右边丢弃,左边补原来的符号位)

2.逻辑右移 (规则:右边丢弃,左边补0)

 右移的形式取决于编译器,常见的编译器都是算术右移。

所以对于正整数,算术右移与逻辑右移的结果都一样

3.2.2负整数右移

  

//对于移位运算符,不要移动负数位,这个是标准未定义的。

int num = 10;
num>>-1;  //这是错误的。

4.位操作符(这里的位使二进制位)

//注:他们的操作数必须是整数

& - 按(二进制)位与   (全1为1,有0为0)

   | - 按(二进制)位或(规则:有1为1,全0为0)     

 ^ - 按(二进制)位异或 (规则:相同为0,相异为1)

 

5.赋值操作符

复合赋值

+=      -=     *=      /=     %=     >>=     <<=     &=     |=      ^=

6.单目操作符

          !      逻辑反操作
         -      负值
        +      正值
        &      取地址
   sizeof    操作数的类型长度(以字节为单位)
        ~      对一个数的二进制按位取反
       --      前置、后置--
       ++      前置、后置++  
        *      间接访问操作符(解引用操作符) 

  (类型)    强制类型转换  

7.关系操作符

>       >=          <           <=         !=  用于测试“不相等”            ==    用于测试“相等

8.逻辑操作符 

&&   逻辑与     事件A并且事件B
||      逻辑或 

 

 //a后置++,先使用,在自增;a=0,对于&&前面为假时,后面不论什么情况都不用计算,整个表达式为假。

 //对于逻辑或,前面为真,后面就不用计算,条件全为真。

9.条件操作符   (exp1 ? exp2 : exp3)

例子:求两个整数之间的较大数

int main()
{
	int a = 10;
	int b = 20;
	int max = 0;

	if (a > b)
		max = a;
	else
		max = b;
//条件操作符
	max = (a > b ? a : b);


	return 0;
}

10.逗号表达式 (exp1, exp2, exp3, …expN)

逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果

11. 下标引用、函数调用和结构成员

11.1. [ ] 下标引用操作符
操作数:一个数组名 + 一个索引值

int arr[10];//创建数组
arr[9] = 10;//实用下标引用操作符。
[ ]的两个操作数是arr和9。

11.2 ( ) 函数调用操作符

接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。

void test1()
{
	printf("hehe\n");
}
void test2(const char* str)
{
	printf("%s\n", str);
}
int main()
{
	test1();    //实用()作为函数调用操作符。
	test2("hello");//实用()作为函数调用操作符。
	return 0;
}

11.3 访问一个结构的成员

. 结构体.成员名
-> 结构体指针->成员名

12.表达式求值

表达式求值的顺序一部分是由操作符的优先级和结合性决定。同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。

12.1 隐式类型转换

C的整型算术运算总是至少以缺省整型类型的精度来进行的。
为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升

整型提升的意义:
表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。
因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。

如何进行整体提升呢?

整形提升是按照变量的数据类型的符号位来提升的。

①负数的整形提升
char c1 = -1;
变量c1的二进制位(补码)中只有8个比特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为1
提升之后的结果是:
11111111111111111111111111111111


②正数的整形提升
char c2 = 1;
变量c2的二进制位(补码)中只有8个比特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,高位补充符号位,即为0
提升之后的结果是:
00000000000000000000000000000001


③无符号整形提升,高位补0

例子:

 变量a,b,c都是char类型,进行运算时需要进行整型提升。

        按照整型提升的规则将a,b从1字节提升到4字节,然后相加,相加出的4字节数据需要截取最后1字节数据保存到char c中;然后需要以%d形式打印出char c 的值,继续进行整型提升,此时开头的数为1,按照规则,前面全补1,此时的补码为负数,按照负数原、反、补码的计算规则求出此时的原码,原码的值,就是以%d形式打印出char c 的值。 

12.2 算术转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换

         如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。

int a =3;
float b =2.3;

float c = a+ b;//需要将a转换成float类型

 

12.3操作符的属性、

复杂表达式的求值有三个影响的因素。
1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序。
两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值