C 语言的一些笔记



C 语言中 &&|| 优先级、结合性

分析下题的答案

在这里插入图片描述

C 语言运算符的优先级和结合性

首先,要知道 C 语言运算符的优先级和结合性。
查阅资料得知:&& 的优先级比 || 高,结合性是从左往右。运算时,会把 && 左边的表达式看做一个整体。
在这里插入图片描述

分析几个简单的示例

第 1 个示例

先来几个简单的示例,进行分析:

#include <stdio.h>

int main()
{
	int a = 1, b = 0;

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

	return 0;
}

/*
运行结果:

0
1
1
*/
第一条语句

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

  1. && 优先级比 || 高,会先执行 b 这个表达式。b 的结果为 0,C 语言中 0 为假。&& 的特性:只要任何一边的结果为假,整个表达式的结果即为假。
  2. b 的结果已经为假,就不会再去理会右边整个 a || b,直接短路并返回结果,不往后面走了。
第二条语句

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

  1. && 优先级比 || 高,&& 左边的 b 先被计算,得到结果为 0&& 只要有任意一边为 0,整个表达式的结果都为 0。于是 b && a 的结果为 0。现在的表达式为:a || 0
  2. || 右边的 b && a 已经有了结果 0,现在要计算 || 左边的表达式。a1,整个表达式的结果是:1 || 0|| 任意一边为 1,整个表达式的结果都为 1。于是最终返回 1
第三条语句

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

  1. 同样先执行 && 左边的 b,得到结果为 0,于是表达式 b && b 的结果为 0
  2. a1,表达式为:1 || 0。返回结果 1

第 2 个示例
#include <stdio.h>

int main()
{
	int a = 1, b = 0;

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

	return 0;
}

/*
运行结果:

1
*/

b || a && a

  1. && 的优先级比 || 高,会先去执行 && 左边的 a,结果为 1。表达式为:b || 1 && a
  2. 继续计算 && 右边的 a,结果同样为 1a && a 的结果为 1。现在的表达式为:b || 1
  3. || 的右边为 1 了,它就判定整个表达式为 1,不会再去管左边的 b 是什么结果了,|| 发生短路。
  4. 直接返回 1

第 3 个示例
#include <stdio.h>

int main()
{
	int a = 1, b = 0, c = 1;

	printf("%d\n", b || a && c && b);

	return 0;
}

/*
运行结果:

0
*/

表达式 b || a && c && b 中,有两个 &&。按照结合性,可以写成:b || (a && c && b)

  1. 先执行 b || (a && c && b) 中的 (a && c && b)
  2. (a && c && b) 中,先执行 a && c,已知 a = 1, c = 1,因此表达式的值为 1(a && c && b) 变成了:(1 && b)
  3. 执行 (1 && b) 中的 bb=0,因此表达式为 1 && 0。有一边为 0,整个表达式为 0
  4. 至此,b || a && c && b 中,|| 右边的表达式已经计算完毕,值为 0。现在表达式为:b || 0
  5. b=0,表达式的结果是 0 || 0|| 两边的结果都为 0,最终的结果为 0,返回这个结果。

再来一题

#include <stdio.h>

int main()
{
	int a = 1, b = 0, c = 0;

	c = (a+=10) || (b+=5) && (b+=5);
	printf("a=%d, b=%d, c=%d\n", a, b, c);

	a = 1, b = 0;
	c = (a+=10) || ( (b+=5) && (b+=5) );
	printf("a=%d, b=%d, c=%d\n", a, b, c);

	a = 1, b = 0;
	c = ( (a+=10) || (b+=5) ) && (b+=5);
	printf("a=%d, b=%d, c=%d\n", a, b, c);

	return 0;
}


/*
运行结果:

a=11, b=0, c=1
a=11, b=0, c=1
a=11, b=5, c=1
*/
第一条语句

c = (a+=10) || (b+=5) && (b+=5);

  1. 有三个“加后赋值语句”,都被小括号包裹了起来。
  2. 小括号的优先级最高,根据算术运算的进栈规则,首先遇到的是 (a+=10) 这个表达式。
  3. (a+=10) 执行完后,a 被赋值为 11,表达式结果为 1|| 遇到左边的为 1,就直接短路,不会去管后面的结果是什么。整个表达式的结果都为 1。将 1 赋值给 c,并结束本条语句。

第二条语句

c = (a+=10) || ( (b+=5) && (b+=5) );

  1. 在第一条语句基础上,把 || 后面的语句用小括号再次包裹了起来。现在变成了 2 个小括号语句:(a+=10) || ( ... )。(不再是第一条语句那样的 3 个小括号语句了!)
  2. 依然根据算术运算的进栈规则,首先遇到的还是 (a+=10) 这个表达式。
  3. 其他的执行顺序,与第一条语句一致。

第三条语句

c = ( (a+=10) || (b+=5) ) && (b+=5);

  1. 还是根据算术运算的进栈规则,首先遇到的语句是:( (a+=10) || (b+=5) )。(&& (b+=5) 会稍后执行)。
  2. 先执行 ( (a+=10) || (b+=5) ) 中的 (a+=10)a 被赋值为 11,表达式的结果为 1。该表达式变成了:( 1 || (b+=5) )
  3. ( 1 || (b+=5) ) 中,|| 的左边为 1。触发 || 短路特性,不会去理会后面的 (b+=5) 语句,整个表达式的结果为 1
  4. 现在的语句是:c = 1 && (b+=5);。左边的结果为真,但 && 还需要右边的结果。b+=5b 被赋值为 5,语句运行结果为 1
  5. 两边都为 1,将 1 赋值给 c

回到最初的问题

#include <stdio.h>

int main()
{
	int a = 2, b = 2, c = 2;

	c = (a = 3) || (a = 4) && (b = 5);
	printf("a=%d, b=%d, c=%d\n", a, b, c);

	return 0;
}


/*
运行结果:

a=3, b=2, c=1
*/

c = (a = 3) || (a = 4) && (b = 5);

  1. 语句也是由 3 个小括号包裹着。根据算术运算的进栈规则,第一个遇到的是:(a = 3)
  2. a 被赋值为 3,表达式的执行结果为 1,现在表达式为:c = 1 || (a = 4) && (b = 5)|| 左边为 1,触发短路特性。
  3. 不会再去管 || 右边一大坨的 (a = 4) && (b = 5)。直接将 1 赋值给 c,并结束本条语句。

参考文献

C 语言运算符的优先级和结合性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
水资源是人类社会的宝贵财富,在生活、工农业生产中是不可缺少的。随着世界人口的增长及工农业生产的发展,需水量也在日益增长,水已经变得比以往任何时候都要珍贵。但是,由于人类的生产和生活,导致水体的污染,水质恶化,使有限的水资源更加紧张。长期以来,油类物质(石油类物质和动植物油)一直是水和土壤中的重要污染源。它不仅对人的身体健康带来极大危害,而且使水质恶化,严重破坏水体生态平衡。因此各国都加强了油类物质对水体和土壤的污染的治理。对于水中油含量的检测,我国处于落后阶段,与国际先进水平存在差距,所以难以满足当今技术水平的要求。为了取得具有代表性的正确数据,使分析数据具有与现代测试技术水平相应的准确性和先进性,不断提高分析成果的可比性和应用效果,检测的方法和仪器是非常重要的。只有保证了这两方面才能保证快速和准确地测量出水中油类污染物含量,以达到保护和治理水污染的目的。开展水中油污染检测方法、技术和检测设备的研究,是提高水污染检测的一条重要措施。通过本课题的研究,探索出一套适合我国国情的水质污染现场检测技术和检测设备,具有广泛的应用前景和科学研究价值。 本课题针对我国水体的油污染,探索一套检测油污染的可行方案和方法,利用非分散红外光度法技术,开发研制具有自主知识产权的适合国情的适于野外便携式的测油仪。利用此仪器,可以检测出被测水样中亚甲基、甲基物质和动植物油脂的污染物含量,为我国众多的环境检测站点监测水体的油污染状况提供依据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值