日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 單片機 > C語言與CPP編程
[導(dǎo)讀]在 C/C++ 中,sizeof() 是一個判斷數(shù)據(jù)類型或者表達(dá)式長度的運算符。 1 sizeof 定義 sizeof 是 C/C++ 中的一個操作符(operator),返回一個對象或者類型所占的內(nèi)存字節(jié)數(shù)。 The sizeof keyword gives the amount of storage, in bytes, associated with a va


C/C++ 中,sizeof() 是一個判斷數(shù)據(jù)類型或者表達(dá)式長度的運算符。

1 sizeof 定義

sizeofC/C++ 中的一個操作符(operator),返回一個對象或者類型所占的內(nèi)存字節(jié)數(shù)。

The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type(including aggregate types). This keyword returns a value of type size_t.                                                                                              ——來自MSDN

其返回值類型為 size_t ,在頭文件 stddef.h 中定義為: typedef unsigned int size_t;

sizeof 的定義可以看出:sizeof 不是一個函數(shù),因為函數(shù)調(diào)用必須有一對括號。

#include <stdio.h>

int main(void)
{
   int num = 97;

   printf("sizeof(num = 0)的值:%d\n",sizeof(num = 0));   
   printf("num 的值:%d\n",num);   
   return 0;
}
運行結(jié)果為4,97;并不是4,0

說明:sizeof 不是標(biāo)準(zhǔn)意義上的一元操作符,不支持鏈?zhǔn)奖磉_(dá)式,sizeof 作用域范圍內(nèi)的語句不會編譯成機器碼,如 sizeof(num++) 中的 ++ 不執(zhí)行。sizeof 也不是函數(shù), sizeof 更像一個特殊的宏,在編譯階段求值。

2 sizeof 用法

sizeof 有兩種語法形式,如下:

sizeof(type_name);    //sizeof(類型);
sizeof (object);      //或sizeof object 都屬于 sizeof對象;

所以:

int i;
sizeof(i);    //合理
sizeof i;     //合理
sizeof(int);  //合理
sizeof int;   //不合理
  • 對類型使用 sizeof 時, sizeof type_name 是非法的,必須寫為 sizeof(type_name);
  • 無論是對對象還是類型取值, sizeof () 這種形式都是對的;

1 基本數(shù)據(jù)類型的 sizeof

這里的基本數(shù)據(jù)類型是指short、int、long、float、double這樣的簡單內(nèi)置數(shù)據(jù)類型。

由于它們的內(nèi)存大小是和系統(tǒng)相關(guān)的,所以在不同的系統(tǒng)下取值可能不同。

#include <iostream>
using namespace std;
 
int main()
{
   cout << "Size of char : " << sizeof(char) << endl;
   cout << "Size of int : " << sizeof(int) << endl;
   cout << "Size of short int : " << sizeof(short int) << endl;
   cout << "Size of long int : " << sizeof(long int) << endl;
   cout << "Size of float : " << sizeof(float) << endl;
   cout << "Size of double : " << sizeof(double) << endl;
   cout << "Size of wchar_t : " << sizeof(wchar_t) << endl;
   return 0;
}

在 32 位系統(tǒng)下內(nèi)置數(shù)據(jù)類型與其 sizeof 運算結(jié)果如下:

Size of char : 1
Size of int : 4
Size of short int : 2
Size of long int : 4
Size of float : 4
Size of double : 8
Size of wchar_t : 4
  • unsigned 不影響內(nèi)置類型 sizeof 的取值

2 指針類型的 sizeof

指針主要用于存儲地址,前幾天文章C語言指針詳解提到過,指針變量的位寬等于機器字長,機器字長由 CPU 寄存器位數(shù)決定。在 32 位系統(tǒng)中,一個指針變量的返回值為 4 字節(jié), 64 位系統(tǒng)中指針變量的 sizeof 結(jié)果為 8 字節(jié)。

char *p =”hello”; 
sizeof( p );       // 結(jié)果為4 
sizeof(*p);        // 結(jié)果為1 
int *pi; 
sizeof( pi );      //結(jié)果為4 
sizeof(*pi);       //結(jié)果為4 
char **pp = &p; 
sizeof( pp );      // 結(jié)果為4 
sizeof( *pp );     // 結(jié)果為4 
  • 指針變量的 sizeof 值與指針?biāo)傅膶ο箢愋蜎]有任何關(guān)系,與指針申請多少空間沒有關(guān)系,所有的指針變量所占內(nèi)存大小均相等。
  • 如果使用 32 位編譯器編譯得到程序是 32 位,那么在 64bits 系統(tǒng)下,指針變量大小仍然是 4 個字節(jié)。

3 函數(shù)類型的 sizeof

函數(shù)類型以其返回類型作為自身類型,進(jìn)行 sizeof 取值。

void fun1()
{
}
int fun2()
{
   return 0;
}
double fun3()
{
   return 0.0;
}
cout << sizeof(fun1()) << endl;  //錯誤!無法對void類型使用sizeof
cout << sizeof(fun2()) << endl;  //fun2()返回值類型為int,輸出4
cout << sizeof(fun3()) << endl;  //fun3()返回值類型為double,輸出8
  • 注意:不能對返回 void 函數(shù)和函數(shù)指針進(jìn)行 sizeof 取值。

4 數(shù)組類型的 sizeof

當(dāng) sizeof 作用于數(shù)組時,求取的是數(shù)組所有元素所占用的大小。

    int A[3][5];
    char c[]="abcdef";
    double*(*d)[3][6];

    cout<<sizeof(A)<<endl;      //輸出60
    cout<<sizeof(A[4])<<endl;   //輸出20
    cout<<sizeof(A[0][0])<<endl;//輸出4
    cout<<sizeof(c)<<endl;      //輸出7
    cout<<sizeof(d)<<endl;      //輸出4
    cout<<sizeof(*d)<<endl;     //輸出72
    cout<<sizeof(**d)<<endl;    //輸出24
    cout<<sizeof(***d)<<endl;   //輸出4
    cout<<sizeof(****d)<<endl;  //輸出8

A 的數(shù)據(jù)類型是 int[3][5] ,A[4] 的數(shù)據(jù)類型是 int[5],A[0][0]數(shù)據(jù)類型是 int 。所以:

sizeof(A)==sizeof(int[3][5])==3*5*sizeof(int)==60
sizeof(A[4])==sizeof(int[5])=5*sizeof(int)==20
sizeof(A[0][0])==sizeof(int)==4

如果字符數(shù)組表示字符串,數(shù)組末自動插入 '\0',所以 c 的數(shù)據(jù)類型是 char[7] ,所以 sizeof(c)=sizeof(char[7])==7。

d 是一個很奇怪的定義,他表示一個指向 double*[3][6] 類型數(shù)組的指針。既然是指針,所以 sizeof(d) 就是4。

既然 d 是執(zhí)行 double*[3][6] 類型的指針, *d 就表示一個 double*[3][6] 的多維數(shù)組類型,因此 sizeof(*a)=3*6*sizeof(double*)=72 。

**d 表示一個 double*[6] 類型的數(shù)組,所以 sizeof(**d)=6*sizeof (double*)=24。

***d 表示其中的一個元素,也就是 double* ,所以 sizeof(***d)=4

****d 是一個 double ,所以 sizeof(****d)=sizeof(double)=8

當(dāng)數(shù)組作為函數(shù)形參時,下面輸出結(jié)果應(yīng)該是多少呢?

int GetStrLength(char str[])
{
   return sizeof(str);
}

int main()
{
   char szStr[] = "abcdef";
   cout<< GetStrLength() << endl;
   return 0;
}

輸出不是 7 ,這里函數(shù)參數(shù) str[] 已不再是數(shù)組類型,而是蛻變成指針,我們調(diào)用函數(shù) GetStrLength() 時,程序會在棧上分配一個大小為 7 的數(shù)組嗎?不會!數(shù)組是“傳址”的,調(diào)用者只需將實參的地址傳遞過去,所以 str 自然為指針類型 (char*) ,輸出值為:4 。

  • 數(shù)組的大小是各維數(shù)的乘積*數(shù)組元素的大小。
  • 向函數(shù)形參傳遞數(shù)組,數(shù)組將會退化為指針,失去原來數(shù)組的特性。

4 結(jié)構(gòu)體類型的 sizeof

對于 struct 數(shù)據(jù)結(jié)構(gòu)由 CPU 的對齊問題導(dǎo)致 struct 的大小變得比較復(fù)雜。具體可以查看以前的文章一文輕松理解內(nèi)存對齊。

理論上,int 占 4byte , char 占一個 byte ,那么將它們放到一個結(jié)構(gòu)體中應(yīng)該占 4+1=5byte ;但是實際上,通過運行程序得到的結(jié)果是 8byte 。

#include<stdio.h>

struct{
    int x;
    char y;
}Test;

int main()
{
    printf("%d\n",sizeof(Test)); // 輸出8不是5
    return 0;
}

結(jié)構(gòu)體的大小跟結(jié)構(gòu)體成員對齊有密切關(guān)系,而并非簡單地等于各個成員的大小之和!比如對如下結(jié)構(gòu)體兩個結(jié)構(gòu)體 A、B 使用 sizeof 的結(jié)果分別是:16,24??梢钥闯?sizeof(B) 并不等于 sizeof(int)+sizeof(double)+sizeof(int)=16

struct A
{
  int num1;
  int num2;
  double num3;
};
struct B
{
  int num1;
  double num3;
  int num2;
};

結(jié)構(gòu)體A和B中包含的成員都一樣,只不過順序不同而已,為什么其大小不一樣呢?要解釋這個問題,就要了解結(jié)構(gòu)體成員對齊的規(guī)則。

  • 結(jié)構(gòu)體的大小等于結(jié)構(gòu)體內(nèi)最大成員大小的整數(shù)倍
  • 結(jié)構(gòu)體內(nèi)的成員的首地址相對于結(jié)構(gòu)體首地址的偏移量是其類型大小的整數(shù)倍,比如說 double 型成員相對于結(jié)構(gòu)體的首地址的地址偏移量應(yīng)該是 8 的倍數(shù)。
  • 為了滿足規(guī)則 1 和 2 編譯器會在結(jié)構(gòu)體成員之后進(jìn)行字節(jié)填充!

從三個規(guī)則我們來看看為什么 sizeof(B) 等于 24 :首先假設(shè)結(jié)構(gòu)體的首地址為0,第一個成員 num1 的首地址是 0 (滿足規(guī)則2),它的類型是 int ,因此它占用地址空間 0——3 。第二個成員 num3 是 double 類型,它占用 8 個字節(jié),由于之前的 num1 只占用了 4 個字節(jié),為了滿足規(guī)則 2 ,需要使用規(guī)則 3 在 num1 后面填充 4 個字節(jié)(4——7),使得 num3 的起始地址偏移量為 8 ,因此 num3 占用的地址空間是:8——15。第三個成員 num2 是 int 型,其大小為 4 ,由于 num1 和num3 一共占用了 16 個字節(jié),此時無須任何填充就能滿足規(guī)則 2。因此 num2 占用的地址空間是 16——19 。那么是不是結(jié)構(gòu)體的總大小就是 0——19 共 20 個字節(jié)呢?請注意,別忘了規(guī)則1!由于結(jié)構(gòu)體內(nèi)最大成員是 double 占用 8 個字節(jié),因此最后還需要在 num2 后面填充 4 個字節(jié),使得結(jié)構(gòu)體總體大小為 24 。

struct S{ }; 
sizeof(S); // 結(jié)果為1
  • 對于一個空 struct 結(jié)構(gòu)體取 sizeof 運算,運算結(jié)果為 1 并非 0 。因為編譯器為保證此空 struct 存在,專門分配一個字節(jié)。
  • 如果存在結(jié)構(gòu)體嵌套,無論內(nèi)層還是外層均需要采用內(nèi)存對齊。

5 類的 sizeof

  1. 不含繼承和 static 成員變量的類。

在這種情況下,只需要考慮對齊方式即可。

class A 

  public: 
  int b; 
  float c; 
  char d; 
};
class B

};

int main(void) 

  cout << “sizeof(A) is ” << sizeof(A) << endl; 
  //輸出結(jié)果為12
  cout << “sizeof(B) is ” << sizeof(B) << endl; 
  //輸出結(jié)果為1
  return 0 ; 
}
  • 空的 class 同樣也占用 1 個字節(jié)。
  • 計算類對象的大小時,類成員函數(shù)不占用對象空間,只需要考慮類中數(shù)據(jù)成員的大小。
  1. 類中存在靜態(tài)成員變量
class A 

  public: 
  static int a; 
  int b; 
  float c; 
  char d; 
};

int main() 

  A object; 
  cout << “sizeof(object) is ” << sizeof(object) << endl; 
  //輸出結(jié)果為12
  return 0 ; 
}

因為在程序編譯期間,就已經(jīng)為 static 變量在靜態(tài)存儲區(qū)域分配了內(nèi)存空間,并且這塊內(nèi)存在程序的整個運行期間都存在。而每次聲明了類 A 的一個對象的時候,為該對象在堆上,根據(jù)對象的大小分配內(nèi)存。

  1. 類中包含成員函數(shù)
class A 

  public: 
  static int a; 
  int b; 
  float c; 
  char d; 
  int add(int x,int y) 
  { 
    return x+y; 
  } 
};

int main() 

  A object; 
  cout << “sizeof(object) is ” << sizeof(object) << endl; 
  b = object.add(3,4); 
  cout << “sizeof(object) is ” << sizeof(object) << endl; 
  //輸出結(jié)果為12
  return 0 ; 
}

因為只有非靜態(tài)類成員變量在新生成一個object的時候才需要自己的副本。所以每個非靜態(tài)成員變量在生成新object需要內(nèi)存,而function是不需要的。

3 sizeofstrlen 區(qū)別

  • sizeof 是一個操作符, strlen 是庫函數(shù)。
  • sizeof 的參數(shù)可以是數(shù)據(jù)的類型,也可以是變量,而 strlen 只能以結(jié)尾
  • 編譯器在編譯時就計算出了 sizeof 的結(jié)果,而 strlen 函數(shù)必須在運行時才能計算出來。并且 sizeof 計算的是數(shù)據(jù)類型占內(nèi)存的大小,而 strlen 計算的是字符串實際的長度。
  • 數(shù)組做 sizeof 的參數(shù)不退化,傳遞給 strlen 就退化為指針了。如:
 int ss[20]="0123456789";
 sizeof(ss)=80, //ss表示在內(nèi)存中的大小,20*4。
 strlen(ss)    //錯誤,strlen的參數(shù)只能是char*,且必須是以“\0”結(jié)尾的。
 char *ss="0123456789";
 sizeof(ss)=4,  //ss是指向字符串常量的字符指針。
 sizeof(*ss)=1, // *ss是第一個字符。
 

參考資料

  1. https://www.cnblogs.com/Western-Trail/p/10326180.html
  2. C/C++實踐進(jìn)階之道》

點【在看】是最大的支持 

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計成為提升電機驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗。要解決這一問題,需從設(shè)計、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉