欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言自定義類型全解析

 更新時間:2022年02月10日 11:27:59   作者:誠摯的喬治  
在C語言中自定義類型主要有結(jié)構(gòu)體類型、位段、枚舉類型、聯(lián)合體類型,自定義類型是面試常會碰到的內(nèi)容,今天我們來詳細(xì)了解一下它

前言

初學(xué)C語言

我們先接觸的都是內(nèi)置的類型

比如說int char short float double long等等

這一期就來聊一聊自定義類型的知識

結(jié)構(gòu)體類型

首先我們要知道什么是結(jié)構(gòu)體

結(jié)構(gòu)體就是各種值集合

這些值被稱作結(jié)構(gòu)體成員,這些成員可包括各種不同的類型

struct tag         //這里的struct是結(jié)構(gòu)體的關(guān)鍵字,tag是結(jié)構(gòu)體標(biāo)簽,也就是結(jié)構(gòu)體的名稱
{
	number - list; //結(jié)構(gòu)體成員列表
}veriable-list;    //結(jié)構(gòu)體的變量 

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

如果結(jié)構(gòu)體的標(biāo)簽是student,我拿student來舉例子

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

struct Student
{
    char name[20];//姓名
    char sex;//性別
    int age;//年齡
    int num;//學(xué)號
};   //這里的分號不能丟

結(jié)構(gòu)體的不完全聲明(匿名結(jié)構(gòu)體類型)

struct
{
	int a;
	char b;
	double c;
}s;   //這s不能省略

匿名結(jié)構(gòu)體的特點(diǎn)就是沒有結(jié)構(gòu)體標(biāo)簽

但這樣寫用戶使用時只能使用一次,也就是說只能在結(jié)構(gòu)體聲明時就定義變量

因?yàn)槟阏也坏浇Y(jié)構(gòu)體標(biāo)簽,就相當(dāng)于找不到門牌號一樣,無法再對其定義一個變量

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

結(jié)構(gòu)體的定義大致分為三種情況

<1>結(jié)構(gòu)體聲明的同時定義

struct Student 
{
    char name[20];//姓名
    char sex[20];//性別
    int age;//年齡
}s={"zhangsan","nan",20};

<2>結(jié)構(gòu)體先聲明,再定義

#include<stdio.h>
struct Student
{
    char name[20];//姓名
    char sex;//性別
    int age;//年齡
    int num;//學(xué)號
};
 
 
int main()
{
    struct Student s = { "zhangsan",'w',20,111 };
	return 0;
}

<3>匿名結(jié)構(gòu)體定義

struct 
{
    char name[20];//姓名
    char sex[20];//性別
    int age;//年齡
} s = { "zhangsan","nan",20};

注意:結(jié)構(gòu)體初始化與數(shù)組相同,都必須整體進(jìn)行賦值。

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

struct Node //初始話鏈表
{
	int a;
	struct Node next;
};

結(jié)構(gòu)體的自引用就是結(jié)構(gòu)體再套用自己

學(xué)過數(shù)據(jù)結(jié)構(gòu)的朋友應(yīng)該知道這是初始化鏈表

不過這一個代碼有問題的

問題在于無法求出這個結(jié)構(gòu)體的大小,不清楚這個結(jié)構(gòu)體有多大,因?yàn)闊o法求出自引用的結(jié)構(gòu)體有多大

所有自引用的結(jié)構(gòu)體要用指針來訪問

struct Node //初始話鏈表
{
	int a;
	struct Node* next;
};

故就可以通過指針來訪問每一個結(jié)點(diǎn)

結(jié)構(gòu)體的訪問

當(dāng)結(jié)構(gòu)體定義且變量初始化完成后,就可以通過操作符來訪問變量中的成員

當(dāng)然,這里給出了兩個操作符

分別是? .操作符和 -> 操作符

當(dāng)使用結(jié)構(gòu)體變量時,就用點(diǎn)操作符,當(dāng)訪問結(jié)構(gòu)體指針變量就用箭頭操作符

(1)通過結(jié)構(gòu)體變量進(jìn)行訪問:

printf("%s\n",s.name);

(2)通過結(jié)構(gòu)體指針進(jìn)行訪問:

printf("%s\n",ps->name);

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

函數(shù)的調(diào)用有時候需要傳一些參數(shù)

參數(shù)的類型可以是不同的類型,可以是數(shù)組,也可以是指針

同樣結(jié)構(gòu)體的傳參也可通過傳結(jié)構(gòu)體或者傳指針

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

#include<stdio.h>  
struct tag
{
	int a;
	char b[20];
}s1 = { 100,"abcdef" };
void print()
{
	printf("%d", s1.a);
}
int main()
{
	print(s1);
	return 0;
}

傳地址

#include<stdio.h>
struct tag
{
	int a;
	char b[20];
}s2 = { 100,"abcdef" };
void print(struct tag*s2)
{
	printf("%d", s2->a);
}
int main()
{
	print(&s2);
	return 0;
}

我們要知道函數(shù)傳參是形參就是實(shí)參的臨時拷貝

參數(shù)是要壓棧的(向系統(tǒng)申請空間),既然是臨時拷貝,就會再次再棧上開辟空間,當(dāng)實(shí)參足夠大時,顯然會浪費(fèi)一定的空間和時間

相比較與傳結(jié)構(gòu)體,傳指針會更好?

結(jié)構(gòu)體的內(nèi)存對齊(強(qiáng)烈建議觀看)

在另外一篇文章詳細(xì)講過——C語言結(jié)構(gòu)體中內(nèi)存對齊的問題理解

位段

可能有人沒有聽過什么是位段

位段的結(jié)構(gòu)類型跟結(jié)構(gòu)體有些類似可以類似結(jié)構(gòu)體去學(xué)習(xí)

也可以說

位段是結(jié)構(gòu)體特殊的實(shí)現(xiàn)

位段的聲明

相較于結(jié)構(gòu)體,位段的聲明有兩點(diǎn)不同

<1>規(guī)定位段的成員的必須是int,unsigned int ,signed int (但是寫成char類型也沒什么大的問題)

<2>位段的成員后面有一個冒號和一個數(shù)字

struct A  //位段的聲明
{
	int _a : 2;
	int _b : 5;
	int _c : 10;
	int _d : 30;
};

位段的內(nèi)存管理

#include<stdio.h>
struct A
{
	int a : 2;
	int b : 5;
	int c : 10;
	int d : 30;
};
int main()
{
	
	printf("大小是%d字節(jié)", sizeof(struct A));
	return 0;
}

為什么位段的大小是八個字節(jié)呢?

成員內(nèi)包含的數(shù)字代表的是這個成員需要利用的內(nèi)存,單位是bit。

位段成員申請內(nèi)存時都是以四個字節(jié)或者一個字節(jié)單位(當(dāng)成員是char類型時)

int a : 2; //申請4個字節(jié),也就是32個bit位,利用兩個還剩30個
int b : 5; //利用5個,還剩25個
int c : 10; //利用10個,還剩15個
int d : 30; //這里的十五不夠,所以再申請了4個字節(jié)

最終的結(jié)果就是八字節(jié)

但問題是,變量d利用的空間是留下的15個bit加上重新申請的空間呢

這個結(jié)果在不同的環(huán)境的結(jié)果是不同的,所以位段的跨平臺性比較差

位段使用的前提是你知道存儲的內(nèi)存大概有多大

就比如說年齡

十個bit位0111111111,最大值就可以達(dá)到1023

就不需要再申請一次利用一個int類型的空間大小

這就達(dá)到了節(jié)省內(nèi)存的作用,存在即合理

位段的應(yīng)用?

struct A
{
	char a : 3;
	char b : 4;
	char c : 5;
};
main()
{
	struct A s = { 0 };
	s.a = 10;
	s.b = 12;
	s.c = 3;
	return 0;
}

位段的跨平臺性

1.int位段被當(dāng)成有符號數(shù)還是無符號數(shù)是不確定的,有時候系統(tǒng)會自動轉(zhuǎn)化為無符號整形。

2.位段中最大位的數(shù)目不能確定。(因?yàn)樵谠缙诘?6位機(jī)器int最大16,而32位機(jī)器int最大32)

3.位段中的成員在內(nèi)存中從左向右分配,還是從右向左分配標(biāo)準(zhǔn)尚未定義。

意思當(dāng)內(nèi)存一個字節(jié)00000000,存入01010,可能會出現(xiàn)00001010或者01010000

4.當(dāng)一個結(jié)構(gòu)包含兩個位段,第二個位段成員比較大,無法容納于第一個位段剩余的位時,是 舍棄剩余的位還是利用,這是不確定的。

?枚舉類型

枚舉類型適用于可以一一列舉的類型

比如說星期、性別

枚舉類型的定義

enum Day   //星期
{
	//枚舉的可能取值
	Mon,
	Tues,
	Wed,
	Thir,
	Fri,
	Sta,
	Sun
};
enum Sex  //性別
{
	MALE,//0
	FEMALE,//1
	SECRET//2
};

枚舉類型是有初始值的

如果你沒賦予它初始值,就會默認(rèn)從零開始,依次加一

枚舉類型賦予初始值

#include<stdio.h>
enum Sex  //性別
{
	MALE = 4,
	FEMALE=10,
	SECRET//
};
main()
{
	printf("%d %d %d", MALE,FEMALE,SECRET);
	return 0;
}

可以看到,其實(shí)默認(rèn)的值是可以改的

當(dāng)某個成員被賦予某個值的時候,后續(xù)的成員就在此基礎(chǔ)上加一

枚舉類型的優(yōu)點(diǎn)

1.相較于數(shù)字,枚舉增加代碼的可讀性和可維護(hù)性

2.和#define定義的標(biāo)識符比較枚舉有類型檢查,更加嚴(yán)謹(jǐn)。

3.防止了命名污染(封裝)

4.便于調(diào)試

5.使用方便,一次可以定義多個常量

聯(lián)合體類型

聯(lián)合體類型也叫共用體

聯(lián)合體的定義

union Un  
{
	int a;
	char b;
};

union是聯(lián)合體關(guān)鍵字,Un是聯(lián)合體的標(biāo)簽

聯(lián)合體的特點(diǎn)

共用體,顧名思義,這里的共用就是公用內(nèi)存

內(nèi)存的也可被折疊

#include<stdio.h>
union Un
{
	char c;
	int i;
};
int main()
{
	union Un u = {0};
	printf("%d\n", sizeof(u));
	printf("%p\n", &u);
	printf("%p\n", &(u.c));
	printf("%p\n", &(u.i));
	return 0;
}

他們有相同的地址

c和i存放在同一塊內(nèi)存空間上,修改c或者i都會影響到另一個成員。

?聯(lián)合體內(nèi)存大小的計(jì)算

<1>聯(lián)合體內(nèi)存大小是最大成員的大小

<2>最大成員的大小如果不是最大對齊數(shù)的整數(shù)倍,就會對齊到最大對齊數(shù)的整數(shù)倍

(聯(lián)合體也存在內(nèi)存對齊)

#include<stdio.h>
union Un1
{
	char c[5];  
	int i;
};          
//Un1成員最大成員大小5,最大對齊數(shù)是4,所以Un1的大小是8;
union Un2
{
	char c[7];
		int i;
};
//Un2成員最大成員大小7,最大對齊數(shù)是4,所以Un2的大小是8;
int main()
{
	printf("%d\n", sizeof(union Un1));
	printf("%d\n", sizeof(union Un2));
	return 0;
}

到此這篇關(guān)于C語言自定義類型全解析的文章就介紹到這了,更多相關(guān)C語言 自定義類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言版掃雷游戲

    C語言版掃雷游戲

    這篇文章主要為大家詳細(xì)介紹了C語言版掃雷游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • C++實(shí)現(xiàn)Dijkstra算法的示例代碼

    C++實(shí)現(xiàn)Dijkstra算法的示例代碼

    迪杰斯特拉算法(Dijkstra)是由荷蘭計(jì)算機(jī)科學(xué)家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是從一個頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法。本文將用C++實(shí)現(xiàn)Dijkstra算法,需要的可以參考一下
    2022-07-07
  • C++?左值引用與一級指針示例詳解

    C++?左值引用與一級指針示例詳解

    這篇文章主要介紹了C++?左值引用與一級指針,本文給大家介紹了C++?(左值)引用和指針簡介,結(jié)合示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • C/C++?Qt?數(shù)據(jù)庫與TableView實(shí)現(xiàn)多組件聯(lián)動

    C/C++?Qt?數(shù)據(jù)庫與TableView實(shí)現(xiàn)多組件聯(lián)動

    Qt?數(shù)據(jù)庫組件與TableView組件實(shí)現(xiàn)聯(lián)動效果,本文通過案例給大家講解的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-12-12
  • C語言中static的作用及C語言中使用靜態(tài)函數(shù)有何好處

    C語言中static的作用及C語言中使用靜態(tài)函數(shù)有何好處

    在C語言中,static的作用有三條:一是隱藏功能,二是保持持久性功能,三是默認(rèn)初始化為0。本文重點(diǎn)給大家介紹C語言中static的作用及c語言中使用靜態(tài)函數(shù)有何好處,對本文感興趣的朋友一起看看吧
    2015-11-11
  • 淺析C語言中typeof關(guān)鍵字用法

    淺析C語言中typeof關(guān)鍵字用法

    typeof關(guān)鍵字是C語言中的一個新擴(kuò)展。在linux內(nèi)核源代碼中廣泛使用。接下來通過本文給大家分享C語言中typeof關(guān)鍵字用法,需要的朋友參考下
    2017-02-02
  • 詳解C語言隨機(jī)數(shù)設(shè)置的三種方式(保姆級教程)

    詳解C語言隨機(jī)數(shù)設(shè)置的三種方式(保姆級教程)

    本篇文章將為大家介紹在C語言中設(shè)置隨機(jī)數(shù)的三大方法的使用,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C語言有一定的幫助,需要的可以參考一下
    2022-11-11
  • C++實(shí)現(xiàn)中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式

    C++實(shí)現(xiàn)中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)中綴表達(dá)式轉(zhuǎn)后綴表達(dá)式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • 詳解C/C++中new?A與new?A()的區(qū)別

    詳解C/C++中new?A與new?A()的區(qū)別

    這篇文章主要通過一些簡單的示例為大家詳細(xì)介紹一下C/C++中new?A與new?A()的區(qū)別,文中的示例代碼簡潔易懂,快跟隨小編一起學(xué)習(xí)起來吧
    2023-07-07
  • 用C語言實(shí)現(xiàn)簡易通訊錄

    用C語言實(shí)現(xiàn)簡易通訊錄

    這篇文章主要為大家詳細(xì)介紹了用C語言實(shí)現(xiàn)簡易通訊錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02

最新評論