我在语言C中有一个问题.考虑以下代码(这是一个最小的例子):
#include <stdio.h>
int f(int**, int*);
int main(int argc, char *argv[])
{
int *u = NULL, t1=0, t2=1;
u = &t1;
printf("t1 : %d\n", t1);
printf("t2 : %d\n\n", t2);
*u = 36;
printf("t1 : %d\n", t1);
printf("t2 : %d\n\n", t2);
*u = f(&u, &t2);
printf("t1 : %d\n", t1);
printf("t2 : %d\n\n", t2);
return 0;
}
int f(int** p, int* e){
*p = e;
return 24;
}
Run Code Online (Sandbox Code Playgroud)
当我运行此程序时,我得到以下结果:
t1 : 0
t2 : 1
t1 : 36
t2 : 1
t1 : 24
t2 : 1
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是表达式的左侧部分(即*u):
*u = f(&u, &t2);
Run Code Online (Sandbox Code Playgroud)
在处理函数f之前固定.事实上,我期待以下结果,因为函数f修改了指针u:
t1 : 0
t2 : 1
t1 : 36
t2 : 1
t1 : 36
t2 : 24
Run Code Online (Sandbox Code Playgroud)
这是正常的吗?我在C班中错过了什么?
赋值表达式中没有序列点,并且在赋值表达式的左右操作数之间没有保证的评估顺序.您编写的代码在C中没有明确定义的行为,因此您看到的行为并不意味着您的编译器不符合要求.
6.5/3:
除如后述指定的(用于函数调用
(),&&,||,?:,和逗号运营商),子表达式的求值的顺序,并且其中的副作用发生均为未指定的顺序.
虽然函数调用中有一个序列点,但无法保证在评估之前或之后调用该函数*u.