C语言操作符小结
2018-03-28 17:19
393 查看
操作符的分类
算术操作符移位操作符
位操作符
赋值操作符
单目操作符
关系操作符
逻辑操作符
条件操作符
逗号表达式
1、算术操作符
+ - * / %
(1) 除了%操作符之外,其他的几个操作符可以作用于整数和浮点数。
(2) 对于/操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数
(3) %操作符的两个操作数必须为整数。返回的是整除之后的余数。
2、移位操作符
>> 右移操作符 << 左移操作符
对于二进制数左移结果相当于 *2,右移结果相当于/2
int n=10;
m = n<<1;
//结果n不变仍为10,m变为20
左移操作符的移位规则:
左边抛弃,右边补0右移操作符规则:
逻辑移位左边用0填充,右边丢弃
算术移位
左边用原该值的符号位(负数补1,正数补0)填充,右边丢弃
警告⚠ :
对于移位运算符,不不要移动负数位,这个是标准未定义的。 例如: int num = 10; num >> -1; // error
3、位操作符
& // 按位与 | // 按位或 ^ // 按位异或(相同位0,不同为1) 注:他们的操作数必须是整数。
一道变态的面试题:
不能创建临时变量(第三个变量),实现两个数的交换。
#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; }
补充:求两个一大一小数的平均值
average = 小+(大 - 小)/2 = 小+((大 - 小)>>1) =(小&大)+((小^大)>>1)
4、赋值操作符
赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。int weight = 120;// 体重 weight = 89;// 不不满意就赋值 double salary = 10000.0; salary = 20000.0;// 使用赋值操作符赋值。 赋值操作符可以连续使用,比如: 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;// 复合赋值 // 其他运算符一样的道理。这样写更加简洁。
5、单目操作符
! 逻辑反操作 - 负值 + 正值 & 取地址 sizeof 操作数的类型长度(以字节为单位) ~ 对一个数的二进制按位取反 -- 前置、后置-- ++ 前置、后置++ * 间接访问操作符(解引用操作符) (类型) 强制类型转换
关于sizeof
sizeof内部的表达式不参与运算 sizeof(数组名)表示计算整个数组的大小,单位为字节 但是在函数内部不能求数组的长度 例如: printf("%d\n", sizeof(a)); //正确 printf("%d\n", sizeof(int));//正确 printf("%d\n", sizeof a);// 正确 printf("%d\n", sizeof int);//不可行,因为sizeof只是一个单目操作符
前置 ++ 和 - -
对于前置的 ++ 和 -- 来说: #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; }
强制类型转换
int a = (int) 3.14;//括号里为要转换的类型
6、关系操作符
> >= < <= != 用于测试“不相等” == 用于测试“相等”
注意一些运算符使用时候的陷阱
比如: x = get_value(); if(x = 5); // 处理事务
这里看似x如果等于5就执行事务处理,实际上代码是不是这个意思呢?
我们将判断的 == 搞成了了赋值的 = ,这样这个事务无论x是多少都会被执行,所以切记不要写错。
警告:
在编程的过程中== 和=不小心写错,导致的错误。
7、逻辑操作符
&& 逻辑与 || 逻辑或
区分逻辑与和按位与
区分逻辑或和按位或
1&2----->0 1&&2---->1 1|2----->3 1||2---->1
逻辑与和或的特点:
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; } // 程序输出的结果是什什么?
总结
如:int i = 0,a = 0,b = 2,c = 3,d = 4; i = a++&&++b&&d++; 输出的结果a,b,c,d分别为 1,2,3,4 因为:a初值为0,再逻辑与任何数都为0 ,后边都可以不计算即为定义的原值,再++,a=1,其它不变
前为真,没有必要 | | , | | 任何数都为真
前为假,没有必要 &&,&&任何数都为假
8、条件操作符
exp1 ? exp2 : exp3
9、逗号表达式
exp1, exp2, exp3, …expN
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式,从左向右依次执行。整个表达式的结果是最后一个表达式的结果。
10、下标引用、函数调用和结构成员
1.[ ]操作数:一个数组名 + 一个索引值
int arr[10];// 创建数组 arr[9] = 10;// 实用下标引用操作符。
2.( )
函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
#include <stdio.h> void test1() { printf("hehe\n"); } void test2(const char *str) { printf("%s\n", str); } int main() { test1(); // 实用()作为函数调用操作符。 test2("hello .");// 实用()作为函数调用操作符。 return 0; }
3.访问一个结构的成员
. 结构体.成员名
-> 结构体指针->成员名
#include <stdio.h> struct Stu { char name[10]; int age; char sex[5]; double score;//此处name,age,sex,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; }
表达式求值
顺序为:long double double float unsigned long int long int unsigned int int
操作符的属性
复杂表达式的求值有三个影响的因素。1. 操作符的优先级
2. 操作符的结合性
3. 是否控制求值顺序。
两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。