C語言基礎六(結構體以及一些巨集定義)

2021-08-14 03:32:25 字數 2864 閱讀 2932

結構體宣告時,成員大小必須確定,因此不能有未定義大小的資料型別作為成員,同樣也不能用函式作為結構體成員。

但是,每個系統指標型別的大小是確定的,所以可以以結構體指標或者函式指標作為結構體成員。

結構體位元組對齊

結構體變數本身從4位元組對齊的位置開始存放。

整個結構體所佔空間還要是成員中『佔位元組最大的基本資料型別』的整數倍,不夠的在末尾補齊。

short型別從位址是2的倍數處開始儲存,int型別從位址是4的倍數處開始儲存,double型別從位址是8的倍數處開始儲存,空出來的部分記憶體由編譯器填充。

struct da

;

struct data //24位元組 ,內部結構體對齊規則會影響外部結構體

;

struct da

;struct data //24位元組,外部結構體對齊規則不會影響內部結構體

;

柔性陣列

在結構體內的乙個陣列,必須是結構體最後的乙個元素,除了這個陣列,結構體還必須至少有乙個成員

特定形式:a[ ]或a[0]。並且這個陣列不佔空間,只是乙個符號(代表乙個常量位址)。

一般情況下,結構體內會有乙個成員專門表示柔性陣列的元素個數。

typedef

struct

s;

對齊指令
#pragma pack(n) //(1、2、4、8、.....)

#pragma pack()

這兩個配合使用,表示乙個區間,只有這個區間內的結構體按照n位元組對齊。

設定為1,就是不對齊

如果n設定的小,充分利用記憶體空間,犧牲了速度,降低了訪問效率。

如果n設定的大,提高效率、效能,犧牲了記憶體空間。

用這個指令指定的對齊方式和結構體自身預設對齊方式,倆者取最小的。

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

結構體成員的型別必須是 int 或者 unsigned int,單個成員大小不能超過乙個int大小(32位)

注意 : 欄位不可取位址,因為位址最小單位為位元組。

struct data

s, *p = &s;

//乙個字段 32位 就是乙個int

struct data1

s1;//位欄位:下乙個字段不夠在剩餘的bit存放時,必須另起乙個字。字段不能跨字。

struct data3 //佔2個int

s2;

專門用於獲得型別,()裡可以放變數名,或者表示式

int

*p;typeof(p) a; //相當於 int

*atypeof(*p) b; //相當於 int a

#include 

#include

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

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

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

#define handle_error(msg) dowhile(0)

//用do{}while(0),是為了巨集定義多條語句,並可以匹配到使用巨集定義時後面的分號

int main(void)

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

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

//得到成員相對於結構體首位址的偏移位元組大小

//將0位址開始的這段空間強制轉化為結構體型別,這時(type *)0是指向這個結構體首位址的指標,

//指向member成員時,再取位址,&(((type *)0)->member))表示的是member成員的位址值。

//member成員的位址值減去結構體首位址值,就是成員位址的偏移量,結構體首位址為0.

//此時得到的差值再強制型別轉換為乙個int型資料,64位為long int型

//因為沒有賦值和指向運算,所以不對記憶體操作,也就不會出現非法記憶體訪問, 或者說 段錯誤。

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

//通過成員的指標得到該成員所在結構體的首位址

//1、typeof()得到結構體成員變數的型別 2、指標賦值,得到真實成員變數的位址值

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

#include 

struct in_addr

;/* structure describing an internet socket address. */

struct sockaddr_in

;

網路結構體賦值

//htons()和inet_addr()函式都是庫函式,用來將本地位址和埠號轉換為網路位址和埠號,

//網路上資料一般是大端儲存

void set_net_struct(struct sockaddr_in *p)

e;

typedef

enum state

s;int main(void)

if (current_state == state4)

if (current_state == state1)

printf("初始狀態.\n");

}return

0;}

c語言中的巨集 指標以及結構體的簡述

目錄 一.define定義常量和巨集 二.指標 三.結構體 很重要 定義 巨集在c語言中相當於 文字替換 include include 巨集在 c 語言裡面相當於 文字替換 define max 100 define add x,y x y 在這裡不能加分號 int main 在介紹指標之前,先來...

C語言巨集定義的一些用法

do while 0 在巨集定義中合理使用do while 0 可以更規範地使用巨集定義 沒有使用do while 0 前 define led on int main void 多了個分號 使用do while 0 define led on dowhile 0 int main void whi...

C語言一些基礎語法

1,程式中以 開頭的語句成為預處理命令 2,實型常量 小數形式,指數形式 字元常量 a 字串常量 a 雙引號 3,ddd 1 3位八進位制數所代表的ascii碼 xhh 1 2位十六進製制數所代表的ascii碼 0 空字元 4,sizeof 求位元組數運算子 sizeof double 表示求雙精度...