導航:首頁 > 源碼編譯 > 編譯時輸出sizeof

編譯時輸出sizeof

發布時間:2023-05-13 06:20:34

Ⅰ sizeof返回的值到底是什麼

sizeof的用法是:sizeof(表達式)。

如果表達式是一個變數或常量,可以省略括弧。否則,有括弧、無括弧的結果是不同的。作用是返回為表達式分配的位元組數。

在本例中,s是字元數組,sizeof(s)返回6,說明為數組分配了6位元組,你的理解是對的。

而在sizeof(s+2)中,s+2的結果是一個unsigned long long int類型的整數,sizeof返回的是為存儲這種類型的整數需分配的位元組數,在你的系統上,它就是8。

也就是說,sizeof(表達式)返回的值與表達式的結果的類型有關,另外喚歲sizeof返回的值本身的類型是unsigned long int的。

比如:

假設在一個系統上,int為4位元組,long int為4位元組,long long int為8位元組,float為4位元組,double為8位元組。則,sizeof(1)返回4,sizeof(1L)返回8,sizeof(1LL)返回8。同時,sizeof(1+2)返回4,sizeof(1.0+2)返回8,而sizeof(1.0F+2)就會返回4。

下面是一個綜合例子:

#include <stdio.h>

int main()

{

int a=1;

struct ss

{

int i;

char s[8];

}s1;

typedef ss s;

printf("%lu ",sizeof a);

printf("%lu "枝鏈衫,sizeof 1);

printf("%lu ",sizeof(a+1));

printf("%lu ",sizeof a+1);

printf("%lu ",sizeof(1+2));

printf("%lu ",sizeof 1+2);

printf("%lu ",sizeof(1));

printf("%lu ",sizeof s1);

printf("%lu ",sizeof(s));

printf("%lu ",sizeof((short)1));

printf("%lu ",sizeof(1L));

printf("猛腔%lu ",sizeof 1LL);

printf("%lu ",sizeof 1.0);

printf("%lu ",sizeof(1.0F));

printf("%lu ",sizeof 1.0d);

printf("%lu ",sizeof(1.0+2));

printf("%lu ",sizeof(1.0F+2));

printf("%lu ",sizeof(1.0d+2));

return 0;

}

Ⅱ c++中的sizeof是什麼意思

sizeof()是C/C++中的一個操作符,其作用就是返廳沖回一個對象或者類型所佔的內皮毀存位元組數。

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.

其返回值類型為size_t,在頭文件stddef.h中定義。這是一個依賴於編譯系統的值,一般定義為

typedefunsignedintsize_t;

在C99及以上標准中,sizeof(char)、sizeof(int)、sizeof(long)、sizeof(long long)、sizeof(float)、sizeof(double)、sizeof(long double)的值分別是1,4,4,8,4,8,16。

拓展資料:sizeof與strlen區別

strlen(char*)函數求的是字元串的實際長度,直到遇到第一個'',然後就返回計數值,且不包括''。

char aa[10];cout<<strlen(aa)<<endl; //結果是不定的,因為未初始化,''在內存中的位置不確定

char aa[10]={''}; cout<<strlen(aa)<<endl; //結果為0

char aa[10]="jun"; cout<<strlen(aa)<<endl; //結果為3

而sizeof()函數返回的是變數聲明後所佔的內燃伏備存數,不是實際長度。

sizeof(aa) 返回10 int a[10]; sizeof(a) 返回40

1.sizeof操作符的結果類型是size_t,它在頭文件中typedef為unsignedint類型。

該類型保證能容納實現所建立的最大對象的位元組大小。

2.sizeof是算符,strlen是函數。

3.sizeof可以用類型做參數,strlen只能用char*做參數,且必須是以''''結尾的。

sizeof還可以用函數做參數。

sizeof_網路

Ⅲ C語言中sizeof和strlen函式區別在哪

C語言中sizeof和strlen函式區別在哪?

一、sizeof
sizeof(...)是運運算元,在標頭檔案中typedef為unsigned int,其值在編譯時即計算好了,引數可以是陣列、指標、型別、物件、函式等。
它的功能是:獲得保證能容納實現所建立的最大物件的位元組大小。
由於在編譯時計算,因此sizeof不能用來返回動態分配的記憶體空間的大小。實際上,用sizeof來返回型別以及靜態分配的物件、結構或陣列所佔的空間,返回值跟物件、結構、陣列所儲存的內容沒有關系。
具體而言,當引數分別如下時,sizeof返回的值表示的含義如下:
陣列——編譯時分配的陣列空間大小;
指標——儲存該指標所用的空間大小(儲存該指標的地址的長度,是長整型,應該為4);
型別——該型別所佔的空間大小;
物件——物件的實際佔用空間大小;
函式——函式的返回型別所佔的空間大小。函式的返回型別不能是void。
二、strlen
strlen(...)是函式,要在執行時才能計算。引數必須是字元型指標(char*)。當陣列名作為引數傳入時,實際上陣列就退化成指標了。
它的功能是:返回字串的長度。該字串可能是自己定義的,也可能是記憶體中隨機的,該函式實際完成的功能是從代表該字串的第一個地址開始遍歷,直到遇到結束符NULL。返回的長度大小不包括NULL;
1.sizeof操作符的結果型別是size_t,它在標頭檔案中typedef為unsigned int型別。
該型別保證能容納實現所建立的最大物件的位元組大小。
2.sizeof是算符,猛毀strlen是函式。
3.sizeof可以用型別做引數,strlen只能用char*做引數,且必須是以''''結尾的。
sizeof還可以用函式做引數,比如:
short f();
printf("%d ", sizeof(f()));
輸出的結果是sizeof(short),即2。
4.陣列做sizeof的引數不退化,傳遞給strlen就退化為指標了。
5.大部分編譯程式 在編譯的時候就把sizeof計算過了 是型別或是變數的長度這就是sizeof(x)可以用來定義陣列維數的原因
char str[20]="0123456789";
int a=strlen(str); a=10;
int b=sizeof(str); 而b=20;
6.strlen的結果要在執行的時枝謹備候才能計算出來,時用來計算字串的長度,不是型別占記憶體的大小。
7.sizeof後如果是型別必須加括弧,如果是變數名可以不加括弧。這是因為sizeof是個操作符不是個函式。
8.當適用了於一個結構型別時或變數, sizeof 返回實際的大小,
當適用一靜態地空間陣列, sizeof 歸還全部陣列的尺寸晌哪。
sizeof 操作符不能返回動態地被分派了的陣列或外部的陣列的尺寸
9.陣列作為引數傳給函式時傳的是指標而不是陣列,傳遞的是陣列的首地址,
如:
fun(char [8])
fun(char [])
都等價於 fun(char *)
在C++里引數傳遞陣列永遠都是傳遞指向陣列首元素的指標,編譯器不知道陣列的大小
如果想在函式內知道陣列的大小, 需要這樣做:
進入函式後用memcpy拷貝出來,長度由另一個形參傳進去
fun(unsiged char *p1, int len)
{
unsigned char* buf = new unsigned char[len+1]
memcpy(buf, p1, len);
}

C語言中關於sizeof 和 strlen的區別分析

sizeof獲得是所佔的位元組數,所分配的空間的位元組數。
strlen獲得是長度(實際字元的個數)。
例如: char a[5]="abc";
sizeof(a) 等於5,因為分配了5個位元組的空間。
而strlen(a)等於3,這是其實際字元的個數

c語言中lei與lei區別在哪?

你題目兩個都是lei
沒有區別的。
完全相同。

c語言中的sizeof和strenl的區別

sizeof 是佔用實際空間的大小。 這個對一個變數來說 是固定不變的。
strlen 僅可以用在字串上,是統計到結束符的長度。
一般情況下 strlen必然會比sizeof小。不過 這個也不是絕對的。

C語言中 memcmp 和 strcmp 函式有哪些區別

1、cmp 是 pare,比較的縮寫。
2、strcmp是C語言中標頭檔案<string.h>(字串函式)中定義的一個用於對兩組字串進行比較的函式,它的返回值是int型別。
假設有兩組字串cs和ct,當cs<ct時,函式返回一個負數;當cs==ct時,函式返回0;當cs>ct時,函式返回一個正數。
即:兩個字串自左向右逐個字元相比(按ASCII值大小相比較),直到出現不同的字元或遇''為止。如:"A"<"B" ,"a">"A" ,"puter">"pare" ,"put">"p"
strcmp函式原型為:int strcmp(const char *s1,const char * s2);

C語言中的sizeof和length怎麼區別?

sizeof可以計算一個型別乃至一個結構的大小空間
length只是針對字串而言的
而且標准c里沒有length這個函式
只有在C++中的string類中才有length這個函式

求C語言中strlen()函式的原始碼

unsigned int strlen(const char *s)
{
int len = 0;
while(*s++)
len++;
return len;
}

請問c語言中malloc函式和realloc的區別

1.malloc(n*sizeof(int)) /* 請求n個連續的、每個長度為整型的空間,若成功返回這些空間的首地址,失敗返回0 */
2.realloc(p,sizeof(int)*n) /* 給一個已經分配了地址的指標重新分配空間,引數p為原有的空間地址*/

c語言中,void在函式括弧內和在函式前面的區別.

void在函式括弧內:該函式的引數為空,或者說該函式不帶引數
void在函式前面:該函式返回值為空

Ⅳ C語言中sizeof的用法

sizeof是C/C++中的一個操作符(operator),作用就是返回一個對象或者類型所佔的內存位元組數。返回值類型為size_t,在頭文件stddef.h中定義

這是一個依賴於編譯系統的值,一般定義為typedef unsigned int size_t;編譯器林林總總,但作為一個規范,都會保證char、signed

char和unsigned char的sizeof值為1,畢竟char是編程能用的最小數據類型。

MSDN上的解釋為:

The sizeof keyword gives the amount of storage, in bytes, associated with avariable or a

type (including aggregate types). This keyword returns a value of type

size_t.

2、語法:

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

1) sizeof( object ); // sizeof( 對象 );

2) sizeof( type_name ); // sizeof( 類型 );

3) sizeof object; // sizeof 對象;

所以一下三種sizeof的使用都是對的

復制代碼 代碼如下:

#include

main()

{

int b;

printf("%dn",sizeof b);

printf("%dn",sizeof(b));

printf("%dn",sizeof(int));

}

4、基本數據類型的sizeof

這里的基本數據類型指short、int、long、磨唯float、double這樣的簡單內置數據類型,由於它們都是和系

統相關的,所以在不同的系統下取值可能不同,這務必引起我們的注意,盡量不要在

這方面給自己程序的移植造成麻煩。一般的,在32位編譯環境中,sizeof(int)的取值為4。

5、指針變數的sizeof

等於計算機內部地址匯流排的寬度。所以在32位計算機中,一個指針變數的返回值必定是4(注意結果是以

位元組為單位),可以預計,在將來的64位系統中指針變數的sizeof結果為8。

指針變數的sizeof值與指針所指的對象沒有任何關系,正是由於所有的指針變數所佔內存大小相等,所以

MFC消息處理函數使用兩個參數WPARAM、LPARAM就能傳遞各種復雜的消息結構(使用

指向結構體的指針)。

6、數組的sizeof

數組的sizeof值等於數組所佔用的內存位元組數,如:

char a1[] = "abc";

int a2[3];

sizeof( a1 ); // 結果為4,字元 末尾還存在瞎纖培一個NULL終止符

sizeof( a2 ); // 結果為3*4=12(依賴於int)

sizeof當作了求數組元素的個豎銀數是不對的,求數組元素的個數有下面兩種寫法:int c1 = sizeof( a1 )

/ sizeof( char ); // 總長度/單個元素的長度

int c2 = sizeof( a1 ) / sizeof( a1[0] ); // 總長度/第一個元素的長度。注意數組名做函數參數傳遞

時退化為指針。

7、結構體的sizeof

struct S1

{

char c;

int i;

};

sizeof的結果等於對象或者類型所佔的內存位元組數,好吧,那就讓我們來看看S1的內存分配情況:S1 s1

= { 'a', 0xFFFFFFFF };s1的地址為0x0012FF78,其數據內容如下:

0012FF78: 61 CC CC CC FF FF FF FF中間夾雜了3個位元組的CC看看MSDN上的說明:When applied to a

structure type or variable, sizeof returns the actual size, which may

include padding bytes ed for alignment.

這就是位元組對齊!為什麼需要位元組對齊計算機組成原理教導我們這樣有助於加快計算機的取數速度,否則

就得多花指令周期了。為此,編譯器默認會對結構體進行處理(實際上其它地方的數

據變數也是如此),讓寬度為2的基本數據類型(short等)都位於能被2整除的`地址上,讓寬度為4的基本

數據類型(int等)都位於能被4整除的地址上,以此類推。這樣,兩個數中間就可能

需要加入填充位元組,所以整個結構體的sizeof值就增長了。

1、sizeof是運算符,跟加減乘除的性質其實是一樣的,在編譯的時候進行執行,而不是在運行時才執行。

那麼如果編程中驗證這一點呢?

復制代碼 代碼如下:

#include

using namespace std;

int main()

{

int i=1;

cout<

sizeof(++i);

cout<

return 1;

}

輸入結果為 1

1

sizeof 中的++i 的副作用並沒有顯示出來,原因只可能有一個,在編譯的時候sizeof執行以後將++i 處理了,++i 的副作用因此被消除了。如果sizeof 是在運行時進行的話,則肯定要注意++i 。實際上sizeof的實現應該是用宏來做的,宏在編譯時進行執行。具體實現可以參考下面。

2、sizeof('a')在C語言中的結果是4,在C++中結果是1,看過某篇文章說C中sizeof側重於「數」,而C++中sizeof更側重於「字元」。

3、文章中講了兩個用宏實現sizeof的經典應用

復制代碼 代碼如下:

//適用於非數組

#define _sizeof(T) ((size_t)((T*)0 + 1))

//適用於數組

#define array_sizeof(T) ((size_t)(&T+1)-(size_t)(&T))

先舉兩個小例子說明兩個宏的應用,對於第一個如 _sizeof(int); 的結果就是4;對於第二個先聲明一個大小為4的數組int a[4];那麼array_sizeof(a)結果為16.

對於非數組的宏定義,先是將0轉換為T*類型的指針所指向的地址(此時地址為0)。然後對T類型的地址加1,相當於加上了T類型的大小(即得到了非數組T的大小)。前面的size_t只是將地址轉化為int型的整數返回。

一個簡單的例子:int* p; p=p+1; ——p是一個int*類型的指針, p+1在地址空間上相當於加上了4個位元組。

對 於數組的宏定義,類似於非數組的宏定義,為了方便理解,這里可以把數組T看成一個用戶自定義的類型,&T表示數組類型的指針,對於數組類型指針加 1相當於在地址上加上了該數組大小。由於是用戶自定義的類型所以不能強制將0轉化為數組類型的地址,只能用加1後的地址減去之前的地址,得到的差值就是數 組本身所佔的位元組大小。

拓展閱讀:C語言變數理解

一、變數的概念

程序設計就是讓計算機按照一定的指令來進行工作,可以說數據的處理是程序設計的主要任務。那麼數據是怎麼加入到計算機的內存中呢?計算機最初的功能就是能夠存儲數據並處理數據的機器。那麼數據是怎麼加入到計算機的內存中呢?在學習程序設計之前,很多學生對計算機的硬體設施都大概已經很熟悉了。計算機的硬體設施中有一個區域是用來存儲數據的,計算機在工作的過程中會頻繁的從這個區域讀入和讀出數據。要想讓計算機按照某些指令(程序)自動工作,首先必須把數據存儲到計算機的存儲空間中。在某種計算機語言中實現這種數據存儲功能的就是變數。變數就是計算機內存中的某一個存儲單元。

二、變數的定義

C語言中變數在使用之前必須先對其進行定義,變數的定義的一般形式如下:【存儲類別】數據類型變數名;其中存儲類別是可以省略的。

1、存儲類別計算機的內存一般分為三個部分:1)程序區;2)靜態存儲區;3)動態存儲區;為了高效的發揮計算機的功能,不同類型的變數存放在不同的內存區域。變數的存儲類別決定了變數中的數據在計算機內存中的存儲位置。C語言中局部變數存放在動態存儲區,全局變數或者靜態變數存放在靜態存儲區。

2、數據類型在用程序處理問題之前,首先必須確定用何種方式描述問題中所涉及到的數據。這個問題在C語言中是由數據類型來決定的。變數的本質表現為在計算機中的存在時間和存儲空間。變數的數據類型是用來決定變數在計算機中佔用內存空間的大小。比如:整型數據在TC編譯系統中佔用兩個位元組的存儲空間。C語言變數的類型不僅確定了數據在計算機內存中的存儲區域的大小,同時確定了該數據能夠參與的各種運算。任何一個C語言的變數必須有確定的數據類型,不管這個變數如何變化,變數的值都必須符合該變數數據類型的規定。

3、變數的名字通過以上介紹我們知道C語言中的變數就是計算機的某個存儲單元,假設你給某個變數賦予了一個數值,對變數的處理其實就是對這個數據的處理。那麼計算機是如何快速准確的找到這個數據呢?計算機的內存是以位元組為單位進行劃分的。每個存儲單元都有自己的地址編號,就向賓館中房間的房間號一樣。計算機就是通過地址來准確的確定數據的存儲位置。但是對於程序員特別是非專業計算機人士,如果用計算機內存地址記錄數據是非常難操作的。

為了更好的掌控變數,C語言規定可以給每個變數其一個容易識別的名字。這個名字的命名規則遵循C語言的標識符命名規則。C語言的變數名的命名在遵循C語言標識符規則的前提下,原則上可以是任意長度字元的組合。但是目前很多的C語言編譯系統只能識別前31個字元,如果兩個變數的前31個字元相同,則編譯系統會認為這兩個變數時同一個變數。為了避免這種混淆的出現最好避免使用多餘31個字元的變數名。變數的理解變數就是計算機中的某個存儲單元。定義某個變數本質上就是向計算機申請一些存儲區域。這個存儲區域的大小由變數的數據類型決定,這個存儲區域的位置有變數的存儲類類別決定。給變數賦予某個數值,其實就是向該變數對應的存儲單元讀入數據,對變數的處理就是對這個存儲單元中的數據的處理。並且這個存儲單元中的數據在程序的運行期間是可以發生變化的。

Ⅳ c語言里:sizeof怎樣用法

1、首先打開VS,新建一個 使用sizeof求出數組的大小 project。

Ⅵ c語言sizeof函數

(1)sizeof不是函數,它只是一個操作符(operator)。

(2)sizeof的作用是返回一個對象或者類型所佔的內存位元組數,它的返回值的類型是size_t類型,而size_t是在頭文件stddef.h中定義的。size_t 這是一個依賴於編譯系統的值,一般定義為
「typedef unsigned int size_t;」,也就是無符余譽號整型。

(3)sizeof有三種語法形式,如下:
1) sizeof( object ); // sizeof( 對象 );
2) sizeof( type_name ); // sizeof( 類型 );
3) sizeof object; // sizeof 對象;
所以,

inti;
sizeof(i);//ok
sizeofi;//ok
sizeof(int);//ok
sizeofint;//error

既然寫法3可以用寫法1代替,為求形式統一以及減少我們大腦的負擔,只用寫法1就行了!

(4)說回你的提問,既然sizeof的返回值是unsigned int型,那麼很明顯可以用 %u 、%o 、%x 來輸出,這三個都是無符號整型的格式符,分別對應十進制、八進制、十六進制。

(5)而%zd是修飾符z與有符號十進制整型格式符%d組合而成的格式符,表示按 size_t 的類型來輸出。那麼,肯定,%zd 可以用來輸出 sizeof 的返回值。

(6)而%d是按有符號整型來輸宏毀並出蔽跡數值,所以與unsigned int的表示範圍是不一樣的,如果 sizeof 的返回值超出了 %d 的表示範圍的話,是會輸出一個不正確的數值的。

總結一下:sizeof 的返回值可以用 %u 、 %o 、 %x 、 %zd 來正常輸出,而用 %d 的時候需要注意返回值是否會超出 %d (即 signed int 型)的表示範圍。

另外,有的操作系統或編譯器里,size_t 的類型可能是 long unsigned int 型,所以 輸出 sizeof 的返回值的時候, 應該用 %lu 等。

以上,如有幫助,煩請點採納,謝謝!

Ⅶ C語言中 sizeof 運算的值是在編譯時還是運

一、在 Pascal 語言中,sizeof() 是一種內存容量度量函數,功能是返回一個變數或者類型的大小(以位元組為單位);在 C 語言中,sizeof() 是一個判斷數據類型或者表達式長度的運算符。在Pascal 語言與C語言中,對 sizeof() 的處理都是在編譯階段進行。

二、C語言中

  1. 判斷數據類型長度符的關鍵字

  2. 用法

    sizeof(類型說明符,數組名或表達式);
    或sizeof (變數名);

  3. 定義

  4. sizeof是C/C++中的一個操作符(operator),簡單的說其作用就是返回一個對象或者類型所佔的內存位元組數。

    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.

    其返回值類型為size_t,在頭文件stddef.h中定義。這是一個依賴於編譯系統的值,一般定義為

  5. typedefunsignedintsize_t;

  6. 在C99及以上標准中,sizeof(char)、sizeof(int)、sizeof(long)、sizeof(long long)、sizeof(float)、sizeof(double)、sizeof(long double)的值分別是1,4,4,8,4,8,16。[1]

  7. 語法

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

  8. sizeof(object);//sizeof(對象);
    sizeof(type_name);//sizeof(類型);
    sizeofobject;//sizeof對象;

    所以,

  9. inti;
    sizeof(i);//ok
    sizeofi;//ok
    sizeof(int);//ok
    sizeofint;//error

    既然寫法3可以用寫法1代替,為求形式統一以及減少我們大腦的負擔,第3種寫法,忘掉它吧!實際上,sizeof計算對象的大小也是轉換成對對象類型的計算,也就是說,同種類型的不同對象其sizeof值都是一致的。這里,對象可以進一步延伸至表達式,即sizeof可以對一個表達式求值,編譯器根據表達式的最終結果類型來確定大小,一般不會對表達式進行計算。如:

  10. sizeof(2);//2的類型為int,所以等價於sizeof(int);
    sizeof(2+3.14);//3.14的類型為double,2也會被提升成double類型,所以等價於sizeof(double);
  11. sizeof也可以對一個函數調用求值,其結果是函數返回類型的大小,函數並不會被調用,我們來看一個完整的例子:

  12. charfoo()
    {
    printf("foo()hasbeencalled. ");
    return'a';
    }
    intmain()
    {
    size_tsz=sizeof(foo());
    //foo()的返回值類型為char,所以sz=sizeof(char),foo()並不會被調用
    printf("sizeof(foo())=%d ",sz);
    }
  13. C99標准規定,函數、不能確定類型的表達式以及位域(bit-field)成員不能被計算sizeof值,即下面這些寫法都是錯誤的:[1]

  14. sizeof(foo);//error
    voidfoo2(){}
    sizeof(foo2());//error
    structS
    {
    unsignedintf1:1;
    unsignedintf2:5;
    unsignedintf3:12;
    };
    sizeof(S.f1);//error
  15. sizeof的常量性

    sizeof的計算發生在編譯時刻,所以它可以被當作常量表達式使用,如:

    charary[sizeof(int)*10];//ok

  16. 最新的C99標准規定sizeof也可以在運行時刻進行計算,如下面的程序在Dev-C++中可以正確執行:[1]

  17. intn;
    n=10;//n動態賦值
    charary[n];//C99也支持數組的動態定義
    printf("%d ",sizeof(ary));//ok.輸出10
  18. 但在沒有完全實現C99標準的編譯器中就行不通了,上面的代碼在VC6中就通不過編譯。所以我們最好還是認為sizeof是在編譯期執行的,這樣不會帶來錯誤,讓程序的可移植性強些。

    基本數據類型的sizeof

    這里的基本數據類型指short、int、long、float、double這樣的簡單內置數據類型,由於它們都是和系統相關的,所以在不同的系統下取值可能不同,這務必引起我們的注意,盡量不要在這方面給自己程序的移植造成麻煩。

    一般的,在32位編譯環境中,sizeof(int)的取值為4。

  19. 指針變數的sizeof

    學過數據結構的你應該知道指針是一個很重要的概念,它記錄了另一個對象的地址。既然是來存放地址的,那麼它當然等於計算機內部地址匯流排的寬度。所以在32位計算機中,一個指針變數的返回值必定是4(注意結果是以位元組為單位),但是,在64位系統中指針變數的sizeof結果為8。

  20. char*pc="abc";
    int*pi;
    string*ps;
    char**ppc=&pc;
    void(*pf)();//函數指針
    sizeof(pc);//結果為4
    sizeof(pi);//結果為4
    sizeof(ps);//結果為4
    sizeof(ppc);//結果為4
    sizeof(pf);//結果為4
  21. 指針變數的sizeof值與指針所指的對象沒有任何關系,正是由於所有的指針變數所佔內存大小相等,所以MFC消息處理函數使用兩個參數WPARAM、LPARAM就能傳遞各種復雜的消息結構(使用指向結構體的指針)。

    數組的sizeof

    數組的sizeof值等於數組所佔用的內存位元組數,如:

    char a1[] = "abc"; int a2[3]; sizeof( a1 ); // 結果為4,字元末尾還存在一個NULL終止符 sizeof( a2 ); // 結果為3*4=12(依賴於int)

    一些朋友剛開始時把sizeof當作了求數組元素的個數,如今你應該知道這是不對的,那麼應該怎麼求數組元素的個數呢Easy,通常有下面兩種寫法:

  22. intc1=sizeof(a1)/sizeof(char);//總長度/單個元素的長度char型
    intc2=sizeof(a2)/sizeof(a2[0]);//總長度/第一個元素的長度int型

    寫到這里,提一問,下面的c3,c4值應該是多少呢

  23. voidfoo3(chara3[3])
    {
    intc3=sizeof(a3);//c3==
    }
    voidfoo4(chara4[])
    {
    intc4=sizeof(a4);//c4==
    }

    也許當你試圖回答c4的值時已經意識到c3答錯了,是的,c3!=3。這里函數參數a3已不再是數組類型,而是蛻變成指針,相當於char* a3,為什麼仔細想想就不難明白,我們調用函數foo3時,程序會在棧上分配一個大小為3的數組嗎不會!數組是「傳址」的,調用者只需將實參的地址傳遞過去,所以a3自然為指針類型(char*),c3的值也就為4。

    結構體的sizeof

    這是初學者問得最多的一個問題,所以這里有必要多費點筆墨。讓我們先看一個結構體:

    structS1{charc;inti;};

    問sizeof(s1)等於多少聰明的你開始思考了,char佔1個位元組,int佔4個位元組,那麼加起來就應該是5。是這樣嗎?你在你機器上試過了嗎?也許你是對的,但很可能你是錯的!VC6中按默認設置得到的結果為8。

    我們來好好琢磨一下sizeof的定義——sizeof的結果等於對象或者類型所佔的內存位元組數,好吧,那就讓我們來看看S1的內存分配情況:

    S1 s1={'a',0xFFFFFFFF};

    定義上面的變數後,加上斷點,運行程序,觀察s1所在的內存,你發現了什麼

    以我的VC6.0為例,s1的地址為0x0012FF78,其數據內容如下:

    0012FF78: 61 CC CC CC FF FF FF FF

    發現了什麼怎麼中間夾雜了3個位元組的CC看看MSDN上的說明:

    When applied to a structure type or variable, sizeof returns the actual size, which may include padding bytes inserted for alignment.

    原來如此,這就是傳說中的位元組對齊啊!一個重要的話題出現了。

    為什麼需要位元組對齊計算機組成原理教導我們這樣有助於加快計算機的取數速度,否則就得多花指令周期了。為此,編譯器默認會對結構體進行處理(實際上其它地方的數據變數也是如此),讓寬度為2的基本數據類型(short等)都位於能被2整除的地址上,讓寬度為4的基本數據類型(int等)都位於能被4整除的地址上,以此類推。這樣,兩個數中間就可能需要加入填充位元組,所以整個結構體的sizeof值就增長了。

    讓我們交換一下S1中char與int的位置:

    struct S2{inti;charc;};

    看看sizeof(S2)的結果為多少,怎麼還是8再看看內存,原來成員c後面仍然有3個填充位元組,這又是為什麼啊別著急,下面總結規律。

    位元組對齊的細節和編譯器實現相關,但一般而言,滿足三個准則:

  24. 1)結構體變數的首地址能夠被其最寬基本類型成員的大小所整除;

    2)結構體每個成員相對於結構體首地址的偏移量(offset)都是成員大小的整數倍,如有需要編譯器會在成員之間加上填充位元組(internal padding);

    3)結構體的總大小為結構體最寬基本類型成員大小的整數倍,如有需要編譯器會在最末一個成員之後加上填充位元組(trailing padding)。

    對於上面的准則,有幾點需要說明:

    1) 前面不是說結構體成員的地址是其大小的整數倍,怎麼又說到偏移量了呢因為有了第1點存在,所以我們就可以只考慮成員的偏移量,這樣思考起來簡單。想想為什麼。

    結構體某個成員相對於結構體首地址的偏移量可以通過宏offsetof()來獲得,這個宏也在stddef.h中定義,如下:

    #define offsetof(s,m)(size_t)&(((s*)0)->m)

    例如,想要獲得S2中c的偏移量,方法為

    size_tpos=offsetof(S2,c);//pos等於4

    2) 基本類型是指前面提到的像char、short、int、float、double這樣的內置數據類型,這里所說的「數據寬度」就是指其sizeof的大小。由於結構體的成員可以是復合類型,比如另外一個結構體,所以在尋找最寬基本類型成員時,應當包括復合類型成員的子成員,而不是把復合成員看成是一個整體。但在確定復合類型成員的偏移位置時則是將復合類型作為整體看待。

    這里敘述起來有點拗口,思考起來也有點撓頭,還是讓我們看看例子吧(具體數值仍以VC6為例,以後不再說明):

    struct S3{charc1;S1s;charc2;};

    S1的最寬簡單成員的類型為int,S3在考慮最寬簡單類型成員時是將S1「打散」看的,所以S3的最寬簡單類型為int,這樣,通過S3定義的變數,其存儲空間首地址需要被4整除,整個sizeof(S3)的值也應該被4整除。

    c1的偏移量為0,s的偏移量呢這時s是一個整體,它作為結構體變數也滿足前面三個准則,所以其大小為8,偏移量為4,c1與s之間便需要3個填充位元組,而c2與s之間就不需要了,所以c2的偏移量為12,算上c2的大小為13,13是不能被4整除的,這樣末尾還得補上3個填充位元組。最後得到sizeof(S3)的值為16。

    通過上面的敘述,我們可以得到一個公式:

    結構體的大小等於最後一個成員的偏移量加上其大小再加上末尾的填充位元組數目,即:

  25. sizeof(struct)=offsetof(lastitem)+sizeof(lastitem)+sizeof(trailingpadding);

    到這里,朋友們應該對結構體的sizeof有了一個全新的認識,但不要高興得太早,有一個影響sizeof的重要參量還未被提及,那便是編譯器的pack指令。它是用來調整結構體對齊方式的,不同編譯器名稱和用法略有不同,VC6中通過#pragmapack實現,也可以直接修改/Zp編譯開關。#pragma pack的基本用法為:

    #pragmapack(n),n為位元組對齊數,其取值為1、2、4、8、16,默認是8,如果這個值比結構體成員的sizeof值小,那麼,該成員的偏移量應該以此值為准,即是說,結構體成員的偏移量應該取二者的最小值,

    公式如下:

    offsetof(item)=min(n,sizeof(item))

  26. 再看示例:

  27. #pragmapack(push)//將當前pack設置壓棧保存
    #pragmapack(2)//必須在結構體定義之前使用
    structS1{charc;inti;};
    structS3{charc1;S1s;charc2;};
    #pragmapack(pop)//恢復先前的pack設置

    計算sizeof(S1)時,min(2, sizeof(i))的值為2,所以i的偏移量為2,加上sizeof(i)等於6,能夠被2整除,所以整個S1的大小為6。

    同樣,對於sizeof(S3),s的偏移量為2,c2的偏移量為8,加上sizeof(c2)等於9,不能被2整除,添加一個填充位元組,所以sizeof(S3)等於10。

    如今,朋友們可以輕松的出一口氣了,:)

    還有一點要注意,「空結構體」(不含數據成員)的大小不為0,而是1。試想一個「不佔空間」的變數如何被取地址、兩個不同的「空結構體」變數又如何得以區分呢於是,「空結構體」變數也得被存儲,這樣編譯器也就只能為其分配一個位元組的空間用於佔位了。如下:

    struct S5 { }; sizeof( S5 ); // 結果為1含位域結構體的sizeof

    前面已經說過,位域成員不能單獨被取sizeof值,我們這里要討論的是含有位域的結構體的sizeof,只是考慮到其特殊性而將其專門列了出來。

    C99規定int、unsigned int和bool可以作為位域類型,但編譯器幾乎都對此作了擴展,允許其它類型類型的存在。使用位域的主要目的是壓縮存儲,其大致規則為:

  28. 1) 如果相鄰位域欄位的類型相同,且其位寬之和小於類型的sizeof大小,則後面的欄位將緊鄰前一個欄位存儲,直到不能容納為止;

    2) 如果相鄰位域欄位的類型相同,但其位寬之和大於類型的sizeof大小,則後面的欄位將從新的存儲單元開始,其偏移量為其類型大小的整數倍;

    3) 如果相鄰的位域欄位的類型不同,則各編譯器的具體實現有差異,VC6採取不壓縮方式,Dev-C++採取壓縮方式;

    4) 如果位域欄位之間穿插著非位域欄位,則不進行壓縮;

    5) 整個結構體的總大小為最寬基本類型成員大小的整數倍。

  29. 還是讓我們來看看例子。

    示例1:

    struct BF1{charf1:3;charf2:4;charf3:5;};

    其內存布局為:

  30. |_f1__|__f2__|_|____f3___|____|

  31. |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|

  32. 0 3 7 8 1316

    位域類型為char,第1個位元組僅能容納下f1和f2,所以f2被壓縮到第1個位元組中,而f3隻

    能從下一個位元組開始。因此sizeof(BF1)的結果為2。

    示例2:

    structBF2{charf1:3;shortf2:4;charf3:5;};

    由於相鄰位域類型不同,在VC6中其sizeof為3,在Dev-C++中為2。

    示例3:

    structBF3{charf1:3;charf2;charf3:5;};

    非位域欄位穿插在其中,不會產生壓縮,在VC6和Dev-C++中得到的大小均為3。

    9.聯合體的sizeof

    結構體在內存組織上是順序式的,聯合體則是重疊式,各成員共享一段內存,所以整個聯合體的sizeof也就是每個成員sizeof的最大值。結構體的成員也可以是復合類型,這里,復合類型成員是被作為整體考慮的。

    所以,下面例子中,U的sizeof值等於sizeof(s)。

  33. unionU
    {
    inti;
    charc;
    S1s;
    };

sizeof還可以用函數做參數,比如:

shortf();
printf("%d ",sizeof(f()));

輸出的結果是sizeof(short),即2。

數組做sizeof的參數不退化,傳遞給strlen就退化為指針了。

大部分編譯程序在編譯的時候就把sizeof計算過了是類型或是變數的長度這就是sizeof(x)可以用來定義數組維數的原因

charstr[20]="0123456789";
inta=strlen(str);//a=10;
intb=sizeof(str);//而b=20;

7.sizeof後如果是類型必須加括弧,如果是變數名可以不加括弧。這是因為sizeof是個操作符不是個函數。

8.當適用於一個結構類型時或變數, sizeof 返回實際的大小,當適用於靜態的空間數組, sizeof 歸還全部數組的尺寸。

sizeof 操作符不能返回被動態分派的數組或外部數組的尺寸

9.數組作為參數傳給函數時傳的是指針而不是數組,傳遞的是數組的首地址,

fun(char[8])fun(char[])

都等價於 fun(char *)

  1. 特別注意:

  2. 1.sizeof是運算符,strlen是函數,具體如下:

  3. sizeof

  4. strlen

  5. 頭文件:stddef.h格式:1) sizeof( object ); // sizeof( 對象 );

  6. 2) sizeof( type_name ); // sizeof( 類型 );

  7. 3) sizeof object; // sizeof 對象

  8. 功能:一個對象或者類型所佔的內存位元組數;

  9. 說明:sizeof操作符的結果類型是size_t,typedef unsigned int size_t;

  10. 原型:extern unsigned int strlen(char *s);頭文件:string.h

  11. 格式:strlen (字元數組名)

  12. 功能:計算字元串s的(unsigned int型)長度,不包括''在內

  13. 說明:返回s的長度,不包括結束符NULL。

  14. 2.strlen只能用char*做參數,且必須是以''''結尾的,而sizeof可用類型做參數,還可用函數做參數,如:

    int sum();

    printf("%d ",sizeof(sum()));//輸出的結果是sizeof(int),即4。

    數組做sizeof的參數不退化,傳遞給strlen就退化為指針了。

    大部分編譯程序,sizeof在編譯時確定,因此sizeof(x)可以用來定義數組維數;而strlen要在運行時才能計算出來,用來計算字元串的長度,而不是類型占內存的大小;

    char str[20]="0123456789";

    int len1=strlen(str);//len1=10;

    int len2=sizeof(str);//len2=20;

  15. sizeof後,若為類型必須加括弧,若為變數名可以不加括弧。這是因為sizeof是個操作符不是個函數。
    當適用於一個結構類型時或變數, sizeof 返回實際的大小;當適用一靜態地空間數組,sizeof 歸還全部數組的尺寸。
    sizeof 操作符不能返回動態地被分派了的數組或外部的數組的尺寸;
    數組作為參數傳給函數時傳的是指針而不是數組,傳遞的是數組的首地址,
    如:

    fun(char[8])

    fun(char[])

  16. 都等價於 fun( char * )
    在C++里參數傳遞數組永遠都是傳遞指向數組首元素的指針,編譯器不知道數組的大小,如果想在函數內知道數組的大小, 需要這樣做:
    進入函數後用memcpy拷貝出來,長度由另一個形參傳進去

  17. fun(unsigedchar*p1,intlen)
    {
    unsignedchar*buf=newunsignedchar[len+1];
    memcpy(buf,p1,len);
    }
  18. 常在用到 sizeof 和 strlen 的時候,通常是計算字元串數組的長度,如果是對指針,結果則會不一樣的:
    char* str = "abacd";
    sizeof(str) //結果 4 --->str是指向字元串常量的字元指針,sizeof 獲得的是一個指針所佔的空間,應該是長整型的,所以是4;
    sizeof(*str) //結果 1 --->*str是第一個字元,其實就是字元串的第一位'a' 所佔的內存空間,是char類型的,佔了 1 位;
    strlen(str)= 5 //--->若要獲得這個字元串的長度,則一定要使用 strlen

  19. 看了上面的詳細解釋,發現兩者的使用還是有區別的,從這個例子可以看得很清楚:

    char str[20]="0123456789";

    int a=strlen(str); //a=10; >>>> strlen 計算字元串的長度,以結束符 0x00 為字元串結束。

  20. int b=sizeof(str); //而b=20; >>>> sizeof 計算的則是分配的數組str[20] 所佔的內存空間的大小,不受裡面存儲的內容改變。上面是對靜態數組處理的結果,如果是對指針,結果就不一樣了

    char* ss = "0123456789";sizeof(ss) 結果 4 ===》ss是指向字元串常量的字元指針,sizeof 獲得的是一個指針的之所佔的空間,應該是長整型的,所以是4

    sizeof(*ss) 結果 1 ===》*ss是第一個字元其實就是獲得了字元串的第一位'0' 所佔的內存空間,是char類型的,佔了 1 個位元組

    strlen(ss)= 10 >>>> 如果要獲得這個字元串的長度,則一定要使用 strlen

    sizeof返回對象所佔用的位元組大小. //正確

    strlen返回字元個數. //正確

  21. 在使用sizeof時,有一個很特別的情況,就是數組名到指針蛻變,

    charArray[3]={'0'};

    sizeof(Array)==3;

    char*p=Array;

    strlen(p)==1;//sizeof(p)結果為4

    在傳遞一個數組名到一個函數中時,它會完全退化為一個指針

    大部分編譯程序 在編譯的時候就把sizeof計算過了 是類型或是變數的長度

    這就是sizeof(x)可以用來定義數組維數的原因

  22. charstr[20]="0123456789";
    inta=strlen(str);//a=10;
    intb=sizeof(str);//而b=20;
    charss[]="0123456789";
    sizeof(ss)結果11===》ss是數組,計算到位置,因此是10+1
    sizeof(*ss)結果1===》*ss是第一個字元
    charss[100]="0123456789";
    sizeof(ss)結果是100===》ss表示在內存中的大小100×1
    strlen(ss)結果是10===》strlen是個函數內部實現是用一個循環計算到為止之前
    intss[100]="0123456789";
    sizeof(ss)結果400===》ss表示在內存中的大小100×4
    strlen(ss)錯誤===》strlen的參數只能是char*且必須是以''結尾的
    charq[]="abc";
    charp[]="a ";
    sizeof(q),sizeof(p),strlen(q),strlen(p);

    結果是 4 3 3 2

  23. 第三個例子

    charszPath[MAX_PATH]

    如果在函數內這樣定義,那麼sizeof(szPath)將會是MAX_PATH,但是將szPath作為虛參聲明時

    (voidfun(charszPath[MAX_PATH]))

    sizeof(szPath) 卻會是4(指針大小)

    還有一位網友的說明也很好:

    其實理解 sizeof 只需要抓住一個要點:棧

    程序存儲分布有三個區域:棧、靜態和動態。能夠從代碼直接操作的對象,包括任何類型的變數、指針,都是在棧上的;動態和靜態存儲區是靠棧上的所有指針間接操作的。 sizeof 操作符,計算的是對象在棧上的投影體積;記住這個就很多東西都很清楚了。

  24. charconst*static_string="Hello";
    //sizeof(static_string)是sizeof一個指針,所以在32bitsystem是4
    charstack_string[]="Hello";
    //sizeof(stack_string)是sizeof一個數組,所以是6*sizeof(char)
    char*string=newchar[6];
    strncpy(string,"Hello",6");
    //sizeof(string)是sizeof一個指針,所以還是4。
    //和第一個不同的是,這個指針指向了動態存儲區而不是靜態存儲區。

    不管指針指向的內容在什麼地方,sizeof 得到的都是指針的棧大小

    C++ 中對引用的處理比較特殊;sizeof 一個引用得到的結果是 sizeof 一個被引用的對象的大小;所以

  25. structtest
    {
    inta,b,c,d,e,f,g,h;
    };
    intmain()
    {
    test&r=*newtest;
    cout<<sizeof(test)<<endl;//32
    cout<<sizeofr<<endl;//也是32
    system("PAUSE");
    }
    r 引用的是整個的 test 對象而不是指向 test 的指針,所以 sizeof r 的結果和 sizeof test 完全相同。

Ⅷ C語言中「SIZEOF(INT)「是什麼意思有什麼作用

sizeof()()顧名思義size
of
...某某的大小長度。如果是sizeof(int)那就意味著一個int型的長度。8位代表一個位元組棚型長度,所以如果是一般使纖衫用的tc編譯器(16位鏈豎猜的)那麼sizeof(int)就等於2。

Ⅸ C語言中sizeof和strlen函數區別在哪

size of求變數佔用的位元組差雀返數,包括結束符\0
strlen求變數的長度但是不歲拍包虛飢括\0

閱讀全文

與編譯時輸出sizeof相關的資料

熱點內容
非科班程序員自學 瀏覽:799
壓縮泡沫鞋底底材 瀏覽:217
程序員職場第一課2正確的溝通 瀏覽:677
遇到不合法app應該怎麼辦 瀏覽:90
匯編程序編譯後的文件 瀏覽:77
大智慧均線源碼 瀏覽:371
單片機排阻的作用 瀏覽:213
滴滴金融app被下架如何還款 瀏覽:210
jpg轉換成pdf免費軟體 瀏覽:741
范里安pdf 瀏覽:443
偽造pdf 瀏覽:75
能刪除android文件夾嗎 瀏覽:446
LINUX使用V2ray 瀏覽:797
找人幫忙注冊app推廣是什麼 瀏覽:820
獨立伺服器如何恢復初始化 瀏覽:11
優秀到不能被忽視pdf 瀏覽:316
導遊程序員家政 瀏覽:586
22乘28的快速演算法 瀏覽:338
軟通動力程序員節2021 瀏覽:846
安卓系統如何卸載安裝包 瀏覽:870