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

C語言編程C++自定義個性化類型

 更新時間:2021年09月28日 11:21:11   作者:小碼農(nóng)UU  
這篇文章主要介紹了C語言編程中如何來自定義C++個性化類型,文中附含詳細(xì)的示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助

自定義類型

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

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

聲明一個結(jié)構(gòu)體類型

//聲明一個學(xué)生類型,是想通過學(xué)生類型來創(chuàng)建學(xué)生變量(對象)
//描述學(xué)生就得有屬性啥的。名字,電話,性別,年齡
struct Stu
{
    char name[20];//名字
    char tele[12];//電話
    char sex[10];//性別
    int age;//年齡
};

struct Stu s3;//創(chuàng)建全局結(jié)構(gòu)體變量

int main()
{
    struct Stu s1;
    struct Stu s2;//創(chuàng)建結(jié)構(gòu)體變量
	return 0;
}

image-20210913094556253

特殊聲明

在聲明結(jié)構(gòu)的時候,可以不完全的聲明。

沒有結(jié)構(gòu)體標(biāo)簽

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

要清楚一點匿名結(jié)構(gòu)體是個類型不占用空間的,就好像int一樣,他們沒有創(chuàng)建一個變量是不會開辟空間的,所以類型不占用空間就沒有銷毀不銷毀這一說,只有有了空間才會有銷毀不銷毀這一說,類型就好像圖紙,變量才是真正要蓋的房子

struct 
{
    char name[20];//名字
    char tele[12];//電話
    char sex[10];//性別
    int age;//年齡
}stu;//直接接結(jié)構(gòu)體變量,匿名的時候后面就把變量給創(chuàng)建好,不然之后也用不到這個結(jié)構(gòu)名,因為沒有結(jié)構(gòu)體名字怎么創(chuàng)建變量呢

匿名結(jié)構(gòu)體指針類型

struct 
{
    char name[20];//名字
    char tele[12];//電話
    char sex[10];//性別
    int age;//年齡
}* pstu;//這時pstu就變成匿名結(jié)構(gòu)體指針了

image-20210917060233748

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

在結(jié)構(gòu)中包含一個類型為該結(jié)構(gòu)本身的成員是否可以呢?

image-20210917061523191

所以節(jié)點(Node)就出來了

一塊表示數(shù)據(jù)一塊表示地址

struct Node
{
	int data;          //數(shù)據(jù)域
	struct Node* next; //指針域
};

這就是結(jié)構(gòu)體自引用 自己類型里的變量找到同類型的另外一個對象

注意

image-20210917063320647

所以對于結(jié)構(gòu)體的自引用是不能省略自己的結(jié)構(gòu)體標(biāo)簽,下面就是解決方案

typedef struct Node
{
	int data;          //數(shù)據(jù)域
	struct Node* next; //指針域
}Node;

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

struct Stu
{
    char name[20];//名字
    char tele[12];//電話
    char sex[10];//性別
    int age;//年齡
};
struct Stu s3;//創(chuàng)建全局結(jié)構(gòu)體變量
int main()
{
    struct Stu s1 = {"zhuzhongyuan","13151732661","nan",22};//(定義)創(chuàng)建結(jié)構(gòu)體變量s1并初始化
    printf("%s %s %s %d",s1.name,s1.tele,s1.sex,s1.age);
	return 0;
}

image-20210917084658329

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

現(xiàn)在我們深入討論一個問題:計算結(jié)構(gòu)體的大小。

這也是一個特別熱門的考點:結(jié)構(gòu)體內(nèi)存對齊

#include<stdio.h>
//內(nèi)存對齊
//結(jié)構(gòu)體內(nèi)存對齊
struct S2
{
	int a;
	char b;
	char c;
};                        
struct S1
{
	char b;
	int a;
	char c;
};
int main()
{
	printf("%d\n", sizeof(struct S1));
	printf("%d\n", sizeof(struct S2));
	return 0;
}

image-20210917090210504

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

  1. 結(jié)構(gòu)體的第一個成員永遠(yuǎn)放在結(jié)構(gòu)體起始位置偏移量為0的位置
  2. 結(jié)構(gòu)體成員從第二成員開始,總是放在一個對齊數(shù)的整數(shù)倍處
  3. 對齊數(shù)是什么呢是編譯器默認(rèn)的對齊數(shù)和變量自身大小的較小值注意一下 linux沒有默認(rèn)對齊數(shù)vs下默認(rèn)對齊數(shù)是8
  4. 結(jié)構(gòu)體的總大小必須是各個成員的對齊數(shù)中最大那個對齊數(shù)的整數(shù)倍
  5. 如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對齊到自己的最大對齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對齊數(shù)(含嵌套結(jié)構(gòu)體的對齊數(shù))的整數(shù)倍

image-20210917093552942

image-20210917094041911

幾個練習(xí)

image-20210917094956838

image-20210917101912669

為什么存在內(nèi)存對齊

1.平臺原因(移植原因)

不是所有的硬件平臺都能訪問任意地址上的任意數(shù)據(jù),某些平臺只能在某些地址某些特定類型的數(shù)據(jù),否則拋出硬件異常

2.性能原因

數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對齊,原因在于,為了訪問未對齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問,而對齊的訪問僅需要一次訪問

總體來說

結(jié)構(gòu)體內(nèi)存對齊就是拿空間換取時間的做法,形象的說就是浪費了內(nèi)存,換來了方便

解決

那在設(shè)計結(jié)構(gòu)體的時候,我們既要滿足對齊,又要節(jié)省空間,如何做到:
讓占用空間小的成員盡量集中在一起。

image-20210917233228992

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

vs默認(rèn)對齊數(shù)是8

我們可以通過#pragma pack()來修改默認(rèn)對齊數(shù)

image-20210917234827620

默認(rèn)設(shè)置對齊數(shù)是2的幾次方

offsetof宏的實現(xiàn)

計算結(jié)構(gòu)體中某變量相對于首地址的偏移

offsetof原格式

image-20210918054155802

image-20210918054846243

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

值傳遞

image-20210918061503779

址傳遞

image-20210918063001860

如何選擇

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

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

結(jié)論: 結(jié)構(gòu)體傳參的時候,要傳結(jié)構(gòu)體的地址。

位段

什么是位段

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

1.位段的成員必須是int,unsiged int 或 signed int

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

image-20210918065432943

image-20210918070011886

位段的內(nèi)存分配 位段的成員可以是int, unsigned int,signed int,或者是char(屬于整形家族)類型位段的空間上是按照需要以4個字節(jié)(int)或者1個字節(jié)(char)的方式來開辟的位段涉及很多不確定因素,位段是不跨平臺的,注重可移植的程序應(yīng)該避免使用位段

image-20210918090139913

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

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

位段的應(yīng)用

image-20210918091635663

枚舉

如果我們沒有對枚舉常量進行初始化的話,他們是默認(rèn)加一的

我們常量分為4種

1.字面常量

2.const修飾的常變量

3.#號定義的標(biāo)識符常量

4.枚舉常量

這里我們就講枚舉常量

image-20210918094024475

枚舉常量是不可以改的,只能初始化

image-20210918094628627

那枚舉怎么用呢

image-20210918095317933

枚舉的優(yōu)點

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

增加代碼的可讀性和可維護性和#define定義的標(biāo)識符比較枚舉有類型檢查,更加嚴(yán)謹(jǐn)。防止了命名污染(封裝)便于調(diào)試

而define是不可以的,因為define是完完全全替換的,在代碼中看到GREEN什么的直接替換為1,代碼中就沒有GREEN的概念了,完完全全的替換

image-20210918100706102

使用方便,一次可以定義多個常量 簡易計算器

#include<stdio.h>
enum Option
{
	exit,
	add,
	sub,
	mul,
	div
};
void menu()
{
	printf("*********************\n");
	printf("****1.add   2.sub****\n");
	printf("****3.mul   4.div****\n");
	printf("****    0.exit   ****\n");
	printf("*********************\n");
}

int main()
{
	int input = 0;
	int a = 0;
	int b = 0;
	int c = 0;
	do
	{
		menu();
		printf("請選擇:>");
		scanf("%d",&input);
		printf("請輸入兩個操作數(shù):>");
		scanf("%d%d", &a, &b);
		switch (input)			
		{
		case add:
			c = a + b;
			printf("%d\n", c);
			break;
		case sub:
			c = a - b;
			printf("%d\n", c);
			break;
		case mul:
			c = a * b;
			printf("%d\n", c);
			break;
		case div:
			if (b == 0)
			{
				printf("分子不能為0\n");
				break;
			}
			else
			{
				c = a / b;
				printf("%d\n", c);
				break;
			}			
		default:
			break;
		}
	} while (input);
	return 0;
}

image-20210918104241635

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

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

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

聯(lián)合類型的聲明

image-20210918105430018

image-20210918105748187

image-20210918110608353

聯(lián)合的特點

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

判斷當(dāng)前機器的大小端存儲【】

之前學(xué)過一個方法

#include<stdio.h>
int main()
{
	int a = 1; //0x 00 00 00 01
	//低 -------------> 高
	//01 00 00 00   小端存儲
	//00 00 00 01   大端存儲
	//想辦法拿到a的第一個字節(jié)
	char* pc = (char*)&a;
	if (*pc == 1)
	{
		printf("小端存儲");
	}
	else
	{
		printf("大端存儲");
	}
	return 0;
}

image-20210918111603326

現(xiàn)在學(xué)到共用體正好利用他的特殊情況

#include<stdio.h>
union Un
{
	char c;
	int i;
};
int main()
{
	union Un u = { 0 };
	u.i = 1;
	if (u.c == 1)
	{
		printf("小端存儲");
	}
	else
	{
		printf("大端存儲");
	}
	return 0;
}

image-20210918112419963

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

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

image-20210918122833572

以上就是C語言編程C++自定義個性化類型的詳細(xì)內(nèi)容,更多關(guān)于C++自定義類型的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言中fgets和fscanf區(qū)別詳解

    C語言中fgets和fscanf區(qū)別詳解

    這篇文章主要介紹了C語言中fgets和fscanf區(qū)別詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • 一文搞懂C++ 動態(tài)內(nèi)存

    一文搞懂C++ 動態(tài)內(nèi)存

    這篇文章主要介紹了C++ 動態(tài)內(nèi)存的的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • C語言遞歸實現(xiàn)歸并排序詳解

    C語言遞歸實現(xiàn)歸并排序詳解

    這篇文章主要為大家詳細(xì)介紹了C語言遞歸實現(xiàn)歸并排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,?希望能夠給你帶來幫助
    2022-03-03
  • 一篇文章教你3分鐘如何發(fā)布Qt程序

    一篇文章教你3分鐘如何發(fā)布Qt程序

    這篇文章主要給大家介紹了關(guān)于教你3分鐘如何發(fā)布Qt程序的相關(guān)資料,文中通過實例代碼結(jié)束的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 關(guān)于C++11的統(tǒng)一初始化語法示例詳解

    關(guān)于C++11的統(tǒng)一初始化語法示例詳解

    C++之前的初始化語法很亂,有四種初始化方式,而且每種之前甚至不能相互轉(zhuǎn)換,但從C++11出現(xiàn)后就好了,所以這篇文章主要給大家介紹了關(guān)于C++11的統(tǒng)一初始化語法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。
    2017-10-10
  • C程序中唯一序列號的生成實例詳解

    C程序中唯一序列號的生成實例詳解

    這篇文章主要介紹了C程序中唯一序列號的生成實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 簡單聊聊C++中線程的原理與實現(xiàn)

    簡單聊聊C++中線程的原理與實現(xiàn)

    C++11?引入了多線程支持,提供了一套基本的線程庫,包括線程、互斥量(mutex)、條件變量(condition_variable)等。這些組件可以幫助你在?C++?程序中實現(xiàn)并發(fā)和多線程編程,本文就來和大家簡單聊聊吧
    2023-03-03
  • C語言結(jié)構(gòu)體數(shù)組常用的三種賦值方法(包含字符串)

    C語言結(jié)構(gòu)體數(shù)組常用的三種賦值方法(包含字符串)

    C語言只有在定義字符數(shù)組的時候才能用“=”來初始化變量,其它情況下是不能直接用“=”來為字符數(shù)組賦值的,下面這篇文章主要給大家介紹了關(guān)于C語言結(jié)構(gòu)體數(shù)組常用的三種賦值方法,需要的朋友可以參考下
    2022-06-06
  • 用標(biāo)準(zhǔn)c++實現(xiàn)string與各種類型之間的轉(zhuǎn)換

    用標(biāo)準(zhǔn)c++實現(xiàn)string與各種類型之間的轉(zhuǎn)換

    這個類在頭文件中定義, < sstream>庫定義了三種類:istringstream、ostringstream和stringstream,分別用來進行流的輸入、輸出和輸入輸出操作。另外,每個類都有一個對應(yīng)的寬字符集版本
    2013-09-09
  • C語言庫函數(shù)中qsort()的用法

    C語言庫函數(shù)中qsort()的用法

    大家好,本篇文章主要講的是C語言庫函數(shù)中qsort()的用法,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12

最新評論