前言
C语言的操作符是C语言的一个重要部分,也是我们以后在编写程序需要经常需要使用的领域,所以了解每一种操作符的使用方法和作用是非常重要的。
1.算数操作符
算数操作符包含了 + - * / %
这里的 + - * / 我相信大家都知道该含义,这里%表示的是求一个数余数的操作,比如就是
12 % 10 = 2;此外,这里还有一些关于这些操作符的细节是我们需要了解一下的。
1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
2.移位操作符
移位操作符移的是二进制位,对于不同的移向,该又分为左移操作符和右移操作符
<< 左移操作符
>> 右移操作符
注意:移位操作符的操作数只能是整数
对于该具体移位规则我需要和大家具体说明一下
左移原则:左边丢弃,右边补0
右移原则:1.算数右移(比较常见):右边丢弃,左边补原来的符号位
2.逻辑右移:右边丢弃,左边直接补0
移位不能为负数,而且不能过大
这里我们还需要注意一点的是在计算机中我们存储的是一个数的补码,对于具体的概念,大家可以到我之前写地深入理解数据存储中具体了解一下。
这里我就和大家具体演示一下:
#include <stdlib.h> int main() { int a = 1;//这里我们给a赋初值1 a = a << 1;//这里我们把a向左移一位 return 0; }
这里我们可以观察到当a=1的时候a在内存中的具体值(这里的存储方式是小端字节序存储,所以大家在理解的时候按小端存储的方式理解),这里我们打开内存查看a的值
由于这里显示的单位是字节,我们可以知道一个整型是4字节,所以把他转化为每个具体比特位是
这里是把a向左移一位的操作,得到a的值是2。
遵循左移的规则,该在内存中的变化是:
接下来就是右移
#include <stdlib.h> int main() { int a = -1;//这里我们给a赋初值-1 a = a >>1;//这里我们把a向右移一位 return 0; }
具体如下:
这里由于我们存储的是补码,而-1的补码是
11111111111111111111111111111111按每个字节理解得到的就是内存中的值
这里我们可以看出该右移的是遵循的是算数右移的规则,具体演示如下
3.位操作符
位操作符一共有三个:
& :按位与(对应的二进制位置上进行运算,有0为0,两个都是1才是1)
| :按位或(对应的二进制位置上进行运算,有1为1,两个都是0才是0)
^ :按位异或(对应的二进制为相同为0,不同为1)
对于^操作符这里有两个推导出来的规律
1.a^a=0
2.0^a=a
这里我给大家证明一下
int main() { int a = 77; int b = 77; a = a^a; b = b ^ 0; printf(" %d \n", a); printf("%d", b); return 0; }
结果如下:
这里还有一道关于和这里有关的操作符,大家可以了解一下
题目要求是:不创建临时变量,实现两个数交换
#include <stdio.h> int main() { int a = 10; int b = 20; a = a^b; b = a^b; a = a^b; printf("a = %d b = %d\n", a, b); return 0; }
4.赋值操作符
赋值操作符我相信大家已经很熟悉了。
int a=0;//这里我们给a赋值为0
然而我们主要介绍的就是
复合赋值符
+=,-=,*=,/=,%=,>>=,<<=,&=,|=,^=
这里我具体给大家举例说明一下复合赋值操作符的用法
比如这里我们定义一个变量
int a=0;
a+=10;//这里的作用相当于a=a+10;
这里我给大家具体证明一下:
int main() { int a = 77; int b = 77; a = a + 10; b += 10; printf(" %d \n", a); printf("%d", b); return 0; }
结果如下:
5.单目操作符
单目操作符的意思就是操作的是一个操作数
对于某些操作符,大家可以自己尝试一下,很多的估计大家在平时也是经常使用的,这里我着重给大家介绍一下sizeof这个操作符
sizeof()的作用是计算操作数的长度
可能大家之前一直觉得sizeof这个操作符是函数,但是函数调用时,后边要写(),但是sizeof后面的括号可以省略(后面是变量的时候),说明sizeof不是函数,还有就是sizeof内部表达式是不计算的,对于数组和sizeof的关系是当sizeof的操作数是数组的话,数组传的一般是数组的首地址,得到的是整个数组的大小,所以这里我们就可以使用sizeof去求一个数组的长度
比如:
int main() { int a = 77; int b[10] = { 1,2,3,4,5,6,7,8,9,10 }; printf(" %d \n", sizeof (a=a+b[0])); printf("%d\n",sizeof b ); printf("%d\n", a);//a值没变化说明这里sizeof的()内的表达式是不参加运算的 int c = sizeof(b) / sizeof(b[0]);//得到数组长度 printf("%d", c); return 0; }
这里的结果是:
还有两个单目操作符这里我也需要和大家提一下
++,--
对于这两个操作符大家需要注意一下该放在操作数前面和后面的区别
#include <stdio.h> int main() { int a = 10; int x = ++a; //先对a进行自增,然后对使用a,也就是表达式的值是a自增之后的值。x为11。 int y = --a; //先对a进行自减,然后对使用a,也就是表达式的值是a自减之后的值。y为10; return 0; } //后置++和-- #include <stdio.h> int main() { int a = 10; int x = a++; //先对a先使用,再增加,这样x的值是10;之后a变成11; int y = a--; //先对a先使用,再自减,这样y的值是11;之后a变成10; return 0; }
6.关系操作符
这些关系运算符比较简单,没什么可讲的,但是我们要注意一些运算符使用时候的陷阱
7.逻辑操作符
&& 逻辑与 :当两个条件都是真的时候才是真c
|| 逻辑或 :当全为假的时候才是假(
逻辑操作符这里我们需要知道 非0即真
这里我给大家演示一下:
int main() { int a = 0; int b = 1; printf("%d\n", a && b); printf("%d\n", a || b); return 0; }
结果如下:
还有一点就是:
1.对于逻辑与:左边为真,为真,右边无需计算
2.对于逻辑或:左边为真,为真,右边无需计算
我给大家演示一下:
int main() { int a = 0; int b = 1; printf("%d\n", a && (b=b+1)); printf("%d\n", b||(a=a+1)); printf("%d\n", a); printf("%d", b); return 0; }
结果如下:
8. 条件操作符
exp1 ? exp2 : exp3
条件表达式的逻辑是,当exp1为真时,执行exp2,当 exp1为假时,执行exp3
实例演示:
int main() { int a = 0; a ? (a = a + 10) : (a = a + 20); printf("%d", a); return 0; }
结果如下:
9. 逗号表达式
exp1 , exp2 , exp3,...,expn
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
实例展示:
int main() { int a = 1; int b = 2; int c = (a > b, a = b + 10, a, b = a + 1); printf("%d\n", a); printf("%d\n", b); printf("%d\n", c); return 0; }
结果如下:
10.下标引用、函数调用和结构成员
10.1 [ ] 下标引用操作符
int arr[10];//创建数组
arr[9] = 10;//实用下标引用操作符。
[ ]的两个操作数是arr和9。
10.2 ( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数
10.3 访问一个结构的成员
. 结构体 . 成员名
-> 结构体指针 -> 成员名
#include <stdio.h> 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; }