C语言操作符大全(建议收藏)
创始人
2024-01-22 13:09:21
0

前言
💖作者龟龟不断向前
简介宁愿做一只不停跑的慢乌龟,也不想当一只三分钟热度的兔子。
👻专栏:C++初阶知识点

👻工具分享

  1. 刷题: 牛客网 leetcode
  2. 笔记软件:有道云笔记
  3. 画图软件:Xmind(思维导图) diagrams(流程图)

在这里插入图片描述

如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持博主🙊,如有不足还请指点,博主及时改正

C语言操作符

1.操作符分类

在这里插入图片描述

 

2.算术操作符

+    -   *   /   %

  1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。

  2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法

#includeint main()
{printf("%d\n", 3 / 2);//整数除法printf("%.1f\n", 3.0 / 2);//浮点数除法
}

  3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

 

1.1%的应用 – 求解最大公因数

方法:辗转相除法

在这里插入图片描述

#includeint max_common_fac(int m, int n)
{int r = 0;do{r = m % n;m = n;//m取上一次的除数n = r;//n取上一次的余数} while (r);//直到r为0,此时的除数为最大公因数return m;
}int main()
{int m = 0, n = 0;scanf("%d %d", &m, &n);int ret = max_common_fac(m, n);printf("%d和%d的最大公因数为%d\n", m, n ,ret);return 0;
}

 

1.2%的应用 – 拆出一个数的每一位

#include//为了让效果明显一点,咱们将每一位打印出来
void seq_print(int n)
{if (n > 9){seq_print(n / 10);}printf("%d ", n % 10);return;
}int main()
{int n = 0;scanf("%d", &n);seq_print(n);return 0;
}

 


 

3.移位操作符

<< 左移操作符
>> 右移操作符

移位移位,移动的是二进制位

  1. 将一个数切换成二进制
  2. 再进行移位

 

2.1左移

移位规则:

左移:左边弃之,右边补0

在这里插入图片描述

ps:是b接收了a<<1的值,b为20,但是a还是原来的10,没有变化

 

2.2右移

移位规则:

  1. 逻辑移位

左边用0填充,右边丢弃

  1. 算术移位

左边用原该值的符号位填充,右边丢弃

在这里插入图片描述

ps1:咱们vs编译器的右移使用的是算术右移

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

 

4.位操作符

& //按位与 -- 同1为1,否则为0
| //按位或 -- 同0为0,反则为1
^ //按位异或 -- 相同为0,相异为1
注:他们的操作数必须是整数。

ps:位操作符,相对于二进制位的操作

 

#includeint main()
{int a = 3;//00000000000000000000000000000011 -- 3的补码int b = -5;//10000000000000000000000000000101//11111111111111111111111111111010//11111111111111111111111111111011 -- -5的补码//a&b//00000000000000000000000000000011 -- &之后的结构,符号位是0,原反补一致//a|b//11111111111111111111111111111011 -- |之后的结果,此时还是补码,打印出来要转换成原码//10000000000000000000000000000100//10000000000000000000000000000101 -- -5//a^b//11111111111111111111111111111000 -- ^之后的结果,此时还是补码,打印出来要转换成原码//10000000000000000000000000000111//10000000000000000000000000001000  -- -8printf("a & b = %d\n", a & b);printf("a | b = %d\n", a | b);printf("a ^ b = %d\n", a ^ b);return 0;
}

 

4.1&与>>的应用 – 计算出二进制下1的个数

解题思路:得到二进制下的每一位,如果是1,计数器count+1,最后count的值是二进制中1的个数

如何得到二进制中的每一位

  1. 通过&1,我们可以得到二进制中的最低位

     

  2. 再配合右移(>>),即可将二进位的每一位都得到

#includeint main()
{int a = 0;while ((scanf("%d", &a)) != EOF)//多组测试用例,方便测试{int count = 0;for (int i = 0; i < 32; ++i){if ((a >> i) & 1){++count;}}printf("%d的二进制的1的个数:%d\n", a, count);}return 0;
}

在这里插入图片描述

 

4.2^的应用 – 不创建临时变量,交换两个数

根据相同为0,相异为1,^有这样的性质

性质1:0与一个数异或,得到的是这个数

0 ^ a = a

性质2:一个数与其本身异或,得到0

a ^ a = 0

性质1和性质2结合:

a ^ a ^ b = 0

b ^ b ^ a = 0

性质3:^具有交换律

a ^ b = b ^ a

所以可以得到:

a ^ b ^ a = b

a ^ b ^ b = a

即我们可以将a ^ b看成一个密匙,将密匙与a进行 ^运算得到b,将密匙与b进行 ^运算得到a

 

#includeint main()
{int a = 3;int b = 5;a = a^b;//a此时变成密匙b = a^b;//密匙 ^ b = a   b此时变成aa = a^b;//密匙 ^ a = b   a此时变成bprintf("%d %d\n", a, b);return 0;
}

 

5.赋值运算符

= – 将右操作数赋给做操作数

例如:

int a = 10;
int x = 0;
int y = 20;
//也可以连续赋值
a = x = y+1;//从右向左赋值
//效果等价于
x = y+1;
a = x;

 

符合赋值符

+=+=效果举例:int x = 10;x = x+10;等价于:x += 10;//复合赋值
-=
*=
/=
%=
>>=
<<=
&=
|=
^=

 

6.单目操作符

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

 

#includeint main()
{int a = 0;int b = 7;printf("!%d = %d\n", a, !a);printf("!%d = %d\n", b, !b);printf("&a = %p\n", &a);printf("&b = %p\n", &b);printf("%u\n", sizeof(int));printf("%u\n", sizeof(a));printf("%u\n", sizeof a);//true//printf("%u\n", sizeof int); //error sizeof后面不接括号,不能接类型名,但是可以接变量名printf("%d\n",~0);//-1 -- 二进制的每一位按位取反return 0;
}

 

6.1前置,后置的++ –

前置:先使用,再++ –

后置:先++ – ,再使用

 

前置:

#includeint main()
{int a = 10;//后置++int b = a++;//先执行b = a ,再执行a++printf("%d\n", b);//10printf("%d\n", a);//11return 0;
}

 

#includeint main()
{int a = 10;//后置++int b = ++a;//先执行a++,后执行b = aprintf("%d\n", b);//11printf("%d\n", a);//11return 0;
}

6.2sizeof和数组

#include void test1(int arr[])
{printf("%d\n", sizeof(arr));//(2)
}void test2(char ch[])
{printf("%d\n", sizeof(ch));//(4)
}int main()
{int arr[10] = {0};char ch[10] = {0};printf("%d\n", sizeof(arr));//(1)printf("%d\n", sizeof(ch));//(3)test1(arr);test2(ch);return 0;
}//(1) -- 40
//(2) -- 10
//(3) -- 4/8
//(4) -- 4/8

 
在函数调用test1test2中,传过去的arrch数组名,是首元素地址的意义,即形参接收实参其实只是一个指针变量来接收,指针变量的大小只与平台有关,与类型无关

7.关系操作符

>
>=
<
<=
!=   	用于测试“不相等”
==      用于测试“相等” -- 注意是两个等号

 

8.逻辑操作符

&&     逻辑与
||     逻辑或

&& 和 ||的理解有很多种

  1. 有些同学理解成botheither
  2. 有些同学理解成并且/都或者
  3. 有些同学理解成电路中的串联并联

大家用适合自己理解的去理解即可

在这里插入图片描述

 

举例1:

#includeint main()
{int a = 1;int b = 2;if (a && b){printf("你们两都来啦\n");}else{printf("你们两怎么没都来");}return 0;
}
int main()
{int a = 0;int b = 0;if (a || b){printf("你们两至少有一个来了\n");}else{printf("你们两怎么没有一个人来\n");}return 0;
}

 

举例2:

int main()
{int age = 0;printf("请输入你的年龄\n");scanf("%d", &age);//if (18 <= age <= 36)//逻辑相差很大if (age >= 18 && age <= 36){printf("你是青年\n");}else{printf("你不是青年\n");}return 0;
}

这里比较容易错,大家如果想要表示一个18-36的范围,千万不要像数学中一样直接来一手18 <= age <= 36,这是一个错误的逻辑,&&是一个二元操作符,一次只能进行两个操作数的操作,无法达到我们一次到位的效果

正确写法: if (age >= 18 && age <= 36)

 


 

8.1&& 与 ||的短路问题

360笔试题

#include 
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;
}

 

修改:

#include 
int main()
{int i = 1,a=0,b=2,c =3,d=4;i = a++||++b||d++;printf("a = %d\n b = %d\n c = %d\nd = %d\n", a, b, c, d);return 0;
}

 

短路条件:

&&:当遇到假时,后面的表达式便不再执行

||:当遇到真时,后面的表达式便不再执行

 

9.条件操作符

​ 下面的图片可以大致解释条件表达式的意思

龟龟小故事:小明和小刚同时爱上了小红,小红也不知道怎么选择,于是绝对让小明和小刚做一个竞争,

小明赢了,那么小红就选择小明,小明输了(小刚赢了),小红就选择小刚

在这里插入图片描述

在这里插入图片描述

代码举例:

#includeint main()
{int a = 3;int b = 10;int c = a > b ? a : b;printf("c = %d\n", c);return 0;
}

上述代码中,如果 a > b,则c = a,否则 c = b

 


 

正经解释:

条件表达式也叫做三目表达式,因为操作数有三个

exp1?exp2:exp3,如果exp1表达式的值为真,那么整个表达式的值就是exp2的值,否则整个表达式的值就是exp3的值

 

所以我们的求两数的最大值的函数可以稍微改善一下了:

改善前:

int Max(int x, int y)
{if (x > y){return x;}else{return y;}
}

 

改善后:

int Max(int x, int y)
{return x > y ? x : y;
}

 


龟龟小故事的结局与条件表达式无关😅
由于龟龟故事的结局有一点点大转变,审核警告我说我有点狂,所以大家可以去我仓库看龟龟小故事结局

 

10.逗号表达式

exp1, exp2, exp3, …expN

 

逗号表达式,就是用逗号隔开的多个表达式。

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

ps:由于逗号表达式是所有表达式中,优先级最低的,咱们尽量加上括号

(exp1, exp2, exp3, …expN)
#includeint main()
{int a = 1;int b = 2;int c = (a>b, a = b + 10, a, b = a + 1);printf("%d\n", c);return 0;
}

 

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

  • [] – 下标引用操作符

    语法:数组名 + [下标]

操作数:数组名 + 下标值

#includeint main()
{int arr[10];//创建数组arr[9] = 10;//实用下标引用操作符。//[ ]的两个操作数是arr和9。printf("%d\n",arr[9]);return 0;
}

 

  • () – 函数调用操作符

    语法: 函数名 + (n个函数参数)

操作数:函数名 + 参数 (所以操作数至少有一个函数名)

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

 

  • 访问一个结构的成员

    .结构体.成员名

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

    #include 
    struct Stu
    {char name[10];int age;char sex[5];double score;
    };void set_age1(struct Stu stu)
    {stu.age = 18;
    }void set_age2(struct Stu* pStu)
    {pStu->age = 18;//结构成员访问
    }int main()
    {struct Stu stu;struct Stu* pStu = &stu;//结构成员访问stu.age = 20;//结构成员访问set_age1(stu);//值传递pStu->age = 20;//结构成员访问set_age2(pStu);//址传递return 0;
    }
    

     

12.操作符的属性

  1. 操作符的优先级
  2. 操作符的结合性
  3. 是否控制求值顺序。

两个相邻的操作符先执行哪个?取决于他们的优先级。

如果两者的优先级相同,取决于他们的结合性

会控制求值顺序的操作符有:&& , || 逗号表达式,三目表达式

&& ||的短路会使每次的表达式求值顺序不一样

关于优先级,大家可以参考这张操作符优先级表

 

12.1编译器也无法知晓的表达式求值

ps:即使有了优先级,结合性,控制求值顺序这些属性,并不就意味着所有的表达式求值都有了一致的求法,代码的不规范,还是会造成编译器也不知该如何处理的情况

#includeint main()
{int i = 10;i = i-- - --i * ( i = -3 ) * i++ + ++i;printf("i = %d\n", i);return 0;
}

 

在《c和指针》这本书中,作者将改代码放在不同的编译器下跑的结果:

在这里插入图片描述

所以咱们还是要写出一些规范的代码,不然编译器也要一个头,两个大了

在这里插入图片描述

在这里插入图片描述

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...