考慮下面的代碼:被調用(派生)函數如何以c語言訪問調用者(基)函數的變量?
void foo(){
.....
}
int main()
{
int arr[3][3] ;
char string[10];
foo();
return 0;
}
如何函數foo訪問我的主要功能的當地人沒有參數傳遞給函數作爲函數的參數?函數foo是否有足夠的權限來訪問和修改main中的變量? 請回復 謝謝
考慮下面的代碼:被調用(派生)函數如何以c語言訪問調用者(基)函數的變量?
void foo(){
.....
}
int main()
{
int arr[3][3] ;
char string[10];
foo();
return 0;
}
如何函數foo訪問我的主要功能的當地人沒有參數傳遞給函數作爲函數的參數?函數foo是否有足夠的權限來訪問和修改main中的變量? 請回復 謝謝
按照C語言規範,函數的局部變量是無法訪問等功能。沒有合法的,支持的方式去做你所要求的。也就是說,在C語言的大多數(全部)實現中,主函數的變量將存儲在堆棧中,這很容易定位,並且可以被任何人讀取(它必須是因爲每個人都需要存儲本地信息在它),所以它在技術上是可能的(儘管這是一個非常糟糕的主意)。
void foo(){
int b; // puts a 4 byte word on the stack atop the return address
(&b)[2]; // interpret b as the first entry in an array of integers (called the stack)
// and offset past b and the return address to get to a
// for completeness
(&b)[0]; // gets b
(&b)[1]; // gets the return address
}
int main()
{
int a; // puts a 4 byte word on the stack
foo(); // puts a (sometimes 4 byte) return address on the stack atop a
return 0;
}
此代碼,可能會在某些系統(比如32位的x86系統)訪問的變量主要功能內,但它很容易破碎(例如,如果該系統上的指針是8個字節,如果有如果堆棧金字塔在使用中,如果每個函數中有多個變量,並且編譯器對它們應該在什麼順序有自己的想法,等等,則此代碼將無法按預期工作)。所以不要使用它,使用參數,因爲沒有理由不這樣做,而且它們工作。
真是極端的答案。而且,在有參數的函數中,這些參數實際上是函數的局部變量,但可能它們駐留在寄存器中 - 而不是堆棧中。所以這個答案是非常糟糕的,即使有時它可以是「正式正確的」。 – linuxfan
你的意思是代碼示例非常糟糕?我同意,但我覺得這裏有一個機會可以讓我們瞭解某些事情是如何「隱藏起來的」(而不是僅僅清理一些關於C語言本身的東西),並且覺得值得提問者的風險可能會跳過「永遠不要做這個警告」並利用這個無意義的代碼。如果你對如何更清楚地表明我不贊同這種行爲有什麼建議,那我就會全神貫注。 – Irisshpunk
不,這不是代碼,正確的你也說「不要使用它」。根據我的口味,這是整個想法,不適合這個答案。幾年前,我確實如此描述了它,並且它工作正常。但我完全知道編譯器的實現,我也用過彙編器,這是一個非常特殊的情況(多任務的實現)。背景非常精確;相反,你回答有人問「擁有足夠的特權......」......這讓我覺得他是初學者,不會被困難的內部調戲。只是。 – linuxfan
可能重複的[可以訪問本地變量的內存超出其範圍?](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-範圍) – Stargateur
這就是參數的用途。 – stark