我目前正在學習計算機記憶體并向自己提出問題以更好地理解它。
我了解了每當呼叫函式時如何在堆疊中分配新空間。 但是為什么我們無法訪問區域變數,即使它們仍在堆疊中?是什么阻止我在它們仍在堆疊上時訪問它們?
考慮以下代碼(請查看評論):
class Program
{
public static void Main()
{
int number = 5;
Method();
} //<------ number variable will be stored in the stack until the program reaches here.
public static void Method()
{
// number=5 variable is still on the stack so why can't I reach it here?
number = 10; // throws an error because it's not defined in this scope but it's still on the stack.
int anotherNumber = 2;
}
}
uj5u.com熱心網友回復:
在 C 及其派生的語言中,函式是單獨編譯的,因此它們無法“看到”彼此的區域變數。這是一個設計決定。
在 Pascal 及其派生的語言中,這是通過允許嵌套函式宣告來實作的。在另一個內部宣告的函式將后者的區域變數視為全域變數。
但請注意,通過相互和遞回呼叫,同一個變數可以存在于堆疊中的多個位置。
uj5u.com熱心網友回復:
如果該代碼可以編譯(即,如果您注釋掉number = 10;),則變數 number 甚至可能不在 Release 構建中的堆疊上,因為它未被使用并且優化器會意識到這一點。
C#對變數使用作用域,變數的作用域number就是Main()方法。如果您在類中定義它,它將是一個類成員,并且也可以從 method 訪問Method()。但是,作為一般經驗法則,始終嘗試限制變數的范圍。
class Program
{
static int number = 5; // class member
public static void Main()
{
Method();
}
public static void Method()
{
number = 10; // no error anymore
int anotherNumber = 2;
}
}
uj5u.com熱心網友回復:
變數仍在堆疊上,為什么我不能在這里訪問它?
這個論點與“所有變數都在記憶體中,所以為什么我不能從任何地方訪問所有變數,包括來自其他程式的變數,畢竟它們都在同一個記憶體中,對嗎?”
你的提議有很多問題。從封裝到名稱污染,再到優化,再到安全性。
區域變數就是:區域變數。對我來說,這是一個實作細節。外界不應該知道它,因為它是我的,我將它用于我的內部目的,我可以隨意更改或洗掉它。你的提議是什么?現在我無法更改我自己的區域變數,因為呼叫鏈中某處的某個函式使用了它。為什么要使用它?如果我想將一些資訊傳遞給我呼叫的函式,那么應該通過引數來完成。
void foo() { int mine; bar(); }
void bar() { void baz(); }
void baz() { mine = 24; } // like wtf??
除了你將如何處理這種情況:
void foo_1()
{
int mine; // I can name it mine because it's a local variable
bar();
}
void foo_2()
{
int mine; // I can also name it mine because it's a local variable
bar();
}
void foo_3()
{
bar();
}
void bar()
{
mine = 24; // ??????
}
為了將資訊從一個函式傳遞到另一個函式,我們使用引數,我們不會污染虛構的“全域本地命名空間”,因為我們不是野蠻人。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/517313.html
標籤:C#记忆
上一篇:如何斷言XUnit中例外的屬性?
