当我运行这个玩具程序时,
#include<stdio.h>
int main(void)
{
int arr[] = {11, 22, 33};
int *ptr = arr;
printf("ptr at: %p\n", (void *)ptr);
printf("Result of expression: %d\n", *ptr++); // line 8
printf("ptr at: %p\n", (void *)ptr);
}
Run Code Online (Sandbox Code Playgroud)
我得到的输出是:
ptr at: 0x7fffffffdbf0
Result of expression: 11
ptr at: 0x7fffffffdbf4
Run Code Online (Sandbox Code Playgroud)
我对发生的事情的理解line 8是,根据优先规则(后增量的++优先级高于取消引用*),表达式*ptr++相当于*(ptr++).这是我经历的一个很好的解释.但是,在那个解释中没有提到序列点.
在混合中抛出序列点,我假设它11是打印的,因为ptr只有在达到序列点(恰好在所有要printf计算的参数之后)才会增加.并且,后增量运算符实际上是在序列点之后完成它(增加和写入)的工作.我的理解是否正确?
我假设打印11是因为ptr仅在序列点之后递增(恰好在printf的所有参数被评估之后)
不.这与序列点无关.后增量表达式增加其参数,但表达式的值是增量前的参数值.
对于int*post增量看起来很像这个函数:
int* postInc(int** p)
{
int* tmp = *p;
*p = *p + 1;
return tmp;
}
Run Code Online (Sandbox Code Playgroud)
而且*p++应该是这样的:
*postInc(&p);
Run Code Online (Sandbox Code Playgroud)
我对第8行发生的事情的理解是,根据优先规则(后增量++的优先级高于去引用*)表达式*ptr ++相当于*(ptr ++)
这是对的.
在混合中投掷序列点......
这与序列点本身没有任何关系,而是与postfix ++的行为有关,指定为(6.5.2.4):
postfix ++运算符的结果是操作数的值.作为副作用,操作数对象的值递增.
/ - /
在更新操作数的存储值的副作用之前,对结果的值计算进行排序.
在简单的英语中,这意味着表达式ptr++将首先"返回" ptr将用作表达式结果的值,然后再增加ptr1.
对于整个表达式printf("Result of expression: %d\n", *ptr++);,在评估所有函数参数之后,但在调用函数之前有一个序列点.再加上一些.
程序流程如下:
"Result of expression: %d\n"和*ptr++.这可以按任何顺序完成.对于子表达式*ptr++,请评估其子表达式.运算符优先级指示生成ptr++一个子表达式.因此,将此表达式计算为值ptr并存储结果.
a)*使用存储的结果作为操作数评估运算符.存储评估结果,以传递给函数.
b)增加ptr1.
3a)和3b)可以相对于彼此以任何顺序排序.
;.如您所见,序列点与*ptr++表达式的评估大多无关.序列点发挥作用的唯一时间是C指示++必须在它之前发生.但++可以发生在2)和5)之间的任何地方.
| 归档时间: |
|
| 查看次数: |
90 次 |
| 最近记录: |