C语言运算符详解

2024-05-24 11:16:02 浏览数 (1)

前言

C语言包含多种运算符,如算术、关系、逻辑、位、赋值和条件等,它们用于执行各种计算和操作,如加减乘除、比较、逻辑判断、位运算、赋值和条件控制等,是C语言编程中不可或缺的元素。

推荐一个网站给想要了解或者学习人工智能知识的读者,这个网站里内容讲解通俗易懂且风趣幽默,对我帮助很大。我想与大家分享这个宝藏网站,请点击下方链接查看。 https://www.captainbed.cn/f1


一、算术操作符

算术操作符包括加法( )、减法(-)、乘法(*)、除法(/)和取模(%)等五种。在写代码时候,一定会涉及到计算。

C语言中为了方便运算,提供了一系列操作符,其中有一组操作符叫:

  • 算术操作符。分别是: % - * ,这些操作符都是双目操作符。

操作符也被叫做:运算符,是不同的翻译,意思是一样的。

和 -

- 用来完成加法和减法。

- 都是有2个操作数的,位于操作符两端的就是它们的操作数,这种操作符也叫双目操作符。

代码语言:javascript复制
#include <stdio.h>
int main()
{
	int x = 4   22;
	int y = 61 - 23;
	printf("%dn", x);
	printf("%dn", y);
	return 0;
}

*

运算符 * 用来完成乘法

代码语言:javascript复制
#include <stdio.h>
int main()
{
	int num = 5;
	printf("%dn", num * num); // 输出 25
	return 0;
}

/

运算符 / 用来完成除法。

除号的两端如果是整数,执行的是整数除法,得到的结果也是整数。

代码语言:javascript复制
#include <stdio.h>
int main()
{
	float x = 6 / 4;
	int y = 6 / 4;
	printf("%fn", x); // 输出 1.000000
	printf("%dn", y); // 输出 1
	return 0;
}

上面示例中,尽管变量 x 的类型是 float (浮点数),但是 6 / 4 得到的结果是 1.0 ,而不是1.5 。原因就在于 C 语言里面的整数除法是整除,只会返回整数部分,丢弃小数部分。

精度问题

如果希望得到浮点数的结果,两个运算数必须至少有一个浮点数,这时 C 语言就会进行浮点数除法。

代码语言:javascript复制
#include <stdio.h>
int main()
{
	float x = 6.0 / 4; // 或者写成 6 / 4.0
	printf("%fn", x); // 输出 1.500000
	return 0;
}

上面示例中, 6.0 / 4表示进行浮点数除法,得到的结果就是 1.5 。

示例

再看一个例子:

代码语言:javascript复制
#include <stdio.h>
int main()
{
	int score = 5;
    score = (score / 20) * 100;
	return 0;
}

上面的代码,你可能觉得经过运算, score 会等于 25 ,但是实际上 score 等于 0 。这是因为score / 20 是整除,会得到一个整数值 0 ,所以乘以 100 后得到的也是 0 。

为了得到预想的结果,可以将除数 20 改成 20.0 ,让整除变成浮点数除法。

代码语言:javascript复制
#include <stdio.h>
int main()
{
	int score = 5;
    score = (score / 20.0) * 100;
	return 0;
}

也可以使用强制类型转换 如 (float)score / 20 ……

%

运算符 % 表示求模运算,即返回两个整数相除的余值。

这个运算符只能用于整数,不能用于浮点数

代码语言:javascript复制
#include <stdio.h>
int main()
{
	int x = 6 % 4; // 2
	return 0;
}
负数求模的规则

负数求模的规则是,结果的正负号由第一个运算数的正负号决定。

代码语言:javascript复制
#include <stdio.h>
int main()
{
	printf("%dn", 11 % -5); // 1  正负由11决定
	printf("%dn",-11 % -5); // -1  由-11 决定
	printf("%dn",-11 % 5); // -1   由-11 决定
	return 0;
}

上面示例中,第一个运算数的正负号( 11 或 -11 )决定了结果的正负号。

二、赋值操作符

在变量创建的时候给一个初始值叫初始化,在变量创建好后,再给一个值,这叫赋值。

代码语言:javascript复制
int a = 100;//初始化
a = 200;//赋值,这⾥使⽤的就是赋值操作符

赋值操作符 = 是一个随时可以给变量赋值的操作符。

连续赋值

赋值操作符也可以连续赋值

如:

代码语言:javascript复制
int a = 3;
int b = 5;
int c = 0;
c = b = a 3;//连续赋值,从右向左依次赋值的。

C语言虽然支持这种连续赋值,但是写出的代码不容易理解,建议还是拆开来写,这样方便观察代码的执行细节

代码语言:javascript复制
int a = 3;
int b = 5;
int c = 0;
b = a 3;
c = b;

这样写,在调试的是,每一次赋值的细节都是可以很方便的观察的。

复合赋值符

在写代码时,我们经常可能对一个数进行自增、自减的操作,如下代码

代码语言:javascript复制
int a = 10;
a = a 3;
a = a-2;

这样代码C语言给提供了更加方便的写法:

代码语言:javascript复制
int a = 10;
a  = 3;
a -= 2;

C语言中提供了复合赋值符,方便我们编写代码,这些赋值符有:

代码语言:javascript复制
 =        -=
*=        /=        %=
//下⾯的操作符后期讲解
>>=       <<=
&=        |=        ^=

特殊情况

可能有些读者会对复合语句有疑惑 假如是 a = a 3 呢?

其实 a = a 3就是 a = a (a 3 )

可以这样理解:操作系统会默认在后面加一个括号

三、单目操作符

前面介绍的操作符都是双目操作符,有2个操作数的。

C语言中还有一些操作符只有一个操作数,被称 为单目操作符。 -- (正)、-(负) 就是单目操作符的。

和- -

是一种自增的操作符,又分为前置 和后置 --是一种自减的操作符,也分为前置--和后置--.

前置
代码语言:javascript复制
int a = 10;
int b =   a;//  的操作数是a,是放在a的前⾯的,就是前置  
printf("a=%d b=%dn",a , b);
计算口诀

先 1,后使用;

a原来是10,先 1,后a变成了11,再使用就是赋值给bb得到的也是11,所以计算技术后,ab都 是11,相当于这样的代码:

代码语言:javascript复制
int a = 10;
a = a 1;
b = a;
printf("a=%d b=%dn",a , b);
后置
代码语言:javascript复制
int a = 10;
int b = a  ;//  的操作数是a,是放在a的后⾯的,就是后置  
printf("a=%d b=%dn",a , b);
计算口诀

先使用,后 1

a原来是10,先使用,就是先赋值给bb得到了10,然后再 1,然后a变成了11,所以直接结束后a是 11,b是10,相当于这样的代码:

代码语言:javascript复制
int a = 10;
int b = a;
a = a 1;
printf("a=%d b=%dn",a , b);
前置- -

如果你听懂了前置 ,那前置--是同理的,只是把加1,换成了减1;

计算口诀

先-1,后使用

代码语言:javascript复制
 int a = 10;
 int b = --a;//--的操作数是a,是放在a的前⾯的,就是前置--
 printf("a=%d b=%dn",a , b);//输出的结果是:9 9
后置–

同理后置--类似于后置 ,只是把加一换成了减一

计算口诀

先使用,后-1

代码语言:javascript复制
int a = 10;
int b = a--;//--的操作数是a,是放在a的后⾯的,就是后置--
printf("a=%d b=%dn",a , b);//输出的结果是:9 10

和 -

这里的 是正号,-是负号,都是单目操作符

运算符 对正负值没有影响,是一个完全可以省略的运算符,但是写了也不会报错。

代码语言:javascript复制
 int a =  10; 等价于 int a = 10;

运算符 - 用来改变一个值的正负号,负数的前面加上 - 就会得到正数,正数的前面加上 - 会得到负 数

代码语言:javascript复制
int a = 10;
int b = -a;
int c = -10;
printf("b=%d c=%dn", b, c);//这⾥的b和c都是-10
int a = -10;
int b = -a;
printf("b=%dn", b); //这⾥的b是10

四、强制类型转换

在操作符中还有一种特殊的操作符是强制类型转换,语法形式很简单,形式如下:

代码语言:javascript复制
 (类型)
 int a = 3.14;
//a的是int类型, 3.14是double类型,两边的类型不⼀致,编译器会报警告
//为了消除这个警告,我们可以使用强制类型转换: 
 int a = (int)3.14;//意思是将3.14强制类型转换为int类型,这种强制类型转换只取整数部分

俗话说,强扭的瓜不甜,我们使用强制类型转换都是万不得已的时候使用,如果不需要强制类型转化 就能实现代码,这样自然更好的。

五、运算符优先级表

优先级

运算符

名称或含义

使用形式

结合方向

说明

1

[ ]

数组下标

数组名[常量表达式]

左到右

1

( )

圆括号

(表达式)/函数名(形参表)

左到右

1

.

成员选择(对象)

对象.成员名

左到右

1

->

成员选择(指针)

对象指针->成员名

左到右

2

-

负号运算符

-表达式

右到左

单目运算符

2

~

按位取反运算符

~表达式

右到左

单目运算符

2

自增运算符

变量名/变量名

右到左

单目运算符

2

--

自减运算符

–变量名/变量名–

右到左

单目运算符

2

*

取值运算符

*指针变量

右到左

单目运算符

2

&

取地址运算

&变量名

右到左

单目运算符

2

!

逻辑非运算符

!表达式

右到左

单目运算符

2

(类型)

强制类型转换

(数据类型)表达式

右到左

2

sizeof

长度运算符

sizeof(表达式)

右到左

3

/

表达式/表达式

左到右

双目运算符

3

*

表达式*表达式

左到右

双目运算符

3

%

余数(取模)

整型表达式%整型表达式

左到右

双目运算符

4

表达式 表达式

左到右

双目运算符

4

-

表达式-表达式

左到右

双目运算符

5

<<

左移

变量<<表达式

左到右

双目运算符

5

>>

右移

变量>>表达式

左到右

双目运算符

6

>

大于

表达式>表达式

左到右

双目运算符

6

<

小于

表达式<表达式

左到右

双目运算符

6

<=

小于等于

表达式<=表达式

左到右

双目运算符

7

==

等于

表达式==表达式

左到右

双目运算符

7

!=

不等于

表达式!= 表达式

左到右

双目运算符

8

&

按位与

表达式&表达式

左到右

双目运算符

9

^

按位异或

表达式^表达式

左到右

双目运算符

10

按位或

表达式|表达式

左到右

11

&&

逻辑与

表达式&&表达式

左到右

双目运算符

12

||

逻辑或

表达式||表达式

左到右

双目运算符

13

?:

条件运算符

表达式1?表达式2: 表达式3

右到左

三目运算符

14

=

赋值运算符

变量=表达式

右到左

14

/=

除后赋值

变量/=表达式

右到左

14

*=

乘后赋值

变量*=表达式

右到左

14

%=

取模后赋值

变量%=表达式

右到左

14

=

加后赋值

变量 =表达式

右到左

14

-=

减后赋值

变量-=表达式

右到左

14

<<=

左移后赋值

变量<<=表达式

右到左

14

>>=

右移后赋值

变量>>=表达式

右到左

14

&=

按位与后赋值

变量&=表达式

右到左

14

^=

按位异或后赋值

变量^=表达式

右到左

14

|=

按位或后赋值

变量|=表达式

右到左

15

逗号运算符

表达式,表达式,…

左到右

说明:

同一优先级的运算符,运算次序由结合方向所决定。 简单记就是:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符

0 人点赞