自定義型別 結構體 記憶體對齊 ,位段,列舉,聯合

2021-10-10 18:59:17 字數 3057 閱讀 7716

結構體的基礎知識

結構是一些值的集合,這些值稱為成員變數。結構的每個成員可以是不同型別的變數。

1.結構的宣告

struct tag //結構體型別名

;

注意:

1. 宣告結構體型別時,必須用關鍵字struct,這裡的tag可以省略,但最好不要省略。

2. 這裡只是宣告了結構體型別,實際並不占用記憶體,只有定義了結構體變數,才占用記憶體。

3. 結構體每個成員可以是相同或不同的型別的變數,但必須至少有乙個成員變數。

比如描述乙個學生:

struct stu

;//注意,分號不能丟

2.結構體的自引用

在結果體中包含乙個型別

struct student

;

不論是什麼型別的指標,在32位平台上所佔的均是4位元組,64位平台上均是8位元組,這樣,結構體變數的大小就可以確定了。

3.結構體變數的定義和初始化

(1)結構體宣告的同時定義變數

struct student

s=;

(2)宣告結構體後再定義變數

struct student

;struct student s=

;

(3)結構體成員的訪問

結構體成員的訪問有下述兩種方法:一是通過結構體變數進行訪問,二是通過結構體指標進行訪問。

struct student

ps;struct student s=

;ps=

&s;

(1)通過結構體變數進行訪問:

printf

("%s\n"

,s.name)

;

(2)通過結構體指標進行訪問:

printf

("%s\n"

,ps->name)

;

先看看下面倆個例子:

struct a

;struct b

;

結構體a的所佔記憶體為:12位元組。結構體b所佔記憶體為:8位元組。

兩個結構體的成員構成完全相同,除了順序不同,為什麼所佔的記憶體不同呢?這裡,就涉及到結構體的記憶體對齊問題:

結構體內存對齊規則:

(1)結構體第乙個成員變數始終在偏移量為0的位址處

(2)其他結構體成員變數的偏移量在對齊數的整數倍處。對齊數:編譯器預設的對齊數與自身型別所佔大小的最小值,vs預設為8,linux預設為4。

(3)結構體的最大小必須是最大對齊數的整數倍

(4)如果巢狀了結構體,巢狀的結構體的對齊數即為自己的最大對齊數。

解析:在結構體a中,第乙個成員變數偏移量為0,佔1個位元組,第二個成員變數,對齊數為4,佔4個位元組,所以從偏移量為4處開始放置4個位元組,第三個成員對齊數為1,佔乙個位元組,所以從偏移量為8處開始放置1個位元組,此時,共占用了9個位元組,但考慮到規則(3),最大對齊數為4,所以共占用12個位元組。結構體b可用相同的方法考慮得到。

注意:結構體內存對齊是拿空間來換取時間

5.修改預設對齊數

#pragma pack(n);

//n為對齊數

6.結構體傳參

結構體傳參與陣列相同,統一傳送結構體指標。

位段的宣告與結構體是類似的,只有兩點不同:

(1)位段的成員必須是整型或字元型

(2)位段的成員名後面有乙個冒號和乙個數字

例如:

struct a

;

位段a的所佔記憶體是多少呢?

首先,a是int型的,會開闢32個位元位,而變數a只占用2個位元位,然後,變數b緊接著a占用10個位元位,此時還剩餘20個位元位,而變數c需要25個位元位,而剩餘的20個位元位不夠容納,所以會在開闢乙個整型的大小,來存放變數c的25個位元位,所以,該位段共占用8個位元組。

列舉型別就是可以將其成員一一枚舉出來的,比如一周的7天,可以從周一到周天一一枚舉出來。

(1)列舉型別的定義

enum weekday

;

注意:

(1)列舉型別的宣告必須使用關鍵字enum

(2)除最後乙個列舉成員無符號外,其餘用逗號分隔

(3)列舉成員都是有值的,預設從0開始,也可以賦初值,之後的成員從初值開始往後依次加1。所以,列舉成員也被稱為列舉常量

(2)列舉變數的定義和賦值

列舉變數的定義與結構體類似,但賦值時只能用列舉常量進行賦值。

共用體的特點是各個成員共用一塊記憶體空間

(1)聯合型別宣告

union u

;

因為聯合體成員變數共用一塊記憶體,所以該聯合體型別所佔的記憶體為4位元組。

(2)共用體變數的定義及使用

union u

un;

此時,&(un.c)和&(un.i)的結果是相同的。
因此,可以用共用體型別判斷計算機的大小端問題

(3)共用體大小的計算

共用體也需要考慮記憶體對齊問題:

(1)共用體的大小至少是最大成員的大小

(2)當最大成員的大小不是最大對齊數的整數倍時,共用體的大小要是最大對齊數的整數倍。

結構體內存對齊與位段

二 位段 總結 編譯器在計算結構體大小時,發生記憶體對齊 如 struct s int main 問 程式的結果是多少?char 乙個位元組 int 4個位元組 1 4 5 答案是 8。a.第乙個成員偏移量為0。b.其他成員要在 偏移 對齊數的整數倍。對齊數 編譯器預設對齊數與成員變數大小中的較小值...

結構體內存對齊,位段,列舉 聯合

結構體內存對齊規則 1.第乙個成員在與結構體變數偏移量為0的位址處2.其他成員變數要對齊到對齊數的整數倍的位址處。對齊數 編譯器預設的乙個對齊數與該成員大小的 較小值vs中預設的值為8,linux中的預設值為43.結構體總大小為最大對齊數 每乙個成員變數都有乙個對齊數 的整數倍4.如果巢狀了結構體的...

自定義型別(結構體,列舉,聯合,位段)

一.結構體 c語言提供了兩種聚合資料型別,分別為陣列和指標,陣列是相同型別元素的集合,它的每個元素是通過下標引用或指標間接訪問的。結構是不同資料型別的集合,對於結構的訪問不能通過下標去訪問,因為乙個結構的成員可能長度不同。結構並不是它自身成員的陣列,結構變數屬於標量型別。舉例 乙個簡單的結構宣告 s...