sizeof運算符介紹以及常見的坑

一、基本概念

sizeof是C語言的關鍵字,它用來計算變量(或數據類型)在當前系統中佔用內存的字節數。

sizeof不是函數,產生這樣的疑問是因爲sizeof的書寫確實有點像函數,sizeof有兩種寫法:

用於數據類型

  sizeof(數據類型);

數據類型必須用括號括住。

  printf("字符型變量佔用的內存是=%d\n",sizeof(char));   // 輸出:字符型變量佔用的內存是=1
  printf("整型變量佔用的內存是=%d\n",sizeof(int));   // 輸出:整型變量佔用的內存是=4

用於變量

  sizeof(變量名);
  sizeof 變量名;

變量名可以不用括號括住,帶括號的用法更普遍,大多數程序員採用這種形式。

  int ii;
  printf("ii佔用的內存是=%d\n",sizeof(ii));   // 輸出:ii佔用的內存是=4
  printf("ii佔用的內存是=%d\n",sizeof ii);   // 輸出:ii佔用的內存是=4

二、注意事項

1、sizeof(結構體)

理論上講結構體的各個成員在內存中是連續存放的,和數組非常類似,但是,結構體佔用內存的總大小不一定等於全部成員變量佔用內存大小之和。在編譯器的具體實現中,爲了提高內存尋址的效率,各個成員之間可能會存在縫隙。用sizeof可以得到結構體佔用內容在總大小,sizeof(結構體名)或sizeof(結構體變量名)都可以。

示例(book90.c)

/*
 * 程序名:book90.c,此程序用於演示C語言的結構體佔用內存的情況
 * 作者:C語言技術網(www.freecplus.net) 日期:20190525
*/
#include <stdio.h>

// #pragma pack(1)  # 告訴編器內存按1字節對齊。

struct st_girl
{
  char name[50];     // 姓名
  int  age;          // 年齡
  int  height;       // 身高,單位:釐米cm
  char sc[30];       // 身材,火辣;普通;飛機場。
  char yz[30];       // 顏值,漂亮;一般;歪瓜裂棗。
};

int main()
{
  struct st_girl queen;
  printf("sizeof(struct st_girl) %d\n",sizeof(struct st_girl));
  printf("sizeof(queen) %d\n",sizeof(queen));
}

運行效果
在這裏插入圖片描述

從上面的示例可以看出,struct st_girl全部成員變量佔用的內存是50+4+4+30+30=118,但是結構體佔用的內存是120。

注意,C語言提供了結構體成員內存對齊的方法,可以使結構體成員變量之間的內存沒有空隙,啓用#pragma pack(1)代碼即可。

2、不要對void使用sizeof

  printf("sizeof(void)=%d\n",sizeof(void));  // 輸出sizeof(void)=1

以上代碼在有些編譯器中可能無法通過。

void是無值型或空類型,不知道存儲空間大小的類型,編譯器也不能確定它的大小。void不能聲明變量,以下代碼編譯無法通過:

  void vv;

但是以下代碼是正確的:

  void *pv;
  printf("sizeof(void*)=%d\n",sizeof(pv));   // 輸出sizeof(void)=8

pv是一個void指針,在64位操作系統中,指針變量佔用的內存的大小都是8,下同。

3、不要在子函數中對字符指針用sizeof

如果把一個字符串(如char strname[21])的地址傳給子函數,子函數用一個字符指針(如char *pstr)來存放傳入的字符串的地址,如果在子函數中用sizeof(pstr),得到的不是字符串佔用內存的字節數,而是字符指針變量佔用內存的字節數(8字節)。

所以,不能在子函數中對傳入的字符串進行初始化,除非字符串的長度也作爲參數傳入到了子函數中。

4、不要在子函數中對結構體指針用sizeof

如果把一個結構體(如struct st_girl stgirl)的地址傳給子函數,子函數用一個結構體指針(如struct st_girl *pgril)來存放傳入的結構體的地址,如果在子函數中用sizeof(pgirl),得到的不是結構體佔用內存的字節數,而是結構體指針變量佔用內存的字節數(8字節)。正確的用法是用sizeof(struct st_girl)。

三、版權聲明

C語言技術網原創文章,轉載請說明文章的來源、作者和原文的鏈接。

來源:C語言技術網(www.freecplus.net

作者:碼農有道

如果這篇文章對您有幫助,請點贊支持,或在您的博客中轉發我的文章,謝謝。

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