[英]Pointer and right evaluation of an expression in C
我在語言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;
}
當我運行此程序時,我得到以下結果:
t1 : 0
t2 : 1
t1 : 36
t2 : 1
t1 : 24
t2 : 1
令我驚訝的是表達式的左側部分(即* u):
*u = f(&u, &t2);
在處理函數f之前固定。 事實上,我期待以下結果,因為函數f修改了指針u:
t1 : 0
t2 : 1
t1 : 36
t2 : 1
t1 : 36
t2 : 24
這是正常的嗎? 我在C班中錯過了什么?
賦值表達式中沒有序列點 ,並且在賦值表達式的左右操作數之間沒有保證的評估順序。 您編寫的代碼在C中沒有明確定義的行為,因此您看到的行為並不意味着您的編譯器不符合要求。
6.5 / 3:
除非后面指定(對於function-call
()
,&&
,||
,?:
和逗號運算符),否則子表達式的計算順序和副作用的順序都是未指定的。
雖然函數調用中有一個序列點,但無法保證在評估*u
之前或之后調用該函數。
運行代碼后,我得到了您期望的答案。 您應該更仔細地檢查您的代碼。
編輯:看完其他答案后,我覺得我應該發布我的規格。 我在Windows 7 Ultimate 64位上運行Visual Studio 2010 64位。
調用該函數時,將存儲返回值的存儲器位置是固定的。 雖然您正在更改指向的內容,但函數調用中發生的分配(內存位置)已經修復。
事實上,如果你嘗試
#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);
printf("u : %d\n\n", *u);
return 0;
}
int f(int** p, int* e){
*p = e;
return 24;
}
你會得到
t1 : 0 t2 : 1 t1 : 36 t2 : 1 t1 : 24 t2 : 1 u : 1
嘿,它不是任何ABNORMAL行為,編譯器正常工作。
*u = f(&u, &t2);
int f(int** p, int* e)
{
*p = e; // It means value of t2 gets copied into memory location pointed by u i.e t1
return 24; // Now this 24 would get stored/overwrite in memory location pointed by u i.e t1
} // Thus no change occurs in t2
記住功能“f”僅對由U指示的存儲位置的值進行更改,而不是由u指示的地址。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.