中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C語言的struct結構體怎么創建

發布時間:2022-04-12 10:32:34 來源:億速云 閱讀:755 作者:iii 欄目:開發技術

本篇內容主要講解“C語言的struct結構體怎么創建”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“C語言的struct結構體怎么創建”吧!

一、本章重點

  • 創建結構體

  • typedef與結構體的淵源

  • 匿名結構體

  • 結構體大小

  • 結構體指針

  • 其他

二、創建結構體

先來個簡單的結構體創建

這就是一個比較標準的結構體

struct people
{
	int age;
	int id;
	char address[10];
	char sex[5];
};//不要少了分號。

需要注意的是不要少了分號。

那么這樣創建結構體呢?

struct phone
{
	char brand[10];//品牌
	int price;//價格
};
 
struct people
{
	int age;
	int id;
	char address[10];
	char sex[5];
	struct phone;
};

很顯然,一個結構體是能夠嵌套另一個結構體的。

沒有這樣的設計,這樣做也行

struct people
{
	int age;
	int id;
	char address[10];
	char sex[5];
	char phone_brand[10];
	int phone_price;
};

但結構體中成員太多了是不利于我們后期的維護的,試問:假設有1000個成員,你能快速的找出你需要的成員嗎?當有了分塊的結構體,我們是能夠迅速的定位和查看的。

????結構體能夠嵌套另一結構體,那么結構體能否嵌套自己呢?

struct phone
{
	char brand[10];
	int price;
	struct phone;
};

這樣做之后編譯器會給你一個報錯

C語言的struct結構體怎么創建

原因是什么呢?

因為這個結構體的大小是未定義的,你能算出這個結構體的大小嗎?這是不可能的!

既然大小不能確定,那么當你用這個結構體去創建變量,編譯器該為這個變量開辟多大的空間呢?所有編譯器在設計之初便杜絕了這種可能。

在提一個問題,結構體是否可以嵌套自己的結構體指針呢?

struct people
{
	int age;
	int id;
	char address[10];
	char sex[5];
	struct people* son[2];
};

答案是:可以

這里并不存在空間該分配多少的問題,因為struct people*是指針類型,它的大小是確定的,在32位機器下是4字節,64為機器是8字節。

三、typedef與結構體的淵源

先上一段代碼

struct people
{
	int age;
	int id;
}a;//a代表什么?
 
 
int main()
{
	a.age = 20;
	printf("%d\n", a.age);
	return 0;
}

提問:a代表什么?

其實我們可以這樣去看這個問題

struct people{int age;int id;} a;
 
 
int main()
{
	a.age = 20;
	printf("%d\n", a.age);
	return 0;
}

對比int b呢?

int b;
struct people{int age;int id;} a;
 
 
int main()
{
	a.age = 20;
	printf("%d\n", a.age);
	return 0;
}

顯然,struct people{int age;int id;}代表的是結構體類型,就像整形類型一樣去創建變量。

那么這里的a就是結構體創建的變量。

這里也能明白結構體創建的最后為什么要保留分號。

那我們再看一段代碼:

typedef struct people
{
	int age;
	int id;
}a;
 
 
int main()
{
	a.age = 20;
	printf("%d\n", a.age);
	return 0;
}

此時加上typedef,a還能當結構體創建的變量嗎?

顯然不行,此時編譯器會報錯。

C語言的struct結構體怎么創建

 理解方式以上述一致。

typedef struct people{int age;int id;} a;

類似于

typedef struct people{int age;int id;} a;
typedef int b;

此時的a就是struct people{int age;int id;}

typedef的作用是把struct people{int age;int id;}這一類型重命名為a。

不知道你有沒有見過這樣的代碼

typedef struct people
{
	int age;
	int id;
}b,a,*c;
 
int main()
{
	a a1;
	b b1;
	c c1 = &a1;
	a1.age = 5;
	b1.age = 6;
	c1->age = 10;
	printf("%d %d %d\n", a1.age, b1.age, c1->age);
	return 0;
}

你知道運行結果嗎?

這里的b、a、c是什么呢?

這里我就不啰嗦了,a和b都是struct people{int age;int id;}結構體類型,c是struct people{int age;int id;}*  結構體指針類型。

運行結果:

C語言的struct結構體怎么創建

那么再次提升一下

typedef struct people
{
	int age;
	int id;
}b, a, c[20];
這里的b、a、c代表什么呢?

期待著你動手解決這一問題。

四、匿名結構體

這就是一個匿名的結構體

struct
{
	int age;
	int id;
};
 
int main()
{
	struct p1;
	p1.age = 10;
	printf("%d\n", p1.age);
	return 0;
}

匿名結構體能這樣創建結構體變量嗎?

此時編譯器會報錯

C語言的struct結構體怎么創建

這樣的匿名結構體只能在創建結構體的時候定義好變量。

比如這樣

struct
{
	int age;
	int id;
}p1;
 
int main()
{
	p1.age = 10;
	printf("%d\n", p1.age);
	return 0;
}

C語言的struct結構體怎么創建

 接下來我們看下這段代碼

typedef struct
{
	int age;
	int id;
}people;
 
int main()
{
	people p1;
	p1.age = 10;
	printf("%d\n", p1.age);
	return 0;
}

這里我們重命名這個匿名結構體,即把這個結構體類型重命名為people。

那么我們自然可以用people類型來創建p1。也可創建p2、p3等等。

運行結果:

C語言的struct結構體怎么創建

以下代碼合法嗎?

//匿名結構體類型
struct
{
 int a;
 char b;
 float c; 
}x;
 
struct
{
 int a;
 char b;
 float c; 
}a[20], *p;
 
int main()
{
    //在上面代碼的基礎上,下面的代碼合法嗎?
    p = &x;
    return 0;
}

警告: 編譯器會把上面的兩個聲明當成完全不同的兩個類型。 所以是非法的。

五、結構體大小

如何求結構體類型的大小?

這需要了解結構體成員在內存是怎么存儲的。

你知道下面這段代碼的運行結果嗎?

struct people
{
	char a;
	int b;
	char c;
};
 
int main()
{
	struct people p1;
	printf("%d\n", sizeof(p1));//大小是6嗎?
	return 0;
}

char是一字節大小

int是四字節大小

char是一字節大小

直接相加等于6

那么這個結構體的大小是6嗎?

但我們發現答案是12

C語言的struct結構體怎么創建

這是為什么呢?

簡單來說編譯器為了讀取內存時提升效率和避免讀取出錯,它做了內存對齊的操作。

什么是內存對齊?

就是讓數據安排在合適的位置上所進行的對齊操作。

為什么要內存對齊?

  • 一、移植原因

1.不是所有的硬件平臺都能訪問任意地址上的任意數據的;

2.某些硬件平臺只能在某些地址處取某些特定類型的數據,否則拋出硬件異常。

  • 二、性能原因:

為了訪問未對齊的內存,處理器需要作兩次內存訪問;而對齊的內存訪問僅需要一次訪問。

對齊規則:

Windows中默認對齊數為8,Linux中默認對齊數為4

  • 一:第一個數據成員從偏移地址為0的地方開始存放。

  • 二:對齊數:等于默認對齊數與與該成員大小的較小值。

  • 三:從第二成員開始,從它對齊數的整數倍的偏移地址開始存放。

  • 四:最后結構體的大小需要調整為最大對齊數的整數倍。

最大對齊數:即所有成員對齊數中最大的對齊數。

struct people
{
	char a;
	int b;
	char c;
};

C語言的struct結構體怎么創建

解析:

第一個為char,直接放在偏移地址為0的位置處。

第二個為int,它的自身大小為4,比默認對齊數小,所以它的對齊數是4。

4是4的整數倍,所以在偏移地址為4處開始放數據。

第三個為char,自身大小為1,比默認對齊數小,它的對齊數是1。

8是1的整數倍,從偏移地址為8的位置開始放。

總大小為9,不是最大對齊數的整數倍

要浪費3個空間,調整后為12。

我們再看看下面這段代碼:

將char 和 int成員變量交換位置后,這結構體的大小還是12嗎?

struct people
{
	char a;
	char c;
	int b;
};
 
int main()
{
	struct people p1;
	printf("%d\n", sizeof(p1));//大小是多少呢?
	return 0;
}

C語言的struct結構體怎么創建

解析:

第一個:直接從0處開始放

第二個是char:對齊數是1,1是1的整數倍,從偏移地址為1的位置開始放。

第二個是int:對齊數是4,4是4的整數倍,從偏移地址為4的位置開始放。

放好各個成員變量后,總大小是8,是最大對齊數(4)的整數倍,不需要調整。

因此這個結構體的大小是8.

C語言的struct結構體怎么創建

再來看看下面這個如何?

struct people
{
	char a;
	int b;
	short c[2];
	char d;
};
 
int main()
{
	struct people p1;
	printf("%d\n", sizeof(p1));//大小是6嗎?
	return 0;
}

C語言的struct結構體怎么創建

解析:

第一個成員是char,直接放再0地址處。

第二個成員是int,對齊數是4,從偏移地址為4的位置處開始存放。

第三個成員是short[2],關于數組,它的對齊數是首元素的大小與默認對齊數的較小值,這里它的對齊數是2,然后從偏移地址為8處開始存放4個字節。

第四個成員是char,對齊數是1,直接放開12位置處。

總大小是13,最大對齊數是4,不是最大對齊數的整數倍,需要對齊到最大對齊數的整數倍,浪費3字節大小,對齊到16.

所以這個結構體的大小是16.

六、結構體指針

先創建一個結構體

struct people
{
	char a;
	int b;
};

然后用該結構體創建變量,再用結構體指針指向該變量。

int main()
{
	struct people p1;
	struct people* p = &p1;
	return 0;
}

所謂結構體指針,即指向結構體的指針。

正如整形指針,即指向整形的指針。

訪問變量方式1:

int main()
{
	struct people p1;
	struct people* p = &p1;
	p1.a = 'a';
	p1.b = 10;
	printf("%c %d\n", p1.a, p1.b);
	return 0;
}

訪問變量方式2:

int main()
{
	struct people p1;
	struct people* p = &p1;
	p->a = 'a';
	p->b = 10;
	printf("%c %d\n", p->a, p->b);
	return 0;
}

訪問變量方式3:

int main()
{
	struct people p1;
	struct people* p = &p1;
	(*p).a = 'a';
	(*p).b = 10;
	printf("%c %d\n", (*p).a, (*p).b);
	return 0;
}

到此,相信大家對“C語言的struct結構體怎么創建”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

讷河市| 兴山县| 青冈县| 定安县| 吉安市| 惠安县| 虎林市| 改则县| 英德市| 张家川| 奉节县| 阳原县| 峨眉山市| 苏州市| 新乐市| 南宁市| 育儿| 弋阳县| 灵川县| 沿河| 洪泽县| 东山县| 周口市| 遂平县| 汝州市| 信丰县| 阳高县| 观塘区| 桑日县| 黔西县| 新田县| 通化市| 多伦县| 林芝县| 辰溪县| 闸北区| 萨嘎县| 巩义市| 东丽区| 信丰县| 普安县|