函数、指针、数组的组合 及结构体和共用体
1.數(shù)組與函數(shù)
1)?數(shù)組元素作參數(shù)
large(int x, int y){...};
large(a[2], a[3]);
?
1)?數(shù)組名作參數(shù)
計(jì)算數(shù)組中用戶6個(gè)月的積分平均值
float aver(float b[6]) {....}
float a[6]...;
av = aver( a );
a.?數(shù)組名作函數(shù)參數(shù),兩個(gè)數(shù)組分別定義。
b.?實(shí)參數(shù)組和形參數(shù)組類型保持一致。
c.?形參數(shù)組大小不起任何作用,因?yàn)?/span>C語(yǔ)言不對(duì)形參數(shù)組大小作檢查,只是將實(shí)參數(shù)組的地址傳遞給了形參數(shù)組名,即在空間上為形參數(shù)組分配了一個(gè)指針大小空間。形參數(shù)組和實(shí)參數(shù)組共用存儲(chǔ)單元,a[2]和b[2]指的同一個(gè)元素。
數(shù)組形式:double ?fun(double b[5]);
地址形式:double ?fun(double *b );
d.?形參數(shù)組可以不指定大小,定義時(shí)保留空方括號(hào)即可。
float aver(float b[]);
e.?實(shí)參數(shù)組大小可以用另一個(gè)形參進(jìn)行傳遞。
float ?aver(float b[], ?int n);
2)?多維數(shù)組名作參數(shù)
a.?函數(shù)調(diào)用時(shí)只需要傳遞數(shù)組名。
b.?形參數(shù)組的一維可以省略,括號(hào)不可以省略。二維不可省略,因?yàn)槎S數(shù)組在內(nèi)存中是按照行存放的,必須指定列數(shù)。
int ?array[3][10]
int ?array[ ][10]
c.?C語(yǔ)言不檢查第一維大小,在第二維數(shù)組相同的情況下,形參一維可以與實(shí)參大小不同。
實(shí)參: int ?marks[5][10];
形參: int ?array[2][10];
練習(xí):對(duì)二維數(shù)組a[4][3]分析,求出最大值。
?
?
?
?
2.指針函數(shù)
整型函數(shù)是返回一個(gè)整型值的函數(shù);
指針函數(shù)是返回一個(gè)地址(指針)值的函數(shù)。
1)?定義形式:
<數(shù)據(jù)類型> ?*<函數(shù)名稱> ?(<參數(shù)說(shuō)明>)??{...}
char ?*mystring (void) ?{}
int ?* fun(int x, int y);
函數(shù)名先和優(yōu)先級(jí)高的()結(jié)合組成函數(shù)。
?
3.函數(shù)指針
函數(shù)地址是函數(shù)的入口地址。函數(shù)指針變量是用來(lái)存放函數(shù)地址的指針變量。
函數(shù)名代表函數(shù)的地址。
PS:
函數(shù)可以通過(guò)函數(shù)名(表示函數(shù)地址)調(diào)用;也可以通過(guò)函數(shù)指針調(diào)用。
當(dāng)一個(gè)整型指針指向一個(gè)整型變量,則可以通過(guò)指針去訪問(wèn)整型變量;
當(dāng)一個(gè)函數(shù)指針指向一個(gè)函數(shù),則可以通過(guò)這個(gè)指針調(diào)用函數(shù)。
1)?函數(shù)指針形式:
<數(shù)據(jù)類型> ?(*<函數(shù)指針名>) ?(<參數(shù)列表>);
數(shù)據(jù)類型是其指向函數(shù)的返回值類型。
int ?(*p)(int x, ?int y);
p先和* 結(jié)合,組成指針變量,然后和()結(jié)合組成指向函數(shù)的指針變量,p指向函數(shù)入口處,不能指向函數(shù)中的某一條指令,不能用*(p+1)表示函數(shù)下一條指令。
3)?函數(shù)指針的賦值:
p = max; //直接給出函數(shù)名,不用給出參數(shù)。(因?yàn)槭前押瘮?shù)地址賦值給p,與參數(shù)無(wú)關(guān))。
4)?函數(shù)指針調(diào)用函數(shù):
調(diào)用時(shí),用(*p)代替函數(shù)即可,且要在(*p)加上實(shí)參。
c = max(a, b);
c = (*p)(a, b);
Ps:
函數(shù)指針指向函數(shù)入口地址,p+n, p++,p--等沒(méi)有意義。
5)?函數(shù)指針作為函數(shù)參數(shù)
void sub(int (*x1)(int), int (*x2)(int , int ))
{
int a, b, i, j;
a = (*x1)(i);
b = (*x2)(j);
}
?
?
?
4.函數(shù)指針數(shù)組
函數(shù)指針數(shù)組是包含多個(gè)函數(shù)地址的數(shù)組;
1)?定義形式:
<數(shù)據(jù)類型> ?(*<函數(shù)指針數(shù)組名> [<大小>]) ?(<參數(shù)列表>);
int ?(*pFunc[2]) (int a, int b);
6)?賦值:
pFunc[1] = fun1;
pFunc[2] = fun2;
7)?調(diào)用:
a = (*pFunc[i])(6, 7)
?
?
?
?
一、結(jié)構(gòu)體
結(jié)構(gòu)體是數(shù)據(jù)類型
數(shù)據(jù)類型可以分為系統(tǒng)定義的類型(int/char/float...)和用戶定義類型。
當(dāng)多個(gè)信息由不同的類型組合在一起的來(lái)描述一個(gè)事物的時(shí)候,開(kāi)發(fā)者會(huì)根據(jù)自己的要求構(gòu)造一個(gè)數(shù)據(jù)類型----結(jié)構(gòu)體(structure)/結(jié)構(gòu)。
結(jié)構(gòu)體是用戶自己定義的一種數(shù)據(jù)類型。
5.定義結(jié)構(gòu)體
struct ?結(jié)構(gòu)體名 //用戶自己決定類型名
{
.......//成員列表
}?;??//用分號(hào) ;作為結(jié)束符,且不能省略。
??結(jié)構(gòu)體類型是用戶自定義的一種數(shù)據(jù)類型。
??由不同基本數(shù)據(jù)類型的數(shù)據(jù)構(gòu)成。
??定義類型不分配空間,聲明變量才分配空間。
6.結(jié)構(gòu)體類型變量定義
定義一個(gè)變量,先要有數(shù)據(jù)類型,然后再定義變量
定義結(jié)構(gòu)體類型的變量有三種方式:
① 先定義結(jié)構(gòu)體類型,再定義
struct ?結(jié)構(gòu)體名/數(shù)據(jù)類型名 struct ?Mytype
{ {
成員列表; int id; ?char ?name[N]; char sex;
} ; } ;
struct ?結(jié)構(gòu)體名 ??變量名; struct ?Mytype ??man1, man2;
man1和man2是變量,它們的類型是 struct ?Mytype 類型。
//Mac頭部,總長(zhǎng)度14字節(jié)???TCP/IP協(xié)議頭部結(jié)構(gòu)體
typedef?struct?_eth_hdr??
{??
????unsigned?char?dstmac[6];?//目標(biāo)mac地址??
????unsigned?char?srcmac[6];?//源mac地址??
????unsigned?short?eth_type;?//以太網(wǎng)類型??
}eth_hdr;??
?
| 技巧1: #define ??MYTYPE ??stuct Mytype. ? MYTYPE ?man1, man2; 技巧2: ???typedef ?struct ??student ???{ ?char ??name[10] ; ???????int ??age ; ???????int ??s1, s2 ; ????} SD; ???SD ??st1, st2;//書寫簡(jiǎn)單, ?移植性增強(qiáng) ? |
② 定義類型同時(shí)定義變量
struct ?結(jié)構(gòu)體名
{
成員列表;
} 變量名;
③ 直接定義結(jié)構(gòu)體變量
struct ?
{
成員列表;
}變量名;
?
7.引用、初始化、賦值
1)?引用
?結(jié)構(gòu)體變量名.成員名 //“?. ”是分量運(yùn)算符(成員運(yùn)算符),優(yōu)先級(jí)最高。
??直接引用單個(gè)成員student1.id = 121; //不能整體引用。
??成員又是一個(gè)結(jié)構(gòu)體類型
student2.birthday.month
??成員可以同普通變量一樣進(jìn)行運(yùn)算。
student2.age++;//age先和studen2結(jié)合。
??可以引用 結(jié)構(gòu)體變量成員 地址,也可以引用 結(jié)構(gòu)體變量 地址。但不能整體引用結(jié)構(gòu)體變量。
scanf(“%d”, &student2.id);
printf(“%p”, &student2);
scanf(“%d,%s,%f,%s...”, &student1);
8)?初始化
定義同時(shí)初始化
?
9)?賦值
相同結(jié)構(gòu)體類型的結(jié)構(gòu)體變量可以相互賦值,不同類型不可以。(數(shù)組完全不可以相互賦值)。
8.結(jié)構(gòu)體的大小
?
9.結(jié)構(gòu)體數(shù)組
具有相同結(jié)構(gòu)體類型的結(jié)構(gòu)體變量組成的數(shù)組。
定義:和結(jié)構(gòu)體變量定義方法相仿,要說(shuō)明是數(shù)組。
(舊標(biāo)準(zhǔn)中只能對(duì)全局和靜態(tài)存儲(chǔ)類別結(jié)構(gòu)體初始化)。
成員引用:stu[1].name
相同類型的結(jié)構(gòu)體可以相互賦值,結(jié)構(gòu)體數(shù)組元素可以直接對(duì)同類型元素賦值。
同樣不能對(duì)整個(gè)結(jié)構(gòu)體操作。
舉例:
?
?
10.結(jié)構(gòu)體指針
指向結(jié)構(gòu)體變量的指針變量稱為結(jié)構(gòu)體指針。
定義形式:
struct 結(jié)構(gòu)體名 *結(jié)構(gòu)體變量名
struct storage ??*p; //系統(tǒng)為指針本身分配內(nèi)存空間。
成員引用:
struct message
{
????uint8_t type; ??//數(shù)據(jù)類型
????uint8_t slave_address;
????uint8_t machine_num; ?
}infor1;
struce message ?*p = &infor1;
(*p).type = char ?//每次使用括號(hào)為編寫帶來(lái)不便,C給出了另一種方法:
p->type。-> 為指向運(yùn)算符。 和分量運(yùn)算符 . 擁有較高的優(yōu)先級(jí)。
| 小結(jié): 結(jié)構(gòu)體成員引用方式: stu.name (*p).name p->name //p為結(jié)構(gòu)體指針變量。 |
| struct ?usr { ??char ?name[10]; ??int num; ??flaot ?score; }; struct usr ?staff[100], *p; p = staff; p++或p = staff+1指向哪里? |
11.結(jié)構(gòu)體變量作參數(shù)
返回結(jié)構(gòu)體類型值的函數(shù)
結(jié)構(gòu)體類型名 函數(shù)名(形參...){...}
struct staff func(int x, char name[N]){...};
舉例:求學(xué)生成績(jī)總分和平均分(分別用結(jié)構(gòu)體變量作為參數(shù)和結(jié)構(gòu)體指針做參數(shù))<結(jié)構(gòu)體作參數(shù).c>
二、共用體 ?
不同數(shù)據(jù)類型使用同一段空間的構(gòu)造類型稱為共用體。(省空間)
共用體(union)在定義、說(shuō)明和使用形式和結(jié)構(gòu)體相似。
union foo
{
int i;
char c;
};
i = 5;
c = ‘a(chǎn)’;
printf(“%d %c”, i, c);
① union用同一個(gè)內(nèi)存空間存儲(chǔ)不同數(shù)據(jù)類型,即不能同時(shí)存下每個(gè)成員的數(shù)據(jù),同時(shí)只有一個(gè)成員。
② union變量中的數(shù)據(jù)時(shí)最后一次存放進(jìn)去的數(shù)據(jù),之前的數(shù)據(jù)會(huì)失去作用。
③ union變量地址和其他成員的地址是同一地址
不能對(duì)共用體變量名賦值,也不能企圖引用變量名來(lái)得到一個(gè)值,并且,不能在定義共用體變量時(shí)對(duì)它進(jìn)行初始化(可以, 僅僅對(duì)第一個(gè)成員初始化,后面的成員會(huì)覆蓋前面的數(shù)據(jù))。共用體變量的初始化[1]??。
(1)union data a=b; //把共用體變量初始化為另一個(gè)共用體
(2)union data a={123}; //初始化共用體為第一個(gè)成員
(3)union data a={.ch='a'}; //指定初始化項(xiàng)目,按照C99標(biāo)準(zhǔn)
| 與結(jié)構(gòu)體的比較: 存儲(chǔ)空間的區(qū)別 結(jié)構(gòu)體變量可以作為函數(shù)參數(shù),函數(shù)也可返回一個(gè)結(jié)構(gòu)體指針變量。聯(lián)合體不可以作為函數(shù)參數(shù)。 |
?
例1:
?
a的大小為結(jié)構(gòu)體大小,x,y,z分別為4,5,6. 對(duì)k賦值,k要共享內(nèi)存,union從首地址開(kāi)始存放數(shù)據(jù),x的位置。
?
| 《格列佛游記》中把人類按照敲雞蛋的方向分為兩類人,計(jì)算機(jī)在數(shù)據(jù)存儲(chǔ)的時(shí)候也有兩種存儲(chǔ)機(jī)制,分別為大小端。 編寫代碼測(cè)試系統(tǒng)大小端 <Endianness.c> |
?
?
總結(jié)
以上是生活随笔為你收集整理的函数、指针、数组的组合 及结构体和共用体的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何测试大端存储和小端存储
- 下一篇: 存储类型_malloc_typedef小