在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ 數(shù)據(jù)庫(kù)/ 15.8 C 語言復(fù)合數(shù)據(jù)類型(結(jié)構(gòu)體,共用體,枚舉類型)
18. RS485 通信與 Modbus 協(xié)議
17.5 A/D 差分輸入信號(hào)
15.8 C 語言復(fù)合數(shù)據(jù)類型(結(jié)構(gòu)體,共用體,枚舉類型)
16.3 NEC 協(xié)議紅外遙控器
13.1 單片機(jī)通信時(shí)序解析
14.4 單片機(jī) EEPROM 單字節(jié)讀寫操作時(shí)序
13.3 多個(gè) .c 文件的初步認(rèn)識(shí)
18.2 Modbus 通信協(xié)議介紹
15.1 BCD 碼介紹
18.3 單片機(jī) Modbus 多機(jī)通信程序設(shè)計(jì)
18.1 單片機(jī) RS485 通信接口、控制線、原理圖及程序?qū)嵗?/span>
15. 實(shí)時(shí)時(shí)鐘 DS1302
14.7 單片機(jī) I2C 和 EEPROM 的綜合編程
17. 模數(shù)轉(zhuǎn)換與數(shù)模轉(zhuǎn)換
16.2 紅外遙控通信原理
13.2 1602 液晶整屏移動(dòng)程序
17.6 D/A 輸出
17.7 單片機(jī)信號(hào)發(fā)生器程序
16.4 溫度傳感器 DS18B20
14.6 單片機(jī)EEPROM的頁(yè)寫入
13.4 單片機(jī)計(jì)算器程序設(shè)計(jì)[詳細(xì)]
17.2 A/D(模數(shù)轉(zhuǎn)換)的主要指標(biāo)
17.4 PCF8591 應(yīng)用程序
17.1 A/D 和 D/A 的基本概念
17.3 PCF8591硬件接口(電路圖引腳圖)
14.3 單片機(jī) EEPROM 簡(jiǎn)介
13.5 單片機(jī)串口通信原理和控制程序
15.5 DS1302 寄存器介紹
15.2 單片機(jī) SPI 通信接口
15.6 DS1302 通信時(shí)序介紹
14.5 單片機(jī) EEPROM 多字節(jié)讀寫操作時(shí)序
16. 紅外通信與 DS18B20 溫度傳感器
14.1 單片機(jī) I2C 時(shí)序介紹
15.3 實(shí)時(shí)時(shí)鐘芯片 DS1302 介紹
15.9 單片機(jī)電子時(shí)鐘程序設(shè)計(jì)
16.1 紅外光的基本原理
15.4 DS1302 的硬件信息
15.7 DS1302 的 BURST 模式
14.2 單片機(jī) I2C 尋址模式
14. 單片機(jī) I2C 總線與 EEPROM
13. 單片機(jī) 1602 液晶與串口的應(yīng)用實(shí)例

15.8 C 語言復(fù)合數(shù)據(jù)類型(結(jié)構(gòu)體,共用體,枚舉類型)

我們?cè)谇斑厡W(xué)數(shù)據(jù)類型的時(shí)候,主要是字符型、整型、浮點(diǎn)型等基本類型,而學(xué)數(shù)組的時(shí)候,數(shù)組的定義要求數(shù)組元素必須是相同的數(shù)據(jù)類型。在實(shí)際應(yīng)用中,有時(shí)候還需要把不同類型的數(shù)據(jù)組成一個(gè)有機(jī)的整體來處理,這些組合在一個(gè)整體中的數(shù)據(jù)之間還有一定的聯(lián)系,比如一個(gè)學(xué)生的姓名、性別、年齡、考試成績(jī)等,這就引入了復(fù)合數(shù)據(jù)類型。復(fù)合數(shù)據(jù)類型主要包含結(jié)構(gòu)體數(shù)據(jù)類型、共用體數(shù)據(jù)類型和枚舉體數(shù)據(jù)類型。

結(jié)構(gòu)體數(shù)據(jù)類型

首先我們回顧一下上面的例程,我們把 DS1302 的7個(gè)字節(jié)的時(shí)間放到一個(gè)緩沖數(shù)組中,然后把數(shù)組中的值稍作轉(zhuǎn)換顯示到液晶上,這里就存在一個(gè)小問題,DS1302 時(shí)間寄存器的定義并不是我們常用的“年月日時(shí)分秒”的順序,而是在中間加了一個(gè)字節(jié)的“星期幾”,而且每當(dāng)我要用這個(gè)時(shí)間的時(shí)候都要清楚的記得數(shù)組的第幾個(gè)元素表示的是什么,這樣一來,一是很容易出錯(cuò),二是程序的可讀性不強(qiáng)。當(dāng)然你可以把每一個(gè)元素都定一個(gè)明確的變量名字,這樣就不容易出錯(cuò)也易讀了,但結(jié)構(gòu)上卻顯得很零散了。于是,我們就可以用結(jié)構(gòu)體來將這一組彼此相關(guān)的數(shù)據(jù)做一個(gè)封裝,它們既組成了一個(gè)整體,易讀不易錯(cuò),而且可以單獨(dú)定義其中每一個(gè)成員的數(shù)據(jù)類型,比如說把年份用 unsigned int 類型,即4個(gè)十進(jìn)制位來表示顯然比2位更符合日常習(xí)慣,而其它的類型還是可以用2位來表示。結(jié)構(gòu)體本身不是一個(gè)基本的數(shù)據(jù)類型,而是構(gòu)造的,它每個(gè)成員可以是一個(gè)基本的數(shù)據(jù)類型或者是一個(gè)構(gòu)造類型。

結(jié)構(gòu)體既然是一種構(gòu)造而成的數(shù)據(jù)類型,那么在使用之前必須先定義它。

聲明結(jié)構(gòu)體變量的一般格式如下:

    struct  結(jié)構(gòu)體名 {
        類型 1
        類型 2
        ……
        類型 n
        變量名1;
        變量名2;
        變量名 n;
    } 結(jié)構(gòu)體變量名1, 結(jié)構(gòu)體變量名2, ... 結(jié)構(gòu)體變量名 n;

這種聲明方式是在聲明結(jié)構(gòu)體類型的同時(shí)又用它定義了結(jié)構(gòu)體變量,此時(shí)的結(jié)構(gòu)體名是可以省略的,但如果省略后,就不能在別處再次定義這樣的結(jié)構(gòu)體變量了。這種方式把類型定義和變量定義混在了一起,降低了程序的靈活性和可讀性,因此我們并不建議采用這種方式,而是推薦用以下這種方式:

 struct  結(jié)構(gòu)體名 {
        類型1  變量名1;
        類型2  變量名2;
        ……
        類型 n  變量名 n;
    };
    struct  結(jié)構(gòu)體名 結(jié)構(gòu)體變量名1, 結(jié)構(gòu)體變量名2, ... 結(jié)構(gòu)體變量名 n;

為了方便大家理解,我們來構(gòu)造一個(gè)實(shí)際的表示日期時(shí)間的結(jié)構(gòu)體。

struct sTime { //日期時(shí)間結(jié)構(gòu)體定義
    unsigned int year; //年
    unsigned char mon;  // 月
    unsigned char day;  // 日
    unsigned char hour; // 時(shí)
    unsigned char min; // 分
    unsigned char sec; // 秒
    unsigned char week;  // 星期
};
struct sTime bufTime;

struct 是結(jié)構(gòu)體類型的關(guān)鍵字,sTime 是這個(gè)結(jié)構(gòu)體的名字,bufTime 就是定義了一個(gè)具體的結(jié)構(gòu)體變量。那如果要給結(jié)構(gòu)體變量的成員賦值的話,寫法是

    bufTime.year = 0x2013;
    bufTime.mon = 0x10;

數(shù)組的元素也可以是結(jié)構(gòu)體類型,因此可以構(gòu)成結(jié)構(gòu)體數(shù)組,結(jié)構(gòu)體數(shù)組的每一個(gè)元素都是具有相同結(jié)構(gòu)類型的結(jié)構(gòu)體變量。例如我們前邊構(gòu)造的這個(gè)結(jié)構(gòu)類型,直接定義成 struct sTime bufTime[3];就表示定義了一個(gè)結(jié)構(gòu)體數(shù)組,這個(gè)數(shù)組的3個(gè)元素,每一個(gè)都是一個(gè)結(jié)構(gòu)體變量。同樣的道理,結(jié)構(gòu)體數(shù)組中的元素的成員如果需要賦值,就可以寫成

    bufTime[0].year = 0x2013;
    bufTime[0].mon = 0x10;

一個(gè)指針變量如果指向了一個(gè)結(jié)構(gòu)體變量的時(shí)候,稱之為結(jié)構(gòu)指針變量。結(jié)構(gòu)指針變量是指向的結(jié)構(gòu)體變量的首地址,通過結(jié)構(gòu)體指針也可以訪問到這個(gè)結(jié)構(gòu)變量。

結(jié)構(gòu)指針變量聲明的一般形式如下:

    struct sTime *pbufTime;

這里要特別注意的是,使用結(jié)構(gòu)體指針對(duì)結(jié)構(gòu)體成員的訪問,和使用結(jié)構(gòu)體變量名對(duì)結(jié)構(gòu)體成員的訪問,其表達(dá)式有所不同。結(jié)構(gòu)體指針對(duì)結(jié)構(gòu)體成員的訪問表達(dá)式為

    pbufTime->year = 0x2013;

或者是

    (*pbufTime).year = 0x2013;

很明顯前者更簡(jiǎn)潔,所以推薦大家使用前者。

共用體數(shù)據(jù)類型

共用體也稱之為聯(lián)合體,共用體定義和結(jié)構(gòu)體十分類似,我們同樣是推薦以下形式:

     union 共用體名 {
        數(shù)據(jù)類型1  成員名1;
        數(shù)據(jù)類型2  成員名2;
        ……
        數(shù)據(jù)類型 n  成員名 n;
    };
    union 共用體名 共用體變量;

共用體表示的是幾個(gè)變量共用一個(gè)內(nèi)存位置,也就是成員1、成員2……成員 n 都用一個(gè)內(nèi)存位置。共用體成員的訪問方式和結(jié)構(gòu)體是一樣的,成員訪問的方式是:共用體名.成員名,使用指針來訪問的方式是:共用體名->成員名。

共用體可以出現(xiàn)在結(jié)構(gòu)體內(nèi),結(jié)構(gòu)體也可以出現(xiàn)在共用體內(nèi),在我們編程的日常應(yīng)用中,最多應(yīng)用是結(jié)構(gòu)體出現(xiàn)在共用體內(nèi),例如:

union{
    unsigned int value;
    struct{
        unsigned char first;
        unsigned char second;
    } half;
} number;

這樣將一個(gè)結(jié)構(gòu)體定義到一個(gè)共用體內(nèi)部,我們?nèi)绻捎脽o符號(hào)整型賦值的時(shí)候,直接調(diào)用 value 這個(gè)變量,同時(shí),我們也可以通過訪問或賦值給 first 和 second 這兩個(gè)變量來訪問或修改 value 的高字節(jié)和低字節(jié)。

這樣看起來似乎是可以高效率的在 int 型變量和它的高低字節(jié)之間切換訪問,但請(qǐng)回想一下,我們?cè)诮榻B數(shù)據(jù)指針的時(shí)候就曾提到過,多字節(jié)變量的字節(jié)序取決于單片機(jī)架構(gòu)和編譯器,并非是固定不變的,所以這種方式寫好的程序代碼在換到另一種單片機(jī)和編譯環(huán)境后,就有可能是錯(cuò)的,從安全和可移植的角度來講,這樣的代碼是存在隱患的,所以現(xiàn)在諸多以安全為首要訴求的 C 語言編程規(guī)范里干脆直接禁止使用共用體。我們雖然不禁止,但也不推薦你用,除非你清楚的了解你所使用的開發(fā)環(huán)境的實(shí)現(xiàn)細(xì)節(jié)。

共用體和結(jié)構(gòu)體的主要區(qū)別如下:

  • 結(jié)構(gòu)體和共用體都是由多個(gè)不同的數(shù)據(jù)類型成員組成,但在任何一個(gè)時(shí)刻,共用體只能存放一個(gè)被選中的成員,而結(jié)構(gòu)體所有的成員都存在。
  • 對(duì)于共同體的不同成員的賦值,將會(huì)改變其它成員的值,而對(duì)于結(jié)構(gòu)體不同成員的賦值是相互之間不影響的。

枚舉數(shù)據(jù)類型

在實(shí)際問題中,有些變量的取值被限定在一個(gè)有限的范圍內(nèi)。例如,一個(gè)星期從周一到周日有7天,一年從1月到12月有12個(gè)月,蜂鳴器有響和不響兩種狀態(tài)等等。如果把這些變量定義成整型或者字符型不是很合適,因?yàn)檫@些變量都有自己的范圍。C 語言提供了一種稱為“枚舉”的類型,在枚舉類型的定義中列舉出所有可能的值,并可以為每一個(gè)值取一個(gè)形象化的名字,它的這一特性可以提高程序代碼的可讀性。

枚舉的說明形式如下:

    enum 枚舉名{
        標(biāo)識(shí)符 1[=整型常數(shù)],
        標(biāo)識(shí)符 2[=整型常數(shù)],
        ……
        標(biāo)識(shí)符 n[=整型常數(shù)]
    };
    enum 枚舉名 枚舉變量;

枚舉的說明形式中,如果沒有被初始化,那么“=整型常數(shù)”是可以被省略的,如果是默認(rèn)值的話,從第一個(gè)標(biāo)識(shí)符順序賦值0、1、2??,但是當(dāng)枚舉中任何一個(gè)成員被賦值后,它后邊的成員按照依次加1的規(guī)則確定數(shù)值。

枚舉的使用,有幾點(diǎn)要注意:

  • 枚舉中每個(gè)成員結(jié)束符是逗號(hào),而不是分號(hào),最后一個(gè)成員可以省略逗號(hào)。
  • 枚舉成員的初始化值可以是負(fù)數(shù),但是后邊的成員依然依次加1。
  • 枚舉變量只能取枚舉結(jié)構(gòu)中的某個(gè)標(biāo)識(shí)符常量,不可以在范圍之外。