中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

響應(yīng)式網(wǎng)頁設(shè)計最方便快速seo網(wǎng)站推廣計劃

響應(yīng)式網(wǎng)頁設(shè)計最方便快速,seo網(wǎng)站推廣計劃,做民宿怎么登錄網(wǎng)站,hp網(wǎng)站自定義類型:結(jié)構(gòu)體,枚舉,聯(lián)合 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)存對齊1.7修改默認(rèn)對齊1.8結(jié)構(gòu)體傳參 2.段位2.1什么是段位2.2段位的內(nèi)存分配2.3位段的跨平臺問…

自定義類型:結(jié)構(gòu)體,枚舉,聯(lián)合

    • 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)存對齊
      • 1.7修改默認(rèn)對齊
      • 1.8結(jié)構(gòu)體傳參
    • 2.段位
      • 2.1什么是段位
      • 2.2段位的內(nèi)存分配
      • 2.3位段的跨平臺問題
      • 2.4位段的應(yīng)用
    • 3.枚舉
      • 3.1枚舉類型的定義
      • 3.2枚舉的優(yōu)點
      • 3.3枚舉的使用
    • 4.聯(lián)合
      • 4.1聯(lián)合類型的定義
      • 4.2聯(lián)合的特點
      • 4.3聯(lián)合大小的計算

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

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

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

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

在這里插入圖片描述
例如描述一個學(xué)生:

struct Stu
{
char name[20];//名字
int age;//年齡
char sex[5];//性別
char id[20];//學(xué)號
}; //分號不能丟

1.3特殊的聲明

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

//匿名結(jié)構(gòu)體類型
struct 
{char name[20];char author[12];float price;
}b1, b2;

上面的兩個結(jié)構(gòu)在聲明的時候省略掉了結(jié)構(gòu)體標(biāo)簽(tag)

當(dāng)我們使用匿名結(jié)構(gòu)體時,以下做法合理么?

struct
{char name[20];char author[12];float price;
}b;
struct
{char name[20];char author[12];float price;
}* p;
int main()
{p = &b;//不建議這樣寫return 0;
}

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

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

//錯誤自引用
struct Node
{int data;struct Node next;
};
//正確自引用
struct Node
{int data;struct Node* next;
};

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

struct Point
{int x;int y;
}p1; //聲明類型的同時定義變量p1,p1為全局變量
struct Point p2; //定義結(jié)構(gòu)體變量p2,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)體嵌套初始化

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

我們已經(jīng)掌握了結(jié)構(gòu)體的基本使用了。
現(xiàn)在我們深入討論一個問題:計算結(jié)構(gòu)體的大小。
這也是一個特別熱門的考點: 結(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
    gcc沒有對齊數(shù),對齊數(shù)就是自身大小
  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ù)倍。
    案例一:
struct S1
{char c1;int i;char c2;
};
int main()
{printf("%d\n", sizeof(struct S1));return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

分析:
在這里插入圖片描述

案例二:

struct S2
{char c1;char c2;int i;
};
int main()
{printf("%d\n", sizeof(struct S2));return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

分析:
在這里插入圖片描述

案例三:

struct S3
{double d;char c;int i;
};
int main()
{printf("%d\n", sizeof(struct S3));return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

分析:
在這里插入圖片描述

案例四:

//練習(xí)4 - 結(jié)構(gòu)體嵌套問題
struct S3
{double d;char c;int i;
};
struct S4
{char c1;struct S3 s3;double d;
};
int main()
{printf("%d\n", sizeof(struct S4));return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

分析:
在這里插入圖片描述

為什么存在內(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)存對齊是拿空間來換取時間的做法。

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

//例如:
struct S1
{char c1;int i;char c2;
};
struct S2
{char c1;char c2;int i;
};

S1和S2類型的成員一模一樣,但是S1和S2所占空間的大小有了一些區(qū)別。

補(bǔ):offsetof(可以計算結(jié)構(gòu)體成員相較于結(jié)構(gòu)體起始位置的偏移量)
在這里插入圖片描述

offsetof案例:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stddef.h>
struct S1
{char c1;//1int i;//4char c2;//1
};
int main()
{struct S1 s1 = { 0 };printf("%d\n", offsetof(struct S1, c1));printf("%d\n", offsetof(struct S1, i));printf("%d\n", offsetof(struct S1, c2));return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

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

之前我們見過了 #pragma 這個預(yù)處理指令,這里我們再次使用,可以改變我們的默認(rèn)對齊數(shù)。

#pragma pack(1)//設(shè)置默認(rèn)對齊數(shù)為1
struct S
{char c1;//1 1 1int a; // 4 1 1char c2;//1 1 1
};
#pragma pack()//取消設(shè)置的默認(rèn)對齊數(shù),還原為默認(rèn)
int main()
{printf("%d\n", sizeof(struct S));return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

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

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

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

運(yùn)行結(jié)果
在這里插入圖片描述

上面的 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)位段的能力。

2.1什么是段位

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

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

代碼案例:
struct A
{int _a : 2;//二進(jìn)制位int _b : 5;int _c : 10;int _d : 30;
};
int main()
{printf("%d\n", sizeof(struct A));return 0;
}

A就是一個位段類型。
那位段A的大小是多少?

運(yùn)行結(jié)果:
在這里插入圖片描述

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;
};
int main()
{struct S s = { 0 };s.a = 10;s.b = 12;s.c = 3;s.d = 4;printf("%d\n", sizeof(s));return 0;
}

空間是如何開辟的?
在這里插入圖片描述

運(yùn)行結(jié)果:
在這里插入圖片描述

2.3位段的跨平臺問題

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

總結(jié):

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

2.4位段的應(yīng)用

在這里插入圖片描述

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)容是枚舉類型的可能取值,也叫 枚舉常量 。

這些可能取值都是有值的,默認(rèn)從0開始,一次遞增1,當(dāng)然在定義的時候也可以賦初值。

enum Color//顏色
{RED = 1,GREEN = 2,BLUE = 4
};

3.2枚舉的優(yōu)點

為什么使用枚舉?
我們可以使用 #define 定義常量,為什么非要使用枚舉?

枚舉的優(yōu)點:

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

3.3枚舉的使用

enum Color
{RED,//0GREEN,//1BLUE//2
};
#define RED 0
int main()
{enum Color c = GREEN;//只能拿枚舉常量給枚舉變量賦值enum Color cc = 3;//.c文件中允許,.cpp文件中不允許return 0;
}

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

運(yùn)行結(jié)果:
在這里插入圖片描述

4.2聯(lián)合的特點

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

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

&un:
在這里插入圖片描述

運(yùn)行結(jié)果:
在這里插入圖片描述

面試題:
判斷當(dāng)前計算機(jī)的大小端存儲

int check_sys()
{union{int i;char c;}un = {.i = 1};return un.c;
}int main()
{int ret = check_sys();if (ret == 1)printf("小端\n");elseprintf("大端\n");return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

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

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

比如:

代碼案例:
union Un1
{char c[5];//5 1 8 1int i;//4 8 4
};
union Un2
{short c[7];//14 2 8 2int i;//4 4 8 4
};
int main()
{printf("%d\n", sizeof(union Un1));//5+3 = 8printf("%d\n", sizeof(union Un2));//16return 0;
}

運(yùn)行結(jié)果:
在這里插入圖片描述

💘不知不覺,自定義類型:結(jié)構(gòu)體,枚舉,聯(lián)合以告一段落。通讀全文的你肯定收獲滿滿,讓我們繼續(xù)為C語言學(xué)習(xí)共同奮進(jìn)!!!

http://www.risenshineclean.com/news/46605.html

相關(guān)文章:

  • 有哪些制作網(wǎng)站的公司嗎鹽酸達(dá)泊西汀片是治療什么的藥物
  • 視頻網(wǎng)站做視頻節(jié)目賺錢嗎推廣互聯(lián)網(wǎng)推廣
  • 做的好的中醫(yī)網(wǎng)站廣州新聞熱點事件
  • 電子通訊錄網(wǎng)站建設(shè)近日網(wǎng)站收錄查詢
  • 國外網(wǎng)站為什么不用備案軟件推廣接單平臺
  • 做網(wǎng)站應(yīng)該注意哪些方面臨沂seo推廣外包
  • 網(wǎng)站首頁被掛黑鏈百度網(wǎng)盤會員
  • 如何做好公司網(wǎng)站接推廣app任務(wù)的平臺
  • 學(xué)完ssm可以做哪些網(wǎng)站搜索引擎優(yōu)化的內(nèi)部優(yōu)化
  • wordpress圖片網(wǎng)站網(wǎng)站要怎么創(chuàng)建
  • 成都 商業(yè)網(wǎng)站建設(shè)app網(wǎng)絡(luò)推廣公司
  • 網(wǎng)站建設(shè) 樂視百度軟件中心下載安裝
  • 網(wǎng)站優(yōu)化推廣怎么做強(qiáng)強(qiáng)seo博客
  • 網(wǎng)站群系統(tǒng)站長工具網(wǎng)站排名
  • 湖州網(wǎng)站制作網(wǎng)站快速排名推廣軟件
  • 24小時二手表網(wǎng)站免費(fèi)友情鏈接平臺
  • thinkphp做網(wǎng)站有什么好處seo網(wǎng)絡(luò)優(yōu)化平臺
  • 門戶網(wǎng)站是指網(wǎng)絡(luò)營銷方式有哪些
  • 南京h5網(wǎng)站開發(fā)seo根據(jù)什么具體優(yōu)化
  • 怎么查網(wǎng)站備案信息查詢運(yùn)營是做什么的
  • 簡述企業(yè)網(wǎng)站建設(shè)的流程百度推廣培訓(xùn)班
  • 網(wǎng)站優(yōu)化怎么做分錄西安seo優(yōu)化系統(tǒng)
  • 高端網(wǎng)站制作哪家專業(yè)怎樣免費(fèi)推廣自己的網(wǎng)站
  • 簡單的個人網(wǎng)站100種宣傳方式
  • 網(wǎng)站建設(shè)模板的seo快速排名源碼
  • 三門峽建設(shè)網(wǎng)站哪家好深圳網(wǎng)絡(luò)推廣
  • 注冊公司后才可以做獨立網(wǎng)站嗎個人主頁網(wǎng)頁設(shè)計
  • 中國建設(shè)部官方網(wǎng)站魯班獎網(wǎng)絡(luò)推廣的方法包括
  • 四川城鄉(xiāng)建設(shè)委員會的網(wǎng)站深圳百度競價托管公司
  • 做網(wǎng)站的空間汽車行業(yè)網(wǎng)站建設(shè)