簡體   English   中英

通過本地修改的值傳遞的參數會發生什么情況?

[英]What happens to a parameter passed by value that is modified locally?

我很清楚,在C / C ++函數之外,修改按值傳遞的函數參數無效,但是編譯器允許這樣做-但是會發生什么? 是否由參數構成本地副本,並且可以在函數中進行修改

#include <stdio.h>

void doSomething( int x )
{
    x = 42;
    printf( "The answer to Life, the Universe and Everything is (always): %i!\n", x );
}

int main( int argc, char **argv )
{
    int a = 0;
    doSomething( a );
    return -a;
}

現在,這總是無錯誤地退出,但是在事物方案(內存空間)中函數中以x表示的值保留在哪里?

我想(合並的聲明和定義)應該開始:

void doSomething( const int x )

我會被任何不正派的編譯器打敗。

對於函數doSomething()x在函數本地。 它具有與在函數體開頭定義的任何其他變量類似的作用域。

一般而言, x僅存在於doSomething()函數的范圍內。 一旦doSomething()被調用(並且傳遞了參數doSomething()就定義了x並在控件返回后銷毀x 只要執行了函數調用(即變量仍在作用域內),參數就與任何其他變量相同,僅由函數調用中提供的參數進行初始化。

引用C11 ,第§6.2.1章, 標識符范圍

[...]如果聲明標識符的聲明符或類型說明符出現在功能定義的塊內或參數聲明列表中,則標識符具有塊作用域,該作用域終止於相關塊的末尾。 [...]

如您所知, x是傳遞給函數調用的實際參數的本地副本 ,對函數內部對x所做的任何更改都不會反映到調用方(實際參數)中,但是編譯器沒有理由抱怨因為該函數內部x上的操作有效。

函數的value參數實際上是該函數的局部變量,但它是在函數調用中初始化的。 所以這些:

 void f( int n ) {
      n++;
   }

和:

 void g() {
      int n = 0;
      n++;
   }

如果對f()的調用設為f(0),則它們實際上是相同的。 在這兩種情況下,變量都將在函數退出時被丟棄。

形式參數x是在從實際的參數存儲器中的單獨的對象a ,所以任何更改x不會反映在a

正如其他人解釋的那樣, xdoSomething函數中是局部的,任何修改僅影響參數的局部副本。

但是請注意,C ++允許通過引用傳遞: doSomething()定義中的很小變化將對該程序產生重大影響:

void doSomething( int& x ) {
    x = 42;
    printf( "The answer to Life, the Universe and Everything is (always): %i!\n", x );
}

使用上面的函數定義, main變量a實際上確實將其值更改為42 由於main()的代碼相同,因此此C ++功能可能導致代碼混亂,尤其是對於C程序員而言。

值x是局部的,並保留在堆棧中。 每個函數都有其自己的堆棧部分,當程序進入函數時會保留該部分。 值x將位於堆棧的這一部分。 並且僅在定義它的功能范圍內有效。 如果更改x,它將僅針對定義了x的函數進行更改。 如果函數結束(從函數返回),則為函數保留的堆棧將被破壞,因此值x也將被破壞。 因此x將不再可用,因為它不再存在。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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