操作符和表达式
本章重点 1.各种操作符的介绍。 2.表达式的求值。
操作符
分类:
- 算数操作符
- 移位操作符
- 位操作符
- 赋值操作符
- 单目操作符
- 关系操作符
- 逻辑操作符
- 条件操作符
- 逗号操作符
- 下标引用、函数调用和结构成员
算数操作符
+ - * / %
1 .除了%操作符之外,其他几个操作符可以作用于整数或浮点数。 2 .对于 / 操作符如果两个操作数都为整数,执行整数除法。而只有一端有浮点数,则执行浮点数除法。 3 .%操作符的两个操作数必须为整数,返回的是整除之后的余数。
移位操作符
<< 左移操作符
>> 右移操作符
int main() {
int a = 2;
int b = a << 1;
int c = a >> 1;
printf("b = %d\n",b);
printf("c = %d\n",c);
return 0;
}
警告:移位不能移动负数位;
位操作符
& 按位与
| 按位或
^ 按位异或
注:他们的操作数必须是整数
int main() {
int a = 3;
int b = 5;
int c = a & b;
int d = a | b;
int e = a ^ b;
printf("c = %d\n",c);
printf("d = %d\n",d);
printf("e = %d\n",e);
return 0;
}
练习:编写代码实现:求一个整数存储在内存中的二进制中1的个数。
赋值操作符
int weight = 100;
weight = 89;
复合操作符
+=
-=
*=
/=
%=
&=
|=
^=
>>=
<<=
int a = 10;
a = a + 10;
a += 10;
单目操作符
单目操作符 - 只有一个操作数
! 逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数的类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作符(解引用操作符)
(类型) 强制类型转换
sizeof是一个操作符,不是函数
int main() {
short s = 5;
int a = 10;
printf("%d\n",sizeof(s = a + 2));
printf("%d\n",s);
int a = 10;
int arr[10] = {0};
printf("%d\n",sizeof(arr));
printf("%d\n",sizeof(int [10]));
return 0;
}
int main() {
int a = 4;
a = ~a;
printf("%d\n",a);
return 0;
}
//& 取地址
int main() {
int a = 10;
printf("%p\n",&a);
int* pa = &a;
*pa = 20;
printf("%d\n",a);
return 0;
}
关系操作符
>
>=
<
<=
!=
==
逻辑操作符
&& 逻辑与
|| 逻辑或
区分逻辑与和按位与 区分逻辑或和按位或
1&2 ---> 0
1&&2 ---> 1
1|2 ---> 3
1||2 ---> 1
逻辑与和逻辑或的特点:
如果 a && b中,a=0,则b不参与运算。 如果a ||b中,a=1,则b不参与运算。
int main() {
int i = 0, a = 0, b = 2, c = 3, d = 4;
i = a++ && ++b && d++;
printf("a = %d\nb = %d\nc = %d\nd = %d\n",a,b,c,d);
return 0;
}
三目操作符(条件操作符)
exp1 ? exp2 : exp3
练习:
int main() {
int a = 0;
int b = (a > 5 ? 1 : -1);
printf("%d\n",b);
return 0;
}
逗号表达式
逗号表达式 ,就是用逗号隔开的多个表达式。要从左向右依次计算,但是整个表达式的结果是最后一个表达式的结果。
int main() {
int a = 5;
int b = 3;
int c = 0;
int d = (c = 1, a = c + 3,b = a - 4,c += 5);
printf("d = %d\n",d);
return 0;
}
a = get_val();
count_val(a);
while(a>0){
a = get_val();
count_val(a);
}
while(a = get_val(),count_val(a),a>0){
}
下标引用、函数调用和结构成员
1.[ ] 下标引用操作符
操作数:一个数组名 + 一个索引值
int main() {
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n",arr[4]);
return 0;
}
2.() 函数调用操作符
接收一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
3.访问一个结构的成员
.结构体.成员名 ->结构体指针->成员名
struct Book {
char name[20];
char id[20];
int price;
};
int main() {
struct Book b = {"C语言","C20102",55};
struct Book* pb = &b;
printf("书名:%s\n",b.name);
printf("书号:%s\n",b.id);
printf("价格:%d\n",b.price);
printf("书名:%s\n", pb->name);
printf("书号:%s\n", pb->id);
printf("价格:%d\n", pb->price);
return 0;
}
表达式求值
隐式类型转换
C的整形算数运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换成为整型提升。 如何进行整型提升?
整型提升是按照变量的数据类型的符号位来进行提升的
整型提升的例子:
int main() {
char a = 3;
char b = 127;
char c = a + b;
printf("%d\n",c);
return 0;
}
算数转换
操作符的属性 复杂表达式的求值有三个影响的因素。
- 操作符的优先级
- 操作符的结核性
- 是否控制求值顺序
|