C語言學習筆記 14

2022-01-31 13:51:40 字數 1592 閱讀 9240

1. 位域

我們來看乙個表示日期的結構體:

typedef struct

mydate;

但是我們可以發現,其實year最大也不會超過四位數,month也就是12,而day最大也就是31。但是我們在上述的結構體中,卻為其分配了4*3=12位元組的記憶體,是不是很浪費呢?

c語言為了解決這個問題,提出了乙個概念,叫位域。看段**:

typedef struct

mydate;

這個的意思是,我為結構體中的每乙個字段分配指定的位數,比如,我為year分配了7位。這樣就有效地節省了記憶體。

c99規定int、unsigned   int和bool可以作為位域型別,但編譯器幾乎都對此作了擴充套件,

允許其它型別型別的存在。

使用位域的主要目的是壓縮儲存,其大致規則為:

1)   如果相鄰位域字段的型別相同,且其位寬之和小於型別的sizeof大小,則後面的字

段將緊鄰前乙個字段儲存,直到不能容納為止;

2)   如果相鄰位域字段的型別相同,但其位寬之和大於型別的sizeof大小,則後面的字

段將從新的儲存單元開始,其偏移量為其型別大小的整數倍;

3)   如果相鄰的位域字段的型別不同,則各編譯器的具體實現有差異,vc6採取不壓縮方

式,dev-c++採取壓縮方式;

4)   如果位域字段之間穿插著非位域字段,則不進行壓縮;

5)   整個結構體的總大小為最寬基本型別成員大小的整數倍。

2. 再談聯合體

例如:

union int_date

;

在上面的程式中,我們就可以用兩種視角(整數視角和日期視角)來看待乙個資料。

我們知道,在x86的機器中,我們常常會用到4個16位暫存器,這四個16位暫存器又可以分成8個8位的暫存器。例如,當我們改變ax的時候,其實al和ah也同時發生了改變,那麼我們可以把這個關係用聯合體來表示。

typedef union 

word;

struct

byte;

}regs;

int main (void)

3. volatile限定符

volatile告訴編譯器,這段記憶體空間所儲存的值是易變的。volatile通常用於指向易變記憶體空間的指標。有個例子我覺得非常恰當。

我們假設*p指向的記憶體空間用於存放使用者通過鍵盤所輸入的字元,然後我們讀取到這個字元,再將其放入到乙個陣列中。

但是一些優秀的編譯器會發現,在這個過程中,p和*p都未被程式顯式地改變,這樣編譯器就會對其作出優化,使*p只被取一次,這樣就讀入了陣列中一些重複的資料,這明顯不是我們想要的。

但是當我們在*p前加上volatile限定符,其實就是在告訴編譯器,不要對該段程式進行優化,因為這段程式是易變的,每次的讀取都要從記憶體中去重新取得。

在c#中也有volatile關鍵字,目的也是一樣,volatile關鍵字代表某個變數可能會被多個併發的執行緒進行修改,所以通知編譯器不要對其進行優化,這樣就能保證每次取出來的值不是被快取的,而是最新的值。

C語言學習筆記

include include void swap int p1,int p2 void swapa int arr,int n void printfa int arr,int n int main int argc,char argv swap i,j printfa array,6 swapa...

C語言學習筆記

file 結構 包含在stdio.h裡 ifndef file defined struct iobuf typedef struct iobuf file define file defined endif fread 功 能 從乙個流中讀資料 函式原型 size t fread void buf...

C語言學習筆記

我們學習c語言最開始入門的時候,都是先從c語言學習 c語言教材書籍開始學習,這些是我摘要的一些內容。第一章 c 語言概述 語言概述 1.1 物件導向程式設計基本概念 1.2 c 語言是一種物件導向的程式設計 語言 1.3 c 程式結構的特點 程式結構的特點 1.4 visual c 6.0簡介 簡介...