c 中的形參和實參以及不按套路的string型別

2021-07-24 02:51:34 字數 3373 閱讀 9853

我自己測試的結果,隨手記,不多說。上**。

using system;

using system.collections.generic;

using system.linq;

using system.text;

using system.threading.tasks;

namespace 形參實參

////// 基本數值型別中除了string外,其他都是值型別

//////

static

void 值型別(int a1)

static

void 引用型別(string str1)

static

void 引用型別(c c1)

}class c

}

結果:

以下內容來自:

.net 框架程式設計(修訂版)中有這樣一段描述:string型別直接繼承自object,這使得它成為乙個引用型別,也就是說執行緒上的堆疊上不會駐留有任何字串。(譯註:注意這裡的「直接繼承」。直接繼承自object的型別一定是引用型別,因為所有的值型別都繼承自system.valuetype。值得指出的是system.valuetype卻是乙個引用型別)。

一:string str1 = 「string」;

string str2 = 「string」;

console.writeline(string.referenceequals(str1, str2));

既然string型別是引用型別,那麼**一輸出的應該是false,然而事實上**一輸出時的是true。

其實這是string型別的自動優化功能。str1,str2引用同一物件,節省記憶體,並不會為str2單獨開闢記憶體空間。clr使用了一種叫字串駐留的技術,當clr初始化時,會建立乙個內部的雜湊表,其中的鍵為字串,值為指向託管堆中字串的引用。剛開始,雜湊表為空,jit編譯器編譯方法時,會在雜湊表中查詢每乙個文字常量字串,首先會查詢」abc」字串,並且因為沒有找到,編譯器會在託管堆中構造乙個新的指向」abc」的string物件引用,然後將」abc」字串和指向該物件的引用新增到雜湊表中。接著,在雜湊表中查詢第二個」abc」,這一次由於找到了該字串,指向同乙個string物件的引用會被儲存在變數str2中,到此str1和str2指向了同乙個引用,所以string.referenceequals(str1, str2)就會返回true了。

另外,c#中是不允許用new操作符建立string物件的,編譯器會報錯。

二:複製**

static void main(string args)

static void change(string str)

複製**

方法傳遞的引數是原內容的拷貝,其過程如果用圖可表示為:

語句str=」changed」之前

語句str=」changed」之後

這樣可以看到原來string物件並未改變str=」changed」只是建立乙個新的string物件(其它引用型別是改變記憶體位址1指向的值),因此這個方法的引數需要加上ref或者out修飾符。因此這裡也可以得出字串具有恒等性,也就是說乙個字串一旦被建立,我們就不能再將其變長、變短、或者改變其中的任何字元。

msdn上這樣解釋:字串物件是不可變的,即它們一旦建立就無法更改。對字串進行操作的方法實際上返回的是新的字串物件。

string在另一種情況下的操作是具有值型別特徵的:str1 == str2 ,僅僅是比較了值,而非位址(是ms重寫了==運算子所致).

三:string 物件是不可改變的。每次使用 system.string 類中的方法之一時,都要在記憶體中建立乙個新的字串物件,這就需要為該新物件分配新的空間。在需要對字串執行重複修改的情況下,與建立新的 string 物件相關的系統開銷可能會非常昂貴。如果要修改字串而不建立新的物件,則可以使用 system.text.stringbuilder 類。例如,當在乙個迴圈中將許多字串連線在一起時,使用 stringbuilder 類可以提公升效能。

下面看乙個極簡單的例子:

複製**

namespace tcp

public string name

set

}public string age

set }}

console.writeline(code);

console.writeline(str);

console.writeline(user.name);

console.writeline(user.age);

console.readline();

} }

複製**

上面**輸如下:

這樣可以看到原來string物件並未改變str=」changed」只是建立乙個新的string物件(其它引用型別是改變記憶體位址1指向的值),因此這個方法的引數需要加上ref或者out修飾符。因此這裡也可以得出字串具有恒等性,也就是說乙個字串一旦被建立,我們就不能再將其變長、變短、或者改變其中的任何字元。

msdn上這樣解釋:字串物件是不可變的,即它們一旦建立就無法更改。對字串進行操作的方法實際上返回的是新的字串物件。

string在另一種情況下的操作是具有值型別特徵的:str1 == str2 ,僅僅是比較了值,而非位址(是ms重寫了==運算子所致).

三:string 物件是不可改變的。每次使用 system.string 類中的方法之一時,都要在記憶體中建立乙個新的字串物件,這就需要為該新物件分配新的空間。在需要對字串執行重複修改的情況下,與建立新的 string 物件相關的系統開銷可能會非常昂貴。如果要修改字串而不建立新的物件,則可以使用 system.text.stringbuilder 類。例如,當在乙個迴圈中將許多字串連線在一起時,使用 stringbuilder 類可以提公升效能。

下面看乙個極簡單的例子:

複製**

namespace tcp

public string name

set

}public string age

set }}

console.writeline(code);

console.writeline(str);

console.writeline(user.name);

console.writeline(user.age);

console.readline();

} }

複製**

上面**輸如下:

從上面可以看到string型別的值並沒有改變,stringbuilder與class的值都改變了。

形參和實參,以及在記憶體中的分配

c 中有兩種型別的資料,一種為值型別 另一種為引用型別。值型別 int char float long bool double struct enum short byte decimal sbyte uint ulong ushort等 引用型別 string class inte ce dele...

mysql裡的實參和形參 形參和實參的區別

形參 全稱為 形式引數 是在定義函式名和函式體的時候使用的引數,目的是用來接收呼叫該函式時傳如的引數.實參 全稱為 實際引數 是在呼叫時傳遞個該函式的引數.形參出現在函式定義中,在整個函式體內都可以使用,離開該函式則不能使用。實參出現在主調函式中,進入被調函式後,實參變數也不能使用。形參和實參的功能...

C C 中的實參和形參

今天突然看到一道關於形參和實參的題,我居然不求甚解。藐視過去在我的腦海裡只有乙個引數的概念,對於形參和實參的區別還真的不知道,作為學習了幾年c 的人來說,真的深深感覺對不起自己對不起c 老師 t。t 我覺得只要明白了值傳遞和位址傳遞,就應該能明白形參和實參的具體工作細節了。1 值傳遞 實參是變數,表...