c char轉int_c/c++基礎之sizeof用法

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

1 sizeof 定義

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

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 不是一個函數,因為函數調用必須有一對括號。

#include <stdio.h>int main(void)
{int num = 97;printf("sizeof(num = 0)的值:%dn",sizeof(num = 0));   printf("num 的值:%dn",num);   return 0;
}

f188b73d0451e4d447948b4672ec9c6b.png

說明:sizeof 不是標準意義上的一元操作符,不支持鏈式表達式,sizeof 作用域范圍內的語句不會編譯成機器碼,如 sizeof(num++) 中的 ++ 不執行。sizeof 也不是函數, 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 基本數據類型的 sizeof

這里的基本數據類型是指short、int、long、float、double這樣的簡單內置數據類型。

由于它們的內存大小是和系統相關的,所以在不同的系統下取值可能不同。

#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 位系統下內置數據類型與其 sizeof 運算結果如下:

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 不影響內置類型 sizeof 的取值

2 指針類型的 sizeof

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

char *p =”hello”; 
sizeof( p );       // 結果為4 
sizeof(*p);        // 結果為1 
int *pi; 
sizeof( pi );      //結果為4 
sizeof(*pi);       //結果為4 
char **pp = &p; 
sizeof( pp );      // 結果為4 
sizeof( *pp );     // 結果為4 
  • 指針變量的 sizeof 值與指針所指的對象類型沒有任何關系,與指針申請多少空間沒有關系,所有的指針變量所占內存大小均相等。
  • 如果使用 32 位編譯器編譯得到程序是 32 位,那么在 64bits 系統下,指針變量大小仍然是 4 個字節。

3 函數類型的 sizeof

函數類型以其返回類型作為自身類型,進行 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 函數和函數指針進行 sizeof 取值。

4 數組類型的 sizeof

sizeof 作用于數組時,求取的是數組所有元素所占用的大小。

    int A[3][5];char c[]="abcdef";double*(*d)[3][6];cout<<sizeof(A)<<endl;      //輸出60cout<<sizeof(A[4])<<endl;   //輸出20cout<<sizeof(A[0][0])<<endl;//輸出4cout<<sizeof(c)<<endl;      //輸出7cout<<sizeof(d)<<endl;      //輸出4cout<<sizeof(*d)<<endl;     //輸出72cout<<sizeof(**d)<<endl;    //輸出24cout<<sizeof(***d)<<endl;   //輸出4cout<<sizeof(****d)<<endl;  //輸出8

A 的數據類型是 int[3][5]A[4] 的數據類型是 int[5],A[0][0]數據類型是 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

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

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

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

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

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

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

當數組作為函數形參時,下面輸出結果應該是多少呢?

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

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

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

4 結構體類型的 sizeof

對于 struct 數據結構由 CPU 的對齊問題導致 struct 的大小變得比較復雜。具體可以查看以前的文章一文輕松理解內存對齊

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

#include<stdio.h>struct{int x;char y;
}Test;int main()
{printf("%dn",sizeof(Test)); // 輸出8不是5return 0;
}

結構體的大小跟結構體成員對齊有密切關系,而并非簡單地等于各個成員的大小之和!比如對如下結構體兩個結構體 A、B 使用 sizeof 的結果分別是: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;
};

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

  • 結構體的大小等于結構體內最大成員大小的整數倍
  • 結構體內的成員的首地址相對于結構體首地址的偏移量是其類型大小的整數倍,比如說 double 型成員相對于結構體的首地址的地址偏移量應該是 8 的倍數。
  • 為了滿足規則 1 和 2 編譯器會在結構體成員之后進行字節填充!

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

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

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; //輸出結果為12cout << “sizeof(B) is ” << sizeof(B) << endl; //輸出結果為1return 0 ; 
}
  • 空的 class 同樣也占用 1 個字節。
  • 計算類對象的大小時,類成員函數不占用對象空間,只需要考慮類中數據成員的大小。
  1. 類中存在靜態成員變量
class A 
{ public: static int a; int b; float c; char d; 
};int main() 
{ A object; cout << “sizeof(object) is ” << sizeof(object) << endl; //輸出結果為12return 0 ; 
}

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

  1. 類中包含成員函數
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; //輸出結果為12return 0 ; 
}

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

3 sizeofstrlen 區別

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

參考資料

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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537704.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537704.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537704.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

汽車怎么保養省錢?

摘要&#xff1a;從4年4萬多公里的大保養&#xff0c;分享如何保養省錢。 如何保養省錢? 1.不花冤枉錢 2.不過度保養 3.平時用車注意 1.不花冤枉錢 除了第一次去4s店免費保養&#xff0c;第二次起就不要了。我第二、三次在朋友店里&#xff0c;第四次開始在途虎養車店。 …

非結構化數據與結構化數據提取---- BeautifulSoup4 解析器

CSS 選擇器&#xff1a;BeautifulSoup4 和 lxml 一樣&#xff0c;Beautiful Soup 也是一個HTML/XML的解析器&#xff0c;主要的功能也是如何解析和提取 HTML/XML 數據。 lxml 只會局部遍歷&#xff0c;而Beautiful Soup 是基于HTML DOM的&#xff0c;會載入整個文檔&#xff0c…

計算機的網絡技術的普及,計算機網絡技術的普及與應用-網絡技術論文-計算機論文(7頁)-原創力文檔...

計算機網絡技術的普及與應用摘要&#xff1a;隨著通信和計算機技術緊密結合與同步發展&#xff0c;我國計算機網絡技術得到飛躍的發展。如今在社會生活的各個領域都可以尋覓到計算機網絡技術的蹤跡&#xff0c;它成為社會發展中必不可少的一門技術。為進一步促進計算機網絡技術…

pyaudio usb playback_5.5寸觸控屏IP電話會議USB全向麥克風NK-OAM600U_影視工業網

寸觸控屏視頻會議USB全向麥克風(拾音器)NK-OAM600U概述&#xff1a;派尼珂NK-OAM600U視頻會議USB全向麥克風&#xff0c;是一款配置多點手勢觸控FHD屏的高清會議電話&#xff0c;便捷的連接方式&#xff1a;支持USB/以太網/WIFI/藍牙Bluetooth連接&#xff0c;同時支持外接視頻…

寫sql語句的經驗之談

1. 不論一個sql中涉及到多少表&#xff0c;每次都用兩個表&#xff08;結果集&#xff09;操作&#xff0c;得到新的結果后&#xff0c;再和下一個表&#xff08;結果集&#xff09;操作。 2. 避免在select f1,(select f2 from tableB ).... from tableA 這樣得到字段列。直接…

微軟發布Azure Storage不可變存儲功能的正式版本

隨著新的不可變存儲功能的發布&#xff0c;blob特性在特定的保留期間內將是不可以擦除和修改的。該特性從今年6月份開始進行預覽使用&#xff0c;現在&#xff0c;微軟宣布它在所有公開Azure region中正式發布。\\微軟添加對不可變存儲的支持&#xff0c;以便于幫助客戶遵循像S…

html 表單控制器,c# – html表單發布到mvc控制器

將Html發布到MVC控制器>使用表單創建HTML頁面(不要忘記引用Jquery.js)User Name Password $(document).ready(function () {//get button by ID$(#btn1).submit(function () {//call a function with parameters$.ajax({url: rec/recieveData, //(rec) Controllers-name//(r…

紅米note5手機插u盤沒反應_認真分析下:榮耀智慧屏x1和紅米x50對比哪個好?用后一個月告訴大家實情...

這二款電視榮耀智慧屏x1和紅米x50區別還是有的哈&#xff0c;外觀和款式是不一樣的&#xff0c;不過家用都是可以的&#xff0c;看個人吧&#xff0c;我自己用的是榮耀智慧屏x1&#xff0c;款式是我喜歡的&#xff0c;多時尚的&#xff0c;整體質感不錯的&#xff0c;看上去很大…

用Excel函數提高效率

今天在計劃20某年項目采購各階段時間點&#xff0c;從合同計劃簽訂日期開始倒退。 規則如下&#xff1a; 項目采購申請----&#xff08;1-2個工作日&#xff09;---->項目立項----&#xff08;1-2個工作日&#xff09;--->采購小組成立-----&#xff08;2-3個工作日&am…

python測試工具開發面試寶典3web抓取

2019獨角獸企業重金招聘Python工程師標準>>> 用requests輸出網站返回頭 輸出 https://china-testing.github.io/ 的返回頭 參考答案In [1]: import requestsIn [2]: url https://china-testing.github.io/In [3]: response requests.get(url)In [4]: response.req…

計算機網絡本直通線的制作方法,電腦網絡:教你一分鐘自制高質量網線(含水晶頭分類),不求人...

在文章開頭&#xff0c;我們首先來介紹一下制作水晶頭需要用到的工具——網線鉗。這不是多么高科技的東西&#xff0c;價格也不貴&#xff0c;普通用戶都能接受&#xff0c;從網上或是線下都能買到。網線水晶頭的制作及檢測方法&#xff0c;從來沒人寫過這么全我們主要用到網線…

Communications link failure,The last packet successfully received from the serve

最近做測試&#xff0c;發現Mysql 過一段時間會無法連接&#xff0c;導致數據庫數據不一至&#xff0c;極其郁悶。 使用Connector/J連接MySQL數據庫&#xff0c;程序運行較長時間后就會報以下錯誤&#xff1a; Communications link failure&#xff0c;The last packet succ…

sap crm button_正值SAP中國成立25周年之際,江蘇金來奇智能科技SAPB1項目正式啟動...

正值SAP中國成立25周年之際&#xff0c;江蘇金來奇智能科技的SAP項目于2020年11月02日正式啟動&#xff0c;代表著SAPB1在智能裝備行業又一成功的案例。江蘇金來奇隸屬于無錫金鑫集團股份有限公司&#xff0c;無錫金鑫集團股份有限公司坐落于風景秀麗的太湖之濱&#xff0c;位于…

安裝hadoop集群---resourcemanager和NameNode不在同一臺機器上

1、復制虛擬機&#xff0c;搞了5臺。 1&#xff1a;namenode 2&#xff1a;secondardNameNode&#xff0c;resourcemanager 3&#xff0c;4&#xff0c;5&#xff1a;DataNode 2、修改了網卡配置&#xff0c;連接上SecureCRT ---------root----用戶---------- 3、date查看了…

cf375D. Tree and Queries(莫隊)

題意 題目鏈接 給出一棵 n 個結點的樹&#xff0c;每個結點有一個顏色 c i 。 詢問 q 次&#xff0c;每次詢問以 v 結點為根的子樹中&#xff0c;出現次數 ≥k 的顏色有多少種。樹的根節點是1。 Sol 想到了主席樹和啟發式合并。。很顯然都不能做。 標算是dfs序上暴力莫隊。。甘…

it項目管理 pdf_IT項目管理的控制經驗

據調查&#xff0c;只有37%的IT項目在計劃時間內完成&#xff0c;42%的在預算內完成。IT項目成功率不高的根源在于IT項目管理是項系統工程&#xff0c;不僅需要項目經理個人具備一定的組織、決策、技術、業務、溝通能力&#xff0c;更需要運用多種手段對項目的時間、質量、成本…

安裝hadoop集群---resourcemanager和NameNode同一臺機器上

1、復制虛擬機&#xff0c;搞了5臺。 1&#xff1a;namenode&#xff0c;resourcemanager 2&#xff1a;secondardNameNode 3&#xff0c;4&#xff0c;5&#xff1a;DataNode 2、修改了網卡配置&#xff0c;連接上SecureCRT ---------root----用戶---------- 3、date查看了…

ps把圖摳到html里,ps摳圖教程:手把手教你如何用ps摳頭發絲

PS摳圖是現在常見的摳圖方法之一&#xff0c;色塊分明的圖是很好摳的&#xff0c;但是如果是需要摳出來的物體是細微凌亂的呢&#xff1f;就像頭發絲。PS如何摳頭發絲才能毫無P圖痕跡&#xff1f;如何摳頭發絲一類的圖像呢&#xff0c;本文介紹的是使用通道結合其余一些命令完成…

臻識科技用全智能相機,把智慧城市的交通/安防/工業制造做到極致

儼然&#xff0c;智慧城市已經是一個技術密集、資本密集、巨頭密集、關注度密集的大熱門領域。 從技術層面來看&#xff0c;智慧城市對當下熱門技術進行了綜合&#xff1a;Cloud、Big Data、AI、AR/VR、5G、IoT、Quantum Computing、Edge Computing、 Block Chain等&#xff0…

熱式氣體質量流量計檢定規程_寧夏熱式氣體質量流量計價位,玻璃管液位計怎么樣...

金湖中原儀表有限公司為您詳細解讀eJxKfc寧夏熱式氣體質量流量計價位的相關知識與詳情&#xff0c;氣體流量計是計量氣體流量的儀表。安拆正在管路中記載流過的氣體量。能夠丈量煤氣&#xff0c;空氣&#xff0c;氮氣&#xff0c;乙炔&#xff0c;&#xff0c;氫氣&#xff0c;…