1. 算术操作符
用于基本数学运算,有以下几类:
`+`:加法。例如,`a + b` 将变量 `a` 和 `b` 的值相加。
`-`:减法。例如,`a - b` 将变量 `a` 的值减去 `b` 的值。
`*`:乘法。例如,`a * b` 计算 `a` 和 `b` 的乘积。
`/`:除法。例如,`a / b` 计算 `a` 除以 `b` 的商。在C语言中,如果两个操作数都是整数,结果也会是整数,即进行整除。
`%`:取模。例如,`a % b` 返回 `a` 除以 `b` 的余数。
`++`:自增。例如,`a++` 将 `a` 的值增加1。
`--`:自减。例如,`a--` 将 `a` 的值减少1。
注意:在C语言中,前置++和后置++都是一元操作符,用于将变量的值增加1。但是它们的使用方式和效果略有不同。
前置++操作符用于先增加变量的值,然后再进行其他操作。例如:
int a = 5;
int b = ++a;
printf("%d %d", a, b); // 输出:6 6
后置++操作符用于先进行其他操作,然后再增加变量的值。例如:
int a = 5;
int b = a++;
printf("%d %d", a, b); // 输出:6 5
2. 关系操作符
用于比较两个值的大小关系,并根据比较结果返回一个布尔值(true或false)。
`==`:等于。检查两个表达式的值是否相等。
`!=`:不等于。检查两个表达式的值是否不相等。
`<`:小于。检查左侧表达式的值是否小于右侧表达式的值。
`>`:大于。检查左侧表达式的值是否大于右侧表达式的值。
`<=`:小于等于。检查左侧表达式的值是否小于或等于右侧表达式的值。
`>=`:大于等于。检查左侧表达式的值是否大于或等于右侧表达式的值。
3. 逻辑操作符
用于进行逻辑运算,它们可以将多个条件组合在一起,形成一个更复杂的逻辑表达式。以下是C语言中常用的逻辑操作符及其作用:
`&&`:逻辑与。两个操作数都为真时,结果为真。
`||`:逻辑或。两个操作数中至少有一个为真时,结果为真。
`!`:逻辑非。反转操作数的真值。
4. 位操作符
用于对整数在内存中的二进制位进行操作。
`&`:按位与。对两个操作数的二进制表示进行逐位与操作。
主要用于清零特定位、保留特定位以及检查特定位是否设置等。按位与操作符可以将一个数中的某些二进制位清零,通常用于屏蔽某些位。
`|`:按位或。对两个操作数的二进制表示进行逐位或操作。
主要用于设置特定位、保留特定位以及检查特定位是否设置等。按位或操作符可以用来将一个数的某些二进制位置1,通常用于设置某些位。
`^`:按位异或。对两个操作数的二进制表示进行逐位异或操作。
主要用于反转特定位、交换两个特定位的值等。按位异或操作符可以用来翻转一个数的某些二进制位,或者用来交换两个位的值。
`~`:按位取反。对操作数的二进制表示进行逐位取反。
主要用于翻转特定位的值。按位反操作符可以将一个数的所有二进制位取反,即将0变为1,将1变为0。
`<<`:左移。将操作数的二进制表示向左移动指定的位数。
左移操作符可以用来实现乘以2的幂次方的效果。
`>>`:右移。将操作数的二进制表示向右移动指定的位数。在C语言中,右移操作符有两种:逻辑右移(`>>`)和算术右移(`>>`),它们在有符号数和无符号数上的行为可能不同。
右移操作符可以用来实现除以2的幂次方的效果。
5. 赋值操作符
`=`:赋值。将右侧表达式的值赋给左侧的变量。
`+=`、`-=`、`*=`、`/=`、`%=`:复合赋值操作符,结合了相应的算术操作和赋值。
6. 条件操作符(三元操作符)
`? :`:如果条件为真,则返回第一个表达式的值;如果条件为假,则返回第二个表达式的值。例如,`condition ? expr1 : expr2`。
例如:
int a = 1;
int b = 9;
int max = (a > b) ? a : b;
因为a
不大于b
,所以max
的值将是b
,即9。
条件操作符是一种方便的写法,它可以在一行代码中完成一个简单的if-else逻辑。但是,对于更复杂的逻辑,用传统的if-else语句更清晰。
7. 逗号操作符
`,`:用于分隔表达式列表。在逗号表达式中,从左到右依次计算每个表达式,整个表达式的值为最后一个表达式的值。
例如:
int a = 0;
int b = 3;
int c = 5;
int d = (a=b+2, c=a-4, b=c+2);
printf("%d\n",d; //等价于d=[(3+2)-4]+2=3
8. 类型转换操作符:
`(type)expression`:
其中 type
是你希望将 expression
转换成的数据类型,expression
是要进行转换的表达式或值。
类型转换在C语言中是非常常见的,因为C语言是一种静态类型语言,这意味着每个变量都有固定的数据类型,并且在编译时检查类型兼容性。
例如:
int i = 10;
float f = (float)i; // 将整数i转换为浮点数f
float f = 10.5;
int i = (int)f; // 将浮点数f转换为整数i,结果为10
unsigned int u = 4294967295; // 最大的无符号32位整数
int s = (int)u; // 将无符号整数u转换为有符号整数s,结果可能是-1,取决于平台和编译器
double *dp;
int *ip = (int *)dp;
// 将double指针dp转换为int指针ip(这通常是不安全的,除非你知道这两个类型实际上指向相同的内存布局)
char c = 'A';
int i = (int)c; // 将字符'A'转换为其ASCII码值65
9. 指针操作符:
指针是一种特殊的变量类型,用于存储内存地址。指针操作符用于操作指针变量,获取或修改指针所指向的值。C语言中的指针操作符主要有两个:*
(解引用操作符)和&
(取地址操作符)。
`&`(取地址操作符): 用于获取变量的内存地址。当作用于一个变量时,它返回该变量在内存中的地址。
int x = 10;
int *p = &x; // p 是一个指针,存储了变量 x 的内存地址
`*`(解引用操作符):用于访问指针所指向的值。当作用于一个指针时,它返回指针指向的内存地址中的值。同时,它也可以用于修改指针指向的值。
int x = 10;
int *p = &x;
// 使用 * 访问指针指向的值
int value = *p; // value 的值是 10
// 使用 * 修改指针指向的值
*p = 20; // 现在 x 的值变成了 20
10. sizeof操作符
-`sizeof`:是C语言中的一个关键字,用于计算变量或数据类型在内存中占据的字节大小。它可以在编译时计算出大小,避免了在运行时进行计算的开销。sizeof
的返回值类型是size_t
,这是一个无符号整数类型,用于表示对象的大小。
sizeof
操作符的用途非常广泛,主要包括以下几个方面:
- 动态分配内存:使用
malloc
函数动态分配内存时,需要知道要分配的内存大小。通过sizeof
可以方便地获取变量或数据类型的大小,从而进行动态内存分配。 - 数据类型大小比较:通过
sizeof
可以得到不同数据类型的大小,便于进行大小比较和类型转换。 - 判断系统平台:通过
sizeof
可以得到一个指针的大小,从而可以判断程序运行的平台是32位还是64位。
例如:
#include <stdio.h>
int main() {
// 获取基本数据类型的大小
printf("Size of int: %zu\n", sizeof(int));
printf("Size of float: %zu\n", sizeof(float));
printf("Size of char: %zu\n", sizeof(char));
// 获取指针的大小
int *ptr = NULL;
printf("Size of int *ptr: %zu\n", sizeof(ptr));
// 动态分配内存和sizeof的使用
int n = 10;
int *arr = (int *)malloc(n * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed\n");
return -1;
}
printf("Size of dynamically allocated memory: %zu\n", n * sizeof(int));
// 获取数组的大小
int myArray[10];
printf("Size of myArray: %zu\n", sizeof(myArray));
return 0;
}
11. 类型限定操作符
类型限定操作符是用于限制或修饰变量或函数类型的关键字。它们提供了更具体、更准确的类型说明,以便更好地控制变量的内存布局和行为。
例如:
const:用于声明一个常量,表示该变量的值不能被修改。
用途:保护变量不被显式地修改,增加代码的可读性和安全性。
volatile:用于告诉编译器该变量的值可能会在任何时候改变,因此编译器不应该对其进行优化。
用途:通常用于硬件编程或多线程编程中,确保每次访问该变量时都从内存中读取其值,而不是使用之前缓存的值
restrict:用于告诉编译器该指针是访问某个对象的唯一途径,编译器可以对该指针进行优化。
用途:帮助编译器进行更好的优化,确保指针指向的内存区域不会被其他指针同时访问。