以前大學的時候?qū)W過半個學期的C語言,除了幾個簡單的循環(huán)還記得外,其他的早就是跟飯一起吃下去了。最近看一些Objective-c稍微一些底層東西的,發(fā)現(xiàn)其中出現(xiàn)太多了struct,我們知道的oc 所有的類都是結(jié)構(gòu)體钾麸,這也就是為什么底層的時候會出現(xiàn)很多結(jié)構(gòu)體了更振,最近沒有事的時候又常常翻翻以前買的一本書《Objective-C高級編程 iOS與OS X多線程和內(nèi)存管理 》可能大家都看過的。自己再看的時候才發(fā)現(xiàn)自己是多么的淺嘗輒止饭尝,也可能因為因為自己在菜了肯腕,理解不了所以才看那的膚淺,再看Block這一章的時候钥平,發(fā)現(xiàn)通過編譯后分析生成的都是結(jié)構(gòu)體实撒,于是才想回過頭來再學學struct,讓自己看起來不再那么吃力。(注:看這篇文章還是要有一點C基礎(chǔ)的)
我們先來看看在C 語言中如何一個聲明一個結(jié)構(gòu)體類型"
struct struct_name {
xxx x1,
xxx x2,
... ...
}
這樣子我們就是聲明一個結(jié)構(gòu)體涉瘾,結(jié)構(gòu)體是什么的知态,結(jié)構(gòu)體就是C語言中的一種復雜數(shù)據(jù)類型,就是就 int float 一樣立叛。我們先來定一個最簡單結(jié)構(gòu)體point 點吧负敏,一個pont 應該是由 x,y 坐標決定的
struct Point {
float x; // x 坐標
float y; // y 坐標
} ;
那怎么如何聲明一個我們定義的Point 類型結(jié)構(gòu)體量呢,也很簡單:
struct Point point; // 這樣子我們就聲明了一個結(jié)構(gòu)體變量這樣子
還有一種聲明方式也很常見就是直接跟定義的后面
struct Point {
float x;
float y;
} point;
那怎么初始化呢秘蛇,一種我們可以在聲明時候用{}進行初始化
struct Point point = {3.0,4.0}; // 這樣子初化一個點坐標為(3.0,4.0)
也可以這樣子
struct Point point;
point.x = 3;
point.y = 4;
還可以這樣子
struct Point point = {.x = 3.0,.y = 4.0};
這是有名字的結(jié)構(gòu)體當然你還可以定義匿名的結(jié)構(gòu)體顧名思義匿名結(jié)構(gòu)體就是沒有名字我先來聲明一個匿名結(jié)構(gòu)體看看
struct {
float x;
float y;
};
注意“ 如果我們這樣子定義一個結(jié)構(gòu)體原在,結(jié)構(gòu)沒有名字那我們就沒有辦法用來用來聲明變量了,
所以一般匿名的結(jié)構(gòu)體再定義的時候我們就會在后面聲明一個變量如
struct {
float x;
float y;
} point;// 當然初化上面的初始沒有差別但是要注意不同的類型的匿名結(jié)構(gòu)體變量他們的類型是不同的 如:
struct {
float x;
float y;
} point1;
struct {
float x;
float y;
} point2;
注意 :point1 和 point2 他們的類型是不同的
所以一般匿名結(jié)構(gòu)體彤叉,一般只用來生成一個變量。還有一個用途下面再說的村怪,我回過頭來再看看聲明每次都要用
struct Point point;
用我們面向?qū)ο笏枷雭砜?Point point 這樣子看起來也簡潔點秽浇,當然c語言中也提供些便利我們看看怎么做,沒有錯你能已經(jīng)想到了甚负,別名typedef 我還用我們上面的點的來舉例 Point 我這次來給Point 起個別名叫CGPoint我們來看看怎做
typedef struct Point {
float x;
float y;
} CGPoint; // 這樣子我就給 struct Point 起了一個別名叫CGPoint
那我們就可以使用 CGPoint point 來聲明一個點了
CGPoint point 與 struct Point point 是完全等價的柬焕。
我們再來看上面的struct 既然我們可以直接使用了 CGPoint 那我們再給它起個起個名字好像顯得有點多余了,那我們是不是可以省略這個名字呢梭域,你是不是已經(jīng)想到了落匿名的 struct 那我們?nèi)サ裘挚纯矗?/p>
typedef struct {
float x;
float y;
} CGPoint;
CGPoint point;是不是簡潔了許多斑举,到這里你是不是發(fā)現(xiàn)了什么了,CGPoint 是不是用到過病涨,那你有沒有看看它到底是個什么呢富玷,是時候在項目中看一下了,按住 Command 點擊一下看看
看明白了嗎既穆,先定義一個名CGPoint 結(jié)構(gòu)體赎懦,又給CGPoint 起了個別名CGPoint 到了這里你不是對結(jié)構(gòu)體有一點了解呢,當然這是簡單的結(jié)構(gòu)體幻工。還有更復雜一點的結(jié)構(gòu)體励两,結(jié)構(gòu)體中引用結(jié)構(gòu)體,結(jié)構(gòu)體中引用指針等我們來看看結(jié)構(gòu)體引用結(jié)構(gòu)體囊颅?
typedef struct Rect {
struct Point {
float x;
float y;
} origin;
struct size {
float width;
float height;
} size;
} CGRect;
但是結(jié)構(gòu)體中不能引用自身結(jié)構(gòu)體当悔,像這樣子是不行的
typedef struct Rect {
struct Rect frame;
} CGRect;
傅瞻,因為struct 定義的時候必需知道數(shù)據(jù)大小,Rect 需要知道frame數(shù)據(jù)大小盲憎,frame 大小又取決的Rect大小好像死鎖了嗅骄,但是我們可以在struct定義指向自身的指針,像這樣子又是可以的
typedef struct Rect {
struct Rect *frame;
} CGRect;
上面就是一些簡單的stuct說明焙畔,注意C 中的struct與C++中的struct 是不同的的掸读,C 中struct 不能函數(shù),但可以函數(shù)指針宏多,繼承什么的就更不用說了儿惫,這里沒有說指針,因為指針要說的多了伸但,注意struct訪問普通成員struct 用點語法肾请,訪問指針成員要用->。 另外struct 存在字節(jié)對齊的更胖,成員聲明順序也可能會影響struct 實際占用內(nèi)存的大小,這些知識又相對深一些了铛铁,這里就不多說有興趣可以google 一下學習。本文只是簡單說明怎么聲明一個struct,及初始化的方法是一些比較淺顯的知識却妨。