1. 程式人生 > >我計算結構體和聯合體大小的方法

我計算結構體和聯合體大小的方法

#include <stdio.h> 
struct A
 {
     int i;
     char ch[9];
          
 };      
         
 void main()
 {       
    struct A a;
     printf("%d\n",sizeof(a));
 }   

我說一下我的小經驗,就是所謂的“位元組對齊”,我是把結構體裡面的所以資料都看成4個位元組對齊,如果不夠就補齊,多了就留下4個剩下的
再放到一邊給再湊齊4個。


用我的道理還分析一下上面的程式。
 i 是4個位元組的,OK ,再看 ch[9]一共是9個位元組,按照我說的來它有9個位元組,我們留下4個,然後把剩下的5個放一邊,然後再拿出4個,還剩下1個,這個時候再看後面有沒有位元組跟它補齊,沒有,系統會跟它自動補齊,加起來是4,4,4,1+3  16個。然後我們把程式碼改一下,char ch[9]放前面,int i放後面,再來用我們的辦法來計算,4,4,1+3,4答案也是16. (1+3是因為它最後只剩1個位元組了,而後面的i是4個位元組,不能跟它補齊,所以系統會自動跟它補齊)

其實我曾經想過如果我的資料大小分別是 3 ,4,1(大小是8還是12呢)<這2個答案這就慢慢體會>
結果證明我說的對了答案是12,這就是我們為什麼上面說當你位元組不夠的時候它會先跟你找後面有沒有正好可以補齊的資料大小,而不是從這個資料中取出一部分給你,如果不能滿足,系統會自己跟你補齊,而不是用下一個資料的大小,我覺得是因為它既然是4位元組對齊,那麼它寫資料和讀資料應該也是4個位元組吧,如果從別的資料把他的記憶體大小給你,讀豈不是混亂了麼?

#include <stdio.h>
 
 struct A
 {
     
     char ch[3];//3
     int   i; //4
     char   c; //1
          
 };      
         
 void main()
 {       
    struct A a;
     printf("%d\n",sizeof(a));
 }   

上面執行結果為12

今天是9月25號,又看到了求union--sizeof的題目所以更新一下

union中可以定義多個成員,union的大小由最大的成員的大小決定。

#include <stdio.h>
  
  union
  {
      int a;
      char b[17];
  }u; 
  
 void main()
  {
      printf("%d\n",sizeof(u));
      
  }
執行結果為20(4位元組對齊)

如果我把char b[ 17]改為char b[14] 結果為16,改為4結果為4,改為5結果為8.........

我們可以看出,這個聯合體內,最大的是char b 佔17個位元組,但是我們是4位元組對齊,所以答案是大於17的最小的4的倍數 為20(聯合體求大小比結構體還是簡單許多的)

如果我們聯合體內只有一個char 型別的變數,則我們的大小就為1.總的來說大小就是1,4,8,16,20.....(4的倍數中)最接近聯合體內最大位元組數的數。

對某一個成員賦值,會覆蓋其他成員的值也不奇怪,因為他們共享一塊記憶體。但前提是成員所佔位元組數相同,當成員所佔位元組數不同時只會覆蓋相應位元組上的值,比如對char成員賦值就不會把整個int成員覆蓋掉,因為char只佔一個位元組,而int佔四個位元組)


下面給2個簡單的例子,大家好好體會吧。

#include <stdio.h>
  
  typedef union
  {
      int a;
      char b;
  }u;
  
  void main()
  
  {
      u dem;
      dem.b='h';
      dem.a=5;
  
     printf("char=%c  int=%d\n",dem.b,dem.a);
   
                      
   }                   
#include <stdio.h>
  
  typedef union
  {
      int a;
      char b;
  }u;
  
  void main()
  
  {
      u dem;
      dem.a=5;
      dem.b='h'
     printf("char=%c  int=%d\n",dem.b,dem.a);
   
                      
   }