目录
前言
一、操作符是什么?
二、操作符的分类
三、算术操作符
四、逻辑操作符
五、比较操作符
六、位操作符
七、赋值操作符
八、其他操作符
九、运算符优先级表格
总结
前言
在编写程序时,最常用到的就是操作符,本文将详细的介绍我们在编写程序时需要用到的操作符
一、操作符是什么?
操作符是一种用于执行特定操作的字符或符号。在编程中,操作符用于执行数学、比较、逻辑和位操作等操作。例如,加号(+)是一个操作符,用于对数字进行加法运算。等于号(==)是一个操作符,用于比较两个值是否相等。其他常见的操作符包括减号(-)、乘号(*)、除号(/)、取模(%)、小于号(<)、大于号(>)、逻辑与(&&)、逻辑或(||)等。
二、操作符的分类
C语言中常见的操作符包括:
-
算术操作符:+、-、*、/、%(取模)
-
逻辑操作符:&&(逻辑与)、||(逻辑或)、!(逻辑非)
-
比较操作符:>、<、>=、<=、==、!=
-
位操作符:&(按位与)、|(按位或)、^(按位异或)、~(按位取反)、<<(左移)、>>(右移)
-
赋值操作符:=、+=、-=、*=、/=、%=、<<=、>>=、&=、|=、^=
-
其他操作符:? :(三目运算符)、,(逗号运算符)、sizeof(大小运算符)、[ ] (下标引用操作符)、( ) (函数调用操作符)、&(取地址操作符)、*(解引用操作符)、.和->(结构成员操作符)、++(自增运算符)、--(自减运算符)、(类型)(强制类型转换)
三、算术操作符
算术操作符包括:+、-、*、/、%(取模)
其中加法操作符(+)、减法操作符(-)和乘法操作符(*)使用的逻辑,就是我们正常的数学使用逻辑,这里就不展开细说了。这个部分我们重点介绍除法运算符(/)和取余运算符(%)。
#include<stdio.h>
int main()
{
printf("%lf\n", 3 / 5);
printf("%lf\n", 3.0 / 5);
return 0;
}
2.取余:% 操作符的两个操作数必须为整数,返回的是整除之后的余数。
#include<stdio.h>
int main()
{
printf("%d\n", 3 % 5);
return 0;
}
四、逻辑操作符
逻辑操作符是一组用于执行布尔逻辑运算的符号,逻辑操作符包括:&&(逻辑与)、||(逻辑或)、!(逻辑非)
1.逻辑与:表示“且”的关系,用符号“&&”表示。有一假即为假,全真才为真。
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = 7;
if (a > b && a < c)//为假,不进入if语句
{
printf("hhhhh\n");
}
return 0;
}
2.逻辑或:表示“或”的关系,用符号“||”表示。有一真即为真,全假才为假。
#include<stdio.h>
int main()
{
int a = 3;
int b = 5;
int c = 7;
if (a > b || a < c)//为真,进入if语句
{
printf("hhhhh\n");
}
return 0;
}
3.逻辑非:表示“非”的关系,用符号“!”表示。0逻辑非运算后为1,非零逻辑非运算后为0.
#include<stdio.h>
int main()
{
int a = 3;
int b = 0;
printf("%d\n", !a);
printf("%d\n", !b);
return 0;
}
五、比较操作符
比较操作符是指用于比较两个值之间关系的符号,比较操作符在编程语言中用于条件语句和循环语句中,常用于判断条件是否成立,从而决定程序的执行流程。比较操作符包括:>、<、>=、<=、==、!=
1.大于操作符(>):检查一个值是否大于另一个值。
2.小于操作符(<):检查一个值是否小于另一个值。
3.大于等于操作符(>=):检查一个值是否大于或等于另一个值。
4.小于等于操作符(<=):检查一个值是否小于或等于另一个值。
5.相等操作符(==):检查两个值是否相等。
6.不等操作符(!=):检查两个值是否不相等。
六、位操作符
位操作符是一种用于操作二进制位的运算符。位操作符包括:&(按位与)、|(按位或)、^(按位异或)、~(按位取反)、<<(左移)、>>(右移)
在介绍位操作符之前,这里先来简单的介绍一下计算机中二进制的表示方式,其中包括原码、反码和补码:
原码(Sign-Magnitude)表示法是最简单、最直接的表示法。一个数用二进制表示,其中最高位是符号位,0表示正数,1表示负数。例如,8位二进制数+5的原码为00000101,-5的原码为10000101。
反码(One’s Complement)表示法是在原码的基础上,对于负数取反,即符号位不变,其余各位取反。例如,8位二进制数+5的反码为00000101,-5的反码为11111010。
补码(Two’s Complement)表示法是在反码的基础上,将反码加1。对于任何一个数,它的补码都是唯一的。例如,8位二进制数+5的补码为00000101,-5的补码为11111011。
补码表示法是计算机中最常用的表示法。它具有以下优点:
- 计算机中可以使用加法器完成加减法的运算,这种运算对于原码和反码都不适用,但对于补码却是可行的。
- 对于补码表示的数值,符号位和数值计算是分开的,计算机不需要将符号位和数值分别进行处理。
- 补码表示法仅有一个零,这种零是可以表示数值的,不会造成计算机中的混淆。
1.按位与(&):将两个操作数的每一位进行与运算,如果两个位都为1,则结果为1,否则为0。
#include<stdio.h>
int main()
{
int a = 3;
int b = -5;
int c = a & b;//按(2进制)位与
//00000000000000000000000000000011 --- 3的补码
//10000000000000000000000000000101
//11111111111111111111111111111010
//11111111111111111111111111111011 --- -5的补码
//00000000000000000000000000000011 --- 3的补码
//00000000000000000000000000000011 --- 3&-5=3
printf("%d\n", c);
return 0;
}
2.按位或(|):将两个操作数的每一位进行或运算,如果两个位中有任意一个为1,则结果为1,否则为0。
#include<stdio.h>
int main()
{
int a = 3;
int b = -5;
int c = a | b;//按(2进制)位或
//00000000000000000000000000000011 --- 3的补码
//10000000000000000000000000000101
//11111111111111111111111111111010
//11111111111111111111111111111011 --- -5的补码
//00000000000000000000000000000011 --- 3的补码
//11111111111111111111111111111011 --- 3|-5
//10000000000000000000000000000100
//10000000000000000000000000000101 --- 3|-5=-5
printf("%d\n", c);
return 0;
}
3.按位异或(^):将两个操作数的每一位进行异或运算,如果两个位不相同,则结果为1,否则为0。
#include<stdio.h>
int main()
{
int a = 3;
int b = -5;
int c = a ^ b;//按(2进制)位异或
//00000000000000000000000000000011 --- 3的补码
//10000000000000000000000000000101
//11111111111111111111111111111010
//11111111111111111111111111111011 --- -5的补码
//00000000000000000000000000000011 --- 3的补码
//11111111111111111111111111111000 --- 3^-5
//10000000000000000000000000000111
//10000000000000000000000000001000 --- 3^-5=-8
printf("%d\n", c);
return 0;
}
4.按位取反(~):将操作数的每一位进行取反运算,即1变为0,0变为1。
#include<stdio.h>
int main()
{
int a = 0;
int b = ~a;//按(2进制)位取反
//00000000000000000000000000000000 --- 0的补码
//11111111111111111111111111111111 --- ~0
//10000000000000000000000000000000
//10000000000000000000000000000001 --- ~0=-1
printf("%d\n", b);
return 0;
}
5.左移(<<):将操作数的二进制位向左移动指定的位数,右边补0。
#include<stdio.h>
int main()
{
//左移操作:左边丢弃,右边补0
int a = 7;
int b = a << 1;
//00000000000000000000000000000111 --- 7的补码
//00000000000000000000000000001110 --- 7<<1=14
//负数同理
printf("%d\n", b);
return 0;
}
6.右移(>>):右移运算分两种,分别是逻辑右移和算数右移,一般编译器中使用的是算术移位
- 逻辑移位:左边用0填充,右边丢弃
- 算术移位:左边用原该值的符号位填充,右边丢弃
#include<stdio.h>
int main()
{
int c = -10;
int d = c >> 1;
//10000000000000000000000000001010
//11111111111111111111111111110101
//11111111111111111111111111110110 —— -10的补码
//11111111111111111111111111111011 —— -10>>1
//10000000000000000000000000000100 ——
//10000000000000000000000000000101 —— -10>>1=-5
printf("%d\n", d);
return 0;
}
七、赋值操作符
赋值操作符是一种用于改变变量的值的运算符,它将右侧的值赋给左侧的变量。赋值操作符包括:=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=
1.=:简单赋值操作符,将右侧的值赋给左侧的变量。
2.+=:加等于操作符,将左侧的变量加上右侧的值,并将结果赋给左侧的变量。
3.-=:减等于操作符,将左侧的变量减去右侧的值,并将结果赋给左侧的变量。
4.*=:乘等于操作符,将左侧的变量乘以右侧的值,并将结果赋给左侧的变量。
5./=:除等于操作符,将左侧的变量除以右侧的值,并将结果赋给左侧的变量。
6.%=:取模等于操作符,将左侧的变量取模右侧的值,并将结果赋给左侧的变量。
7.<<=:左移等于操作符,将左侧的变量左移右侧的值,并将结果赋给左侧的变量。
8.>>=:右移等于操作符,将左侧的变量右移右侧的值,并将结果赋给左侧的变量。
9.&=:按位与等于操作符,将左侧的变量按位与右侧的值,并将结果赋给左侧的变量。
10.|=:按位或等于操作符,将左侧的变量按位或右侧的值,并将结果赋给左侧的变量。
11.^=:按位异或等于操作符,将左侧的变量按位异或右侧的值,并将结果赋给左侧的变量。
这些操作符可以使我们的代码更加简洁,但也比较简单,就不过多的叙述了。
八、其他操作符
包括:? :(三目运算符)、,(逗号运算符)、sizeof(大小运算符)、[ ] (下标引用操作符)、( ) (函数调用操作符)、&(取地址操作符)、*(解引用操作符)、.和->(结构成员操作符)、++(自增运算符)、--(自减运算符)、(类型)(强制类型转换)
1.? :(三目运算符):三目操作符是一种简单的条件表达式,它可以用来代替 if...else 语句的一部分。其基本语法如下:
condition ? expression1 : expression2
其中,condition 是一个布尔表达式,如果为 true,则执行 expression1,否则执行 expression2。expression1 和 expression2 可以是任意合法的表达式,包括常量、变量、函数调用等等。注意,三目操作符返回的是一个值,可以用于赋值操作或表达式计算。
#include<stdio.h>
int main()
{
int a = 3;
int b = 4;
int max = a > b ? a : b;
printf("%d\n", max);
return 0;
}
2.,(逗号运算符):逗号运算符可以分隔两个或多个表达式,依次计算每个表达式,并返回最后一个表达式的值。
var a = 1, b = 2, c = 3;
这里,逗号运算符被用于在一条语句中声明并初始化多个变量。在此过程中,它会依次计算每个表达式(即1、2和3),并返回最后一个表达式的值(即3)。因此,上述代码将a赋值为1,b赋值为2,c赋值为3。
3.sizeof(大小运算符):sizeof用于计算数据类型或变量占用的内存字节数,sizeof计算的结果是size_t 类型的,size_t是无符号整型的,对size_t 类型的数据进行打印,可以使用%zd,sizeof后面的括号在括号中写的不是类型的时候,括号可以省略,这样就可以说明sizeof不是函数.
#include<stdio.h>
int main()
{
int a = 10;
printf("%zd\n", sizeof(a));
printf("%zd\n", sizeof a);
printf("%zd\n", sizeof(int));
int arr[10] = {0};
printf("%zd\n", sizeof(arr));
printf("%zd\n", sizeof(arr[0]));
printf("%zd\n", sizeof(arr) / sizeof(arr[0]));
return 0;
}
4.[ ] (下标引用操作符):下标引用操作符用于访问数组或指针的元素,它是一个方括号[ ]。我们可以使用下标引用操作符来访问数组的元素,对于指针类型的变量,我们也可以使用下标引用操作符来访问其中的元素。
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", arr[5]);//[] 下标引用操作符
int* pa = arr;
printf("%d\n", pa[5]);//[] 下标引用操作符
return 0;
}
5.( ) (函数调用操作符):函数调用操作符()
用于调用函数,它可以接受零个或多个参数。在函数调用时,我们需要提供函数名和参数列表,参数列表中的每个参数都是用逗号分隔的表达式。
#include<stdio.h>
int Add(int a, int b)
{
return a + b;
}
int main()
{
printf("hehe\n");//()函数调用操作符
int r = Add(3, 5);//()函数调用操作符
return 0;
}
6.&(取地址操作符):它返回一个变量的地址。比如,&a
返回变量a
的地址。
#include<stdio.h>
int main()
{
int a = 10;
int*p = &a;//a变量的地址
return 0;
}
7.*(解引用操作符):它用于获取指针指向的值。比如,如果有一个指向a
的指针p
,那么*p
就是a
的值。
#include<stdio.h>
int main()
{
int a = 10;
int*p = &a;//a变量的地址
*p = 20;//*p:对p进行解引用操作,*p是通过p中存放的地址,找到p指向的对象,*p其实是a
return 0;
}
8..和->(结构成员操作符):结构成员操作符用于访问结构体变量的成员
#include<stdio.h>
struct Book
{
char name[20];
int price;
};
int main()
{
struct Book b = {"C语言", 66};
struct Book* pb = &b;
printf("%s %d\n", b.name, b.price);
printf("%s %d\n", (*pb).name, (*pb).price);
printf("%s %d\n", pb->name, pb->price);
return 0;
}
9.++(自增运算符):自增运算符是一种一元运算符,用于增加变量的值。在程序中,自增运算符通常表示为两个加号(++),写在变量的前面或后面。如果写在变量的前面(前缀自增运算符),则先将变量的值加一,再把新的值赋给变量;如果写在变量的后面(后缀自增运算符),则先将变量的原值赋给表达式,再将变量的值加一。
#include<stdio.h>
int main()
{
int a1 = 6;
int a2 = 6;
int b1 = ++a1;
int b2 = a2++;
printf("%d\n", a1);
printf("%d\n", b1);
printf("%d\n", a2);
printf("%d\n", b2);
return 0;
}
10.--(自减运算符)自减运算符和自增运算符非常类似,只不过是将变量的值减一。自减运算符也是一元运算符,表示为两个减号(--),同样可以写在变量的前面或后面。如果写在变量的前面(前缀自减运算符),则先将变量的值减一,再把新的值赋给变量;如果写在变量的后面(后缀自减运算符),则先将变量的原值赋给表达式,再将变量的值减一。
#include<stdio.h>
int main()
{
int a1 = 6;
int a2 = 6;
int b1 = --a1;
int b2 = a2--;
printf("%d\n", a1);
printf("%d\n", b1);
printf("%d\n", a2);
printf("%d\n", b2);
return 0;
}
11. (类型)(强制类型转换)强制类型转换是指在程序中将一种数据类型的值转换为另一种数据类型的值。它可以通过在表达式中使用强制类型转换运算符来实现,这个运算符是小括号,里面写上要转换的数据类型。例如:将一个整数转换为浮点数,可以使用强制类型转换运算符将整数变量括在小括号里,如下所示:
#include<stdio.h>
int main()
{
int a = 10;
float b = (float)a;
return 0;
}
需要注意的是,在进行强制类型转换时,可能会出现数据精度的问题,因为不同的数据类型所能表示的数值范围和精度是不同的,所以在进行强制类型转换时要注意数据是否会出现截断或失真。
九、运算符优先级表格
优先级 | 运算符 | 名称或含义 | 使用形式 | 结合方向 | 说明 |
1 | [] | 数组下标 | 数组名[常量表达式] | 左到右 | -- |
() | 圆括号 | (表达式)/函数名(形参表) | -- | ||
. | 成员选择(对象) | 对象.成员名 | -- | ||
-> | 成员选择(指针) | 对象指针->成员名 | -- | ||
2 | - | 负号运算符 | -表达式 | 右到左 | 单目运算符 |
~ | 按位取反运算符 | ~表达式 | |||
++ | 自增运算符 | ++变量名/变量名++ | |||
-- | 自减运算符 | --变量名/变量名-- | |||
* | 取值运算符 | *指针变量 | |||
& | 取地址运算符 | &变量名 | |||
! | 逻辑非运算符 | !表达式 | |||
(类型) | 强制类型转换 | (数据类型)表达式 | -- | ||
sizeof | 长度运算符 | sizeof(表达式) | -- | ||
3 | / | 除 | 表达式/表达式 | 左到右 | 双目运算符 |
* | 乘 | 表达式*表达式 | |||
% | 余数(取模) | 整型表达式%整型表达式 | |||
4 | + | 加 | 表达式+表达式 | 左到右 | 双目运算符 |
- | 减 | 表达式-表达式 | |||
5 | << | 左移 | 变量<<表达式 | 左到右 | 双目运算符 |
>> | 右移 | 变量>>表达式 | |||
6 | > | 大于 | 表达式>表达式 | 左到右 | 双目运算符 |
>= | 大于等于 | 表达式>=表达式 | |||
< | 小于 | 表达式<表达式 | |||
<= | 小于等于 | 表达式<=表达式 | |||
7 | == | 等于 | 表达式==表达式 | 左到右 | 双目运算符 |
!= | 不等于 | 表达式!= 表达式 | |||
8 | & | 按位与 | 表达式&表达式 | 左到右 | 双目运算符 |
9 | ^ | 按位异或 | 表达式^表达式 | 左到右 | 双目运算符 |
10 | | | 按位或 | 表达式|表达式 | 左到右 | 双目运算符 |
11 | && | 逻辑与 | 表达式&&表达式 | 左到右 | 双目运算符 |
12 | || | 逻辑或 | 表达式||表达式 | 左到右 | 双目运算符 |
13 | ?: | 条件运算符 | 表达式1? 表达式2: 表达式3 | 右到左 | 三目运算符 |
14 | = | 赋值运算符 | 变量=表达式 | 右到左 | -- |
/= | 除后赋值 | 变量/=表达式 | -- | ||
*= | 乘后赋值 | 变量*=表达式 | -- | ||
%= | 取模后赋值 | 变量%=表达式 | -- | ||
+= | 加后赋值 | 变量+=表达式 | -- | ||
-= | 减后赋值 | 变量-=表达式 | -- | ||
<<= | 左移后赋值 | 变量<<=表达式 | -- | ||
>>= | 右移后赋值 | 变量>>=表达式 | -- | ||
&= | 按位与后赋值 | 变量&=表达式 | -- | ||
^= | 按位异或后赋值 | 变量^=表达式 | -- | ||
|= | 按位或后赋值 | 变量|=表达式 | -- | ||
15 | , | 逗号运算符 | 表达式,表达式,… | 左到右 | -- |
总结
本文八千多字,详细的介绍了C语言中几乎所有的操作符,希望对各位读者有所帮助。