筆試題 類中static變數
using System;
namespace Param
{
class Class1
{
static int i = getNum();
int j = getNum();
static int num = 1;
static int getNum()
{
return num;
}
[STAThread]
static void Main(string[] args)
{
Console.WriteLine(string.Format("i={0}",i));
}
}
上面的程式碼是一個網友告訴我的,讓我看看結果,我看了一眼馬上說結果是
i=1
j=1
網友執行後說結果是
i=0
j=1
我嚇了一跳,認真看了程式碼,原來自己真的錯了。
下面我解釋一下為什麼是後一種結果
對一個類來說,static變數是與物件無關的,那麼它們什麼時候被初始化呢?就是在第一次引用的時候。當類生成物件的時候,可以簡單分成3步
1,為所有static變數分配記憶體,這個時候記憶體裡面的值是該變數型別的預設值。關於不同值型別的預設值大家可以去查相關資料,注意值型別和引用型別是不同的。
2,為static變數賦值,同樣要注意值型別和引用型別是不同的。
3,生成物件,呼叫建構函式,先呼叫這個類的父類的建構函式,然後呼叫類本身的建構函式,生成物件。
現在分析上面的程式碼:
Console.WriteLine(string.Format("i={0}",i));這裡i是static變數,而且類class1是第一次被引 用,按照上面說的三步,要先為class1裡面所有的static變數分配記憶體。儘管現在有超執行緒技術,但是指令在邏輯還是一條一條的按順序執行的,所以 先為static int i分配記憶體,並且在該記憶體中保持int的預設值0,接著再為static int num 變數分配記憶體,值當然也為0。
然後執行第二步,為變數賦值:先為static int i變數賦值,i=getNum(),看getNum裡面的程式碼,就是return num,這個時候num的值是0,於是i就為0了。然後對變數num賦值,num=1;這行程式碼執行後,num就為1了。分析到這裡我就不繼續分析了,大 家很容易看出結果是什麼。
稍微熟悉c#的人,只要認真看程式碼,肯定不會出錯,但是如果拿來考人,相信很多人會做錯。我認為這個問題簡單得算不上一個技術問題,所以放在非技術區。之 所以在上面說那麼多廢話來分析,是想說明在程式設計的時候,即使非常熟悉、非常基本的東西,也要認真。當然如果我手下的人寫出這樣的程式碼,肯定在程式碼檢視的時 候被我痛批。事實上對static 值型別變數不直接賦值,而通過方法來賦值,是不常用或者是有點bt的做法,但是我仍然很佩服出題的人。
namespace Param
{
class Class1
{
static int i = getNum();
int j = getNum();
static int num = 1;
static int getNum()
{
return num;
}
[STAThread]
static void Main(string[] args)
{
Console.WriteLine(string.Format("i={0}",i));
Console.WriteLine(string.Format("j={0}",new Class1().j));
Console.Read();
}
}
上面的程式碼是一個網友告訴我的,讓我看看結果,我看了一眼馬上說結果是
i=1
j=1
網友執行後說結果是
i=0
j=1
我嚇了一跳,認真看了程式碼,原來自己真的錯了。
下面我解釋一下為什麼是後一種結果
對一個類來說,static變數是與物件無關的,那麼它們什麼時候被初始化呢?就是在第一次引用的時候。當類生成物件的時候,可以簡單分成3步
1,為所有static變數分配記憶體,這個時候記憶體裡面的值是該變數型別的預設值。關於不同值型別的預設值大家可以去查相關資料,注意值型別和引用型別是不同的。
2,為static變數賦值,同樣要注意值型別和引用型別是不同的。
3,生成物件,呼叫建構函式,先呼叫這個類的父類的建構函式,然後呼叫類本身的建構函式,生成物件。
現在分析上面的程式碼:
Console.WriteLine(string.Format("i={0}",i));這裡i是static變數,而且類class1是第一次被引 用,按照上面說的三步,要先為class1裡面所有的static變數分配記憶體。儘管現在有超執行緒技術,但是指令在邏輯還是一條一條的按順序執行的,所以 先為static int i分配記憶體,並且在該記憶體中保持int的預設值0,接著再為static int num 變數分配記憶體,值當然也為0。
然後執行第二步,為變數賦值:先為static int i變數賦值,i=getNum(),看getNum裡面的程式碼,就是return num,這個時候num的值是0,於是i就為0了。然後對變數num賦值,num=1;這行程式碼執行後,num就為1了。分析到這裡我就不繼續分析了,大 家很容易看出結果是什麼。
稍微熟悉c#的人,只要認真看程式碼,肯定不會出錯,但是如果拿來考人,相信很多人會做錯。我認為這個問題簡單得算不上一個技術問題,所以放在非技術區。之 所以在上面說那麼多廢話來分析,是想說明在程式設計的時候,即使非常熟悉、非常基本的東西,也要認真。當然如果我手下的人寫出這樣的程式碼,肯定在程式碼檢視的時 候被我痛批。事實上對static 值型別變數不直接賦值,而通過方法來賦值,是不常用或者是有點bt的做法,但是我仍然很佩服出題的人。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-617194/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 反射修改 static final 變數反射變數
- C:static 關鍵字、靜態變數、跨類訪問資料變數
- static 靜態變數引起 Laravel 中佇列一個 Bug變數Laravel佇列
- 變數提升的考試題變數
- 面試題:布林變數面試題變數
- Java中變數之區域性變數、本類成員變數、父類成員變數的訪問方法Java變數
- Python中類變數、成員變數、區域性變數的區別Python變數
- JAVA面試題 淺析Java中的static關鍵字Java面試題
- java學習筆記day07 成員變數與區域性變數、形式引數、匿名物件、封裝、private、this、構造方法、類詳細講解、staticJava筆記變數物件封裝構造方法
- 子父類中成員變數變數
- java類變數Java變數
- 理解靜態區域性變數(static)在程式中的執行規則變數
- static變數是否能繼承詳細介紹變數繼承
- private,public,protected,static不可以修飾區域性變數,方法裡的變數變數
- 十四、類變數和實列變數(python)變數Python
- Java中的類(好似結構體) 物件(好似指標變數)變數 方法Java結構體物件指標變數
- Java 變數種類Java變數
- 騰訊研發類筆試面試試題及答案(C++方向)筆試面試C++
- static變數,static程式碼塊,建構函式,程式碼塊等的載入順序變數C程式函式
- static關鍵字---"工具類"
- Java - 24 類變數和類方法Java變數
- ES6中類的靜態方法=> static 的使用
- 變數的分類(臨時(本地)變數、環境變數、全域性變數和系統變數)變數
- Java訪問類變數Java變數
- [筆記](更新中)最短路問題的變形筆記
- Java 學習(09)--方法過載/建構函式/static 變數Java函式變數
- Tensorflow學習筆記: 變數及共享變數筆記變數
- 成員變數、全域性變數、例項變數、類變數、靜態變數和區域性變數的區別變數
- 社招中級前端筆試面試題總結前端筆試面試題
- Java面試中,遇到這類面試題最吃虧!Java面試題
- 面試題-JavaScript交換兩個變數的方法面試題JavaScript變數
- HTML最新面試題(筆試面試題)HTML面試題筆試
- Python 筆試 面試題Python筆試面試題
- 介面測試如何在 json 中引用 mock 變數JSONMock變數
- 介面測試如何在json中引用mock變數JSONMock變數
- Java static變數、作用域、建構函式初始化順序Java變數函式
- PHP中的staticPHP
- 淺談Java類中的變數初始化順序Java變數
- python3類中的Cat變數使用有限制嗎?Python變數