结合性和优先的联系与区别

一、结合性与优先性

————参考文章

1.文中指出:

首先,在多数情况下,C语言对表达式中各子表达式的求值次序并没有严格规定;其次,即使是求值次序确定的场合,也是要先确定了表达式的语义结构,在获得确定的语义之后才谈得上“求值次序”。

条件运算符是C语言中为数不多的对求值次序有明确规定的运算符之一。(另外还有三位,分别是逻辑与“&&”、逻辑或“||”和逗号运算符“,”)。

例如,x > y ? 100 : ++y > 2 ? 20 : 30。
条件运算符“向右结合”这一特性,并没有决定内层的条件表达式先被求值,而是决定了上面表达式的语义结构等价于“x > y ? 100 : (++y > 2 ? 20 : 30)”,而不是等价于“(x > y ? 100 : ++y) > 2 ? 20 : 30”。——这才是“向右结合”的真正含义。

C语言规定:条件表达式首先对条件部分求值,若条件部分为真,则对问号之后冒号之前的部分求值,并将求得的结果作为整个表达式的结果值,否则对冒号之后的部分求值并作为结果值。

因此,对于表达式“x > y ? 100 : (++y > 2 ? 20 : 30)”,首先看x大于y是否成立,在本例中它是成立的,因此整个表达式的值即为100。也因此冒号之后的部分得不到求值机会,它的所有副作用也就没机会生效。

2.案例运行

这里可以看出条件表达式出现了像&&与||逻辑表达式一样的短路。

二、题目

int i = -2;
int n = ++i == 0 ? 99 : i == -1 ? 11 : 22;

请问n的值是多少?

答:n = 11!

why?

首先,先确定语义结构,由于条件运算符其右结合,因此意义为n=++i==0?99:(i==-1?11:22);
其次就是对外层关系运算符判断,++i==0的值,如果是真,就对表达式的值就为99,否则进行后面的运算,
接着,由于优先级,先进行++i操作再判断++i==0,而++i返回的是i+1的值(这个后续有原理的基本解释),因此外层关系运算结果为假,取后面条件表达式
然后,i==-1取11,所以最后结果为11

三、关于++i与i++的变式

i++;与++i;的区别

1.截取里面的一点内容,关于i++与++i的原理实现

int i;
int firstAdd() {
	i = i + 1;
	return i;
}

int lastAdd() {
	int temp = i;
	i = i + 1;
	return temp;
}

int main() {
	i = 0;
	i = firstAdd();//i=++i
	printf("%d\n", i);

	i = 0;
	i = lastAdd();//i=i++
	printf("%d", i);

	return 0;
}

2.运行i++==0

结果如下:

3.运行++i==0

结果如下:

4.思考

注意:int i=-1;++i==0;与i++==0;不一样,前者结果为1后者结果为0。
如果i=-1呢?
如果换成n=i++==0?99:i==-1?11:22;呢?
如果换成n=i++==-1?99:i==-1?11:22;呢?
posted @ 2023-11-17 15:20  彭乐祥  阅读(43)  评论(0编辑  收藏  举报