sizeof 和 strlen 計算陣列大小和長度詳解

丶獨醒發表於2020-02-02

sizeof

首先 sizeof 並非為一個函式,而是C語言中的一個關鍵字。
sizeof 計算物件所佔記憶體的大小,也就是空間大小,它不存在 ‘\0’,也不會去找’\0’,所以不受其影響, 判斷運算元的型別長度,以位元組為單位;
指標在32位系統佔4個位元組,在64位系統佔8個位元組,本例項都在32位機器上操作。
sizeof 求大小看的僅僅是它的型別大小,而非其他。所以我們在計算時只要認清楚它的型別大小就行。

arr 和 &arr 的區別.
int arr[10] = { 0 );
arr -> 本意為陣列arr 的第一個元素的地址,但是在 sizeof (arr) 中被特殊化為求整個陣列 arr 的大小(這是一個特例),所以 sizeof (arr) = 40;
&arr -> 意思為整個陣列的記憶體地址,所以 sizeof (&arr) = 4;(因為它是一個陣列指標)

arr + 1 和 &arr + 1 的區別
arr 為首元素的地址 *,arr + 1 -> 即加了一個int * (4)的大小.
&arr 為陣列的地址, 陣列的地址 + 1 -> 即跳過了整個陣列的大小,所以相當於加了 40;

<1>

	char arr[] = { 'a', 'b', 'c', 'd' };    
1.	printf("%d\n", sizeof(arr));       //4
2.	printf("%d\n", sizeof(arr + 0));   //4
3.	printf("%d\n", sizeof(*arr));      //1
4.	printf("%d\n", sizeof(arr + 1));   //4
5.	printf("%d\n", sizeof(arr[1]));     //1
6.	printf("%d\n", sizeof(&arr));       //4
7.	printf("%d\n", sizeof(*&arr));      //4
8.	printf("%d\n", sizeof(&arr + 1));   //4
9.	printf("%d\n", sizeof(&arr[0]));     //4
10.	printf("%d\n", sizeof(&arr[0] + 1));   //4
  1. 整個陣列的大小(特例)= 4
  2. 陣列首元素的地址,型別為 char* = 4
  3. 陣列首元素,型別為 char = 1
  4. 陣列第二個元素的地址, 型別為 char* = 4
  5. 同3
  6. 陣列的地址,型別為char (*) [4] = 4
  7. 先求陣列地址,在解應用,相當於求陣列大小,同1
  8. 取陣列地址再 + 1 ,相當於跳過整個陣列,型別為 char (*)[4] = 4
  9. 陣列首元素的地址, 型別為 char * = 4
  10. 陣列第二個元素的地址,型別為 char * = 4

<2>

 char arr[] = "abcd";
 printf("%d\n", sizeof(arr));  //5 
 printf("%d\n", sizeof(*&arr)); //5

別忘了這種初始化模式系統會預設給末尾補一個 ‘\0’,所以是5, 其他的和<1> 是一樣的。

strlen

strlen 是庫函式,使用時須引用其標頭檔案 <string.h>
它存在 ‘\0’,會去找’\0’,所以會受到 '\0’的影響
它的格式為 size_t strlen(const char * str); (必須傳 const char * 型別的指標)
<1>

    char arr[] = { 'a', 'b', 'c', 'd' }; 
    char arr[] = { 'a', 'b', 'c', 'd', '\0' }; //自己新增 '\0'
1.	printf("%d\n", strlen(arr));     // 隨機值 
2.	printf("%d\n", strlen(arr + 0));  //隨機值  
3.	printf("%d\n", strlen(*arr));     //型別不匹配
4.	printf("%d\n", strlen(arr[1]));   //型別不匹配
5.	printf("%d\n", strlen(&arr));     //型別不匹配
6.	printf("%d\n", strlen(&arr + 1));  //型別不匹配
7.	printf("%d\n", strlen(&arr[0] + 1));  //隨機值

出現隨機值的原因是這樣定義的陣列後面沒有 ‘\0’,,所以 strlen 不能精確判斷結束條件,有可能在超出陣列很多後才停止。要想避免上述情況,建議用下面的方式進行初始化,或者自己在字元末尾加上 ‘\0’, 加上後的效果和 <2> 是一樣的.

<2>

    char arr[] = "abcd";
1.  printf("%d\n", strlen(arr));       // 4
2.	printf("%d\n", strlen(arr + 0));   //4
3.	printf("%d\n", strlen(*arr));      //型別不匹配
4.	printf("%d\n", strlen(arr[1]));    //型別不匹配
5.	printf("%d\n", strlen(&arr));      //型別不匹配
6.	printf("%d\n", strlen(&arr + 1));  //型別不匹配
7.	printf("%d\n", strlen(&arr[0] + 1)); // 3

這種定義方式系統會自動在字串的末尾位置新增 ‘\0’,所以不會出現隨機值的問題。

相關文章