最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言 自定義類型全面系統(tǒng)理解

 更新時間:2022年02月11日 09:51:44   作者:i跑跑  
在C語言中自定義類型主要有結(jié)構(gòu)體類型、位段、枚舉類型、聯(lián)合體類型,自定義類型是面試常會碰到的內(nèi)容,本篇文章帶你徹底解決自定義類型

一、結(jié)構(gòu)體

結(jié)構(gòu)體是不同類型變量的集合體

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

struct Book      
{
 char name[20];//名字
 int Price;//價格
 char Writer[5];//作者
 char Time[20];//日期
};    //注意分號不能丟

struct為結(jié)構(gòu)體關(guān)鍵字,Book為結(jié)構(gòu)體標(biāo)簽,中間不同類型的變量為結(jié)構(gòu)體的成員。上述現(xiàn)在只是定義了一個結(jié)構(gòu)體類型struct Book。

局部結(jié)構(gòu)體變量

int main()
{
   struct Book B1; // B1為局部結(jié)構(gòu)體變量
   return 0;
}

全局結(jié)構(gòu)體變量

struct Book      
{
 char name[20];
 int Price;
 char Writer[5];
 char Time[20];
}B3,B4,B5;      //在結(jié)構(gòu)體類型后可連續(xù)定義多個全局結(jié)構(gòu)體變量
 
struct Book B2;   //B2為全局結(jié)構(gòu)體變量
 
int main()
{
   return 0;
}

2.特殊聲明

不完全聲明

//匿名結(jié)構(gòu)體類型--沒有結(jié)構(gòu)體標(biāo)簽
struct
{
 int a;
 char b;
 float c;
}x;
//這樣的結(jié)構(gòu)體類型必須緊跟著定義結(jié)構(gòu)體變量
//后面不能定義變量

不完全聲明類型只能在定義使用一次,并且在vs中:

struct
{
 int a;
 char b;
 float c;
}x;
 
struct
{
 int a;
 char b;
 float c;
}* ps;
 
int main()
{
  ps=&x;      //編譯器默認兩者類型不兼容  //且是錯誤寫法
  return 0;
}

因此不完全聲明很少使用,不推薦。?

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

這里可以用鏈表的實現(xiàn)來理解:

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

這樣就實現(xiàn)了自己類型的對象找自己類型對象的方法,這就是結(jié)構(gòu)體的自引用。?

4.結(jié)構(gòu)體變量的初始化

以上面struct Book為例:

struct Book      
{
 char name[20];
 int Price;
 char Writer[5];
 char Time[20];
}; 
 
 
int main()
{
   struct Book B1={"三腳貓",50,“阿里”,“20081001”};
   //初始化要用大括號
   return 0;
}

嵌套結(jié)構(gòu)體的初始化:

struct Data
{
  int a;
  char b[6];
};
 
struct Book      
{
 struct Data D;
 char name[20];
 int Price;
 char Writer[5];
 char Time[20];
}; 
 
 
int main()
{
   struct Book B1={{4,"haha"},"三腳貓",50,"阿里","20081001"};
   //大括號里加大括號
   return 0;
}

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

計算結(jié)構(gòu)體在內(nèi)存中的大小

方法:

1. 第一個成員為起始,設(shè)從下標(biāo)為0的地址開始向后存儲。

2. 其他成員變量要對齊到對齊數(shù)的整數(shù)倍的地址處。 對齊數(shù) = 編譯器默認的一個對齊數(shù)與 該成員大小的較小值。 VS中默認的值為8

3. 結(jié)構(gòu)體總大小為所有成員對齊數(shù)中最大對齊數(shù)的整數(shù)倍。

4. 如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對齊數(shù)(含嵌套結(jié)構(gòu)體的對齊數(shù))的整數(shù)倍。

舉例說明:

#include <stdio.h>
struct S1
{
	char c1;
	int i;
	char c2;
};
 
struct S2
{
	char c1;
	char c2;
	int i;
};
 
int main()
{
	printf("%d\n", sizeof(struct S1));
	printf("%d\n", sizeof(struct S2));
	return 0;
}

分析:

嵌套結(jié)構(gòu)體

#include <stdio.h>
struct S1
{
	char c1;
	int i;
	char c2;
};
 
struct S2
{
	char c1;
	char c2;
	struct S1 s1;
	int i;
};
 
int main()
{
	printf("%d\n", sizeof(struct S1));
	printf("%d\n", sizeof(struct S2));
	return 0;
}

分析:

內(nèi)存對齊的存在,在平臺和性能兩方面,可以使訪問空間更加高效,用空間換取時間。

讓占用空間小的成員盡量集中在一起。

6.修改默認對齊數(shù)

#pragma pack(1)     //修改默認對齊數(shù)為1
 
//一般修改的對齊數(shù)為2^n

舉例說明:

#include <stdio.h>
#pragma pack(1)   //修改為1相當(dāng)于取消了對齊,沒有優(yōu)化,在實際應(yīng)用中很少用
struct S1
{
	char c1;
	int i;
	char c2;
};
int main()
{
	printf("%d\n", sizeof(struct S1));  // 6
	return 0;
}

當(dāng)默認對齊數(shù)被修改后,每個類型的對齊數(shù)都變?yōu)?,整體的最大對齊數(shù)也為1(相當(dāng)于沒有對齊),整體大小是1的倍數(shù),則1+4+1=6。

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

當(dāng)一個函數(shù)涉及到結(jié)構(gòu)體時,最好用傳址調(diào)用:

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;
}

傳址調(diào)用原因:

1.函數(shù)傳參的時候,參數(shù)是需要壓棧,會有時間和空間上的系統(tǒng)開銷。

2.如果傳遞一個結(jié)構(gòu)體對象的時候,結(jié)構(gòu)體過大,參數(shù)壓棧的的系統(tǒng)開銷比較大,所以會導(dǎo)致性能的下降。

二、位段

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

1.位段的成員必須是整型。

2.位段的成員名后邊有一個冒號和一個數(shù)字。

舉例:

struct S
{
 int _a:2;
 int _b:5;
 int _c:20;
 int _d:25;
};

此時S就是一個位段類型

他的大小為8

printf("%d\n", sizeof(struct S));

分析:

下面我們來分析位段在內(nèi)存中的存儲:

注:若初始化的值大于給其指定的空間,則先會發(fā)生截斷(斷左取右),再進行存儲

位段是根據(jù)實際需求來進行開辟空間,目的是為了節(jié)省空間提高效率。

跨平臺問題:

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)包含兩個位段,第二個位段成員比較大,無法容納于第一個位段剩余的位時,是 舍棄剩余的位還是利用,這是不確定的。

三、枚舉

就是把可能的取值一一列舉

枚舉類型的定義:

例子:

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

enum Day就是一個枚舉類型,{}中的內(nèi)容是枚舉類型的可能取值,也叫枚舉常量。

枚舉常量是有值的,默認從0開始,依次遞增。

int main()
{
   enum Day d=Mon;   //定義一個變量,賦予{}內(nèi)可能的取值。
   return 0;
}

在定義的時候也可以賦初值,后面的常量依次遞增一

枚舉的優(yōu)點?

1. 增加代碼的可讀性和可維護性

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

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

4. 便于調(diào)試

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

注:最好用枚舉常量給枚舉變量賦值,才不會出現(xiàn)類型上的差異。

舉例:

當(dāng)用cpp來運行程序時會報錯,因為cpp對代碼的格式會更加嚴格

而c就可以運行過去

養(yǎng)成良好的代碼風(fēng)格,做到認真嚴謹。

四、聯(lián)合

聯(lián)合也是一種特殊的自定義類型

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

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

2.聯(lián)合的特點?

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

union Un
{
	int i;
	char c;
};
union Un un;
 
int main()
{
	printf("%d\n", &(un.i));
	printf("%d\n", &(un.c));
	return 0;
}

共用一塊空間,起始地址相同。

使用案例:

union Un
{
	int i;
	char c;
};
union Un un;
 
int main()
{
	//printf("%d\n", &(un.i));
	//printf("%d\n", &(un.c));
	un.i = 0x11223344;
	un.c = 0x55;
	printf("%x\n", un.i);
	return 0;
}

分析:

3.聯(lián)合大小的計算?

聯(lián)合的大小至少是最大成員的大小。

當(dāng)最大成員大小不是最大對齊數(shù)的整數(shù)倍的時候,就要對齊到最大對齊數(shù)的整數(shù)倍。

舉例:

union Un1
{
	char c[5];
	int i;
};
union Un2
{
	short c[7];
	int i;
};
//下面輸出的結(jié)果是什么?
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語言數(shù)據(jù)結(jié)構(gòu) 棧的基礎(chǔ)操作

    C語言數(shù)據(jù)結(jié)構(gòu) 棧的基礎(chǔ)操作

    這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu) 棧的基礎(chǔ)操作的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • C語言實現(xiàn)遍歷文件夾中的文件

    C語言實現(xiàn)遍歷文件夾中的文件

    這篇文章主要為大家詳細介紹了如何使用C語言實現(xiàn)遍歷文件夾中的文件,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考一下
    2024-02-02
  • C++設(shè)計模式之享元模式(Flyweight)

    C++設(shè)計模式之享元模式(Flyweight)

    這篇文章主要為大家詳細介紹了C++設(shè)計模式之享元模式Flyweight,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • C語言:十進制,BCD碼互換詳解

    C語言:十進制,BCD碼互換詳解

    這篇文章主要介紹了C語言十進制,BCD碼互換實例,小編覺得這篇文章寫的還不錯,實例簡單明了,需要的朋友可以參考下
    2021-09-09
  • C++哈希表之線性探測法實現(xiàn)詳解

    C++哈希表之線性探測法實現(xiàn)詳解

    線性探測法的優(yōu)點:只要散列表未滿,總能找到一個不沖突的散列地址;缺點:每個產(chǎn)生沖突的記錄被散列到離沖突最近的空地址上,從而又增加了更多的沖突機會
    2022-05-05
  • C語言中格式化輸出符號%d、%c、%p、%x等詳解

    C語言中格式化輸出符號%d、%c、%p、%x等詳解

    格式化輸出在C語言中非常常用,提供了多種用法來控制輸出的格式,下面這篇文章主要給大家介紹了關(guān)于C語言中格式化輸出符號%d、%c、%p、%x等的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-06-06
  • opencv?C++模板匹配的簡單實現(xiàn)

    opencv?C++模板匹配的簡單實現(xiàn)

    這篇文章主要介紹了opencv?C++模板匹配的簡單實現(xiàn),本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • Qt數(shù)據(jù)庫應(yīng)用之實現(xiàn)通用數(shù)據(jù)庫清理

    Qt數(shù)據(jù)庫應(yīng)用之實現(xiàn)通用數(shù)據(jù)庫清理

    項目如果需要存儲很多日志記錄比如運行日志,時間長了記錄數(shù)量非常多,數(shù)據(jù)庫體積不斷增大,對應(yīng)數(shù)據(jù)庫表的增刪改查的效率不斷降低,因此需要將早期的數(shù)據(jù)清理。本文將詳細介紹一下通用數(shù)據(jù)庫清理的實現(xiàn),需要的可以參考一下
    2022-02-02
  • C語言實現(xiàn)K-Means算法

    C語言實現(xiàn)K-Means算法

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)K-Means算法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • C語言的程序環(huán)境與預(yù)處理你真的了解嗎

    C語言的程序環(huán)境與預(yù)處理你真的了解嗎

    這篇文章主要為大家詳細介紹了C語言的程序環(huán)境與預(yù)處理,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02

最新評論

定远县| 来安县| 五常市| 日喀则市| 玉环县| 安徽省| 万源市| 綦江县| 建瓯市| 育儿| 永安市| 鲜城| 新龙县| 平山县| 五指山市| 垦利县| 尼木县| 海淀区| 蒙城县| 通河县| 青海省| 合阳县| 车致| 广宗县| 巩留县| 垦利县| 三原县| 曲沃县| 潼关县| 五原县| 蕉岭县| 凤台县| 江口县| 通海县| 会同县| 马鞍山市| 年辖:市辖区| 潮安县| 金坛市| 江源县| 大连市|