2017-01-24 43 views
1

在以下代碼中,打印出2C/C++中的靜態作用域

int x = 1; 
int f(int y) 
{ 
    return x; 
} 

int main() { 
    x = 2; 
    printf("%d", f(0)); 
} 

如果我們在C中有靜態作用域,它會發生什麼?爲什麼不打印1

印刷2在這種情況下是不是一個動態範圍,是嗎?

我認爲,在靜態範圍內,它應該取最接近x的函數定義。

+3

你只在這裏聲明一個'x'(作爲一個全局變量)。因此,從代碼中的任何位置進行的任何修改都會影響以後任何其他代碼的使用。 – NiBZ

+1

爲什麼呢? x不是常量,在返回之前被修改。 – George

+0

這是最接近的一個(只有一個可供選擇),並且該分配發生在函數調用之前,所以它打印出來2.按預期工作(TM)。 – Borgleader

回答

7

確實需要最近的x,但由於您只有一個x這並不重要。

如果你讓你有2 x修改代碼,

int x = 1; 
int f(int y) 
    { 
    return x ; 
    } 

int main() { 
    int x=2;  
    printf("%d", f(0)); 
} 

,全局的和局部的main你會看到越來越1打印。

+0

爲什麼所以我無法理解。 –

+0

@SurajJain你能更具體嗎? – nwp

+0

我意思是爲什麼我們無法打印該值。 ,我不明白你的答案。 –

2

,因爲你有聲明的x本地將否則陰影全球x作用域這裏沒有實際意義。

2被打印。

xmainf時調用參數0之前分配到立即2

(概念上int x = 1;輸入main之前跑。)

1

它是編譯器生成的彙編/機器代碼的方式。

  • 第一全局變量X被存儲在存儲器位置 「ABC」
  • 下一個主要被執行:在 「ABC」 全局變量X被改變爲2
  • 現在函數f()被調用:
    • 函數f在 「ABC」 返回全局變量X的值:爲2
  • f的返回值()被打印。

所以如果你想在主函數範圍內使用一個不同的X,你應該創建一個新的對象,就像nwp的答案一樣。

+1

「你應該做出一個新對象,就像nwp的回答一樣。」這不是@nwp代碼中發生的事情,更不是你使用世界上最糟糕的編譯器。 – George

+0

@george:真的,但看到問題的簡單性,我不想詳細說明編譯器的細節;) – JHBonarius

+0

我從最後一行中得到了類似'printf(「%d」,f(x ));'會打印2 < - 顯然你不能初始化一個變量兩次,所以這可能是一個好主意,澄清一點?直到你,你仍然可以有我的投票:) – George

1

那些通常被稱爲動態和詞法範圍界定。

詞法作用域完全在編譯時確定,在運行時動態作用域。

您只有一個名爲「x」的變量,因此作用域與您的程序無關。

這裏有一個程序,將取決於範圍的規則是不同的:

int x = 0; 

int f() 
{ 
    return x; 
} 

int main() 
{ 
    int x = 1; 
    printf("%d\n", f(x)); 
} 

在詞彙範圍,f返回x的值是詞彙「最近」 - 全球一個。
所以它會打印0;

在動態範圍內,f將返回main中最新的x的值。
所以它會打印1