一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C語言:自定義類型詳解

C語言:自定義類型詳解

2022-01-11 15:05今天我學習了! C/C++

這篇文章主要介紹了C語言自定義函數詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

 

一、結構體

 

1.結構體變量的定義及初始化

直接上代碼:

struct Point {
	int x;
	int y;
}p1;     //創建結構體時順便創建變量,分號一定不能掉
struct Point p2;    //單獨創建變量
struct Point p3 = { 1,2 };   //創建變量時順便賦值
struct Node {
	char str[20];
	struct Point p;     //結構體嵌套
}n1 = { "abcd",{3,4} };
int main() {
	printf("%s
", n1.str);   //結構體訪問時,用.或者->,變量訪問用.,指針訪問用->
	printf("%d
", n1.p.x);
	printf("%d
", n1.p.y);
	return 0;
}

C語言:自定義類型詳解

struct是創建結構體的關鍵字,Point是結構體的名字,p1為結構體Point的一個變量,x,y稱為結構體Point中的成員變量,變量的創建有兩種形式,第一,可以在創建結構體時一起創建,第二,單獨創建,創建規則為類型+名稱,對于結構體的賦值,可以在創建變量的時候順便賦值,可以先創建變量再單獨賦值。結構體的訪問有兩種方式,當使用變量進行訪問時,用.(點),再選擇該變量對應的屬性;當使用指針進行訪問時,用->,再選擇對應的屬性即可。

 

2.結構體內存對齊

當我們想去計算結構體占內存大小的時候,就需要知道結構圖內存對齊這一概念,我們先來看兩個例子:

struct A {
	char a;
	char b;
	int c;
};
struct B {
	char a;
	int c;
	char b;
};
int main(){
	printf("%d
", sizeof(struct A));
	printf("%d
", sizeof(struct B));
	return 0;
}

C語言:自定義類型詳解

結果表明,A和B兩個結構體所占內存大小并不相等,但是其內部成員變量是一樣的,只是順序不一樣。造成結果不同的原因就是因為內存對齊,我們來介紹結構體內存對齊的規則:

1.第一個成員在與結構體變量偏移量為0的地址處。

其他成員變量要對齊到某個數字(對齊數)的整數倍的地址處。 對齊數 = 編譯器默認的一個對齊數 與 該成員大小的較小值。在VS編譯器中,默認對齊數是8。

結構體總大小為最大對齊數(每個成員變量都有一個對齊數)的整數倍。

如果嵌套了結構體的情況,嵌套的結構體對齊到自己的最大對齊數的整數倍處,結構體的整 體大小就是所有最大對齊數(含嵌套結構體的對齊數)的整數倍。

 

3.為什么要內存對齊呢?

從上面的結果我們大概就能猜到,為了節省空間。總的來說,主要原因有兩點:

1.平臺原因:

某些硬件平臺只能在特定的地址處取地址,沒有內存對齊,取值時可能會出錯。

2.性能原因:

對于不對齊的情況,在讀取數據時可能要讀取兩次,以下圖為例:

C語言:自定義類型詳解

在一個32位平臺上,在不對齊的情況下,如果想要讀取int的4個字節,第一次會讀取到char的一個字節,和int的后3個字節(小端),需要再讀取一次,才能將int的4個字節完全讀取出來;相比較而言,如果是在內存對齊的情況下,只需要讀取一次就可以把int的4個直接讀取出來。

 

二、位段

結構體還有實現位段的能力,問題來了,什么是位段呢?

 

1.什么是位段

位段的聲明和結構體是類似的,但有兩點不同:

  • 位段的成員必須是 int、unsigned int 或signed int 。
  • 位段的成員名后邊有一個冒號和一個數字。

例如:

struct A
{
 int _a:2;
 int _b:5;
 int _c:3;
 int _d:4;
};

A就是一個位段類型,想要知道A的大小,同樣可以用sizeof來求。

 

2.位段的內存分配

拿上面的位段A來說,會先在內存中開辟一個4字節的空間,冒號后面的數字表示該成員變量所占內存的大小,單位為bit,位段中的成員在內存中從左向右分配, 當一個結構包含兩個位段,第二個位段成員比較大,無法容納于第一個位段剩余的位時,是 舍棄剩余的位還是利用,這是不確定的。總的來說,跟結構相比,位段可以達到同樣的效果,但是可以很好的節省空間,但是有跨平臺的問題存在。光說不太好理解,我們來看下圖:

C語言:自定義類型詳解

當然,位段雖然比結構體更節省內存,但其存在跨平臺問題,需要謹慎使用。

 

三、枚舉

 

1.枚舉的定義

enum Day//星期
{
 Mon,  //默認情況下Mon值為0,后面的成員變量的值依次遞增
 Tues,
 Wed,
 Thur,
 Fri,
 Sat,
 Sun
};

當然也可以在定義的時候賦值,例如:

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

 

2.枚舉的優點

我們知道,#define可以定義常量,那為什么要用枚舉呢?

枚舉的優點:

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

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

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

既然存在,就有其存在的道理,有些時候#define更方便,有時候枚舉更方便,我們要學會合理使用

 

四、聯合(共用體)

 

1.聯合類型的定義

union Un  //聲明
{
 char c;
 int i;
};
union Un un;  //定義變量
printf("%d
", sizeof(un));  //計算共用體的大小

 

2.聯合的特點

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

union Un
{
 int i;
 char c;
};
union Un un;
// 下面輸出的結果是一樣的嗎?
printf("%d
", &(un.i));
printf("%d
", &(un.c));
//下面輸出的結果是什么?
un.i = 0x11223344;
un.c = 0x55;
printf("%x
", un.i);

C語言:自定義類型詳解

從結果可以看出,i和c的地址是一樣的,因為他們共用一塊空間,當分別給i、c賦值時,后賦值的c會覆蓋之前i的部分值。

 

3.聯合大小的計算

  • 聯合的大小至少是最大成員的大小。
  • 當最大成員大小不是最大對齊數的整數倍的時候,就要對齊到最大對齊數的整數倍。

例如:

union Un1
{
 char c[5];
 int i;
};
union Un2
{
 short c[7];
 int i;
};
//下面輸出的結果是什么?
printf("%d
", sizeof(union Un1));  //8,c占5個字節,比i大,最大對齊數位4,需要為4的倍數,所以為8
printf("%d
", sizeof(union Un2));  //16,c占14個字節,最大對齊數為4,所以為16

 

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!

原文鏈接:https://blog.csdn.net/qq_44888950/article/details/120442843

延伸 · 閱讀

精彩推薦
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
主站蜘蛛池模板: 冰雪奇缘1完整版免费观看 变形金刚第一部 | 日本国产成人精品视频 | 性xxxx中国老妇506070 | spank日本网站脱裤子打屁股 | 美女吃男生鸡鸡 | 国产99视频精品免视看9 | 荡娃艳妇系列小说 | 国产男女性特黄录像 | 把老师操了 | 亚洲qvod图片区电影 | 国产男技师 | 免费岛国片 | 色交视频| 精品AV亚洲乱码一区二区 | 午夜亚洲一区二区福利 | 欧美国产在线观看 | 精品国产麻豆免费人成网站 | 色吧欧美| 26uuu成人人网图片 | 国产欧美精品一区二区三区四区 | 视频一区二区三区在线 | 男女车车好快的车车免费网站 | 无遮无挡免费视频 | 日本又黄又裸一级大黄裸片 | 99爱视频| 美女扒开腿让男人桶爽免费gif | 婷婷在线观看香蕉五月天 | 国产欧美日韩视频在线观看一区二区 | 久久re这里精品23 | 大陆性出航 | 小伙无套内射老女人 | 日韩ab | japanhd粗暴video| 美女bbxx美女bbb| 亚洲日本免费 | 日韩一区视频在线 | 成人做视频免费 | 99久久九九| 亚洲精品αv一区二区三区 亚洲精品91大神在线观看 | 日本中出视频 | jizz女16处|