文章程式碼顯示

2018年2月4日 星期日

《筆記》C語言 - 06_5:陣列名稱與地址、bit & byte、陣列元素與地址

此章做為講解「指標」章節的前哨站,做一些熱身

陣列名稱與地址

#include "stdio.h"

int main(void) {

 char array[] = { 'a', 'b', 'C', 'D', 'e', '\0' };

 printf( "array = %p\n", array );
 printf( "&array = %p\n", &array );
 printf( "&array[0] = %p\n", &array[0] );

 return 0;
}




上方程式碼中 %p 轉換指定詞是用來列印記憶體位址的特殊轉換指定詞

& 為取址運算子,也就是取出記憶體位址的運算子

我們以 %p 分別列印出 「陣列名稱 array」 、「 &array 取址運算子加陣列名稱」以及 「&array[0] 取址運算子加陣列第一個元素」的記憶體位址

結果發現三者的結果相同

這代表著對 C 語言而言

「陣列名稱的記憶體位址 = 陣列第一個元素記憶體位址

bit & byte

如果我們以二進制來表示一個數值,則一個 bit 位元的値可以是 1 或是 0 ,但無論這個値為 1 或是 0,它在電腦裡面都佔了一個坑(也就是 1 bit) 。

倘若我們將 8 個坑(也就是 8 個 bits) 當成一個整體,則稱為一個位元組( 1 byte ) 又稱為字節

一個 bit 只能代表 1 或是 0 兩種值,
那麼一個 byte (整體來看這 8 個 bit ) 就能代表 256 種值了( 2^8),分別是 0 ~ 255(2^8-1)




那如果數值大於 255 呢?

將 byte 再組合起來就行了,例如 short 型別為 16 bits (也就是兩個 bytes ) ; int 型別為 32 bits ( 也就是四個 bytes )

我們回顧一下,當我們宣告一個變數為 char 、 short 以及 int 型別時有什麼不同?

此文中的 Sizeof 與資料型別 我們發現

char 型別的變數在我的電腦中佔用了 8 bits (1 byte)、 short 佔用了 16 個 bits ( 2 bytes) 、 int 佔用了 32 個 bits ( 4 bytes )

不知道讀者有沒有發現,這些資料型態( char, short, int ... ) 的 bits 數都是 8 的倍數

其原因在於電腦發展之初,原本是以 bit 來進行表達的。但隨著記憶體越來越大,發現用幾 bit 幾 bit 來表達實在太麻煩,所以大家就講好將 8 bits 組成的東西稱為 1 byte ,並以此做為電腦用來表示資料與儲存資料的基本單位。

而資料型態等同於容器大小,例如 char 最大可以儲存 1 byte 的資料 ,那麼 short 最大就可以儲存 2 bytes 的資料。

順到一提,如果我們宣告一個 char 型別的變數,並且存放數值 " 1 "
再宣告另一個 char 型別的變數,並且存放數值 "255"
這兩個變數所佔的記憶體空間是相同的(都是 1byte)

因為「當宣告一個 char 型別的變數你就需要在記憶體裡面挪出 1 byte 的空間,不管裡面到底有沒有裝滿水」

陣列元素與地址

#include "stdio.h"

int main(void) {

 char array[] = { 'a', 'b', 'c', 'd', 'e', '\0' };

 printf( "&array[0] = %p\n", &array[0] );
 printf( "&array[1] = %p\n", &array[1] );
 printf( "&array[2] = %p\n", &array[2] );
 printf( "\n");

 short array1[] = { 'a', 'b', 'c', 'd', 'e', '\0' };

 printf( "&array1[0] = %p\n", &array1[0] );
 printf( "&array1[1] = %p\n", &array1[1] );
 printf( "&array1[2] = %p\n", &array1[2] );
 printf( "\n");

 int array2[] = { 'a', 'b', 'c', 'd', 'e', '\0' };

 printf( "&array2[0] = %p\n", &array2[0] );
 printf( "&array2[1] = %p\n", &array2[1] );
 printf( "&array2[2] = %p\n", &array2[2] );


 return 0;
}



在這我想強調的是

宣告陣列為不同的型別(tpye)時 , 各元素對其記憶體位址的存放關係

上述的程式碼中我宣告了三個具有相同內容的陣列 array 、 array 1 與 array 2 ,分別宣告為 char 、 short 與 int 型別

在一開始我們講述陣列時就有提到

陣列是一群具有相同名稱以及相同型別(type)的變數集合,在記憶體中擁有連續存放空間的集合

「記憶體擁有連續存放空間」的含意在本節中就可以體現出來

事實上就是說陣列的變數都是連續存放在記憶體裡面的




舉例來說在程式碼中我先宣告 array 為 char 型別,而 char 型別正好佔用的是 1 byte 的長度,所以當我們在宣告一個具有 char 型別的陣列時,裡面的元素對應到的記憶體位址就正好會差 1 ( 0028FF3A -> 0028FF3B -> 0028FF3C .... )

因為每格裡面都存放了 1 個 byte 長度的資料

short 型別本身是屬於兩個 bytes 的數據,所以儲存在電腦之中就會用掉兩格的位置( 2 bytes)

由記憶體位址來看我們就會發現相鄰的兩個陣列元素之間的地址差為 2 ( 0028FF2E -> 0028FF30 -> 0028FF32 ... )


↓↓↓ 連結到部落格方針與索引 ↓↓↓

Blog 使用方針與索引