C语言的运算符与表达式

本文详细介绍了C语言中的各种运算符,包括算术运算符(如+,-,*,/,%),关系运算符(如>,<,==,!=),逻辑运算符(如&&,||,!),赋值运算符(如=,+=,-=等),位运算符(如&,|,~,^,<<,>>),以及条件运算符(问号运算符)和逗号运算符的用法和特点。同时,文章还涵盖了运算符的优先级和结合性,以及一些实际的示例来帮助理解。
摘要由CSDN通过智能技术生成

一.名词解析

什么是运算符?

运算符就是用来表示某种运算的符号

+ - * / ....

什么是表达式?

用运算符连接的式子就叫做表达式,确切的名字以表达式中最低运算符来确定

1+2、3/4

操作数

参与运算的数据

几目运算符

该运算符需要几个操作数就是几目运算符

优先级

如果有多个运算符出现在一个表达式中,运算符优先级就决定优先进行哪种运算

结合性:

决定先算那个操作数,后算哪个操作数

左到右、右到左

#include <stdio.h>

int main()

{

scanf("%d",&变量);

printf("jcgsjhvj%\n");

//代表一行注释

/*

这一对符号中的所有东西都是注释

*/

return 0;

}

二、算数-关系-逻辑-赋值运算符

1、算术运算符

用来进行数学上的算术运算的运算符

+ - * / %(取余/取模) 双目运算符

注意几点:

/、% 右边不能为 0

% 两边的操作数必须是整型数据

进行/ 运算,如果两个数其中数为小数,结果一定是小数

如果两个数其中数为整数,结果也是整数,那么想让商为小数怎么办?

把其中一个操作数强转为小数

例:

int a = 10;

int b = 20,c = 30; //int b = 20; int c = 30;

printf("%d + %d = %d\n",a,b,a+b);

printf("%d - %d = %d\n",a,b,a-b);

printf("%d * %d = %d\n",a,b,a*b);

printf("%d / %d = %d\n",a,b,a/b);

printf("%d / %d = %f\n",a,b,(float)a/b);

printf("%d %% %d = %d\n",a,b,a%b);

算术运算符的结合性:左到右

2、关系运算符

用来判断两个数据的大小的运算符

< <= > >= ==(注意) !=

双目运算符 ,关系运算符的结合性:左到右

用关系运算符连接起来的式子---> 关系表达式

例:

a > b

a < b

5 > 9

6 != 6

5 > 3

...

关系表达式可以成立也可以不成立,

如果成立表示这个关系表达式的值是1

如果不成立表示这个关系表达式的值是0

关系表达式的值:0 或 1

6 != 6 ---> 0

5 > 2 ---> 1

8 > 6 > 4 关系表达式没问题,但是不成立

1 > 4 不成立 0 C语言中,数学上没问题

6 < 8 并且 6 > 4

并且如何表示?

3、逻辑运算符

&& || !

与 或 非

并且 或者 取反

&& 、 || 是双目运算符

&& 两个结果都为真才是真,否则就是假的

|| 有一个为真就为真,只有两个都为假的时候才是假

! 是单目运算符一个操作数

操作数为真,结果为假;操作数为假,结果为真

0是假 非0是真

用逻辑运算符连起来的就叫逻辑表达式

逻辑表达式结果:0 或者 1 0代表表达式为假,1代表表达式为真

例:

int a = 3;

int b = 4;

a && b --> 真

!a --> 假

!b || a --> 真

练习:

int a,b,c,d,e,f = 6;

a = 1;

b = 2;

c = 3;

d = 4;

(e = (a > b)) && (f = (c > d))

表达式以及e,f的结果

表达式的值为0, e = 0, f = 6

逻辑运算符是"惰性运算符"

如果事先知道了结果,就不会做后面表达式

(e = (a < b)) || (f = (c > d))

e = 1,表达式的值为1,f = 6

(1) a && b && c

只有a 为真,才会判断b,如果b为真,才会判断c ,c决定式子的结果

只要a 为假,整个式子的结果就为假

a && b 整个式子的结果就为假

(2)a || b || c

只有a为假,才会判断b,如果b为假,才会判断c ,c决定式子的结果

int a,b,c,d,e,f,m,n,l;

a = 1;

b = 2;

c = 3;

d = 4;

e = 5;

f = 6;

m = 7;

n = 8;

l = 9;

(m = (a < b)) || (n = (c > d)) && ( l = (e != f))

&& 优先级 高于 ||

m = (a < b)) || ((n = (c > d)) && ( l = (e != f))

m = 1

n = 8

l = 9

3 + 4 * 5 = 3 + (4 * 5) = 23

4、赋值运算符

= 双目运算符,结合性右到左

注意:赋值运算符,左边的操作数一定是变量(左值)

int m = 10;

m = 20;

m = 30;

int n;

n = m;

10 = m; //错误的

m = 1.5; //自动取整

一般来说,“=” 两边操作数类型要一致,或者兼容

m = 'a';

用赋值运算符连起来的就是赋值表达式

赋值表达式的值:是赋值完成后的左边操作数的值

int a , b;

a = b = 10; //相当于先做了 b = 10 , 然后 a = b

b + 5 = 10; //错误的

--------------

复合赋值运算符,赋值运算符可以和其他运算符结合使用,构成复合的赋值运算符

+= -= *= /= ....

如:

int a;

a += 5; <==> a = a + 5;

a -= 5; <==> a = a - 5;

10 += 20; 10 + 10 = 20 //错误的

单目运算符: ++ -- 包含赋值运算

++ 自增1

-- 自减1

只需要一个操作数 可以在左边,也可以在右边

后++ 前++

int m,n; int a,b;

m = 5; a = 5;

n = m++; b = ++a;

n = 5; b = 6;

m = 6; a = 6;

因为对于m,a来说,++的效果都是+1 所以是6

不同是前++ 的表达式是 +1 后的值, 后 ++ 的表达式是 +1 前的值

int a = 8;

printf("a = %d\n",++a); //9

printf("a = %d\n",a++); //9

printf("a = %d\n",a); //10

a = 0;

a++,a-- 成立

5、位运算符

位运算是指把操作数按bit 位 (先换算成二进制补码) 进行一个运算

注意:位运算的操作数必须是整数(char、short、int......)

& 按位与

| 按位或

~ 按位取反

^ 按位异或

上面几个不会产生进位和借位

<< 按位左移

>> 按位右移

除了~ 之外都是双目运算符

所有位运算符都需要转成二进制补码,才能运算

(1) ~ 按位取反

0 --> 1

1 --> 0

例:

int a = 3;

// 00...00 0011

int b = ~3;

// 11...11 1100

//-1 11...1 1011

// 100..0000 0100 -4

b = -4;

int m = -5;

// 000...000 0101

// 111...111 1010

//+1 111...111 1011

int n = ~m;

// 000...000 0100

n = 4;

(2)& 按位与

a 和 b 都是一个bit a&b 值如下所示

a b a&b

1 1 1

1 0 0

0 0 0

0 1 0

对应bit位同为1才为1

3 & 5

3 0000 0011

5 0000 0101

& ---------

0000 0001

char a = -6;

// 0000 0110

// 1111 1001

// 1111 1010

char b = 10;

// 0000 1010

a & b 10

1111 1010

0000 1010

& ---------

0000 1010

结论:

两个bit 同为1 结果才是1 否则就是 0

一个bit 位与 1 进行 & 运算结果是原来的值

一个bit 位与 0 进行 & 运算结果是0

练习:

int 的变量 a 把 a 的 从低位开始第5个bit 位变为0 其他位不变,怎么办

xxxx xxxx xxxx xxxx xxxx xxxx xxxX xxxx

1111 1111 1111 1111 1111 1111 1110 1111

& ----------------------------------------

a & 0xffffffef

a = a & 0xffffffef;

a &= 0xffffffef;

(3) | 按位或

a 和 b 都是一个bit a|b 值如下所示

a b a|b

1 1 1

1 0 1

0 0 0

0 1 1

只要有一个bit位为1就为1

3 | 5

3 0000 0011

5 0000 0101

| ---------

0000 0111

int a = 15,b = 16;

a | b

0000 1111

0001 0000

| ----------

0001 1111 31

结论:

两个bit 同为 0 结果才是0 否则就是 1

一个bit 位与 1 进行 | 运算结果是 1

一个bit 位与 0 进行 | 运算结果是原来的值

练习:

int 的变量 a 把 a 的 从低位开始第5个bit 位变为1 其他位不变,怎么办

xxxx xxxx xxxx xxxx xxxx xxxx xxxX xxxx

0000 0000 0000 0000 0000 0000 0001 0000

| ----------------------------------------

a = a | 0x00000010;

(4)^ 按位异或

求异 不同为1 ,相同为 0

a 和 b 都是一个bit a^b 值如下所示

a b a^b

1 1 0

1 0 1

0 0 0

0 1 1

结论:

一个bit 位和 0 进行 ^,原来的值

一个bit 位和 1 进行 ^,值相反

练习:

int 的变量 a 把 a 的 从低位开始第5个bit 位取反 其他位不变,怎么办

xxxx xxxx xxxx xxxx xxxx xxxx xxxX xxxx

0000 0000 0000 0000 0000 0000 0001 0000

^ ----------------------------------------

a = a ^ 16;

(5) << 按位左移

x << n 把x按 bit 位整体左移 n 个 bit

运算时就需要,先把x变成补码,n不需要

例:

int m = 20;

m << 3;

m: 000...000 0001 0100 16 + 4 2^4 + 2^2

左移时,高位超出的就舍弃,低位补0

000...000 1010 0000 128+32 2^7 + 2^5 = 160

如果左移时,高位舍弃的全是0,对应把需要左移的数乘以 2^n

练习:

有一个int 变量 a ,把 a 的 bitn([0,31]) 变为1 ,其他的 bit 不动

a = a | (1 << n);

有一个int 变量 a ,把 a 的 bitn([0,31]) 变为0 ,其他的 bit 不动

a = a & (~(1 << n))

xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx

1111 1111 1111 1111 1111 1111 1110 1111

0000 0000 0000 0000 0000 0000 0001 0000

& ---------------------------------------

(6) >> 按位右移

x >> n 把x按 bit 位整体右移 n 个 bit

运算时就需要,先把x变成补码,n不需要

低位丢掉,高位会空缺

如果数据是有符号的话,高位就补符号位

如果数据是无符号的话,高位就补0

例:

int m = -3;

// 3的补码: 000...000 0011

// 3补码取反 111...111 1100

// -3的补码: 111...111 1101

m >> 10;

// 111...111 1111

m = -1;

unsigned int n = -3;

// 3的补码: 000...000 0011

// 3补码取反 111...111 1100

// -3的补码: 111...111 1101

n >> 10;

// 0000 0000 00 111...111 1111

n = 2 ^ 22 -1;

交换2个 int 变量的值

(1) int x = 3,y = 5;

int z = x;

x = y;

y = z;

(2) int x = 3,y = 5; // 交换后两数的和以及积不会变的

x = x + y;

y = x - y; //x + y - y = x;

x = x - y; //x + y - x = y;

(3) int x = 3,y = 5; //利用位运算

1 ^ 1 = 0;

2 ^ 2 = 0;

n ^ n = 0;

0 ^ x = x;

1 ^ x = ~x;

x = x ^ y;

0011

0101

x = 0110

y = x ^ y; //y = x ^ y ^ y = y ^ y ^ x = 0 ^ x = x;

0110

0101

y = 0011

x = x ^ y; //x = x ^ y ^ (x ^ y ^ y) = (x ^ x) ^ (y ^ y) ^ y = 0 ^ 0 ^ y = y;

0110

0011

y = 0101

6、条件运算符(问号运算符)

"? :" 三目运算符,需要三个操作数结合性右到左

语法:

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

怎么理解?

先判断? 前的表达式1的是否成立,

如果成立的话,就只执行表达式2 ,整个表达式的值就是表达式2的值

如果不成立的话,就只执行表达式3 ,整个表达式的值就是表达式3的值

例:

(3 > 5) ? 2 : 1

int m = 10;

int n = 20;

int c ;

c = (m > n ? m : n); //求最大值

7、逗号运算符

双目运算符,优先级最低,结合性左到右

语法:

表达式1 , 表达式2

逗号运算符的执行顺序左到右,先执行表达式1,再执行表达式2;

整个逗号表达式的值是表达式2的值

例:

int a = 10;

int b = 20;

a = 10,b = 20; //逗号表达式

int c ;

c = a = 10,b = 20;

int c = (a = 10,b = 20);

8、其它运算符

sizeof

sizeof(类型)

求该类型的数据所占的字节数目

sizeof(short) ---> 2

或者

sizeof(值)

求该值对应类型的所占字节数目

sizeof('a') <---> sizeof(char) --> 1

sizeof(a) <---> sizeof(int) --> 4

typeof 求一个变量/常量的类型

int a = 100;

typeof(a); ---> int

typeof(100); ---> int

typeof('a'); ---> char

.......

强制转换运算符

(目标类型)值

(int)3.1415 = 3;

float f = 3.14;

f + 3.1 --->6.24

(int)f + 3.1 --->6.1

(int)(f + 3.96) --->7

& 取地址符 单目运算符

* 解引用运算符 单目运算符

. 取成员变量

-> 取成员变量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新棉衣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值