結(jié)構(gòu)與聯(lián)合形式和概述_第1頁
結(jié)構(gòu)與聯(lián)合形式和概述_第2頁
結(jié)構(gòu)與聯(lián)合形式和概述_第3頁
結(jié)構(gòu)與聯(lián)合形式和概述_第4頁
結(jié)構(gòu)與聯(lián)合形式和概述_第5頁
已閱讀5頁,還剩44頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、 C語言程序中少量變化的數(shù)據(jù)用簡單類型的變量來處理。數(shù)量不宜多。 批量同類型數(shù)據(jù)的處理用數(shù)組。 不同類型的數(shù)據(jù)的集合用什么數(shù)據(jù)結(jié)構(gòu)來存放呢?這就是本單元要介紹的內(nèi)容:用結(jié)構(gòu)和聯(lián)合類型處理不同類型數(shù)據(jù)的集合。 結(jié)構(gòu)是個數(shù)固定、類型可以不同的元素的集合。它的元素一般稱為成員。 對結(jié)構(gòu)成員的訪問只能按名訪問。 9.1 概述1結(jié)構(gòu)與聯(lián)合形式和概述9.2 結(jié)構(gòu)的聲明9.2.1 結(jié)構(gòu)聲明的一般形式 聲明一個結(jié)構(gòu)類型的一般格式為: struct 結(jié)構(gòu)標記 成員列表變量列表; 三者任擇其二 上述聲明的書寫形式: struct 結(jié)構(gòu)標記 數(shù)據(jù)類型 成員名1; 數(shù)據(jù)類型 成員名2; 數(shù)據(jù)類型 成員名n; 變量列表

2、;2結(jié)構(gòu)與聯(lián)合形式和概述 例如,日期是由年、月、日組成,我們可以把日期聲明為一個結(jié)構(gòu):enum mons(jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec); struct date enum mons month; short day; int year; ; 下面是結(jié)構(gòu)聲明的另一個例子: struct unsigned long number; char name15; char department20; student;3結(jié)構(gòu)與聯(lián)合形式和概述 下面看兩個例子: struct date int day, month, year; ; stru

3、ct student char *name; int student_no; struct date birthdate; ; 在student中的結(jié)構(gòu)成員birthdate是一個具有date結(jié)構(gòu)的結(jié)構(gòu)變量9.2.2 嵌套結(jié)構(gòu)與自引用結(jié)構(gòu)4結(jié)構(gòu)與聯(lián)合形式和概述 struct node int data; struct node *next; ;結(jié)構(gòu)標記為node的結(jié)構(gòu)成員next是一個指向自身結(jié)構(gòu)的指針5結(jié)構(gòu)與聯(lián)合形式和概述注意以下幾點: 結(jié)構(gòu)成員可以是任何基本數(shù)據(jù)類型, 也可以是數(shù)組、指針、聯(lián)合、枚舉類型變量 結(jié)構(gòu)類型可以嵌套定義, 即一個結(jié)構(gòu)中的的一個或多個成員是其他結(jié)構(gòu)類型的變量或指向結(jié)

4、構(gòu)變量的指針,但不能是自身結(jié)構(gòu)的結(jié)構(gòu)變量, 可以是指向自身結(jié)構(gòu)的指針 同一結(jié)構(gòu)內(nèi)成員的名稱不能相同 結(jié)構(gòu)定義只是給出了結(jié)構(gòu)的組織形式,并不占有存儲空間6結(jié)構(gòu)與聯(lián)合形式和概述 例9-3: struct s int a; char s10; float b; a, s50; 結(jié)構(gòu)標記s結(jié)構(gòu)s中的結(jié)構(gòu)成員s(它是一個數(shù)組名)具有s 結(jié)構(gòu)類型的結(jié)構(gòu)數(shù)組s結(jié)構(gòu)s的成員a(整型變量)具有s 結(jié)構(gòu)類型的結(jié)構(gòu)變量a7結(jié)構(gòu)與聯(lián)合形式和概述 定義結(jié)構(gòu)變量(三種方式) 結(jié)構(gòu)的定義說明了該結(jié)構(gòu)類型的組成,要使用該結(jié)構(gòu),必須定義結(jié)構(gòu)類型的變量 定義結(jié)構(gòu)變量就是為該變量分配所需的存儲空間。 結(jié)構(gòu)變量也具有某種存儲類型,

5、結(jié)構(gòu)變量的存在域和作用域同其它變量一樣. 結(jié)構(gòu)變量定義的一般格式: 存儲類型 struct ; 結(jié)構(gòu)變量存儲單元的分配是按照其類型的樣板配置的, 依據(jù)各個成員在結(jié)構(gòu)中出現(xiàn)的先后次序來分配空間.8結(jié)構(gòu)與聯(lián)合形式和概述 1) 先定義結(jié)構(gòu)類型再定義變量名struct student int num; char name20; char sex; int age; float score; char addr30;struct student student1,student2;9結(jié)構(gòu)與聯(lián)合形式和概述2)在定義類型的同時定義變量struct student int num; char name20;

6、char sex; int age; float score; char addr30; student1,student2;10結(jié)構(gòu)與聯(lián)合形式和概述 3)無名定義(不出現(xiàn)結(jié)構(gòu)標記)struct int num; char name20; char sex; int age; float score; char addr30; student1, student2; 無名結(jié)構(gòu)只能一次性將要定義的結(jié)構(gòu)變量寫在其后, 不能再用它多次定義結(jié)構(gòu)變量。11結(jié)構(gòu)與聯(lián)合形式和概述9.2.3 用typedef創(chuàng)建新的類型 typedef常用來為一個類型取名。例如: typedef struct unsigne

7、d long number; char *name; struct date birthday; char *department; STUD; STUD student1,student2; 12結(jié)構(gòu)與聯(lián)合形式和概述 typedef struct stud StudType; StudType student; 下面是用typedef定義新的類型名的幾個例子: typedef char STRING80;定義了名為STRING的類型,它是一個具有80個字符的數(shù)組。于是,語句 STRING text;與下面的定義語句等價: char text80; typedef char *PString;

8、這個語句把PString定義為指向字符的指針類型名,于是,語句 PString ptr1,ptr2;定義ptr1和ptr2是一個指向字符的指針變量。 13結(jié)構(gòu)與聯(lián)合形式和概述9.3 訪問結(jié)構(gòu)成員結(jié)構(gòu)變量名 . 成員名 “.”是成員運算符,具有左結(jié)合性, 它與運算符( ) 、 、-具有同等優(yōu)先級, 比“*”運算符優(yōu)先級高.因此 對結(jié)構(gòu)的引用通常是對結(jié)構(gòu)中各成員的引用. 結(jié)構(gòu)成員可用如下表達式表示:*結(jié)構(gòu)變量名 . 成員名等價于 *(結(jié)構(gòu)變量名 . 成員名)14結(jié)構(gòu)與聯(lián)合形式和概述 struct student int num; char name20; char sex; int age; st

9、udent1, student2; 訪問結(jié)構(gòu)成員的一個例子:例如: student1.num = 10010; student1.age+; printf(”%dn”, student1.num); 結(jié)構(gòu)成員變量可以施加何種運算,取決于該成員變量的類型.結(jié)構(gòu)變量在其整體上只有賦值運算,例如: student1 = student2;15結(jié)構(gòu)與聯(lián)合形式和概述 結(jié)構(gòu)類型可以嵌套定義, 即一個結(jié)構(gòu)中的一個或多個成員是其他結(jié)構(gòu)類型的變量。并且只有最內(nèi)層的成員才能參加運算,要連續(xù)使用“ .”運算符, 從外層結(jié)構(gòu)變量找到內(nèi)層結(jié)構(gòu)變量,逐層存取,直至最內(nèi)層的成員。16結(jié)構(gòu)與聯(lián)合形式和概述訪問嵌套的結(jié)構(gòu)成員s

10、truct date int month; int day; int year;struct student int num; char name20; char sex; int age; struct date birthday; char addr30; stu;numnamesexagebirthdayaddrmonthdayyearstu. birthday.month = 6;stu. birthday.day = 7;17結(jié)構(gòu)與聯(lián)合形式和概述9.4 結(jié)構(gòu)的初始化 給結(jié)構(gòu)變量賦值的方法同于數(shù)組。初始數(shù)據(jù)個數(shù)、順序和類型應與結(jié)構(gòu)成員一一對應。 #include int main( )

11、 struct student int num; char name20; char sex; stu printf(”%d, %s, %cn”,stu.num, , stu.sex ); =10001, ”WangPing”, F;18結(jié)構(gòu)與聯(lián)合形式和概述嵌套的結(jié)構(gòu)變量的初始化:struct date int month; int day; int year;struct student int num; char name20; char sex; struct date birthday; int age;stu=10001,”WangPing”,F, 5,24,1986

12、, 24;19結(jié)構(gòu)與聯(lián)合形式和概述9.5 結(jié)構(gòu)與函數(shù)9.5.1 結(jié)構(gòu)成員作函數(shù)參數(shù) 當你將一個結(jié)構(gòu)變量的成員作為實參傳遞給函數(shù)時,可以采用傳值方式,也可以采用傳址方式。值傳遞時,相應的形式參數(shù)應說明為同類型的變量;而地址傳遞時,相應的形式參數(shù)應說明為指向同類型的指針,調(diào)用時,在實參前用“&”操作符。20結(jié)構(gòu)與聯(lián)合形式和概述9.5.2 結(jié)構(gòu)作函數(shù)參數(shù) 當一個結(jié)構(gòu)作為一個參數(shù)傳遞給函數(shù)時,按標準的賦值調(diào)用的方法可將整個結(jié)構(gòu)傳遞給函數(shù)。這意味著,在調(diào)用函數(shù)時,函數(shù)內(nèi)部結(jié)構(gòu)內(nèi)容的改變不會影響到作為實參被調(diào)用的那個結(jié)構(gòu)變量。 當用一個結(jié)構(gòu)作為一個形式參數(shù)時,要注意的一點是:形參的類型必須與實參的類型一致

13、。最簡單的方法是定義一個全程結(jié)構(gòu),然后用結(jié)構(gòu)名來說明所需的結(jié)構(gòu)變量和參數(shù)。21結(jié)構(gòu)與聯(lián)合形式和概述9.5.3 結(jié)構(gòu)型函數(shù) 當函數(shù)的返回值是結(jié)構(gòu)變量時, 該函數(shù)稱為結(jié)構(gòu)型函數(shù)。其定義格式為: struct 函數(shù)名( ) #include #include struct data char s20; int a; ; 下面看一個例子:22結(jié)構(gòu)與聯(lián)合形式和概述 main( ) struct data var, fun( ); /*調(diào)用前先說明 */ var = fun( ); printf(”vab.s=%s var.a=%dn”,var.s,var.a); struct data fun( ) s

14、truct data temp; strcpy(temp.s, ”program”); temp.a=256; return(temp); 23結(jié)構(gòu)與聯(lián)合形式和概述9.6 結(jié)構(gòu)數(shù)組 所謂結(jié)構(gòu)數(shù)組,即數(shù)組中的每個元素都是一個結(jié)構(gòu)類型的數(shù)據(jù)。struct student int num; char name20; char sex;struct student stu2;struct student int num; char name20; char sex;stu2; 結(jié)構(gòu)體數(shù)組的定義方法:24結(jié)構(gòu)與聯(lián)合形式和概述 結(jié)構(gòu)數(shù)組描述的是一個二維表格。對結(jié)構(gòu)數(shù)組的初始化分別遵循數(shù)組和結(jié)構(gòu)的初始化規(guī)則

15、。 方法:將數(shù)組中的每個元素(即結(jié)構(gòu)變量)的數(shù)據(jù)分別用花括號括起來。 struct student int num; char name20; char sex; stu2=1001,”LiuLi”,F,1101,”HeFei”,M; 如果賦初值的數(shù)據(jù)組的個數(shù)與所定義的數(shù)組元素個數(shù)相同,則數(shù)組的長度可省略。如; stu =1001,”LiuLi”,F,1101,”HeFei”,M;25結(jié)構(gòu)與聯(lián)合形式和概述 如果賦初值的數(shù)據(jù)組的個數(shù)少于所定義的數(shù)組元素個數(shù),則數(shù)組的長度不可省略。如; stu 2=1001, ”LiuLi”, F; 執(zhí)行初始化語句時就用初值表中的初值符按序?qū)ε旁谇懊娴臄?shù)組元素進行

16、賦值,而余下沒有對應初值符的數(shù)組元素就被隱式初始化,即:所有算術(shù)型成員被賦值0,字符型成員賦以“空”即“0”,所有指針類型的成員被賦予空指針常量NULL。 對結(jié)構(gòu)體數(shù)組元素的引用也就是對結(jié)構(gòu)變量的引用。因此有: stu1.sex = F; stu0.num = 1001;26結(jié)構(gòu)與聯(lián)合形式和概述9.7 結(jié)構(gòu)與指針9.7.1 指向結(jié)構(gòu)的指針 指向結(jié)構(gòu)的指針,它指向一個結(jié)構(gòu)變量,即指向該變量所分配的存儲區(qū)域的首地址。 struct student int num; char name20; char sex; stu,*p; p = &stu; /* 結(jié)構(gòu)指針p指向結(jié)構(gòu)變量stu */27結(jié)構(gòu)與聯(lián)

17、合形式和概述 結(jié)構(gòu)指針定義的一般格式: struct 結(jié)構(gòu)標記 *結(jié)構(gòu)指針名;如:struct student wang, zhao; /*定義結(jié)構(gòu)變量*/ struct student man3; /*定義結(jié)構(gòu)數(shù)組*/ struct student *p1, *p2; /*定義結(jié)構(gòu)指針*/ p1 = &wang; /* 指針指向結(jié)構(gòu)變量 */ p1 wang28結(jié)構(gòu)與聯(lián)合形式和概述 結(jié)構(gòu)指針的存儲特性和運算規(guī)則同普通指針。 結(jié)構(gòu)指針自身地址值的修改量取決于它所指向的結(jié)構(gòu)變量的類型。 通過結(jié)構(gòu)指針引用結(jié)構(gòu)成員的常用方法: 結(jié)構(gòu)指針 -結(jié)構(gòu)成員名 它與下式等價: (*結(jié)構(gòu)指針). 結(jié)構(gòu)成員名 “

18、-”是指向運算符,左結(jié)合性 根據(jù)前面的定義,下列各式等價: (*p1).num p1-num29結(jié)構(gòu)與聯(lián)合形式和概述 選擇填空: 設(shè)有如下聲明 struct person char name20; int age; char sex; a = ”Lining”, 20, m,*p = &a;則對字符串Lining 的引用方式可以是_ A. (*p). name B. C. D. p-name 30結(jié)構(gòu)與聯(lián)合形式和概述 下面討論指向結(jié)構(gòu)數(shù)組的指針。struct student int num; char name20; char sex;stu20,*p;p=stu;

19、 首先要注意,該指針變量的類型是數(shù)組元素的類型即相應的結(jié)構(gòu)類型。 請問下面兩個表達式 (+p)-num (p+)-num的結(jié)果分別為何?1001”LiuLi”F1101”HeFei”M1201”WanLi”Fstu0stu1stu2p1101100131結(jié)構(gòu)與聯(lián)合形式和概述9.8 結(jié)構(gòu)的存儲分配 結(jié)構(gòu)在內(nèi)存中是如何存儲的呢?其成員變量是如何安排空間的呢? 一般說來,編譯器按照各個成員它們被聲明的順序一個接一個地給每個成員分配內(nèi)存空間,第一個成員的地址和整個結(jié)構(gòu)的地址相同。但是,為了提高運算效率,如有必要,編譯器會自動進行結(jié)構(gòu)成員變量的邊界對齊。何謂邊界對齊?由于時間關(guān)系,請同學們閱讀教材。關(guān)于

20、這方面更詳細的討論請查閱有關(guān)資料。 32結(jié)構(gòu)與聯(lián)合形式和概述9.9 位段9.9.1 為什么要引入位段 C語言提供了多種位操作,我們在節(jié)已經(jīng)作了介紹。位操作使得對字節(jié)或字按位存取成為可能。下面看一個例子: 設(shè)有五個數(shù)據(jù)的類型及其值域如下: b1 布爾值 b2 布爾值 b3 布爾值 value 取112之間的整數(shù) index 取0500之間的整數(shù)1114933結(jié)構(gòu)與聯(lián)合形式和概述 可見,存儲這五個數(shù)據(jù)共需16位。我們恰可定義一個整型變量: unsigned int intdata;來存儲這五個值。并可隨意在intdata內(nèi)部分配某些位用于存儲這五個數(shù)據(jù)。下面就是一種分配:b1 b2 b3 valu

21、e index 設(shè)0n15,下面的語句通過使用位操作把value域置為值n:34結(jié)構(gòu)與聯(lián)合形式和概述 Intdata=(intdata&(0 xf9)|(n&0 xf)9) 設(shè)intdata的原值為: 0 x55BA n的值為: 0 xB 11010 0X55BA下面我們用豎式計算上述表達式: &:value域:首先被清為零,其他域不變. |: 00000 (n&0 xf)9 n=0 xB 置入value域35結(jié)構(gòu)與聯(lián)合形式和概述 上面表達式中intdata&(0 xf9) 僅是為了確保值n一定在015之間。若已知0n15,則表達式 Intdata=(intdata&(0 xf9)|(n&0

22、xf)9)可簡化為下式: intdata|=n9)&0 xf; 可見位操作不能將某一特定的數(shù)據(jù)域作為一個數(shù)據(jù)單位來存取。位字段提供了一個存取位域的方法。 位段提供了一個存取位域的簡便方法。36結(jié)構(gòu)與聯(lián)合形式和概述9.9.2 位段的聲明和訪問 位段(又稱位結(jié)構(gòu))是一種特殊的結(jié)構(gòu),它以二進制位為單位分配成員空間。在需按位訪問一個字節(jié)或字的某些位時, 位結(jié)構(gòu)比按位運算更加方便。 位結(jié)構(gòu)定義的一般形式為: struct 位結(jié)構(gòu)標記 數(shù)據(jù)類型 成員名1: 整型常數(shù)1; 數(shù)據(jù)類型 成員名2: 整型常數(shù)2; 位結(jié)構(gòu)變量;必須是int(unsigned int或signed int)必須是非負的整數(shù), 范圍是

23、015, 表示二進制位的個數(shù) 如果需要,成員名可以為空37結(jié)構(gòu)與聯(lián)合形式和概述 下面是一個位段聲明的例子: struct packed unsigned a: 8; unsigned b: 4; unsigned c: 3; unsigned d: 1; ; 上述位結(jié)構(gòu)的一種可能的空間分配38結(jié)構(gòu)與聯(lián)合形式和概述說明: 1.位結(jié)構(gòu)中的成員可以定義為unsigned, 也可定義為signed, 但當成員長度為1時, 會被認為是unsigned類型。因為單個位不可能具有符號。 2.位結(jié)構(gòu)中的成員不能使用數(shù)組和指針, 但位結(jié)構(gòu)變量可以是數(shù)組和指針,如果是指針, 其成員訪問方式同結(jié)構(gòu)指針。 3.位結(jié)構(gòu)

24、總長度(位數(shù)), 不一定是各個位成員定義的位數(shù)之和。 4.不能定義返回值為位段的函數(shù);39結(jié)構(gòu)與聯(lián)合形式和概述 5.位段成員不能跨越“整型數(shù)邊界”。若發(fā)生這種情況,對應的位段成員將被移至下一個int型空間存放。 例如:定義位段: struct unsigned a1: 1; unsigned a2: 9; unsigned a3: 12; a; a1 a2 0 1 9 10 15 a3 0 1 11 12 15 40結(jié)構(gòu)與聯(lián)合形式和概述 防止位段成員跨越“整型數(shù)邊界”有兩種方法: 使用無名成員。無名成員的作用是所定義的空間不用。如: struct bit unsigned d1:3, d2:3

25、, d3:8; unsigned :2; unsigned d4:3, d5:5, d6:8; 無名成員,表示此處要空2位不用,下面的位成員接著往下存放。41結(jié)構(gòu)與聯(lián)合形式和概述 使用0作特殊的位長。長度為0的位成員表示下一個位成員要從下一個int型空間開始存放。如: struct bits unsigned count: 5; unsigned flag: 2; unsigned next: 0; unsigned num: 10; 第一個int型空間數(shù)據(jù)存放結(jié)束從第二個int型空間開始存放42結(jié)構(gòu)與聯(lián)合形式和概述 6.位結(jié)構(gòu)成員可以與其它結(jié)構(gòu)成員一起使用。例如: struct info char name8; int age; struct addr address; float pay; unsigned state: 1; unsigned pay: 1; workers; 由此可見位段成員的訪問與結(jié)構(gòu)成員的訪問相同。如: 43結(jié)構(gòu)與聯(lián)合形式和概述9.10 聯(lián)合 “聯(lián)合”也是一種構(gòu)造類型的數(shù)據(jù)結(jié)構(gòu),它能使幾個不同類型的變量共同占用同一段內(nèi)存空間。因此,當需要在不同的時刻把不同的數(shù)據(jù)存儲于同一個位置時,可使用聯(lián)合。 44結(jié)構(gòu)與聯(lián)合形式

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論