① 結構體數據類型的內存大小
要判斷一個結構體所佔的空間大小,大體來說分三步走:
1.先確定實際對齊單位,其由以下三個因素決定
1>CPU周期
WIN vs qt 默認8位元組對齊
Linux 32位 默認4位元組對齊,64位默認8位元組對齊
2> 結構體最大成員(基本數據類型變數)
3> 預編譯指令#pragma pack(n)手動設置 n--只能填1 2 4 8 16
上面三者取最小的,就是實際對齊單位(這里的「實際對齊單位」是我為了方便區分隨便取的概念)
2.除結構體的第一個成員外,其他所有的成員的地址相對於結構體地址(即它首個成員的地址)的偏移量必須為實際對齊單位或自身大小的整數倍(取兩者中小的那個)
3.結構體的整體大小必須為實際對齊單位的整數倍。
所以結構體實際占的內存大小大於等於結構體內所以成員數據的大小之和。
② 怎樣在預編譯的時候判斷某個結構體的大小是否符合要求
The constant-expression is an integer constant expression with these additional restrictions:
Expressions must have integral type and can include only integer constants, character constants, and the defined operator.
The expression cannot use sizeof or a type-cast operator.
The target environment may not be able to represent all ranges of integers.
The translation represents type int the same as type long, and unsigned int the same as unsigned long.
The translator can translate character constants to a set of code values different from the set for the target environment. To determine the properties of the target environment, check values of macros from LIMITS.H in an application built for the target environment.
The expression must not perform any environmental inquiries and must remain insulated from implementation details on the target computer.
//////////////
在pascal里卻又可以這樣,
tBootControlSize=sizeof(tBootControl);
{$if tBootControlSize<>4} tBootControlSize size error {$ifend}
把pas改成c
③ sizeof 結構體
不是這里錯了,是內存對齊的問題。
看看這篇文章:
有的時候,在腦海中停頓了很久的「顯而易見」的東西,其實根本上就是錯誤的。就拿下面的問題來看:
struct T
{
char ch;
int i ;
};
使用sizeof(T),將得到什麼樣的答案呢?要是以前,想都不用想,在32位機中,int是4個位元組,char是1個位元組,所以T一共是5個位元組。實踐出真知,在VC6中測試了下,答案確實8個位元組。哎,反正受傷的總是我,我已經有點麻木了,還是老老實實的接受吧!為什麼答案和自己想像的有出入呢?這里將引入內存對齊這個概念。
許多實際的計算機系統對基本類型數據在內存中存放的位置有限制,它們會要求這些數據的首地址的值是某個數k(通常它為4或8)的倍數,這就是所謂的內存對齊,而這個k則被稱為該數據類型的對齊模數(alignment molus)。當一種類型S的對齊模數與另一種類型T的對齊模數的比值是大於1的整數,我們就稱類型S的對齊要求比T強(嚴格),而稱T比S弱(寬松)。這種強制的要求一來簡化了處理器與內存之間傳輸系統的設計,二來可以提升讀取數據的速度。比如這么一種處理器,它每次讀寫內存的時候都從某個8倍數的地址開始,一次讀出或寫入8個位元組的數據,假如軟體能保證double類型的數據都從8倍數地址開始,那麼讀或寫一個double類型數據就只需要一次內存操作。否則,我們就可能需要兩次內存操作才能完成這個動作,因為數據或許恰好橫跨在兩個符合對齊要求的8位元組內存塊上。某些處理器在數據不滿足對齊要求的情況下可能會出錯,但是Intel的IA32架構的處理器則不管數據是否對齊都能正確工作。不過Intel奉勸大家,如果想提升性能,那麼所有的程序數據都應該盡可能地對齊。
ANSI C標准中並沒有規定,相鄰聲明的變數在內存中一定要相鄰。為了程序的高效性,內存對齊問題由編譯器自行靈活處理,這樣導致相鄰的變數之間可能會有一些填充位元組。對於基本數據類型(int char),他們佔用的內存空間在一個確定硬體系統下有個確定的值,所以,接下來我們只是考慮結構體成員內存分配情況。
Win32平台下的微軟C編譯器(cl.exe for 80×86)的對齊策略:
1) 結構體變數的首地址能夠被其最寬基本類型成員的大小所整除;
備註:編譯器在給結構體開辟空間時,首先找到結構體中最寬的基本數據類型,然後尋找內存地址能被該基本數據類型所整除的位置,作為結構體的首地址。將這個最寬的基本數據類型的大小作為上面介紹的對齊模數。
2) 結構體每個成員相對於結構體首地址的偏移量(offset)都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充位元組(internal adding);
備注:為結構體的一個成員開辟空間之前,編譯器首先檢查預開辟空間的首地址相對於結構體首地址的偏移是否是本成員的整數倍,若是,則存放本成員,反之,則在本成員和上一個成員之間填充一定的位元組,以達到整數倍的要求,也就是將預開辟空間的首地址後移幾個位元組。
3) 結構體的總大小為結構體最寬基本類型成員大小的整數倍,如有需要,編譯器會在最末一個成員之後加上填充位元組(trailing padding)。
備註:結構體總大小是包括填充位元組,最後一個成員滿足上面兩條以外,還必須滿足第三條,否則就必須在最後填充幾個位元組以達到本條要求。
根據以上准則,在windows下,使用VC編譯器,sizeof(T)的大小為8個位元組。
而在GNU GCC編譯器中,遵循的准則有些區別,對齊模數不是像上面所述的那樣,根據最寬的基本數據類型來定。在GCC中,對齊模數的准則是:對齊模數最大隻能是4,也就是說,即使結構體中有double類型,對齊模數還是4,所以對齊模數只能是1,2,4。而且在上述的三條中,第2條里,offset必須是成員大小的整數倍,如果這個成員大小小於等於4則按照上述准則進行,但是如果大於4了,則結構體每個成員相對於結構體首地址的偏移量(offset)只能按照是4的整數倍來進行判斷是否添加填充。
看如下例子:
struct T
{
char ch;
double d ;
};
那麼在GCC下,sizeof(T)應該等於12個位元組。
如果結構體中含有位域(bit-field),那麼VC中准則又要有所更改:
1) 如果相鄰位域欄位的類型相同,且其位寬之和小於類型的sizeof大小,則後面的欄位將緊鄰前一個欄位存儲,直到不能容納為止;
2) 如果相鄰位域欄位的類型相同,但其位寬之和大於類型的sizeof大小,則後面的欄位將從新的存儲單元開始,其偏移量為其類型大小的整數倍;
3) 如果相鄰的位域欄位的類型不同,則各編譯器的具體實現有差異,VC6採取不壓縮方式(不同位域欄位存放在不同的位域類型位元組中),Dev-C++和GCC都採取壓縮方式;
備註:當兩欄位類型不一樣的時候,對於不壓縮方式,例如:
struct N
{
char c:2;
int i:4;
};
依然要滿足不含位域結構體內存對齊准則第2條,i成員相對於結構體首地址的偏移應該是4的整數倍,所以c成員後要填充3個位元組,然後再開辟4個位元組的空間作為int型,其中4位用來存放i,所以上面結構體在VC中所佔空間為8個位元組;而對於採用壓縮方式的編譯器來說,遵循不含位域結構體內存對齊准則第2條,不同的是,如果填充的3個位元組能容納後面成員的位,則壓縮到填充位元組中,不能容納,則要單獨開辟空間,所以上面結構體N在GCC或者Dev-C++中所佔空間應該是4個位元組。
4) 如果位域欄位之間穿插著非位域欄位,則不進行壓縮;
備註:
結構體
typedef struct
{
char c:2;
double i;
int c2:4;
}N3;
在GCC下占據的空間為16位元組,在VC下占據的空間應該是24個位元組。
5) 整個結構體的總大小為最寬基本類型成員大小的整數倍。
ps:
對齊模數的選擇只能是根據基本數據類型,所以對於結構體中嵌套結構體,只能考慮其拆分的基本數據類型。而對於對齊准則中的第2條,確是要將整個結構體看成是一個成員,成員大小按照該結構體根據對齊准則判斷所得的大小。
類對象在內存中存放的方式和結構體類似,這里就不再說明。需要指出的是,類對象的大小隻是包括類中非靜態成員變數所佔的空間,如果有虛函數,那麼再另外增加一個指針所佔的空間即可。
④ 關於#pragma pack()的預處理指令
既然是團隊求助,那我來回答好了。
是這樣的,設定為4位元組對齊之後,每個成員變數所佔空間應該是4的倍數,
char m1,本來是一個位元組,要加入3個位元組,所以是4;
double m4;本來就是8個位元組,為4的倍數,不必補齊,是8;
int m3;佔4個位元組,也是4的倍數,不必補齊,是4;
那麼4+8+4是16,這沒錯。
同理,設定為#pragma pack(8),8位元組對齊,那麼裡面全是8,有8X3=24;
你所說的有誤。M1的時候偏移量是0,但是M3的時候偏移量卻不是4,而應該是12;你自己理解一下就知道了,我沒找到網路的例子,你可以發個鏈接給我,如果真是這么寫的那我給你去修改。
⑤ 51單片機 c語言中
#define E2P_RECORD_ADDR 0x00
#define POWER_UP_MARK 0xAB
是預編譯,就是在告訴編譯器: E2P_RECORD_ADDR=0x00,POWER_UP_MARK=0xAB;
編譯器在編譯你的程序之前,在你的代碼里尋找,遇到 E2P_RECORD_ADDR 這個名字就把它替換成0x00, 遇到 POWER_UP_MARK 這個名字就把它替換成0xAB;
這就叫預編譯。
結構體struct是一種數據類型,同 int 或 char 一樣,它是一種數據類型,不同的是結構體是你自定義的,而int和char是系統自帶的,你可以把它想像成和 int 、char 一樣的東西,不過它是由你設計的。比如 定義一個結構體類型 ——「人」這個類型,每個人都有名字,同時人都有年齡,那麼你可以這樣定義:
typedef struct {
string name;
char age;
}HUMAN;
那麼HUMAN就是一個類型名,同int、char一樣,它是「人」這個類型,可以用這個類型名定義實體變數:
struct HUMAN zhangsan;
struct HUMAN lisi;
這里「struct HUMAN」就相當於「int」或「char「,這時zhangsan、lisi就是一個結構體變數了,它們都有name和age這兩個屬性了,可以對它們進行操作:
比如張三10歲,李四20歲,可以這樣:
zhangsan.age=10;
lisi.age=20;
⑥ C語言里的預編譯語句里怎麼獲取結構體大小
如果s是結構體變數,則sizeof(s)就能測出s的大小;若s是結構體名,則用sizeof(struct s)同樣能測出s的大小。都以位元組數表示。
⑦ c語言什麼叫結構體
結構體定義
結構體(struct)是由一系列具有相同類型或不同類型的數據構成的數據集合,也叫結構。
結構體作用
結構體和其他類型基礎數據類型一樣,例如int類型,char類型 只不過結構體可以做成你想要的數據類型。以方便日後的使用。
在實際項目中,結構體是大量存在的。研發人員常使用結構體來封裝一些屬性來組成新的類型。
結構體在函數中的作用不是簡便,其最主要的作用就是封裝。封裝的好處就是可以再次利用。讓使用者不必關心這個是什麼,只要根據定義使用就可以了。
結構體的大小與內存對齊
結構體的大小不是結構體元素單純相加就行的,因為我們現在主流的計算機使用的都是32Bit字長的CPU,對這類型的CPU取4個位元組的數要比取一個位元組要高效,也更方便。所以在結構體中每個成員的首地址都是4的整數倍的話,取數據元素是就會相對更高效,這就是內存對齊的由來。每個特定平台上的編譯器都有自己的默認「對齊系數」(也叫對齊模數)。
程序員可以通過預編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一系數,其中的n就是你要指定的「對齊系數」。
規則:
1、數據成員對齊規則:結構(struct)(或聯合(union))的數據成員,第一個數據成員放在offset為0的地方,以後每個數據成員的對齊按照#pragma pack指定的數值和這個數據成員自身長度中,比較小的那個進行。
2、結構(或聯合)的整體對齊規則:在數據成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大數據成員長度中,比較小的那個進行。
3、結合1、2顆推斷:當#pragma pack的n值等於或超過所有數據成員長度的時候,這個n值的大小將不產生任何效果。
C++中的結構體
在C語言中,可以定義結構體類型,將多個相關的變數包裝成為一個整體使用。在結構體中的變數,可以是相同、部分相同,或完全不同的數據類型。在C語言中,結構體不能包含函數。在面向對象的程序設計中,對象具有狀態(屬性)和行為,狀態保存在成員變數中,行為通過成員方法(函數)來實現。C語言中的結構體只能描述一個對象的狀態,不能描述一個對象的行為。在C++中,考慮到C語言到C++語言過渡的連續性,對結構體進行了擴展,C++的結構體可以包含函數,這樣,C++的結構體也具有類的功能,與class不同的是,結構體包含的函數默認為public,而不是private。
C++控制台輸出例子:
#include <cstdlib>
#include <iostream>
//定義結構體
struct point
{ //包含兩個變數成員
int x;
int y; };
using namespace std;
int main(int argc, char *argv[])
{
struct point pt;
pt.x=1;
pt.y=2;
cout<<pt.x<<endl<<pt.y<<endl;
return EXIT_SUCCESS;
}
C++中的結構體與類的區別
類與結構體在C++中只有兩點區別,除此這外無任何區別。 (1)class中默認的成員訪問許可權是private的,而struct中則是public的。 (2)從class繼承默認是private繼承,而從struct繼承默認是public繼承。
⑧ 以下對結構體類型變數的定義中,不正確的是
答案是C。
A.使用了typedef,AA是struct
aa的另一個名字,所以可以用AA來定義變數
B.使用了預編譯指令#define把AA定義成struct
aa,編譯器在編譯時會把AA直接替換成struct
aa
C.在定義結構體的時候可以不指定結構體的名字直接定義變數,aa是個結構體變數,不能用來定義變數
D.參考C的解釋
⑨ c語言中如何定義一個結構體
結構體的定義如下所示,struct為結構體關鍵字,tag為結構體的標志,member-list為結構體成員列表,其必須列出其所有成員;variable-list為此結構體聲明的變數。在一般情況下,tag、member-list、variable-list這3部分至少要出現2個。
結構體的成員可以包含其他結構體,也可以包含指向自己結構體類型的指針,而通常這種指針的應用是為了實現一些更高級的數據結構如鏈表和樹等。如果兩個結構體互相包含,則需要對其中一個結構體進行不完整聲明。
(9)預編譯結構體大小擴展閱讀:
一、結構體作用:
結構體和其他類型基礎數據類型一樣,例如int類型,char類型,只不過結構體可以做成你想要的數據類型,以方便日後的使用。
在實際項目中,結構體是大量存在的,研發人員常使用結構體來封裝一些屬性來組成新的類型。由於C語言內部程序比較簡單,研發人員通常使用結構體創造新的「屬性」,其目的是簡化運算。
結構體在函數中的作用不是簡便,其最主要的作用就是封裝。封裝的好處就是可以再次利用。讓使用者不必關心這個是什麼,只要根據定義使用就可以了。
二、結構體的大小與內存對齊:
結構體的大小不是結構體元素單純相加就行的,因為我們主流的計算機使用的都是32bit字長的CPU,對這類型的CPU取4個位元組的數要比取一個位元組要高效,也更方便。
所以在結構體中每個成員的首地址都是4的整數倍的話,取數據元素時就會相對更高效,這就是內存對齊的由來。每個特定平台上的編譯器都有自己的默認「對齊系數」(也叫對齊模數)。
程序員可以通過預編譯命令#pragma pack(n),n=1,2,4,8,16來改變這一系數,其中的n就是你要指定的「對齊系數」。
三、結構體的規則:
1、數據成員對齊規則:結構(struct)(或聯合(union))的數據成員,第一個數據成員放在offset為0的地方,以後每個數據成員的對齊按照#pragma pack指定的數值和這個數據成員自身長度中,比較小的那個進行。
2、結構(或聯合)的整體對齊規則:在數據成員完成各自對齊之後,結構(或聯合)本身也要進行對齊,對齊將按照#pragma pack指定的數值和結構(或聯合)最大數據成員長度中,比較小的那個進行。
3、結合1、2可推斷:當#pragma pack的n值等於或超過所有數據成員長度的時候,這個n值的大小將不產生任何效果。
⑩ C#編程語言的特點與優勢
C#比其它語言的優勢
C#(讀做 "C sharp")是微軟公司在去年六月發布的一種新的編程語言,並定於在微軟職業開發者論壇(PDC)上登台亮相.C#是微軟公司研究員Anders Hejlsberg的最新成果.C#看起來與Java有著驚人的相似;它包括了諸如單一繼承,界面,與Java幾乎同樣的語法,和編譯成中間代碼再運行的過程.但是C#與Java有著明顯的不同,它借鑒了Delphi的一個特點,與COM(組件對象模型)是直接集成的,而且它是微軟公司.NET windows網路框架的主角.
在本文中,我將考察創建一種新計算機語言的一般動機,並將特別指明是什麼原因導致了C#的出現.然後我將介紹C#和它與Java,c,c++的相似之處.其次我將討論一些存在於Java和C#之間的高層次的,和基礎的差別.我將以衡量在用多種語言開發大型應用程序的時候所需的知識(或者對這種知識的缺乏程度)來結束本文,而這正是.NET和C#的一個主要戰略.目前,C#和.NET還只能以C#語言規則,以及Windows 2000的一個"d預覽版本",還有MSDN上迅速增多的文檔集子的形式獲得(還沒有最終定型).
微軟c#語言定義主要是從C和C++繼承而來的,而且語言中的許多元素也反映了這一點.C#在設計者從C++繼承的可選選項方面比Java要廣泛一些(比如說structs),它還增加了自己新的特點(比方說源代碼版本定義).但它還太不成熟,不可能擠垮Java.C#還需要進化成一種開發者能夠接受和採用的語言.而微軟當前為它的這種新語言大造聲勢也是值得注意的.目前大家的反應是:"這是對Java的反擊."
C#更象Java一些,雖然微軟在這個問題上保持沉默.這也是意料中的事情,我覺得,因為Java近來很成功而使用Java的公司都報告說它們在生產效率上比C++獲得了提高.
Java所帶來的巨大影響和大家對它的廣泛接受已經由工作於這種語言和平台之上的程序員數量明顯的說明了(估計世界范圍內共有兩百五十萬程序員使用Java).由這種語言寫成的應用程序的數量是令人驚訝的並已經滲透了每一個級別的計算,包括無線計算和行動電話(比如日本發明的Java電話).C#能夠在用戶領域獲得這樣的禮遇嗎?我們必須等待並觀望,就象已經由SSI公司的CEO和主席Kalpathi S. Suresh指出來的那樣,"我發現所有這些都是漸進的.如果C#不存在,我們總能回到Java或C和C++.這些都不完全是新技術;它們在更大的意義上來說只是大公司製造的市場噱頭.我們必須給他們時間安頓下來看看這些是不是真的對IT工業有什麼影響."
C#從Java繼承而來的特點
類:在C#中類的申明與Java很相似.這是合理的因為經驗告訴我們Java模型工作得很好.Java的關鍵字import已經被替換成using,它起到了同樣的作用.一個類開始執行的起點是靜態方法Main().下面的Hello World程序展示了基本的形式:
using System;
class Hello {
static void Main() {
Console.WriteLine("Hello, world");
}
}
在這個例子中,System這個名字指向一個包括了基本C#實用類集合的命名空間(namespace).這個命名空間包括了Console類,它在這個例子中被用來輸出一個字元串.類可以是抽象的和不可繼承的:一個被申明成abstract的類不能被實例化;它只能被用做一個基類.C#關鍵字lock就象Java關鍵字final,它申明一個類不是抽象的,但是它也不能被用做另一個類的基類.界面:就象在Java中一樣,一個界面是一組方法集合的抽象定義.當一個類或結構體實現一個界面的時候,它必須實現這個界面中定義的所有方法.一個單一的類可以實現幾個界面.也許以後會出現一些微妙的差別,但是這個特點看起來與Java相比沒有變化.布爾運算:條件表達式的結果是布爾數據類型,布爾數據類型是這種語言中獨立的一種數據類型.從布爾類型到其他類型沒有直接的轉換過程.布爾常量true和false是C#中的關鍵字.錯誤處理:如Java中那樣,通過拋出和捕捉異常對象來管理錯誤處理過程.內存管理:由底層.NET框架進行自動內存垃圾回收.
C#從C和C++繼承的特點
編譯:程序直接編譯成標準的二進制可執行形式.如果前面的Hello World程序被保存成一個文本文件並被命名為Hello.cs,它將被編譯成命名Hello.exe的可執行程序.
結構體:一個C#的結構體與C++的結構體是相似的,因為它能夠包含數據申明和方法.但是,不象C++,C#結構體與類是不同的而且不支持繼承.但是,與Java相同的是,一個結構體可以實現界面.
預編譯:C#中存在預編譯指令支持條件編譯,警告,錯誤報告和編譯行控制.可用的預編譯指令有:
#define
#undef
#if
#elif
#else
#endif
#warning
#error
#line []
沒有了#include 偽指令.你無法再用#define 語句對符號賦值,所以就不存在源代碼替換的概念--這些符號只能用在#if和#elif偽指令里.在#line偽指令里的數字(和可選的名字)能夠修改行號還有#warning和#error輸出結果的文件名.
操作符重載:一些操作符能夠被重載,而另一些則不能.特別的是,沒有一個賦值運算符能夠被重載.能夠被被重載的單目操作符是:
+ - ! ~ ++ -- true false
能夠被重載的二元運算符是:
+ - * / % & | ^ << >> == != > < >= <=
C#獨有的特點
C#最引人入勝的地方是它和Java的不同,而不是相似的地方.這一節(和這個系列第二部分的大部分地方)講述了C#實現的和Java不同的地方或者Java根本沒有的特點.
中間代碼:微軟在用戶選擇何時MSIL應該編譯成機器碼的時候是留了很大的餘地.微軟公司很小心的聲稱MSIL不是解釋性的,而是被編譯成了機器碼.它也明白許多--如果不是大多數的話--程序員認為Java程序要不可避免的比C編寫的任何東西都要慢.而這種實現方式決定了基於MSIL的程序(指的是用C#,Visual Basic,"Managed C++"--C++的一個符合CLS的版本--等語言編寫的程序)將在性能上超過"解釋性的"Java代碼.當然,這一點還需要得到事實證明,因為C#和其他生成MSIL的編譯器還沒有發布.但是Java JIT編譯器的普遍存在使得Java和C#在性能上相對相同.象"C#是編譯語言而Java是解釋性的,"之類的聲明只是商業技巧.Java的中間代碼和MSIL都是中間的匯編形式的語言,它們在運行時或其它的時候被編譯成機器代碼.
命名空間中的申明:當你創建一個程序的時候,你在一個命名空間里創建了一個或多個類.同在這個命名空間里(在類的外面)你還有可能聲明界面,枚舉類型和結構體.必須使用using關鍵字來引用其他命名空間的內容.
基本的數據類型:C#擁有比C,C++或者Java更廣泛的數據類型.這些類型是bool, byte, ubyte, short, ushort, int, uint, long, ulong, float, double,和decimal.象Java一樣,所有這些類型都有一個固定的大小.又象C和C++一樣,每個數據類型都有有符號和無符號兩種類型.與Java相同的是,一個字元變數包含的是一個16位的Unicode字元.C#新的數據類型是decimal數據類型,對於貨幣數據,它能存放28位10進制數字.
兩個基本類:一個名叫object的類是所有其他類的基類.而一個名叫string的類也象object一樣是這個語言的一部分.作為語言的一部分存在意味著編譯器有可能使用它--無論何時你在程序中寫入一句帶引號的字元串,編譯器會創建一個string對象來保存它.
參數傳遞:方法可以被聲明接受可變數目的參數.預設的參數傳遞方法是對基本數據類型進行值傳遞.ref關鍵字可以用來強迫一個變數通過引用傳遞,這使得一個變數可以接受一個返回值.out關鍵字也能聲明引用傳遞過程,與ref不同的地方是,它指明這個參數並不需要初始值.
與COM的集成:C#對Windows程序最大的賣點可能就是它與COM的無縫集成了,COM就是微軟的Win32組件技術.實際上,最終有可能在任何.NET語言里編寫COM客戶和伺服器端.C#編寫的類可以子類化一個以存在的COM組件;生成的類也能被作為一個COM組件使用,然後又能使用,比方說,JScript語言子類化它從而得到第三個COM組件.這種現象的結果是導致了一個運行環境的產生,在這個環境里的組件是網路服務,可用用任何.NET語言子類化.
索引下標:一個索引與屬性除了不使用屬性名來引用類成員而是用一個方括弧中的數字來匿名引用(就象用數組下標一樣)以外是相似的.
public class ListBox: Control {
private string[] items;
public string this[int index] {
get {
return items[index];
}
set {
items[index] = value;
Repaint();
}
}
}
可以用一個循環器來匿名引用字元串內部數組成員,就象下面這樣:
ListBox listBox = ...;
listBox[0] = "hello";
Console.WriteLine(listBox[0]);
代理和反饋:一個代理對象包括了訪問一個特定對象的特定方法所需的信息.只要把它當成一個聰明的方法指針就行了.代理對象可以被移動到另一個地方,然後可以通過訪問它來對已存在的方法進行類型安全的調用.一個反饋方法是代理的特例.event關鍵字用在將在事件發生的時候被當成代理調用的方法聲明中.