C语言的操作符共分为算术操作符,移位操作符,位操作符,赋值操作符,单目操作符,关系操作符,逻辑操作符,条件操作符,逗号表达式,下表引用、函数调用和结构成员这10大类。
1.算术操作符
此类操作符由 +(加), -(减), *(乘), /(整除), %(求模)这5个组成,由于它们的计算规则和我们的数学中所学的大致相同,所以是比较容易理解的。只有以下3点需要注意:1.除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。2.对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。3.% 操作符的两个操作数必须是整数,返回的是整除之后的余数。
2.移位操作符
此类操作符只有 <<(左移操作符)和 >>(右移操作符)。(我们要知道整数在内存中存的是二进制补码。)
(1).左移操作符移位规则:
左边抛弃,右边补0
(2).右移操作符移位规则:
首先右移运算分两种:
逻辑移位,左边用0填充,右边丢弃
算术移位,左边用原该值的符号位填充,右边丢弃
注:对于移位运算符,不要移动负数位,这个是标准未定义的。
3.位操作符
首先位操作符有 & (按位与), | (按位或), ^ (按位异或) 【注:他们的操作数必须是整数】
整数在内存中是以二进制补码形式存储的,所以我们在计算这三个操作符时,应该先将十进制数转换为二进制表示,然后再将其二进制的补码给写出来(正数的补码就是原码本身,而负数的补码是其反码加1),再进行运算。运算时,按位与即有0为0,全1为1,按位或即有1为1,全0为0,按位异或即相同为0,不同为1。再计算出结果后我们要注意的是这是的结果是输出十进制结果的二进制补码形式,所以我们要将其变为十进制形式。正数不变直接将二进制改为十进制表示,若是负数,则需先减1得其反码,再除符号位不变其余位取反得其二进制原码,最后将二进制改为十进制表示。
4.赋值操作符
赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的的值。也就是你可以自己重新赋值。
int weight = 120;//体重 weight = 89;//如果对上面的体重不满意,就可以重新赋值 //赋值操作符可以继续连续使用 int a = 10; int x = 0; int y = 20; a = x = y+1;//连续赋值
复合赋值符:+= , -= , *= ,/= , %= , >>= , <<= ,&=, |=, ^= 。
这些运算符都可以写成复合的效果,比如:
int x = 10; x = x+10; x += 10;//复合赋值,与上面一个代码表达意思一样,这样写更加简洁
5.单目操作符
单目操作符包括:! (逻辑反操作),- (负值),+ (正值),& (取地址), sizeof (以字节为单位的操作数的类型长度), ~ (对一个数的二进制按位取反), -- (前置、后置--),++ (前置、后置++),* (间接访问符即解引用操作符), (类型) (强制类型转换) 。
#includeint main(){ int a = -10;//赋值 int *p = NULL;//解引用操作符 printf("%d\n", !2);//结果为0 printf("%d\n", !0);//非0为1 a = -a;//负值 p = &a;//取a的地址存在p中 printf("%d\n", sizeof(a));//结果为4,因为a是int型,所以为4个字节 printf("%d\n", sizeof(int));//结果为4 printf("%d\n", sizeof a);//这样写也可以,结果也是4 printf("%d\n", sizeof int);//这样写是错误的写法 return 0;}
sizeof和数组:
数组名可以表示整个数组的情况:sizeof(数组名) 和 &数组名
数组名可以表示首元素地址的情况:除了以上两种情况以外的所有情况都是表示首元素地址
--和++运算符:
//前置++和前置-- #includeint main() { int a = 10; int x = ++a; //先对a进行自增,然后再使用a,也就是表达式的值是a自增后的值。x为11。 int y = --a; //先对a进行自减,然后再使用a,也就是表达式的值是a自减后的值。y为10。 return 0; } //后置++和后置-- #include int main() { int a = 10; int x = ++a; //先使用a再对a自增,这样x的值为10,a变成11。 int y = --a; //先使用a再对a自减,这样y的值为11,a变成10。 return 0; }
6.关系操作符
C语言中的关系操作符有: >(大于),>=(大于等于),<(小于),<=(小于等于),!=(用于测试“不相等”),==(用于测试“相等”)。
此类操作符较为简单,就不多说了。
7.逻辑操作符
逻辑操作符有:&&(逻辑与),||(逻辑或)。
区分逻辑与和按位与 区分逻辑或和按位或:1&2=0,1&&2=1; 1|2=3,1||2=1。
8.条件操作符
exp1 ? exp2 : exp3 (即若表达式exp1成立,则返回表达式exp2,若表达式exp1不成立,则返回表达式exp3)。
如:b = (a>5) ? 3 : -3; //表示如果a>5成立,则b值为3,若a>5不成立,则b值为-3。
9.逗号表达式
exp1, exp2, exp3, ...expN
逗号表达式,就是用逗号隔开的多个表达式。逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
//代码1 int a = 1; int b = 2; int c = (a>b, a=b+10, a, b = a+1);//逗号表达式 //结果c为13 //代码2 if(a = b+1, c = a/2, d>0) //就相当于 if(d>0)
10.下标引用、函数调用和结构成员
(1). [ ]下标引用操作符
操作数:一个数组名 + 一个索引值
int arr[10];//创建数组 arr[9] = 10;//实用下标引用操作符 //[ ] 的两个操作数是arr和9。
(2). ()函数调用操作符,接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数是传递给函数的参数
#includevoid sheena1() { printf("hello\n"); } void sheena2() { printf("%s\n",str) } int main() { sheena1(); //实用()作为函数调用操作符 sheena2("hello word!");//实用()作为函数调用操作符 return 0; }
(3).访问一个结构的成员
.结构体.成员名
->结构体指针->成员名
#includestruct 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; }