国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合)

這篇具有很好參考價值的文章主要介紹了詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


?? 作者簡介 :RO-BERRY 致力于C、C++、數(shù)據(jù)結(jié)構(gòu)、TCP/IP、數(shù)據(jù)庫等等一系列知識,對純音樂有獨特的喜愛
?? 日后方向 : 偏向于CPP開發(fā)以及大數(shù)據(jù)方向,如果你也感興趣的話歡迎關(guān)注博主,期待更新


詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言

1.結(jié)構(gòu)體

1.1 結(jié)構(gòu)體的基礎(chǔ)知識

??結(jié)構(gòu)體是一些值的集合,這些值稱為成員變量。結(jié)構(gòu)的每個成員可以是不同類型的變量。


1.2 結(jié)構(gòu)體的聲明

struct tag   結(jié)構(gòu)體類型(struct)  自定義結(jié)構(gòu)體名稱(tag)
{
member-list;           成員列表(member-list)
}variable-list;        結(jié)構(gòu)體變量列表(variable-list)

??我們可以定義多個結(jié)構(gòu)體,我們可以給一類結(jié)構(gòu)體定義一個自定義的類型名,比如說學(xué)生、教師等
我們就可以這樣定義:

struct Stu            學(xué)生結(jié)構(gòu)體
{
	char name[20];    名字
	int age;          年齡
	char sex[5];      性別
	char id[20];      學(xué)號
};                    分號不能丟

struct Teacher        教師結(jié)構(gòu)體
{
	char name[20];    名字
	int age;          年齡
	char sex[5];      性別
};      

我們想初始化變量就可以利用上面的名稱
例如我們想定義學(xué)生a,學(xué)生b

定義方法1

struct Stu           
{
	char name[20];    
	int age;          
	char sex[5];      
	char id[20];      
};                    

int main()
{
	struct Stu a,b;    //定義學(xué)生a,b
}

我們也可以這樣定義:
定義方法2

struct Stu            
{
	char name[20];    
	int age;          
	char sex[5];      
	char id[20];      
}a,b;                      //定義學(xué)生a,b

這兩種方法定義都是可以的,效果是完全一樣的
想取哪種方式取決于程序員的需求


1.3 特殊的聲明

??在聲明結(jié)構(gòu)的時候,可以不完全的聲明。
這種不完全聲明叫做匿名結(jié)構(gòu)體類型
比如:

struct
{
	int a;
	char b;
	float c;
}x;
struct
{
	int a;
	char b;
	float c;
}*p;

?我們在這種定義的時候,這種結(jié)構(gòu)體是無法在主函數(shù)main里定義結(jié)構(gòu)體變量的,我們只能采用初始化定義方式1在結(jié)構(gòu)體定義的時候在尾部加入變量名,因為我們沒有給這個名稱自定義一個名稱,無法在后面程序中定義


我們在第二個結(jié)構(gòu)體中定義了結(jié)構(gòu)體指針*p,而且第二個結(jié)構(gòu)體的結(jié)構(gòu)成員和第一個結(jié)構(gòu)成員一樣,那我們可不可以使p=&x呢?

我們來試一下
我們發(fā)現(xiàn)程序報錯,并且錯誤如下:
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
這說明了不可以,因為我們的程序認(rèn)為這兩個是不同類型的結(jié)構(gòu)體,雖然都是匿名結(jié)構(gòu)體,而且成員列表相同,但是類型不同,無法執(zhí)行操作

??我們以后在寫結(jié)構(gòu)體的時候也要注意,匿名結(jié)構(gòu)體我們只能在定義上寫,我們下次想用也用不了(匿名結(jié)構(gòu)體的使用是很少的


1.4 結(jié)構(gòu)體的自引用

我們先來看在一個結(jié)構(gòu)體里定義以自己命名的結(jié)構(gòu)體會發(fā)生什么

struct Node
{
	int data;
	struct Node next;
};

我們在程序上走一走
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
??我們會發(fā)現(xiàn)不可以這樣定義,錯誤報告說我們使用正在定義的Node,也就是我們不能在定義的時候在結(jié)構(gòu)成員里使用自身

其實我們也可以發(fā)現(xiàn),如果對于計算機來說。我們結(jié)構(gòu)體中定義自身結(jié)構(gòu)體,結(jié)構(gòu)體成員里面還有結(jié)構(gòu)體,這樣會不停的定義,其內(nèi)存是無限大,不可能停下來

可是當(dāng)我們將結(jié)構(gòu)體成員變成結(jié)構(gòu)體指針,我們就不會報錯了
比如:

struct Node
{
	int data;
	struct Node* next;
};

next是結(jié)構(gòu)體指針,存的是下一個Node指針的地址,這樣引用自身的定義方法,就叫做結(jié)構(gòu)體的自引用


在這里我們不得不提到一個數(shù)據(jù)結(jié)構(gòu),叫做鏈表

1.4.1 鏈表

??定義:

鏈表是一種物理存儲上非連續(xù),數(shù)據(jù)元素的邏輯順序通過鏈表中的指針鏈接次序,實現(xiàn)的一種線性存儲結(jié)構(gòu)。

??特點:
鏈表由一系列節(jié)點(鏈表中每一個元素稱為節(jié)點)組成,節(jié)點在運行時動態(tài)生成 (malloc),每個節(jié)點包括兩個部分:

 一個是存儲數(shù)據(jù)元素的數(shù)據(jù)域

 另一個是存儲下一個節(jié)點地址的指針域

詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
??鏈表的構(gòu)成:
鏈表由一個個節(jié)點構(gòu)成,每個節(jié)點一般采用結(jié)構(gòu)體的形式組織,例如:

typedef struct student
{
	 int num;                      //結(jié)點序號
	 char name[20];                //數(shù)據(jù)內(nèi)容
	 struct student *next;         //指向下一個結(jié)點的指針
 }STU;

鏈表中數(shù)據(jù)域存放數(shù)據(jù),指針域指向的是下一個結(jié)點,這樣便于我們訪問下一個數(shù)據(jù),而且這樣存儲方便修改、刪除等

鏈表是一個很顯著應(yīng)用結(jié)構(gòu)體的自引用的例子


接下來我們再看一例子:

typedef struct
{
	int data;
	Node* next;
	}Node;
//這樣寫代碼,可行否?

我們可以看到,我們使用typedef將這個結(jié)構(gòu)體的名字定義為Node,那么這樣可以定義成功嗎?

??答案是否定的,我們不可以在定義的時候使用結(jié)構(gòu)體名,如上例,我們在定義next結(jié)構(gòu)體指針的時候,編譯器會去看定義這個結(jié)構(gòu)體的上方是否有定義結(jié)構(gòu)體Node,一看發(fā)現(xiàn)沒有,所以就會報錯

我們正確的代碼應(yīng)該是這樣:

typedef struct Node
{
	int data;
	struct Node* next;
}Node;

1.5 結(jié)構(gòu)體變量的定義和初始化

有了結(jié)構(gòu)體類型,那如何定義變量,其實很簡單。

struct Point
{
	int x;
	int y;
}p1; 						  //聲明類型的同時定義變量p1
struct Point p2;	    	  //定義結(jié)構(gòu)體變量p2
struct Point p3 = {x, y};     //初始化:定義變量的同時賦初值。
struct Stu     //類型聲明
{
	char name[15];//名字
	int age;    //年齡
};
struct Stu s = {"zhangsan", 20};	//初始化
struct Node
{
	int data;
	struct Point p;
	struct Node* next;
}n1 = {10, {4,5}, NULL}; 					//結(jié)構(gòu)體嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};		//結(jié)構(gòu)體嵌套初始化

??針對于不同結(jié)構(gòu)體我們有不同的初始化方式,我們所有對于結(jié)構(gòu)體初始化的知識,在上面代碼里都有展示


1.6 結(jié)構(gòu)體內(nèi)存對齊

結(jié)構(gòu)體內(nèi)存對齊是結(jié)構(gòu)體知識最難懂的點,讓我們來一起學(xué)習(xí)一下。
我們知道了結(jié)構(gòu)體如何定義,如何初始化,我們來思考一下,結(jié)構(gòu)體里面有那么多元素,其內(nèi)存是什么樣的呢?

??有人可能會說,結(jié)構(gòu)體的內(nèi)存大小不就是其中的元素有多少,將每個元素的大小算出來相加嗎,數(shù)組里面就是元素的個數(shù)乘元素大小就得到了內(nèi)存大小

答案真的是這樣嗎,如果這樣簡單就不會有人說結(jié)構(gòu)體內(nèi)存很難算了。
回歸正題,讓我們來進(jìn)入結(jié)構(gòu)體世界來看看到底是怎么存儲的。

1.6.1 結(jié)構(gòu)體內(nèi)存對齊規(guī)則

??要想算出結(jié)構(gòu)體的內(nèi)存空間大小
首先得掌握結(jié)構(gòu)體的對齊規(guī)則:

  1. 第一個成員存儲在與結(jié)構(gòu)體變量偏移量為0的地址處。
  2. 其他成員變量要對齊到某個數(shù)字(對齊數(shù))的整數(shù)倍的地址處。
    對齊數(shù) = 編譯器默認(rèn)的一個對齊數(shù)與該成員大小的較小值。
  • VS中默認(rèn)的值為8
  • Linux中沒有默認(rèn)對齊數(shù),對齊數(shù)就是成員自身的大小
  1. 結(jié)構(gòu)體總大小為最大對齊數(shù)(每個成員變量都有一個對齊數(shù))的整數(shù)倍。
  2. 如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整
    體大小就是所有最大對齊數(shù)(含嵌套結(jié)構(gòu)體的對齊數(shù))的整數(shù)倍。

為什么存在內(nèi)存對齊?
大部分的參考資料都是如是說的:

  1. 平臺原因(移植原因):
    不是所有的硬件平臺都能訪問任意地址上的任意數(shù)據(jù)的;某些硬件平臺只能在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。
  2. 性能原因:
    數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對齊。
    原因在于,為了訪問未對齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問;而對齊的內(nèi)存訪問僅需要一次訪問。

總體來說:
結(jié)構(gòu)體的內(nèi)存對齊是拿空間來換取時間的做法。

1.6.2 內(nèi)存計算實例

??正所謂實踐是檢驗真理的唯一標(biāo)準(zhǔn),我們知道了其內(nèi)存對齊的規(guī)則,但是沒有實際操作也是不行的,我們通過下面幾個例子來學(xué)習(xí)


例1

struct S1
{
	char c1;
	int i;
	char c2;
};
printf("%d\n", sizeof(struct S1));

我們通過內(nèi)存對齊規(guī)則來一個一個看:
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
我們來輸出結(jié)果看看最后的內(nèi)存大小是不是12
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
沒錯就是12,證明我們算的是正確的
第一次總是很艱難,我們再來多實踐幾次


例2

struct S2
{
	char c1;
	char c2;
	int i;
};

我們接著通過對齊規(guī)則看:
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
我們計算出結(jié)果為8
輸出結(jié)果看一看是不是一致的
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
結(jié)果果然為8
隨著我們的實踐,是不是結(jié)構(gòu)體內(nèi)存空間的計算變的逐漸簡單起來了?


例3

struct S3
{
	double d;
	char c;
	int i;
};

詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言

再來看在vs上的輸出結(jié)果
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
結(jié)果正確
是不是很簡單?


例4

最后我們來看一個結(jié)構(gòu)體嵌套問題,我們應(yīng)該怎么求

struct S4
{
	char c1;
	struct S3 s3;
	double d;
};

詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
我們來看輸出結(jié)果:
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
答案就是我們的32


1.7 修改默認(rèn)對齊數(shù)

??這里介紹 #pragma 這個預(yù)處理指令,可以改變我們的默認(rèn)對齊數(shù)。
我們在代碼里面介紹這個用法:

#include <stdio.h>
#pragma pack(8)//設(shè)置默認(rèn)對齊數(shù)為8
struct S1
{
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消設(shè)置的默認(rèn)對齊數(shù),還原為默認(rèn)
#pragma pack(1)//設(shè)置默認(rèn)對齊數(shù)為1
struct S2
{
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消設(shè)置的默認(rèn)對齊數(shù),還原為默認(rèn)
int main()
{
  //輸出的結(jié)果是什么?
  printf("%d\n", sizeof(struct S1));
  printf("%d\n", sizeof(struct S2));
  return 0;
}

我們可以通過上面方法的計算,這里我不再演示
通過對齊數(shù)的改變我們算出S1的大小為12,S2的大小為6
看我們的輸出結(jié)果:
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
結(jié)果的的確確是我們改變過后算出的答案。
結(jié)論:

結(jié)構(gòu)在對齊方式不合適的時候,我們可以自己更改默認(rèn)對齊數(shù)。


1.8 結(jié)構(gòu)體傳參

直接上代碼:

struct S
{
	int data[1000];
	int num;
};
struct S s = {{1,2,3,4}, 1000};
//結(jié)構(gòu)體傳參
void print1(struct S s)
{
	printf("%d\n", s.num);
}
//結(jié)構(gòu)體地址傳參
void print2(struct S* ps)
{
	printf("%d\n", ps->num);
}
int main()
{
	print1(s);  //傳結(jié)構(gòu)體
	print2(&s); //傳地址
	return 0;
}

上面的 print1 和 print2 函數(shù)哪個好些?
答案是:首選print2函數(shù)。
原因:
函數(shù)傳參的時候,參數(shù)是需要壓棧,會有時間和空間上的系統(tǒng)開銷。
如果傳遞一個結(jié)構(gòu)體對象的時候,結(jié)構(gòu)體過大,參數(shù)壓棧的的系統(tǒng)開銷比較大,所以會導(dǎo)致性能的下降。
??結(jié)論:
結(jié)構(gòu)體傳參的時候,要傳結(jié)構(gòu)體的地址。


2. 位段

??結(jié)構(gòu)體講完就得講講結(jié)構(gòu)體實現(xiàn) 位段 的能力。

結(jié)構(gòu)體里面我們可以發(fā)現(xiàn),我們之前算過的很多結(jié)構(gòu)體都是有很多的內(nèi)存浪費的,因為在結(jié)構(gòu)體里面我們需要考慮每個結(jié)構(gòu)體成員的對齊數(shù),在考慮了對齊數(shù)之后我們才可以進(jìn)行存儲,那我們?nèi)绾蜗朕k法節(jié)省空間呢?
這就是位段解決的問題
??位段就是用來給結(jié)構(gòu)體的成員給予固定的內(nèi)存大小給其存儲

2.1 什么是位段

位段的聲明和結(jié)構(gòu)是類似的,有兩個不同:

  • 1.位段的成員必須是 int、unsigned int 或signed int 。
  • 2.位段的成員名后邊有一個冒號和一個數(shù)字。

比如:

struct A
{                         //二進(jìn)制
	int _a:2;             //2比特位
	int _b:5;			  //5比特位
	int _c:10;            //10比特位
	int _d:30;            //30比特位
};

A就是一個位段類型。
那位段A的大小是多少?
我們輸出一下A的大小

詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
輸出結(jié)果為8個字節(jié)

我們口頭計算一下所有成員的大小之和,2+5+10+30=47比特位
一個字節(jié)為8個比特位,那么我們需要應(yīng)該需要8*6=48,6個字節(jié)才對,為什么是8個字節(jié)呢?
??接下來我們來看看位段是如何存儲數(shù)據(jù)的:

2.2 位段的內(nèi)存分配

  1. 位段的成員可以是 int unsigned int signed int 或者是 char (屬于整形家族)類型
  2. 位段的空間上是按照需要以4個字節(jié)( int )或者1個字節(jié)( char )的方式來開辟的。
  3. 位段涉及很多不確定因素,位段是不跨平臺的,注重可移植的程序應(yīng)該避免使用位段。
//一個例子
struct S
{
	char a:3;
	char b:4;
	char c:5;
	char d:4;
};
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
//空間是如何開辟的?

詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
對比一下我們的答案:
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
我們的計算是對的

2.3 位段的跨平臺問題

  1. int 位段被當(dāng)成有符號數(shù)還是無符號數(shù)是不確定的。
  2. 位段中最大位的數(shù)目不能確定。(16位機器最大16,32位機器最大32,寫成27,在16位機器會出問題。
  3. 位段中的成員在內(nèi)存中從左向右分配,還是從右向左分配標(biāo)準(zhǔn)尚未定義。
  4. 當(dāng)一個結(jié)構(gòu)包含兩個位段,第二個位段成員比較大,無法容納于第一個位段剩余的位時是舍棄剩余的位還是利用,這是不確定的。

??總結(jié):
跟結(jié)構(gòu)相比,位段可以達(dá)到同樣的效果,并且可以很好的節(jié)省空間,但是有跨平臺的問題存在。

2.4 位段的應(yīng)用

我們?nèi)绻麑W(xué)習(xí)過計算機網(wǎng)絡(luò),里面講述過IP數(shù)據(jù)報的格式
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
里面的幾位幾位都是用比特來做單位的,就是使用位段,才能將其中的每個部分都精確到比特位存儲。
這樣操作不僅僅節(jié)省空間,也節(jié)省了很多時間

3. 枚舉

??枚舉顧名思義就是一一列舉。
把可能的取值一一列舉。
比如我們現(xiàn)實生活中:
一周的星期一到星期日是有限的7天,可以一一列舉。
性別有:男、女、保密,也可以一一列舉。
月份有12個月,也可以一一列舉
這里就可以使用枚舉了。

3.1 枚舉類型的定義

enum Day//星期
{
	Mon,
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun
};
enum Sex//性別
{
	MALE,
	FEMALE,
	SECRET
};
enum Color//顏色
{
	RED,
	GREEN,
	BLUE
};

以上定義的 enum Day , enum Sex , enum Color 都是枚舉類型。
{}中的內(nèi)容是枚舉類型的可能取值,也叫 枚舉常量 。


注意

    1. 每個成員變量中間需要以逗號(,)隔開
    1. 如果我們沒有給其中的變量賦初值的話,枚舉是會從首元素開始從0開始枚舉。從上往下依次遞加賦值,比如:在枚舉變量Day里,我們并沒有給其中任何一個變量賦初值,那么Mon的值就為0,Tues的值為1,以此類推

當(dāng)然在聲明枚舉類型的時候也可以賦初值。
例如:

enum Day//星期
{
	Mon=1,
	Tues,
	Wed,
	Thur=10,
	Fri,
	Sat,
	Sun
};

我們來依次打印每個值:
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
??我們可以發(fā)現(xiàn),在前面的變量賦值之后,后面的變量會在其基礎(chǔ)上進(jìn)行枚舉,這也是枚舉的特點

3.2 枚舉的優(yōu)點

為什么使用枚舉?
我們可以使用 #define 定義常量,為什么非要使用枚舉?
??枚舉的優(yōu)點:

  1. 增加代碼的可讀性和可維護(hù)性
  2. 和#define定義的標(biāo)識符比較枚舉有類型檢查,更加嚴(yán)謹(jǐn)。
  3. 便于調(diào)試
  4. 使用方便,一次可以定義多個常量

3.3 枚舉的使用

enum Color//顏色
{
	RED=1,
	GREEN=2,
	BLUE=4
};
int main()
{
	enum Color cl=RED;         //枚舉變量的定義,我們想給cl為RED,就定義RED,想給GREEN也可以
{

我們給cl賦值為5,這樣賦值可以嗎?
我們試試:

enum Color//顏色
{
	RED=1,
	GREEN=2,
	BLUE=4
};
int main()
{
	enum Color cl=5;         
{

編譯器出現(xiàn)了報錯
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
我們是不可以這樣進(jìn)行賦值的,只能使用枚舉里的變量值


4. 聯(lián)合(共用體)

4.1 聯(lián)合類型的定義

聯(lián)合也是一種特殊的自定義類型
??這種類型定義的變量也包含一系列的成員,特征是這些成員公用同一塊空間(所以聯(lián)合也叫共用體)。
比如:

//聯(lián)合類型的聲明
union Un
{
	char c;
	int i;
};
int main()
{
	//聯(lián)合變量的定義
	union Un un;
	//計算這個變量的大小
	printf("%d\n", sizeof(un));
	return 0;
}

如果是結(jié)構(gòu)體變量,un的大小根據(jù)內(nèi)存對齊計算為8
我們來看聯(lián)合體un的大小是多少
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
我們發(fā)現(xiàn)是4,一個char一個int加起來都有5個字節(jié)了,它的大小竟然是4??
我們來看其中變量存儲的地址為多少:
詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言

我們可以看到,聯(lián)合體中兩個變量使用的是同一塊地址
這正是聯(lián)合體的特點:
內(nèi)部成員共用一塊地址,彼此的改變會互相影響

4.2 聯(lián)合的特點

聯(lián)合的成員是共用同一塊內(nèi)存空間的,這樣一個聯(lián)合變量的大小,至少是最大成員的大小(因為聯(lián)合至少得有能力保存最大的那個成員)。

union Un
{
	int i;
	char c;
};
int main()
{
	union Un un;
	// 下面輸出的結(jié)果是一樣的嗎?
	printf("%d\n", &(un.i));
	printf("%d\n", &(un.c));
	//下面輸出的結(jié)果是什么?
	un.i = 0x11223344;
	un.c = 0x55;
	printf("%x\n", un.i);
	return 0;
}

詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
前面的地址一模一樣我們不足為奇
可是i的十六進(jìn)制我們賦值為0x11223344
輸出的結(jié)果為11223355
我們的i為int類型,占4個字節(jié),我們的c為char占一個字節(jié),我們改變了c的值,改變了一個字節(jié)的內(nèi)容,我們的i中4個字節(jié)里也有個字節(jié)的內(nèi)容也被改變了,
所以輸出為11223355


4.3 聯(lián)合大小的計算

??聯(lián)合的大小至少是最大成員的大小。
當(dāng)最大成員大小不是最大對齊數(shù)的整數(shù)倍的時候,就要對齊到最大對齊數(shù)的整數(shù)倍。

  • 聯(lián)合的大小至少是最大成員的大小。
  • 當(dāng)最大成員大小不是最大對齊數(shù)的整數(shù)倍的時候,就要對齊到最大對齊數(shù)的整數(shù)倍。

比如:

union Un1
{
	char c[5];
	int i;
};
union Un2
{
	short c[7];
	int i;
};
//下面輸出的結(jié)果是什么?
printf("%d\n", sizeof(union Un1));
printf("%d\n", sizeof(union Un2));

詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合),c語言,windows,開發(fā)語言
輸出結(jié)果為8和16文章來源地址http://www.zghlxwxcb.cn/news/detail-602793.html

到了這里,關(guān)于詳解C語言自定義類型(結(jié)構(gòu)體,枚舉,聯(lián)合)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • C語言—自定義類型(結(jié)構(gòu)體、枚舉、聯(lián)合)

    C語言—自定義類型(結(jié)構(gòu)體、枚舉、聯(lián)合)

    結(jié)構(gòu)是一些值的集合,這些值稱為成員變量。結(jié)構(gòu)的每個成員可以是不同類型的變量。 實例一(描述一本書): 在聲明結(jié)構(gòu)的時候,可以不完全的聲明。 實例一: 注:匿名結(jié)構(gòu)體類型創(chuàng)建好之后只能用一次(沒有標(biāo)簽構(gòu)不成結(jié)構(gòu)體類型) 實例一: 注:在結(jié)構(gòu)中包含一個類型

    2024年02月06日
    瀏覽(19)
  • 【C語言】自定義類型:結(jié)構(gòu)體、枚舉、聯(lián)合

    【C語言】自定義類型:結(jié)構(gòu)體、枚舉、聯(lián)合

    目錄 前言: 一、結(jié)構(gòu)體 (1)結(jié)構(gòu)體的特殊聲明 (2)結(jié)構(gòu)體的自引用 (3)結(jié)構(gòu)體嵌套初始化 (4)結(jié)構(gòu)體內(nèi)存對齊 (5)修改默認(rèn)對齊數(shù) (6)結(jié)構(gòu)體傳參 (7)位段 二、枚舉 (1)枚舉的定義 (2)枚舉的優(yōu)點 (3)枚舉的使用 三、聯(lián)合(共用體) (1)聯(lián)合類型的定義 (

    2024年02月16日
    瀏覽(20)
  • 【進(jìn)階C語言】自定義類型:結(jié)構(gòu)體,枚舉,聯(lián)合

    【進(jìn)階C語言】自定義類型:結(jié)構(gòu)體,枚舉,聯(lián)合

    前言 作者簡介: 熱愛跑步的恒川 ,正在學(xué)習(xí)C/C++、Java、Python等。 本文收錄于 C語言進(jìn)階 系列,本專欄主要內(nèi)容為數(shù)據(jù)的存儲、指針的進(jìn)階、字符串和內(nèi)存函數(shù)的介紹、自定義類型結(jié)構(gòu)、動態(tài)內(nèi)存管理、文件操作等,持續(xù)更新! 相關(guān)專欄Python,Java等正在發(fā)展,拭目以待!

    2023年04月14日
    瀏覽(38)
  • 進(jìn)階C語言——自定義類型:結(jié)構(gòu)體,枚舉,聯(lián)合

    進(jìn)階C語言——自定義類型:結(jié)構(gòu)體,枚舉,聯(lián)合

    結(jié)構(gòu)是一些值的集合,這些值稱為成員變量。結(jié)構(gòu)的每個成員可以是不同類型的變量。 例如描述一個學(xué)生: 也可以寫成下面這樣: 在聲明結(jié)構(gòu)的時候,可以不完全的聲明。 比如: 上面的兩個結(jié)構(gòu)在聲明的時候省略掉了結(jié)構(gòu)體標(biāo)簽(tag)。 那么問題來了? 在上面代碼的基礎(chǔ)

    2023年04月09日
    瀏覽(18)
  • 【C語言進(jìn)階】自定義類型:結(jié)構(gòu)體,枚舉,聯(lián)合

    【C語言進(jìn)階】自定義類型:結(jié)構(gòu)體,枚舉,聯(lián)合

    1.1結(jié)構(gòu)體類的基礎(chǔ)知識 結(jié)構(gòu)是一些值的集合,這些值稱為成員變量。結(jié)構(gòu)的每個成員可以是不同類型的變量。 1.2結(jié)構(gòu)的聲明 例如描述一個學(xué)生: 1.3特殊的聲明 在聲明結(jié)構(gòu)的時候,可以不完全的聲明 上面的兩個結(jié)構(gòu)在聲明的時候省略掉了結(jié)構(gòu)體標(biāo)簽(tag) 當(dāng)我們使用匿名結(jié)

    2024年02月07日
    瀏覽(23)
  • C語言自定義類型 — 結(jié)構(gòu)體、位段、枚舉、聯(lián)合

    C語言自定義類型 — 結(jié)構(gòu)體、位段、枚舉、聯(lián)合

    本期主要對通訊錄三篇博客文章進(jìn)行補充 通訊錄文章:通訊錄系列文章 對 結(jié)構(gòu)體 進(jìn)行詳細(xì)介紹,其次講解位段、枚舉、聯(lián)合體 在C語言中,結(jié)構(gòu)是一種用戶自定義的數(shù)據(jù)類型,它可以由不同類型的數(shù)據(jù)成員組成,每個數(shù)據(jù)成員可以是不同的數(shù)據(jù)類型。 結(jié)構(gòu)的作用是將多個不

    2024年02月14日
    瀏覽(21)
  • 手撕自定義類型:結(jié)構(gòu)體,枚舉,聯(lián)合——【C語言】

    手撕自定義類型:結(jié)構(gòu)體,枚舉,聯(lián)合——【C語言】

    ? 在開始學(xué)習(xí)之前我們先來欣賞一下五岳之一華山的風(fēng)景,來營造一個好心情,只有一個好心情我們才能更好的學(xué)習(xí) 目錄 結(jié)構(gòu)體 1 結(jié)構(gòu)體的聲明 1.1 結(jié)構(gòu)的基礎(chǔ)知識 1.2 結(jié)構(gòu)的聲明 1.3 特殊的聲明 1.4 結(jié)構(gòu)的自引用 1.5 結(jié)構(gòu)體變量的定義和初始化? 1.6 結(jié)構(gòu)體內(nèi)存對齊(重點)

    2024年02月16日
    瀏覽(19)
  • 【C語言進(jìn)階】自定義類型之結(jié)構(gòu)體,枚舉和聯(lián)合

    【C語言進(jìn)階】自定義類型之結(jié)構(gòu)體,枚舉和聯(lián)合

    人一能之,己百之;人十能之,己千之。? ? ? ? ? ? ? ? ? ? ? ? ? ? ?——《中庸》 ? 目錄 一.結(jié)構(gòu)體 1.結(jié)構(gòu)的基礎(chǔ)知識 2.結(jié)構(gòu)體的聲明 3.結(jié)構(gòu)體成員的類型 4.結(jié)構(gòu)體變量的定義和初始化: 5.結(jié)構(gòu)體成員的訪問: 6.結(jié)構(gòu)體傳參? 7.結(jié)構(gòu)體內(nèi)存對齊:結(jié)構(gòu)體的大小 8.為什么要

    2023年04月23日
    瀏覽(26)
  • 【C語言】自定義類型:結(jié)構(gòu)體【結(jié)構(gòu)體內(nèi)存具詳細(xì)】,枚舉,聯(lián)合

    【C語言】自定義類型:結(jié)構(gòu)體【結(jié)構(gòu)體內(nèi)存具詳細(xì)】,枚舉,聯(lián)合

    ? 目錄 一、結(jié)構(gòu)體 1.結(jié)構(gòu)的聲明 ?2.特殊的聲明 3.結(jié)構(gòu)的自引用 4.結(jié)構(gòu)體變量的定義和初始化? ?5.結(jié)構(gòu)體內(nèi)存對齊(重點來了) 6.為什么會存在內(nèi)存對齊? 7.修改默認(rèn)對齊數(shù) 8.結(jié)構(gòu)體傳參 二、位段 1.什么是位段 2.位段的內(nèi)存分配 3.位段的跨平臺問題 三、枚舉 1.枚舉類型的定

    2024年02月07日
    瀏覽(23)
  • C/C++之自定義類型(結(jié)構(gòu)體,位段,聯(lián)合體,枚舉)詳解

    C/C++之自定義類型(結(jié)構(gòu)體,位段,聯(lián)合體,枚舉)詳解

    專欄分類:C語言初階? ? ??C語言程序設(shè)計————KTV? ? ? ?C語言小游戲? ? ?C語言進(jìn)階 C語言刷題 歡迎大家點贊,評論,收藏。 一起努力,一起奔赴大廠。 目錄 個人主頁:點我進(jìn)入主頁 ? 1.前言 2.結(jié)構(gòu)體 2.1結(jié)構(gòu)體聲明 2.2結(jié)構(gòu)體初始化 2.3結(jié)構(gòu)體的自引用 2,4結(jié)構(gòu)體的內(nèi)存

    2024年02月08日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包