C 語言中 struct 的陷阱

2021-09-05 23:34:07 字數 3591 閱讀 6976

假設我們要為某大學寫乙個工資管理程式。首先是表示員工的 employee 類(employee.cs):

01:  

namespace skyiv.ben

02:

06:

public string name

07:

public decimal salary

08:

09:

public employee(string department, string name, decimal salary)

10:

15:

16:

public override string tostring()

17: 工資:", department, name, salary);

19: }

20: }

21: }

接著是表示學校中各系的 department 類(department.cs):

01:  

namespace skyiv.ben

02:

06:

public int count

07:

public decimal totalsalary

08:

09:

public department(string name)

10:

13:

14:

public void add(employee employee)

15:

19:

20:

public override string tostring()

21: 人數: 總工資:", name, count, totalsalary);

23: }

24: }

25: }

最後就是主程式 program.cs :

01:  

using system;

02:

using system.collections.generic;

03:

04:

namespace skyiv.ben

05:

12:

13:

void run()

14:

19:

20:

list

initializeemployees()

21:

30:

31:

void salaryraise(list

employees)

32:

37:

38:

void statistic(list

employees)

39:

48:

console.writeline(environment.newline + "三閭大學工資統計表:");

49:

foreach (var kvp in departments) console.writeline(kvp.value);

50: }

51: }

52: }

這個程式的執行結果如下所示:

三閭大學工資明細表:

校長室 高松年 工資:72,767.58

政治系 方鴻漸 工資:31,982.45

政治系 趙辛楣 工資:40,126.31

加薪之後:

校長室 高松年 工資:82,767.58

政治系 方鴻漸 工資:41,982.45

政治系 趙辛楣 工資:50,126.31

三閭大學工資統計表:

校長室 人數:1 總工資:82,767.58

政治系 人數:2 總工資:92,108.76

如果我們把 employee 類(class)改為結構(struct),則在編譯時就會報以下錯誤:

cs1612: 無法修改「system.collections.generic.list.this[int]」的返回值,因為它不是變數。
這個錯誤發生在 program.cs 第 33 行中的 employees[i].salary += 10000; 語句。

如果我們把 department 類(class)改為結構(struct):

01:  

namespace skyiv.ben

02:

06:

public int count

07:

public decimal totalsalary

08:

09:

public department(string name) : this()

10:

13:

14:

public void add(employee employee)

15:

19:

20:

public override string tostring()

21: 人數: 總工資:", name, count, totalsalary);

23: }

24: }

25: }

注意上述程式中第 09 行最後要加上「 : this() 」,否則 microsoft c# 編譯器會報錯(但是 mono c# 編譯器不會報錯,請參見:** microsoft c# 編譯器和 mono c# 編譯器)。

再次執行該程式,執行結果的最後三行如下所示:

三閭大學工資統計表:

校長室 人數:0 總工資:0.00

政治系 人數:0 總工資:0.00

這是因為現在的 department 結構是值型別,而不是引用型別。所以在 program.cs 第 46 行的 dep.add(employee); 語句中,dep 的值的更改不會影響到 departments 字典中的值。所以統計出來的人數和總工資都是零了。

要繞過這個陷阱很簡單,在第 46 行的 dep.add(employee); 語句後面加一句 departments[name] = dep; 就行了。

在 .net framework base class library 中,有很多的結構(struct)。如:

使用時也要小心陷阱。

此外,還有注意 datetime 的 add 和 adddays 等方法並不更改此 datetime 的值。而是返回乙個新的 datetime,其值是此運算的結果。因此以下語句是不成立的:

for (var date = datetime.minvalue; date < datetime.today; date.adddays(1))
正確的應該是:

for (var date = datetime.minvalue; date < datetime.today; date = date.adddays(1))

C 語言中 struct 的陷阱

假設我們要為某大學寫乙個工資管理程式。首先是表示員工的 employee 類 employee.cs 01 namespace skyiv.ben 02 06 public string name 07 public decimal salary 08 09 public employee stri...

C語言中的技術陷阱

c語言深入學習階段,我正在讀 c語言程式設計之道 這本書,整理了c語言中的一些技術陷阱。這本書上的封面上有一句話我覺得挺有道理 每多學一點知識,就少寫一行 知識便是財富。一 c語言中的識別符號是區分大小寫的 這是很基本的問題,初學者也很容易忽視。二 與 的混淆使用 例如 int main 本想定義二...

C語言中的struct 記憶體對齊

sizeof計算結構體大小的時候具體是怎樣計算的 記憶體對齊的原則是根據最寬資料型別的大小進行對齊的 struct a 大小是8個位元組要進行記憶體對齊,是根據int 4個位元組對齊的 char short 4位元組 int 4位元組 如上是這樣對齊的 struct a 大小是8個位元組 int 4...