c語言複習總結

大小端問題

在我們發送數據的時候,我們首先要確定的是大端還是小端模式來進行的,在接收方接收的數據必須知道數據是大端還是小端模式,這個才能正確地讀取和存儲數據,否則就會出現問題。
一個三十二位的二進制程序中存儲有兩種方式,
1:高字節對高地址(大端模式)
2:高字節對應低地址(小端模式)
區分大小端的方法
1:利用地址強制類型轉換

void test()
{
    int i = 1;
    char j = *((char*)&i);
    if(j == 1)
    {
        printf("小端\n");
    }
}

2:利用聯合體性質:不同類型變量共享同一塊內存

void test2()
{
    union un
    {
        int i;
        char c;
    }u;
    u.i = 1;
    if(u.c ==1)
    {
        printf("小端");
    }
}

因爲他們是公用同一塊內存的,所以定義i = 1;
那麼,我們就可以查看c是多少,因爲c是char型的,所以只能看八個比特位,所以當查到u.c == 1時,我們就可以知道它是小端存儲。

const與volatile介紹

我們知道const修飾變量後,變量是隻讀的;
但是到底是爲什麼呢?
編譯器在編譯期間,可能對代碼進行了優化,
當編譯器看到這裏的num被const修飾,從語義上講這裏的num是不希望被改變的。那優化的時候就可以吧num的值存放到寄存器(以提高訪問效率)。以後只要使用num的地方都去寄存器中取,那即使num對應的內存中的值發生變化,寄存器也是感知不到的。

volatile關鍵字對num修飾
這個時候num可以被改變
劃重點了
編譯時不優化,執行時不緩存,每次需從內存中讀出(保證內存的可見性)

static小結

static修飾局部變量
改變該變量的“記憶性”,“全局性”
所謂“記憶性”:指的是在兩次函數調用時,在第二次調用進入時,能保持第一次調用退出時的值。
全局性:延長變量的生命週期
注意事項:每次調用時,都指向同一塊內存,具有不可重入性。

static修飾靜態變量/函數
用來表示不能被其他文件訪問的全局變量和函數。修飾函數使其成爲靜態函數,但此處“static”的含義不是指存儲方式,而是指對函數作用域僅侷限本文件(即內部函數),此時的static只起作用域限制作用。
防止不同人編寫不同函數時,跟其他文件中的函數重名。

結構體的內存對齊

首先得掌握結構體對齊規則:
1:第一個成員在結構體變量偏移量爲0的地址處。
2:其他成員變量要對齊到某個數字(對齊數)的整數倍的地址處。
對齊數=編譯器默認的一個對齊數與該成員大小的較小值。
vs中默認的值爲8
Linux中的默認值爲4
3:結構體總大小爲最大對齊數的整數倍。
4:如果嵌套了結構體的情況,嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整體大小就是所有最大對齊數的整數倍。

下面在Linux環境下展示
這裏寫圖片描述
這裏寫圖片描述
所以我們看到兩個大小是不一樣的

那麼爲什麼存在內存對其

1:平臺原因:
不是所有的硬件平臺都能訪問任意地址上的任意數據;某些平臺只能在某些地址處取某些特定類型的數據,否則拋出硬件異常。
2:性能原因:
數據結構(尤其是棧)應該儘可能的在自然邊界上對齊,
原因在於,爲了訪問未對齊的內存,處理器需要做兩次內存訪問;而對其的內存訪問僅需要一次訪問。
內存對齊是拿空間換時間的方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章