1、赋值运算符、条件运算符、逗号运算符:
测试代码:
#include <stdio.h>
int main() {
// 基本赋值运算符
int a = 5;
printf("a = %d\n", a);
// 复合赋值运算符
a += 3; // 等同于 a = a + 3;
printf("a += 3; a = %d\n", a);
a -= 2; // 等同于 a = a - 2;
printf("a -= 2; a = %d\n", a);
a *= 2; // 等同于 a = a * 2;
printf("a *= 2; a = %d\n", a);
a /= 2; // 等同于 a = a / 2;
printf("a /= 2; a = %d\n", a);
a %= 3; // 等同于 a = a % 3;
printf("a %= 3; a = %d\n", a);
// 条件运算符
// 如果第一个操作数的值为真(非零),则条件运算符的结果为第二个操作数的值;否则,为第三个操作数的值。
int b = 10, c;
c = (b > 5) ? b : 5; // 如果b大于5,则c为b的值,否则为5
printf("b > 5 ? b : 5; c = %d\n", c);
// 逗号运算符
int d, e, f;
d = 5, e = 10, f = (d++, e *= 2, d + e); // 逗号运算符从左到右评估,返回最后一个表达式的值
printf("d = %d, e = %d, f = %d\n", d, e, f);
return 0;
}
运行结果如下:
...........................................................................................................................................................
2、指针运算符:
测试代码1:
#include <stdio.h>
int main() {
int arr[] = {1, 2, 3, 4, 5};
int *start = arr; // 指向数组的第一个元素
int *end = arr + sizeof(arr) / sizeof(arr[0]); // 指向数组的最后一个元素之后的位置
int *ptr;
// 使用指针遍历数组(增量运算)
for (ptr = start; ptr != end; ptr++) {
printf("%d ", *ptr); // 访问当前指针指向的值
}
printf("\n");
// 计算数组中元素的数量(指针减法运算)
// 需要end在循环中作为条件,并用于计算数组长度
// 由于计算的是两个指针之间的差值(以元素数量计),
//end已经考虑了最后一个元素的偏移,所以直接使用end-start
int length = end - start;
printf("The array has %d elements.\n", length);
return 0;
}
运行结果如下:
测试代码2:
#include <stdio.h>
int main() {
int var = 10;
int arr[] = {20, 30, 40, 50};
int *ptr;
// 取地址运算
ptr = &var; // 将变量var的地址赋给指针ptr
printf("Address of var: %p\n", (void*)ptr); // 打印var的地址
printf("Value of var: %d\n", *ptr); // 通过指针访问var的值
// 指针的增量运算
ptr = arr; // 指针ptr现在指向数组arr的第一个元素
printf("First element: %d\n", *ptr); // 访问并打印第一个元素
ptr++; // 指针ptr向前移动到下一个元素
printf("Second element: %d\n", *ptr); // 访问并打印第二个元素
// 指针的减量运算,一般不会手动对指针进行减量运算遍历数组,
// 减量运算更多用于特定的场景,
// 比如当需要回退到之前访问过的某个元素时。
ptr--; // 指针ptr向后移动回第一个元素
printf("Back to first element: %d\n", *ptr);
return 0;
}
运行结果如下:
..........................................................................................................................................................
3、求字节运算符、强制类型转换符、分量运算符、下标运算符:
测试代码:
#include <stdio.h>
#include <string.h> // 用于strcpy函数
//定义一个Person结构体
struct Person {
char name[50];
int age;
};
int main() {
// 创建一个Person类型的数组people
struct Person people[3];
//点运算符.:用于结构体变量,直接访问结构体成员。
//点运算符初始化结构体数组中的每个元素
strcpy(people[0].name, "Alice");
people[0].age = 30;
strcpy(people[1].name, "Bob");
people[1].age = 25;
strcpy(people[2].name, "Charlie");
people[2].age = 35;
// 下标运算符访问并打印结构体数组中的元素
for (int i = 0; i < 3; i++) {
printf("Name: %s, Age: %d\n", people[i].name, people[i].age);
}
// sizeof运算
printf("Size of struct Person: %zu bytes\n", sizeof(struct Person));
// 制类型转换
int intValue = 10;
float floatValue = (float)intValue;
printf("Int as float: %f\n", floatValue);
//从void*转换回原始类型
void* ptr = &people[0]; // 假设不知道ptr指向什么类型,只知道是void*
struct Person* personPtr = (struct Person*)ptr; // 强制转换为struct Person*
// 箭头运算符->:用于结构体指针,通过指针访问结构体成员。
printf("Name from void* pointer: %s\n", personPtr->name); // 箭头运算符访问结构体成员。
return 0;
}
运行结果如下:
.......................................................................................................................................................
4、运算符优先级:
运算符的优先级决定了表达式中运算的顺序,而结合性则决定具有相同优先级的运算符之间操作的顺序。运算符(按照优先级从高到低排列),以及结合性(左结合或右结合)。
1. 括号和成员访问运算符
():函数调用,表达式求值
[]:数组下标
.:结构体或联合体成员访问
->:结构体指针成员访问
(类型):类型转换
结合性:不适用(括号内运算视为一个整体)
2. 后缀运算符
++(后缀):自增
--(后缀):自减
结合性:左结合
3. 前缀运算符
++(前缀):自增
--(前缀):自减
+(一元):正号
-(一元):负号
~:按位取反
!:逻辑非
*(指针解引用)
&(取地址)
(类型) {}(复合字面量,C99起)
结合性:右结合
4. 乘法运算符
*:乘法
/:除法
%:取模(余数)
结合性:左结合
5. 加法运算符
+:加法
-:减法
结合性:左结合
6. 位移运算符
<<:左移
>>:右移
结合性:左结合
7. 关系运算符
<:小于
>:大于
<=:小于或等于
>=:大于或等于
结合性:左结合
8. 相等运算符
==:等于
!=:不等于
结合性:左结合
9. 位与运算符
&:按位与
结合性:左结合
10. 位异或运算符
^:按位异或
结合性:左结合
11. 位或运算符
|:按位或
结合性:左结合
12. 逻辑与运算符
&&:逻辑与
结合性:左结合
13. 逻辑或运算符
||:逻辑或
结合性:左结合
14. 条件运算符
?::三元条件运算符
结合性:右结合
15. 赋值运算符及其复合赋值运算符
=:赋值
+=、-=、*=、/=、%=、<<=、>>=、&=、^=、|=:复合赋值
结合性:右结合
16. 逗号运算符
,:逗号运算符
结合性:左结合
测试代码:
#include <stdio.h>
int main() {
int a = 5, b = 3, c = 2, d = 4;
// 后缀运算符
printf("Postfix increment: %d\n", a++);
// 前缀运算符
printf("Prefix increment: %d\n", ++b);
// 算术运算符(乘法优先级高于加法)
printf("Multiplication and addition: %d\n", a * b + c);
// 位移运算符
printf("Left shift: %d\n", c << 2);
// 关系运算符
printf("Relational comparison: %d\n", a > b);
// 相等运算符
printf("Equality comparison: %d\n", d == c * 2);
// 位运算符
printf("Bitwise AND: %d\n", a & b);
printf("Bitwise XOR: %d\n", a ^ b);
printf("Bitwise OR: %d\n", a | b);
// 逻辑运算符
int e = 0, f = 1;
printf("Logical AND: %d\n", e && f);
printf("Logical OR: %d\n", e || f);
// 条件运算符
printf("Conditional (ternary) operator: %d\n", e ? 0 : f);
// 赋值运算符及其复合形式
a = b = c = 0; // 链式赋值,c=0, b=0, a=0
printf("Assignment: a=%d, b=%d, c=%d\n", a, b, c);
a += b; // 相当于 a = a + b
printf("Compound assignment: a=%d\n", a);
// 逗号运算符
printf("Comma operator: %d\n", (a = 1, b = 2, b)); // 逗号运算符从左到右计算,返回最右边的值,即2
return 0;
}
运行结果如下: