前言
运算符相对来说比较简单,但其中有一些细节问题值得我们注意,下面我分享了一些我在学习过程中值得注意的细节及使用实例。
一、位运算符
1.位运算符及其用途
~:逻辑反
&:位逻辑与
特点:0与任何树都是0,1或任何数该数都保持不变
特色作用:用于将某位置0
|:位逻辑或
特点:1或任何树都是1,0或任何数该数都保持不变
特色作用:用于将某位置1
^:位逻辑异或
特点:1异或任何数都是将该数取反,0异或任何数该数都保持不变
特色作用:用于将特定位取反
>>(右移位)<<(左移位)
特点:将数据进行按位移动
特色作用:用于高低位转化
注:红色字为宝典,最好记下来
2.实例
实例1:
#include <stdio.h>
int main(int argc, const char *argv[])
{
//置0与0,置1或1
unsigned short a = 0xab18;//1010 1011 0001 1000
printf("原数:%#x\n",a);
//(1)将第四位和第五位变为0,1010 1011 0001 0000
printf("将第四位和第五位变为0:%#x\n",a & 0xffe7);
//
//(2)将第7位和第8位变为1,1010 1011 1101 1000
printf("将第7位和第8位变为1:%#x\n",a | 0x00c0);
//(3)将低8位和高8位交换,1010 1011 0001 0000
printf("将第8位和高8位交换:%#x\n",(a&0xff) << 8 | a >> 8);
return 0;
}
输出
实例2
#include <stdio.h>
int main(int argc, const char *argv[])
{
//置0与0,置1或1
unsigned short a = 0xab18;//1010 1011 0001 1000
printf("原数:%#x\n",a);
//(1)将第四位和第五位变为0,1010 1011 0001 0000
printf("将第四位和第五位变为0:%#x\n",a & 0xffe7);
//
//(2)将第7位和第8位变为1,1010 1011 1101 1000
printf("将第7位和第8位变为1:%#x\n",a | 0x00c0);
//(3)将低8位和高8位交换,1010 1011 0001 0000
printf("将第8位和高8位交换:%#x\n",(a&0xff) << 8 | a >> 8);
return 0;
}
输出
实例3(本题曾是一道笔试题):
//问题描述:宏定义一个函数,用于使一个数的第n位取反
#include <stdio.h>
#define FUN(a,n) (1<<n)^a
int main(int argc, const char *argv[])
{
unsigned short a,n;
printf("请输入a的值:");
scanf("%hd",&a);
printf("\n");
printf("置第n位:");
scanf("%hd",&n);
printf("\n");
printf("原始数据:%#x\n",a);
printf("转化后数据:%#x\n",FUN(a,n));
return 0;
}
调试结果
二、逗号运算符
1.执行逻辑
从左往右依次计算表达式,以最右表达式的值作为整个表达式的值。
注意:当进行赋值操作时,逗号运算符必须结合括号因为逗号运算符优先级比赋值运算符底
2.实例
#include <stdio.h>
int main(int argc, const char *argv[])
{
int a = 100,b,c = 100;
b = ++a,a++,++a;
printf("++a,a++,++b = %d\n",b);
b = (++a,a++,++a);
printf("(++a,a++,++b) = %d\n",b);
b = (++c,c++,++c);
printf("(++a,a++,++b) = %d\n",b);
if(b = 1,a = 1,c = 0)
{
printf("ture\n");
}
else
{
printf("false\n");
}
return 0;
return 0;
}
结果剖析:
- 第一个b的值为101是因为上面说过的逗号运算符优先级比赋值运算符低,所以b = ++a
- 第二个b的值为106由来,b = (100+1) +(100+1)+(100+1)+(100+1) +(100+1)+(100+1)
- 第三个b的值为103由来,b=100+1+100+1+100+1
- 最后输出为false是因为(b = 1,a = 1,c = 0)表达式采用了c = 0的值
三、运算符优先级
1.运算符优先级表
优先级 | 运算符 | 结合律 | |
---|---|---|---|
1 | 后缀运算符:[] () · -> ++ --(类型名称){列表} | 从左到右 | |
2 | 一元运算符:++ -- ! ~ + - * & sizeof_Alignof | 从右到左 | |
3 | 类型转换运算符:(类型名称) | 从右到左 | |
4 | 乘除法运算符:* / % | 从左到右 | |
5 | 加减法运算符:+ - | 从左到右 | |
6 | 移位运算符:<< >> | 从左到右 | |
7 | 关系运算符:<<= >>= | 从左到右 | |
8 | 相等运算符:== != | 从左到右 | |
9 | 位运算符 AND:& | 从左到右 | |
10 | 位运算符 XOR:^ | 从左到右 | |
11 | 位运算符 OR:| | 从左到右 | |
12 | 逻辑运算符 AND:&& | 从左到右 | |
13 | 逻辑运算符 OR:|| | 从左到右 | |
14 | 条件运算符:?: | 从右到左 | |
15 | 赋值运算符: = += -= *= /= %= &= ^= |= <<= >>= | 从右到左 | |
16 | 逗号运算符:, | 从左到右 |
2.分析步骤
①看优先级
②同等运算级看运算方向(从右往左还是从左往右)
3.示例:
*p++:++优先级等*,所以先算p++,再算*p
注意:这里是p++,区别于++p,由于p++是先用p后自加,所以进行赋值运算时,先用p初始值运算,p再自加。
问:如果优先级一样,而且两个运算符运算方向相反怎么算
答:看表,不存在的。