簡體   English   中英

C中表達式的指針和正確評價

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM