筆試題 類中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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 數學類筆試題筆試
- PHP類的靜態(static)方法和靜態(static)變數PHP變數
- static變數變數
- Java中static變數作用和用法詳解Java變數
- C語言中的 static變數、static函式C語言變數函式
- Spring 注入static變數Spring變數
- 反射修改 static final 變數反射變數
- static靜態變數的理解變數
- static變數在php和java中的生命週期變數PHPJava
- C:static 關鍵字、靜態變數、跨類訪問資料變數
- iOS 靜變數static、全域性變數extern、區域性變數、例項變數iOS變數
- static 靜態變數引起 Laravel 中佇列一個 Bug變數Laravel佇列
- 函式的靜態變數 static函式變數
- 變數提升的考試題變數
- Java中變數之區域性變數、本類成員變數、父類成員變數的訪問方法Java變數
- 關於web應用的static變數Web變數
- 子父類中成員變數變數
- 研發類C++筆試題目C++筆試
- Python中類變數、成員變數、區域性變數的區別Python變數
- java學習筆記day07 成員變數與區域性變數、形式引數、匿名物件、封裝、private、this、構造方法、類詳細講解、staticJava筆記變數物件封裝構造方法
- C++ static variable(靜態變數) 學習C++變數
- java類變數Java變數
- ruby中的類例項變數和例項的例項變數變數
- Python面試題1:類變數在繼承中的深入理解Python面試題變數繼承
- Java中可以宣告一個類為Static嗎?Java
- 理解靜態區域性變數(static)在程式中的執行規則變數
- js中變數作用域問題JS變數
- 騰訊研發類筆試面試試題及答案(C++方向)筆試面試C++
- C++ static、const和static const變數 以及它們的初始化C++變數
- 何時使用static類(工具類)
- Java中的類(好似結構體) 物件(好似指標變數)變數 方法Java結構體物件指標變數
- static變數是否能繼承詳細介紹變數繼承
- Java 變數種類Java變數
- private,public,protected,static不可以修飾區域性變數,方法裡的變數變數
- Java - 24 類變數和類方法Java變數
- 如何保證一個類中的例項變數不被改變變數
- 十四、類變數和實列變數(python)變數Python
- static變數,static程式碼塊,建構函式,程式碼塊等的載入順序變數C程式函式