當(dāng)前位置:首頁 > 芯聞號 > 充電吧
[導(dǎo)讀]1 結(jié)構(gòu)體結(jié)構(gòu)是由若干(可不同類型的)數(shù)據(jù)項(xiàng)組合而成的復(fù)合數(shù)據(jù)對象,這些數(shù)據(jù)項(xiàng)稱為結(jié)構(gòu)的成分或成員。(1)字段C語言的結(jié)構(gòu)還提供了一種定義字段的機(jī)制,使人在需要時(shí)能把幾個(gè)結(jié)構(gòu)成員壓縮到一個(gè)基本數(shù)據(jù)類型

1 結(jié)構(gòu)體

結(jié)構(gòu)是由若干(可不同類型的)數(shù)據(jù)項(xiàng)組合而成的復(fù)合數(shù)據(jù)對象,這些數(shù)據(jù)項(xiàng)稱為結(jié)構(gòu)的成分或成員。

(1)字段

C語言的結(jié)構(gòu)還提供了一種定義字段的機(jī)制,使人在需要時(shí)能把幾個(gè)結(jié)構(gòu)成員壓縮到一個(gè)基本數(shù)據(jù)類型成員成員里存放,這可以看作是一種數(shù)據(jù)壓縮表示方式。

struct pack{
	unsigned a:2;
	unsigned b:8;
	unsigned c:6;
}pk1,pk2;

結(jié)構(gòu)變量pk1或者pk2的三個(gè)成員將總共占用16位存儲(chǔ),其中a占用2位,b占用8位,c占用6位。

(2)結(jié)構(gòu)體內(nèi)部的成員對齊

在計(jì)算結(jié)構(gòu)體長度(尤其是用sizeof)時(shí),需要注意!根據(jù)不同的編譯器和處理器,結(jié)構(gòu)體內(nèi)部成員有不同的對齊方式,這會(huì)引起結(jié)構(gòu)體長度的不確定性。

#include 
struct a{char a1; char a2; char a3;}A;
struct b{short a2; char a1;}B;

void main(void)
{
	printf("%d,%d,%d,%d",sizeof(char),sizeof(short),sizeof(A),sizeof(B));
}

在Turbo C 2.0中結(jié)果都是
1,2,3,3
在VC6.0中是

1,2,3,4

字節(jié)對齊的細(xì)節(jié)和編譯器實(shí)現(xiàn)相關(guān),但一般而言,滿足三個(gè)準(zhǔn)則:

1)結(jié)構(gòu)體變量的首地址能夠被其最寬基本類型成員的大小所整除;
2)結(jié)構(gòu)體每個(gè)成員相對于結(jié)構(gòu)首地址的偏移量(offset)都是成員大小的整數(shù)倍,如有需要編譯器會(huì)在成員之間加上填充字節(jié)(internal adding);
3)結(jié)構(gòu)體的總大小為結(jié)構(gòu)體最寬基本類型成員大小的整數(shù)倍,如有需要編譯器會(huì)在最末一個(gè)成員之后加上填充字節(jié)(trailing padding)。

對于上面的準(zhǔn)則,有幾點(diǎn)需要說明:

1)結(jié)構(gòu)體某個(gè)成員相對于結(jié)構(gòu)體首地址的偏移量可以通過宏offsetof()來獲得,這個(gè)宏也在stddef.h中定義,如下:

#define offsetof(s,m) (size_t)&(((s *)0)->m)

2) 基本類型是指前面提到的像char、short、int、float、double這樣的內(nèi)置數(shù)據(jù)類型,這里所說的“數(shù)據(jù)寬度”就是指其sizeof的大小。由于結(jié)構(gòu)體的成員可以是復(fù)合類型,比如另外一個(gè)結(jié)構(gòu)體,所以在尋找最寬基本類型成員時(shí),應(yīng)當(dāng)包括復(fù)合類型成員的子成員,而不是把復(fù)合成員看成是一個(gè)整體。但在確定復(fù)合類型成員的偏移位置時(shí),則是將復(fù)合類型作為整體看待。

2 聯(lián)合體

在一個(gè)結(jié)構(gòu)(變量)里,結(jié)構(gòu)的各成員順序排列存儲(chǔ),每個(gè)成員都有自己獨(dú)立的存儲(chǔ)位置。聯(lián)合變量的所有成員共享從同一片存儲(chǔ)區(qū)。因此一個(gè)聯(lián)合變量在每個(gè)時(shí)刻里只能保存它的某一個(gè)成員的值。

(1)聯(lián)合變量的初始化

聯(lián)合變量也在可以定義時(shí)直接進(jìn)行初始化,但這個(gè)初始化只能對第一個(gè)成員做。例如下面的描述定義了一個(gè)聯(lián)合體變量,并進(jìn)行了初始化:

union data 
{
	char n;
	float f;
};
union data u1 = {3};//只有u1.n被初始化



3 枚舉枚舉是一種用于定義一組命名常量的機(jī)制,以這種方式定義的常量一般稱為枚舉常量。
一個(gè)枚舉說明不但引進(jìn)了一組常量名,同時(shí)也為每個(gè)常量確定了一個(gè)整數(shù)值。缺省情況下其第一個(gè)常量自動(dòng)給值0,隨后的常量值順序遞增。

(1)給枚舉常量指定特定值

與給變量指定初始值的形式類似。如果給某個(gè)枚舉量指定了值,跟隨其后的沒有指定值的枚舉常量也將跟著順序遞增取值,直到下一個(gè)有指定值的常量為止。

例如寫出下面枚舉說明:

enum color 
{
	RED = 1,
	GREEN,
	BLUE,
	WHITE = 11,
	GREY,
	BLACK = 15
};

這時(shí),RED、GREEN、BLUE的值將分別是1、2、3,WHITE、GREY的值將分別是11、12,而BLACK的值是15。

(2)用枚舉常量作為數(shù)組長度

typedef enum {
	WHITE,
	RED,
	BLUE,
	YELLOW,
	BLACK,
	COLOR_NUM
}COLOR;

... ...

float BallSize[COLOR_NUM];

上例中當(dāng)顏色數(shù)量發(fā)生變化時(shí),只需要在枚舉類型定義中假如或刪去顏色。無需修改COLOR_NUM的定義。與大量使用#define相比既簡潔又可靠。如:

typedef enum {
	WHITE,
	RED,
	BLUE,
	COLOR_NUM
}COLOR;

4 sizeof的定義和使用

sizeof 是c/c++中的一個(gè)操作符(注意!不是函數(shù)!就像return一樣)。其作用就是返回一個(gè)對象或者類型所占的內(nèi)存字節(jié)數(shù)。

sizeof有三種使用形式,如下:

1> sizeof(var);	???????????????? //sizeof(變量);
2> sizeof(type_name);????????????//sizeof(類型);
3> sizeof var;			 //sizeof 變量;

所以,

int i;
sizeof(i);????????//ok
sizeof i;????????//ok
sizeof(int);????//ok
sizeof int; ????//error
為求形式統(tǒng)一,不建議采用第3種寫法,忘掉它吧!


數(shù)組的sizeof
數(shù)組的sizeof值等于數(shù)組所占用的內(nèi)存字節(jié)說,如:

char* SS = "0123456789";
sizeof(SS);		//結(jié)果 4,SS是指向字符串常量的字符指針
sizeof(*SS);	????????//結(jié)果 1,*SS是第一個(gè)字符

char SS[] = "0123456789";
sizeof(SS);		//結(jié)果 11,計(jì)算到‘