c語言基礎(八)

2021-08-14 02:29:13 字數 3111 閱讀 5858

結構體內成員對齊規則:

1、我們的結構體變數本身就是在4位元組對齊的位置,編譯器幫我們做的事。

2、第乙個成員,就從結構體開始的位址處,存放。這個元素,具體佔多少位元組,由緊挨著下個元素決定。

3、整個成員變數自身都對齊 了,還沒有結束。

4、整個結構體還要是預設位元組對齊的最小整數倍。

結構體預設的位元組對齊:成員變數最大的那個型別所佔位元組

#include

typedef

struct data

d;int main(void)

結果為8byte

注意:

struct

data

s;

int main(void)

結果如下:sizeof(*p1

<< i)=4

0x00x12

#include

struct data

s;int main(void)

結果為16byte

#include

struct data1

;//24

typedef

struct data

s;int main(void)

結果為40

位欄位:專用於結構體,結構體成員的型別必須是:int || unsigned int

有時侯,結構體成員表示的資料很小,就用幾個位來表示。

0欄位,不可訪問,只是佔位整個字中剩下的位,全部寫0

無名字段,不可訪問,只是佔位

字(word)=32bit

下乙個字段不夠在剩餘的字存放時,必須另起乙個字。字段不能跨字。

超出字段表示的資料範圍,結果不可預期

若最後乙個字沒有填滿則也將填滿後返回

欄位不可取位址

#include 

struct data1

s1;int main(void)

結果為8byte,同時也是2word

特別的是:

struct

;

#pragma pack(n) (1、2、4、8、.....)

#pragma pack()

這兩個配合使用,表示乙個區間,只有這個區間內的結構體享受這個待遇。

設定 對齊。

如果將n設定為1,就是不對齊

1、充分利用記憶體空間,犧牲了速度,降低了訪問效率。

2、提高效率、效能,犧牲了記憶體空間。

總結:你指定的對齊方式和結構體自身預設對齊方式,倆者取最小的。

#include 

#include

#pragma pack(2)

struct data // 16

s;struct data1

s1;#pragma pack()

一旦發生了,系統錯誤就會產生乙個錯誤數字(errno),對應相應的錯誤字串。

c標準定義了兩個值 exit_success 和 exit_failure,可以作為exit()的引數,來分別指示是否為成功退出。

exit(引數)傳遞給的是父程序,或者shell終端

#define

handle_error(msg) dowhile(0)

linux核心裡的兩個巨集:在驅動應用中很廣泛。

off_set_of(type, member)計算結構體內元素的偏移量

containe_of(ptr, type, member),ptr是結構體裡成員的指標,通過呼叫這個巨集計算出結構體的首位址.包含兩句**(表示式),必須要加{}.

這兩個巨集:核心雙鏈表。

分析:

#define off_set_of(type, member) ((long)&(((type *)0)->member))

1、(type *)0指向結構體零位址

2、((type *)0)->member得到了結構體某個成元變數名

3、給這成員變數名,取位址(相對於零位址),此時&(((type *)0)->member)表示是指標型別

4、強制型別轉換成(long)

#define

container_of

(ptr, type, member)

()1、得到結構體成員變數的型別

2、指標賦值(得到真實成員變數的位址值)

4、最後強制型別轉換為結構體指標型別

舉個栗子:

#include 

#define off_set_of(type, member) ((long)&(((type *)0)->member))

#define container_of(ptr, type, member) ()

struct da

; // 16

struct data

s = ;

//1、不會因為有結構體成員,而影響你的基本型別,決定預設對齊

//2、裡面的結構體對齊方式,已經在外面決定了(遍歷整個完整結構體)

int main(void)

p->a == (struct data *)0->a;

/*//讓你明白強制轉換0位址

struct data *p;

unsigned long a = 0;

p = (struct data *)a;

p->a == (struct data *)0->a;

*/

typeof(),()裡面的引數可以是變數名或者表示式。

typeof(int) p

int *p, a;

typeof(p) p_a = &a;//將p_a的型別轉換為p的型別,即指標型別

C語言基礎八

define是一條預處理指令,可以用來編寫巨集定義語句。巨集定義語句可以用來給數字起名字。可以在編譯時使用 d選項給乙個名字指定對應的數字,例如 gcc dsize 6 02circle.巨集是可以帶引數的,巨集的引數通常表示乙個名稱 巨集的引數直接參與計算,函式的引數要先製作出乙個替身然後才參與計...

c 基礎 筆記(八)

1 函式模板 1.1 模板分類 函式模板 類模板 1.2 template typename t 告訴編譯器緊跟著下面的函式或類出現 t不要報錯 1.3 void myswap t a t b 1.4 呼叫時候 兩種方式 1.4.1 自動型別推導,比如推導出t型別才能使用模板,不要出現二義性問題 1...

C語言 八 陣列

一維陣列定義與使用 int array 10 定義乙個一維陣列,名字叫array,一共有10個元素,每個元素都是int型別的 array 0 20 array 1 30 array 9 80 陣列索引是從0開始的。陣列在記憶體的儲存方式 陣列在記憶體中就是一段連續的空間,每乙個元素的型別是一樣的。一...