程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> c語言中的結構體和字節對齊

c語言中的結構體和字節對齊

編輯:關於C語言

結構體

結構體的概念

★ 計算機程序設計語言都有數據類型的概念

★ 數據類型一般有基本類型和用戶自定義類型

★ 在c語言中,基本類型有int型、double型、char型等等。

★ 而結構體類型則屬於用戶自定義類型,是由基本類型組合而成的復雜類型。

★ 定義好的結構體類型可以像基本類型一樣去定義此類型的變量。 定義結構體類型和定義結構體類型變量

★ 我們先看看定義結構體類型的一般形式:

struct 結構體標示符

{

結構體元素;

};

如下:

struct StructDemo

{

char c;

int i;

};

★ 定義結構體類型變量方式一:

定義類型的同時定義變量,如下:

struct StructDemo

{

char c; int i;

}

sd1,sd2;

這樣就定了兩個結構體變量sd1,sd2了,這兩個變量的類型是struct StructDemo類型。

★ 定義結構體類型變量方式二:

定義類型之後定義變量,如下:

struct StructDemo

{

char c; int i;

};

這個定義說明我們已經定義完成了一個新的類型,這個類型說明符就是struct StructDemo。

所以我們可以用此來定義變量了。如下:

struct StructDemo sd1,sd2;

★ 定義結構體類型變量方式三:

類型說明符重命名的方法。

學習C語言的朋友,對typedef估計不會陌生的,用它可以給類型說明符一個別名,此名字和原來的名字具有同樣意義。 如:

typedef int zhengxing;

那麼int i和zhengxing i是一樣的意思。 同樣的道理也可運用於我們自定義的數據類型。 t

ypedef struct StructDemo SD;

SD sd1,sd2;

結構體類型的初始化 ★ 定義的同時初始化,如:

struct StructDemo sd1 = {‘A’,10},sd2 = {‘B’,12}; SD sd1 = {‘A’,10},sd2 = {‘B’,12};

struct StructDemo { char c; int i; } sd1 = {‘A’,10},sd2 = {‘B’,12};

★ 定義之後再初始化,如:

sd1 = {‘A’,10};

sd2 = {‘B’,12};

sd1.c = ‘D’;

sd1.i = 20;

結構體運用舉例1 我們將上面所說的結構體的定義、定義結構體類型變量、初始化用一個實際的程序來呈現,我現在這台機器上裝的linux系統是OpenSuSe,所以我們打開OpenSuSe,打開終端,利用vim編輯程序StructDemo01.c如下:

編譯運行如下: 結構體的大小問題 計算機程序語言中的數據類型在使用時在計算機中都會占有一定的內存空間,結構體類型是用戶自定義類型,也屬於數據類型的一種,那麼它在計算機內存中占有的空間大小又是什麼情況呢?下面我們來看一下。 我們定義一個結構體類型如下:

Struct StuctDemo { char c; int i; };

我們先嘗試估計一下這個結構體類型所占有的內存空間的大小,我們知道一個char類型占有1個字節,而一個int類型占有4個字節,那麼我們是否可以認為這個結構體類型占有的內存空間為5個字節呢? 下面我們用程序來驗證這個問題,這也是我們學習計算機所有的常用手法,快捷方便准確。 在舉例子之前我們說一下一個關鍵字sizeof,sizeof可以告訴我們一個數據類型占有的內存空間到底有多大,具體形式:sizeof(類型說明符)得到字節數。 下面我們創建一個c語言源程序文件命名為Demo02.c,我們用vim打開編輯如下: 我們編譯運行: 結果大出我們所料,結果竟然是8,為什麼不是5呢? 現代計算機中內存空間都是按照byte劃分的,從理論上講似乎對任何類型的變量的訪問可以從任何地址開始,但實際情況是在訪問特定類型變量的時候經常在特 定的內存地址訪問,這就需要各種類型數據按照一定的規則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。 各個硬件平台對存儲空間的處理上有很大的不同。一些平台對某些特定類型的數據只能從某些特定地址開始存取。比如有些架構的CPU在訪問 一個沒有進行對齊的變量的時候會發生錯誤,那麼在這種架構下編程必須保證字節對齊.其他平台可能沒有這種情況,但是最常見的是如果不按照適合其平台要求對 數據存放進行對齊,會在存取效率上帶來損失。比如有些平台每次讀都是從偶地址開始,如果一個int型(假設為32位系統)如果存放在偶地址開始的地方,那 麼一個讀周期就可以讀出這32bit,而如果存放在奇地址開始的地方,就需要2個讀周期,並對兩次讀出的結果的高低字節進行拼湊才能得到該32bit數 據。 其實字節對齊的細節和具體編譯器實現相關,但一般而言,滿足三個准則:   1) 結構體變量的首地址能夠被其最寬基本類型成員的大小所整除;   2) 結構體每個成員相對於結構體首地址的偏移量都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充字節;例如上面第二個結構體變量的地址空間。   3) 結構體的總大小為結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充字節。 看了這段文字相信我們很容易理解為什麼是8而不是5了,正是因為字節對齊的需要。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved