C語言中的Sizeof

1.C11標準中的sizeof

   Constraints

  1  The sizeof operator shall not be applied to an expression that has function type or an incomplete type, to the parenthesized name of such a type, or to an expression that designates a bit-field member. The _Alignof operator shall not be applied to a function type or an incomplete type.

  sizeof不應該用在函數類型、不完整類型、前面兩種帶上括號、位域成員類型
  Semantics
  2  The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.

  sizeof的操作數可能是一個表達式或者帶上括號的表達式,size由操作數的類型決定。如果操作數是一個可變長度的數組,則size是一個估計的數。

  3  The _Alignof operator yields the alignment requirement of its operand type. The operand is not evaluated and the result is an integer constant. When applied to an array type, the result is the alignment requirement of the element type.
  4  When sizeof is applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1. When applied to an operand that has array type, the result is the total number of bytes in the array.103) When applied to an operand that has structure or union type, the result is the total number of bytes in such an object, including internal and trailing padding.

  當sizeof的操作數爲char、unsigned char、signed char,結果都是1。當操作數是數組類型,結果是數組的長度。當是結構體或聯合體,結果是總共需要的字節。

  5  The value of the result of both operators is implementation-defined, and its type (an unsigned integer type) is size_t, defined in <stddef.h> (and other headers).
  6  EXAMPLE 1 A principal use of the sizeof operator is in communication with routines such as storage allocators and I/O systems. A storage-allocation function might accept a size (in bytes) of an object to allocate and return a pointer to void. For example:

1     extern void *alloc(size_t);
2     double *dp = alloc(sizeof *dp);

   The implementation of the alloc function should ensure that its return value is aligned suitably for conversion to a pointer to double.
  7  EXAMPLE 2 Another use of the sizeof operator is to compute the number of elements in an array:

1     sizeof array / sizeof array[0]

  8  EXAMPLE 3 In this example, the size of a variable length array is computed and returned from a function:

 1 #include <stddef.h>
 2    
 3 size_t fsize3(int n)
 4 {
 5    char b[n+3];          // variable length array
 6    return sizeof b;      // execution time sizeof      
 7 }
 8 int main()
 9 {
10   size_t size;
11   size = fsize3(10);   // fsize3 returns 13
12   return 0;    
13 }

2.例子解析

  (1)如果是數組首地址,sizeof會輸出數組的元素個數。如果是一個指針的話,則輸出在該系統中地址的字節寬度。 

1 1 int *a;
2 2 char b[10];
3 3 char *b;
4 4 
5 5 sizeof(a)=4  sizeof(b)=10  sizeof(c)=4

  (2)對於函數傳遞的地址或數組首地址,sizeof都認爲是指針,以下例子輸出4和4

 1 void test_sizeof_addr(char *a)  
 2 {  
 3     printf("%d\n", sizeof(a));  
 4 }  
 5 void test_sizeof_array(char a[10])  
 6 {  
 7     printf("%d\n", sizeof(a));  
 8 }  
 9 int main()  
10 {  
11     char b[30];  
12   
13     test_sizeof_addr(b);  
14     test_sizeof_array(b);  
15   
16     return 0;  
17 }  

  (3)綜合 sizeof不能對void類型使用,但可以對void類 

 1 #include <stdio.h>   
 2 #include <string.h>   
 3 char str[] = "Hello";  
 4 struct size_b{  
 5      float f;  
 6      char p;  
 7      int a[3];  
 8 }block;  
 9    
10 struct flag_s1{  
11     char ch, *ptr;      
12     union{  
13          short a, b;  
14          unsigned int c : 2;  
15          unsigned int d : 1;   
16      }u;  
17      struct flag_s1 *next;  
18 }s1;  
19    
20 sizeof(str) = 6
21 strlen(str) = 5   // 比sizeof少一個'\0'
22 sizeof(block) =  20  //  p在這裏需4字節對齊
23 sizeof(s1) = 16  // ch對齊4字節,指針ptr始終是4字節地址,聯合體u選最大4字節,next指針還是4字節地址 
24             // 結構體對齊規則:(1)結構體大小等於結構體內最大成員大小的整數倍;
25                     //              (2)結構體內的成員的首地址相對於結構體首地址的偏移量是其類型大小的整數倍,
26             //                 比如說double型成員相對於結構體的首地址的偏移量應該是8的整數倍;
27             //        (3)爲了滿足規則1和規則2編譯器會再結構體成員之後進行字節填充

  (4)對指向字符串的指針

1 char*aa=”0123456789”;   //字符串常量的情況
2 sizeof(aa);        //結果爲4,指針的長度
3 sizeof(*aa);       //結果爲1,第一個字符的空間
4 strlen(aa);         //結果爲0,該字符串的長度

 (5)對表達式只計算類型大小,不求值

1 char ch=1;
2 int num=1;
3 int n1=sizeof(ch+num);           //n1=4  ch在計算時會轉換爲int類型
4 int n2=sizeof(ch=ch+num);     //n2=1,ch=1實際是n2=sizeof(ch)

  (6)sizeof的操作數爲函數體時,計算的實際是函數體返回值的類型大小,並且不會執行函數體


 

 

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