学嵌入式C语言,看这一篇就够了(5)
C语言的运算符
学习编程语言,应该遵循“字-->词-->句-->段--->章”,对于一条有意义的语句而言,是离不开标点符号的
https://img2024.cnblogs.com/blog/3602479/202503/3602479-20250316204040180-416613343.png
运算符指明要进行的运算和操作,操作数是指运算符的操作对象,根据运算符操作数的数目不同,C语言标准把运算符分为三种:单目运算符(一元运算符)、双目运算符(二元运算符)、三目运算符(三元运算符)
C语言运算符优先级详细列表
(1)算术运算符
C语言中提供了7种算术运算符,分别是
+-*/%++--++和--都属于单目运算符,使用的时候比较特殊,其他五种都属于双目运算符
加法运算符+和减法运算符-一般没有特别需要注意的,作为双目运算符,需要两个操作对象,但是有时候 - 也会作为负号使用就变为单目运算符,使用规则发生变化
*和/是作为乘法运算符和除法运算符,属于双目运算符,但是除法运算符的使用规则有些不同
当除法运算符两端的操作数都是整数的时候,得到的结果也是整数,当两个操作数无法被整数,会舍弃小数,只保留整数
[*]Question1:求以下程序执行的结果
#include <stdio.h>
int main()
{
int x = 'f';
printf("%c\n",'a'+(x-'a'+1));
}
A.g B.h C.i D.j
[*]Answer1:
首先,int x = 'f'; 中,字符 'f' 的 ASCII 码值为 102。接着分析表达式 'a' + (x - 'a' + 1):
'a' 的 ASCII 码值为 97
x - 'a' 即 102 - 97 = 5,再加 1 得到 6
最后 'a' + 6 即 97 + 6 = 103,对应字符 'g'
因此,程序输出结果为 g,正确答案是 A
当除法运算符两端的操作数不全是整数,比如其中一个操作数是浮点数,则得到的结果也是浮点数,如果不指定精度,则默认是6位精度
C语言中提供%作为求余运算符,也可以称为取模运算符,C语言标准中规定%符号两端的操作数必须是整数
可以知道,C语言中的运算符是有优先级的,运算符的优先级指的是多个运算符出现在同一个表达式中,优先执行哪个运算符,可以知道算术运算符* / %的优先级是高于算术运算符+和-
[*]Question2:既然运算符有优先级,那如果一个表达式使用的运算符的优先级都一样,那应该如何进行运算?
[*]Answer2:
当表达式中运算符优先级相同时,需通过结合性(左结合或右结合)确定运算顺序:
左结合:从左至右依次运算。例如算术运算符+、-,表达式a - b + c,先计算a - b,再用结果与c运算
右结合:从右至左依次运算。例如赋值运算符=,表达式a = b = c,先计算b = c,再将结果赋给aC语言中的运算符是有结合性的,运算符的结合性指的是多个优先级相同的运算符出现在同一个表达式中,优先执行哪个运算符
运算符的结合性分为两种:一种是左结合性,遵循先左后右原则,比如 a + b - c,相当于(a+b)-c,另一种是右结合性,遵循先右后左原则,比如双目运算符中的赋值运算符 = ,比如表达式a=b=c,相当于a=(b=c)
注意:C语言中的单目运算符和三目运算符都是遵循右结合性,当然也包含双目运算符中的赋值运算符=,其他的运算符都遵循左结合性
C语言中提供了两个增量运算符++和--,属于单目运算符,只能在变量中使用,一般可以作为变量的后缀增量或者后缀减量,++和--也被称为自加运算符和自减运算符,注意:C语言标准中规定++和--也可以作为变量的前缀增量和前缀减量。 作用是让变量的值自动加1或者减1。
a++ :在表达式中则表示先让变量a参与表达式运算,运算之后才会让变量a的值自加
++a :在表达式中则表示先让变量a的值自加,自加之后再参与表达式运算
[*]Question3:请问结果是什么?请给出简单的推理过程
#include <stdio.h>
int main()
{
int a,b,c,d;
a = 10;
b = a++;
c = ++a;
d = 10*a++;
printf("b,c,d:%d,%d,%d",b,c,d);
return 0;
}
[*]Answer3:
b = 10; c = 12; d = 120;
[*]Question4:前缀增量和后缀增量都属于单目运算符,如果一个表达式中同时出现两种运算符,那应该如何进行解释?比如表达式 ++i++ 如何解释?
[*]Answer4:
++(i++)遵循右结合性
[*]Question5:请问结果是什么?请给出简单的推理过程
int main()
{
int i=3;
int j;
j = sizeof(++i + i++);
printf("i=%d j=%d",i,j);
}
A.i=4 j=2 B.i=3 j=2 C.i=3 j=4 D.i=3 j=6
[*]Answer5:
sizeof 特性:sizeof 是编译期确定结果的操作符,其操作数表达式不会实际执行。因此 ++i + ++i 不会执行,i 仍为初始值 3
sizeof(int) 的结果:int 类型在多数系统中占 4 字节,故 j = sizeof(++i + ++i) 实际等价于 j = sizeof(int),即 j = 4
最终输出 i=3 j=4,对应选项 C注意sizeof在C语言中是一个操作符,作用是计算数据类型的大小,结果以字节为单位,sizeof括号中的表达式是不会实现运算和处理的
另外,虽然sizeof运算符中的表达式不会被运算,但是如果sizeof表达式中出现多个数据类型的大小计算,这个时候会涉及到C语言基本数据类型的转换,转换的意思指的是将数据(变量、数值、表达式的结果等)从一种类型转换为另一种类型
一般程序中的数据类型转换分为两种情况:自动类型转换 or 强制类型转换。两者区别如下:
[*]自动类型转换
自动类型转换就是编译器默默地、隐式地进行的数据类型转换,这种转换不需要程序员干预,会自动发生。比如将一种类型的数据赋值给另外一种类型的变量时就会发生自动类型转换
在赋值运算中,赋值号两边的数据类型不同时,需要把右边表达式的类型转换为左边变量的类型,这可能会导致数据失真,或者精度降低;所以说自动类型转换并不一定是安全的。对于不安全的类型转换,编译器一般会给出警告
在不同类型的混合运算中,编译器也会自动地转换数据类型,将参与运算的所有数据先转换为同一种类型,然后再进行计算
转换的规则:转换按数据长度增加的方向进行,以保证数值不失真,或者精度不降低。例如int 和 long 参与运算时,先把 int 类型的数据转成 long 类型后再进行运算。所有的浮点运算都是以双精度进行的,即使运算中只有 float 类型,也要先转换为 double 类型,才能进行运算。另外char 和 short 参与运算时,必须先转换成 int 类型
[*]强制类型转换
自动类型转换是编译器根据代码的上下文环境自行判断的结果,有时候并不是那么“智能”,不能满足所有的需求。如果需要,程序员也可以自己在代码中明确地提出要进行类型转换,这称为强制类型转换
自动类型转换是编译器默默地、隐式地进行的一种类型转换,不需要在代码中体现出来;强制类型转换是程序员明确提出的、需要通过特定格式的代码来指明的一种类型转换。换句话说,自动类型转换不需要程序员干预,强制类型转换必须有程序员干预
强制转换规则:(需要转换的数据类型)变量
例如:(int *)a (unsigned char)b
总结:无论是自动类型转换还是强制类型转换,都只是为了本次运算而进行的临时性转换,转换的结果也会保存到临时的内存空间(栈空间),不会改变数据本来的类型或者值
(2)位操作运算符
C语言中提供了6种位操作运算符,分别是~ & ^ | >,其中~属于单目运算符,其他五种都属于双目运算符。
~:按位取反,对于二进制数而言,0变为1,1变为0~ 1101_1110 = 0010_0001
&:按位与,对于二进制而言,当两个bit同时为1,则结果为1,如果bit存在0,结果为0
|:按位或,对于二进制而言,当两个bit同时为0,则结果为0,如果bit存在1,结果为1
^:按位异或,对于二进制而言,当两个bit相同,则结果为0,两个bit不同,则结果为1
> 3 -- 0000 1111
[*]Question6:请问结果是什么?请给出简单的推理过程
int a= 3,b =6执行语句“int k= a^b
页:
[1]