嵌入式LinuxC语言运算符与表达式-创新互联
运算符与表达式
当前文章:嵌入式LinuxC语言运算符与表达式-创新互联
浏览路径:http://azwzsj.com/article/pjsci.html
1. 运算符
运算符:用来进行某种运算的符号
eg:
+ - * / %
a、几目运算符
运算符需要带几个操作数
单目运算符:运算符只需要一个操作数
eg: ++ -- ……
双目运算符:运算符需要两个操作数
eg:+ - * / % ……
三目运算符:运算符需要三个操作数
eg:(表达式1) ? (表达式2):(表达式3)
b、结合性
决定运算式先算哪个,后算哪个
从左至右的结合性,从右至左的结合性
eg:
+ 从左至右的结合性
a + b
先算表达式a的值,再算表达式b的值,最后a+b
在C语言中,表达式a+b和表达式b+a不一样
eg:
int i = 5, j = 6;
(i++) + (i+j);//17 5+12 i++=5 i=6
(i+j) + (i++);//16 11+5 i++=5 i=5
c、优先级
在一个含有多个运算符的表达式中,先算哪个运算符后算哪个运算符
单目运算符 >算数运算符 >关系运算符 >逻辑运算符 >条件运算符 >赋值运算符 >d逗号运算符
(1)算数运算符
++ --:单目运算符
* / % + -:双目运算符,从左至右的结合性
eg:
3 + 5 =>8
5 / 4 =>1 (整数进行算数运算的结果为整数)
5.0 / 4 =>1.25
typeof(5 / 4) =>int
typeof(5.0 / 4) =>double
(double)(3 / 2) =>1.0
(double)3 / 2 =>1.5
用C语言的表达式来描述一个数学表达式:
数学:a / b
C语言:(double)a / b
1.0*a / b
%:求余,取膜,要求两边的操作数都必须为整数
5 % 4 =>1
5 % 1.0 =>ERROR
4 % 5 =>4
++:自增运算符
i++
++i
--:自减运算符
i--
--i
++和-- 单目运算符,要求操作数必须为一个lvalue
左值:location value 可写的地址 变量一边都会具备左值
eg:
5++ ERROR 常量
(a+b)++ ERROR 表达式
(a++)++ ERROR
表达式的值 做完表达式后i的值
i++ i i=i+1
++i i+1 i+i+1
i-- i i=i-1
--i i-1 i=i-1
eg:
int i = 5;
int a = i++;
printf("%d\n", a); //5
printf("%d\n", i); //6
int i = 6;
(i++) + (i++) + (i++) //无意义,看编译器
(2)关系运算符
用来判断两个东西关系的运算符。
"关系":数值大小关系
>< ==
>=<= !=
双目运算符,结合性从左至右
关系表达式:用关系运算符连接起来的式子
关系表达式的值:
关系成立 1
关系不成立 0
eg:
表达式 表达式的值
5 >4 1
3<= 2 0
5 >4 >3 0
<=>(5 >4) >3
5 >4表达式的值与3比较
1 >3
(3)逻辑运算符
用来描述逻辑关系的运算符
! 逻辑非 单目运算符 “取反”
&& 逻辑与 双目运算符 “并且” 从左至右的结合性
|| 逻辑或 双目运算符 “或者” 从左至右的结合性
逻辑表达式:用逻辑运算符连接起来的式子
逻辑表达式的真:
逻辑真(非0,1)
逻辑假 0
eg:
a = 4, b = 5
!a + 5 =>5
5 >3 && 8< 3 - !0 //0
->!0 1
->3-1 = 2
->1 && 0 =>0
int a, b, c, d, m, n;
a = 1;
b = 2;
c = 3;
d = 4;
m = n = 1;
(m = a >b) && (n = c >d);
printf("%d\n", m); //0
printf("%d\n", n); //1
C语言中的运算符是 惰性运算
(1) a && b && c
只有a为真时,才需要判断b的值
只有a和b都为真时,才会判断c的值
只要a为假,后面的b和c都不会判断
(2) a || b || c
只有a为假时,才需要判断b的值
只有a和b都为假时,才需要判断c的值
只要a为真,后面的b和c都不会判断
用逻辑表达式判断y(年份)是否为闰年
1.平常闰年:能被4整除,但是不能被100整除
2.世纪闰年:嫩被400整除
if((y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0)))
{
printf("%d是闰年\n", y);
}
else
{
printf("%d不是是闰年\n", y);
}
用逻辑表达式判断y(年份)是否不为闰年
!(y % 400 == 0) || ((y % 4 == 0) && (y % 100 != 0))
(4)位运算符
位运算符是指按bit位来进行的运算
位运算要求操作数必须是整数
有如下:
& 按位与
| 按位或
^ 按位异或
~ 按位取反
<< 按位左移
>>按位右移
除了~是单目运算符之外,其他都是双目运算符,结合性都是从左至右
位运算符操作数只能是整数
所有位运算都需要把操作数变成bit序列,然后再按bit位来进行计算
~ (按位取反) :单目运算
0 ->1
1 ->0
eg:
int a = ~3;
printf("%d\n", a);//-4
printf("%u\n", a);//2^32-4
3: 00000000 00000000 00000000 00000011
~3: 11111111 11111111 11111111 11111100
a: 11111111 11111111 11111111 11111100
%d: 符号位 1 负数
-1: 11111111 11111111 11111111 11111011
取反: 000000000 00000000 00000000 00000100
|负数|:4
%u:11111111 11111111 11111111 11111100
&(按位与) :双目运算符
a b a&b
0 0 0
0 1 0
1 0 0
1 1 1
两个bit位都为1是才为1
eg:
int a = 3 & 5;//a=1
3:00000000 00000000 00000000 00000011
5:00000000 00000000 00000000 00000101
&:-----------------------------------
a:00000000 00000000 00000000 00000001
假设一个整型变量a,把a的第bit4位变为0,其他bit位不变。
a: xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxXxxx
&: 11111111 11111111 11111111 1111110111<- ~(1<< 3)
=>xxxxxxxx xxxxxxxx xxxxxxxx xxxxxx0xxx
a = a & ~(1<< 3);
一个bit位与0进行“按位与”的操作,结果为0
x & 0 =>0
证明:
x为bit位,0 or 1
when x == 0, x & 0 =>0
when x == 1, x & 0 =>0
一个bit位与1进行 “按位与”的操作,结果位其本身
x & 1 =>x
证明:
x为bit位,0 or 1
when x == 0, x & 1 =>0
when x == 1, x & 1 =>1
| (按位或) : 双目运算符
a b a|b
0 0 0
0 1 1
1 0 1
1 1 1
两个bit位都为0时才为0否则为1
eg:
int a = 3 | 5;// a=7
3:00000000 00000000 00000000 00000011
5:00000000 00000000 00000000 00000101
|:-----------------------------------
a:00000000 00000000 00000000 00000111
假设一个整型变量a,把a的第bit5位置1,其他bit位不变。
a: xxxxxxxx xxxxxxxx xxxxxxxx xxxXxxxxx
|: 00000000 00000000 00000000 0000100000<- 1<< 5
=>xxxxxxxx xxxxxxxx xxxxxxxx xxxx1xxxxx
a = a | (1<< 5);
一个bit为与0进行“按位或”的操作,其结果保留其原值
一个bit为与1进行“按位或”的操作,其结果1
(按位异或):双目运算符
异或:求异(相同位0,不同为1)
a b a^b
0 0 0
0 1 1
1 0 1
1 1 0
eg:
int a = 3 ^ 5;
3:00000000 00000000 00000000 00000011
5:00000000 00000000 00000000 00000101
^:-----------------------------------
a:00000000 00000000 00000000 00000110
假设一个整型变量a,把a的第bit5位置1,
a: xxxxxxxx xxxxxxxx xxxxxxxx xxxXxxxxx
x ^ 0 =>x
x ^ 1 =>~x
^: 111111111 11111111 11111111 111011111 =>……(~(1<<5))
=>~(xxxxxxxx xxxxxxxx xxxxxxxx xxxx)X~(xxxxx)
a=a ^ (~(1<<5))
一个bit为与0进行“按位或”的操作,其结果保留其原值
一个bit为与1进行“按位或”的操作,其结果其值取反
交换两个整数a和b的值,不使用临时变量
#includeint main(){
int a = 1, b = 2;
a = a^b;
b = b^a;
a = a^b;
a= a+b;
b = a-b;
a = a-b;
printf("%d %d", a, b);
return 0;
}
a:00000000 00000000 00000000 00000001
b:00000000 00000000 00000000 00000010
a^b: 00000000 00000000 00000000 00000011
a:00000000 00000000 00000000 00000011
b^a:00000000 00000000 00000000 00000001
b:00000000 00000000 00000000 00000001
a^b:00000000 00000000 00000000 00000010
a:00000000 00000000 00000000 00000010
<< (按位左移) :双目运算符
按bit位整体往左移
a<< n 把a按bit位形式整体往左移n个bit位
高位左移后,舍弃。
低位会空出n个bit位,直接补0
如果左移后舍弃的高位都是0,左移n位,(这个数必须是无五号是)表示原值乘以2的n次幂4
1<<8
00000000 00000000 000000000 00000001 1
00000000 00000000 000000001 00000000 1<<8 =>1 * 2^8
10000000 00000000 000000000 00000000 1<<32 是个负数
>>(按位右移) :
按bit位整体往右移
x >>n 把x按bit位形式整体往右移n个bit位
低位多出n位舍弃
高位空出n位,无符号数,高位补0;有符号数补符号位。
汇编中 逻辑位移 算数位移 循环位移
逻辑位移:无符号位,逻辑左移和逻辑右移都补0
算数位移:有符号位,算数右移补符号位,算数左移补0
循环位移:移除的bit位补到空缺的bit位
eg:
int a = -1;
a = a >>31;
printf("%d\n", a);// -1
printf("%u\n", a);// 2^32 - 1
|-1|: 000000000 00000000 000000000 00000001
取反: 11111111 11111111 11111111 11111110
+1: 11111111 11111111 11111111 11111111
-1: 11111111 11111111 11111111 11111111 在计算机中的存储形式
a: 11111111 11111111 11111111 11111111
a>>31: 11111111 11111111 11111111 11111111
%d:
符号位为 1
-1: 11111111 11111111 11111111 11111110
取反:000000000 00000000 000000000 00000001
|-1|:000000000 00000000 000000000 00000001
%u:11111111 11111111 11111111 11111111
unsigned int a = -1;
a = a >>31;
printf("%d\n", a);// 1
printf("%u\n", a);// 1
|-1|: 000000000 00000000 000000000 00000001
取反: 11111111 11111111 11111111 11111110
+1: 11111111 11111111 11111111 11111111
-1: 11111111 11111111 11111111 11111111 在计算机中的存储形式
a: 11111111 11111111 11111111 11111111
a>>31: 0000000 00000000 00000000 00000001
%d: 000000000 00000000 000000000 00000001
%u:`000000000 00000000 000000000 00000001
char a = -1;
a = a >>31;
printf("%d\n", a);// -1
printf("%u\n", a);// 2^32 - 1
|-1|: 000000000 00000000 000000000 00000001
取反: 11111111 11111111 11111111 11111110
+1: 11111111 11111111 11111111 11111111
-1: 11111111 11111111 11111111 11111111 在计算机中的存储形式
a: 11111111
a >>31 短变长 11111111 11111111 11111111 11111111
%d: int
11111111 11111111 11111111 11111111
|-1|:000000000 00000000 000000000 00000001
%u:11111111 11111111 11111111 11111111
unsigned char a = -1;
a = a >>31;
printf("%d\n", a);// 0
printf("%u\n", a);// 0
|-1|: 000000000 00000000 000000000 00000001
取反: 11111111 11111111 11111111 11111110
+1: 11111111 11111111 11111111 11111111
-1: 11111111 11111111 11111111 11111111 在计算机中的存储形式
a: 11111111
a >>31 短变长 00000000 00000000 000000000 00000000 11111111
00000000 000000000 00000000 00000000 00000000
%d:00000000 000000000 00000000 00000000 00000000
%u:00000000 000000000 00000000 00000000 00000000
(5) 赋值运算符
双目运算符,结合性从右至左
优先级排倒数第二,仅比都好运算符的优先级要高
eg:
a = x; 把表达式x的值赋值给a
5 = 5; ERROR
赋值运算符要求左边的操作数必须为一个"可写的地址" lvalue
if(i = 0){
}
错误,等价于if(0)逻辑错误,运行不会错
赋值表达式:由赋值运算符连接起来的式子
赋值表达式的值:就是最后赋值给左边变量(左边可写地址)的那个值
eg:
表达式 表达式的值
a = 6 6
b = a = 6 6 把表达式(a = 6)的值,赋值给b
复合赋值运算符:
赋值运算符可以和算数运算符、位运算符组合成一个复合运算符
+= -= *= /= %=
<<= >>= |= ^\ &\
eg:
a += 5;<==>a = a + 5;
a += 5 + 6;<==>a = a + (5 + 6);
a >>= 5;<==>a = a>>5;
(6) 条件运算符 :三目运算符
条件表达式:expression ? a:b
如果expression值为真,那么表达式的值为a
如果expression值为假,那么表达式的值为b
eg:
a = 5 >4 ? 1 : 0; //1
(7) 逗号运算符 :双目运算符,优先级最低,结合性从左至右
表达式1,表达式2
逗号表达式的值,求值顺序:
先求表达式1的值,然后再求表达式2的值,
最后整个逗号表达式的值就是表达式2的值
eg:
int a = 5, b = 6;
a = (a = 6, a + b)
先算a = 6
再说a+b的值12
整个逗号表达式为12
a = 6, b = 7, c = 8, d = 9
逗号表达式扩展形式
表达式1,表达式2,……,表达式n
先算表达式1的值,
再算表达式2的值,
...
最后求表达式n的值
整个逗号表达式的值就是表达式n的值
(8) 指针运算符
*
&(取值符)
&对象 : 取这个对象的地址,就表示是对象的指针
输入:scanf("%d", &b);
(9) 分量运算符
求结构体中的成员变量(分量)
.
->struct test
{
int a;
char b;
short c;
};
struct test t;
t.a;
t.b;
t.c;
(10) 下标运算符
[下标]
int a[10];
下标范围:[0,9]
a[0]
a[1]
...
a[9]
(11) 强制类型转换运算符
(类型)
(unsigned char)255
(double)3 / 2<==>1.5 3.0/2
(double)(3 / 2)<==>1
(12)求字节运算符
sizeof 单目运算符,求一个对象或类型所占空间的字节数
typeof(x)求类型 sizeof(typeof(x))
sizeof(x)
sizeof 不要求x存在,但是要求x的类型是确定的,因为类型确定,就可以知道所占内存的大小。
sizeof(int);//4字节
int a[10];
sizeof(typeof(a[0]));//4字节
2. 表达式
表达式:用来表达某个含义的式子
在C语言中,表达式一般是用运算符连接起来的式子
只要是一个合法的表达式,那么它就一定会有一个值,这个值就是该表达式需要表达的含义
总结:
1. 运算符
a、几目运算符
b、结合性
c、优先级
单目运算符 >算数运算符 >关系运算符 >逻辑运算符 >条件运算符 >赋值运算符 >逗号运算符
1. 算数运算符
/ % ++ --
表达式的值 做完表达式之后i的值
i++ i i = i+1
++i i+1 i = i+1
i-- i i = i-1
--i i-1 i = i-1
2. 关系运算符
>< >=<= == !=
3. 逻辑运算符
&& || !
4. 位运算符
& | ^ ~ >><<
x & 0 =>0 x & 1 = x
x | 0 =>x x | 1 = 1
x ^ 0 =>x x ^ 1 = ~x
5. 条件运算符
? :
6. 赋值运算符
=
赋值表达式的值是赋值符号右边的表达式的值,即最终赋值给左边变量的值
7. 逗号运算符
8. sizeof(typeof(x))
9. 其他
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
为夏津等地区用户提供了全套网页设计制作服务,及夏津网站建设行业解决方案。主营业务为网站制作、成都网站设计、夏津网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!当前文章:嵌入式LinuxC语言运算符与表达式-创新互联
浏览路径:http://azwzsj.com/article/pjsci.html