日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

sizeof小览

發布時間:2023/12/10 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sizeof小览 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
sizeof小覽

一、文章來由—一道面試題遷出的探究

我發現我已經形成一種習慣寫來由了,以后看博客的時候能夠讓我回顧起為什么出現這個問題,我用什么方法解決的,既然形成習慣就讓這個習慣保持下去吧。今天實驗室師姐在看書,一處不解。是關于sizeof的,大家討論此問題后,我一向信服做了才知道答案,于是有了這篇文章。

可是僅僅能叫小覽,由于不可能總結完sizeof的使用方法,歡迎補充和討論。

二、從這道題目說起

我直接將問題的關鍵部分提出來:

string strArr1[] = { "Trend", "Micro", "Soft" }; cout << "sizeof(strArr1) == " << sizeof(strArr1) << endl;

請問輸出多少。書上的答案這樣寫道:

而字符串strArr1是由3段構成的,所 以sizeof(strArr1)大小是12。


首先要明白sizeof不是函數,也不是一元運算符,它是個相似宏定義的特殊關鍵字,特別是sizeof(string)=4

這個不去試是不知道的。由于編譯器那么多。編譯器做什么事情不去試怎么可能知道

果然,在vs2013 release Win32模式(x64模式還要更大)下結果是

sizeof(string) == 24
sizeof(strArr1) == 72

debug模式

sizeof(string) == 28
sizeof(strArr1) == 84

也是3倍關系,由于這是一個string數組。里面有三個string對象

那么為什么string有不同的結果?

查閱了相關資料得出結論:我們知道char*肯定是4字節,string里面可能不止包括一個char*那么簡單,還包括有長度信息等其它信息。string的實如今各庫中可能有所不同,可是在同一庫中同樣一點是,不管你的string里放多長的字符串,它的sizeof()都是固定的。字符串所占的空間是從堆中動態分配的,與sizeof()無關。

sizeof(string)=4可能是最典型的實現之中的一個,只是也有sizeof()為12、32字節的庫實現。 可是VC6.0測試后sizeof(string)=16.還是跟編譯器有關

為了全然測試一些東西。我測試越寫越多,然后我來了威力加強版。見代碼:

#include<iostream>using namespace std;int main() {char p[] = { 'a', 'b', 'c', 'a', 'b', 'c' };char *p1 = "abcabc";char p2[] = "abcabc";char p3[][2] = { { 'a', 'b' }, { 'c', 'a' }, { 'b', 'c' } };printf("p == %s\n", p);cout << p << endl;cout << "sizeof(p) == " << sizeof(p) << endl;cout << "sizeof(p1) == " << sizeof(p1) << endl;cout << "sizeof(p2) == " << sizeof(p2) << endl;cout << "sizeof(p3) == " << sizeof(p3) << endl;cout<<"sizeof(string) == " << sizeof(string) << endl;string strArr1[] = { "Trend", "Micro", "Soft" };cout << "sizeof(strArr1) == " << sizeof(strArr1) << endl;int a = 0;cout <<"sizeof(a = 3) == " << sizeof(a = 3) << endl;cout << "a == " << a << endl;cout << "sizeof(999999) == " << sizeof(999999) << endl;cout << "sizeof(9999999999999999999) == " << sizeof(9999999999999999999) << endl;cout << "sizeof(9 / 5) == " << sizeof(9 / 5) << endl;cout << "sizeof((double)9 / 5) == " << sizeof((double)9 / 5) << endl;return 0; }

執行結果如圖所看到的:

我來一一解釋我的這些測試在做什么:
(1)首先p的這種初始化方式。在末尾不會加’\0’。所以 sizeof(p) == 6;并且一個有趣的問題是printf和cout直接輸出p是不同的,printf是要碰到’\0’結束,我也看了printf和cout的匯編代碼,可是沒有細究,之后又空具體研究一下
(2)p1和p2的sizeof不同。由于一個是指針,一個是字符數組。指針在Win32編譯環境下的sizeof都是4。由于是4字節的地址。32bits可尋址空間
(3)p3是還有一個有趣的問題,p3不能寫成p3[3][]來初始化,由于這樣初始化要保證二維數組每一行的個數同樣。也就是不能出現“參差不齊”的情況,那種情況要動態分配
(4)這是一個陷阱

int a = 0; cout<<sizeof(a=3)<<endl; cout<<a<<endl;

輸出為什么是4。0 而不是期望中的4。3???就在于sizeof在編譯階段處理的特性。由于sizeof不能被編譯成機器碼。所以sizeof作用范圍內,也就是()里面的內容不能被編譯,而是被替換成類型。=操作符返回左操作數的類型。所以a=3相當于int,而代碼也被替換為:

cout<<4<<endl; cout<<a<<endl;

所以,sizeof是不可能支持鏈式表達式的。這也是和一元操作符不一樣的地方。

不要把sizeof當成函數,也不要看作一元操作符,把他當成一個特殊的編譯預處理。

(5)這種原因是999999是一個編譯器int型能夠搞定的數。所以按int來處理,太大的數不能用int搞定,可是8個字節一定能夠搞定的

sizeof(999999) == 4
sizeof(9999999999999999999) == 8

(6)最后是看了(9 / 5)編譯器是作為int看待的。強制轉換后才是double

三、sizeof 能總結多少是多少

sizeof博大精深。即使看了非常多資料,一口氣總結完也是不可能了,總結經常使用的就好。

1、什么是sizeof

首先看一下sizeof在msdn上的定義:

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.

看到return這個字眼,是不是想到了函數?錯了,sizeof不是一個函數。你見過給一個函數傳參數,而不加括號的嗎?sizeof能夠,所以sizeof不是函數。網上有人說sizeof是一元操作符。可是我并不這么覺得,由于sizeof更像一個特殊的宏,它是在編譯階段求值的。

舉個樣例:

cout<<sizeof(int)<<endl; // 32位機上int長度為4 cout<<sizeof(1==2)<<endl; // == 操作符返回bool類型。相當于 cout<<sizeof(bool)<<endl; 在編譯階段已經被翻譯為: cout<<4<<endl; cout<<1<<endl;

2、語法

sizeof有三種語法形式。例如以下:

1) sizeof( object ); // sizeof( 對象 );
2) sizeof( type_name ); // sizeof( 類型 );
3) sizeof object; // sizeof 對象;
所以,

int i;
sizeof( i ); // ok
sizeof i; // ok
sizeof( int ); // ok
sizeof int; // error
既然寫法1能夠全然代替寫法3,為求形式統一以及降低我們大腦的負擔,第3種寫法。忘掉它吧!

實際上。sizeof計算對象的大小也是轉換成對對象類型的計算。也就是說,同種類型的不同對象其sizeof值都是一致的。這里,對象能夠進一步延伸至表達式,即sizeof能夠對一個表達式求值。編譯器依據表達式的終于結果類型來確定大小,一般不會對表達式進行計算。

如:

sizeof( 2 ); // 2的類型為int。所以等價于 sizeof( int );
sizeof( 2 + 3.14 ); // 3.14的類型為double,2也會被提升成double類型。所以等價于 sizeof( double );

3、函數的sizeof

函數類型

考慮以下的問題: int f1(){return 0;}; double f2(){return 0.0;} void f3(){}cout<<sizeof(f1())<<endl; // f1()返回值為int,因此被覺得是int cout<<sizeof(f2())<<endl; // f2()返回值為double,因此被覺得是double cout<<sizeof(f3())<<endl; // 錯誤。無法對void類型使用sizeof cout<<sizeof(f1)<<endl; // 錯誤!無法對函數指針使用sizeof cout<<sizeof*f2<<endl; // *f2,和f2()等價,由于能夠看作object,所以括號不是必要的。被覺得是double

結論:對函數使用sizeof,在編譯階段會被函數返回值的類型代替

4、數組的sizeof

char a[] = "abcdef"; int b[20] = {3, 4}; char c[2][3] = {"aa", "bb"};cout<<sizeof(a)<<endl; // 7 cout<<sizeof(b)<<endl; // 20*4=80 cout<<sizeof(c)<<endl; // 6

數組a的大小在定義時未指定。編譯時給它分配的空間是依照初始化的值確定的。也就是7。

c是多維數組,占用的空間大小是各維數的乘積,也就是6。

能夠看出。數組的大小就是他在編譯時被分配的空間。也就是各維數的乘積*數組元素的大小。

結論:數組的大小是各維數的乘積*數組元素的大小。

這里有一個陷阱:

int *d = new int[10];cout<<sizeof(d)<<endl; // 4

d是我們常說的動態數組。可是他實質上還是一個指針,所以sizeof(d)的值是4。


再考慮以下的問題:

double* (*a)[3][6]; cout<<sizeof(a)<<endl; // 4 cout<<sizeof(*a)<<endl; // 72 cout<<sizeof(**a)<<endl; // 24 cout<<sizeof(***a)<<endl; // 4 cout<<sizeof(****a)<<endl; // 8

a是一個非常奇怪的定義,他表示一個指向 double*[3][6]類型數組的指針。

既然是指針,所以sizeof(a)就是4。

既然a是指向double*[3][6]類型的指針,*a就表示一個double*[3][6]的多維數組類型,因此sizeof(*a)=3*6*sizeof(double*)=72。同樣的,**a表示一個double*[6]類型的數組,所以sizeof(**a)=6*sizeof(double*)=24。***a就表示當中的一個元素,也就是double*了,所以sizeof(***a)=4。至于****a,就是一個double了,所以sizeof(****a)=sizeof(double)=8。

差點兒相同也要結束了,假設更進一步了解,須要查閱很多其它的資料~~~

—END—


參考文獻

[1] http://blog.csdn.net/freefalcon/article/details/54839
[2] http://www.cnblogs.com/wanghetao/archive/2012/04/04/2431760.html

posted on 2017-07-07 14:21 mthoutai 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/mthoutai/p/7131998.html

總結

以上是生活随笔為你收集整理的sizeof小览的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。