1.
数组与函数
1)
数组元素作参数
large(int x, int y){...};
large(a[2], a[3]);
2)
数组名作参数
计算数组中用户6
个月的积分平均值
float aver(float b[6]) {....}
float a[6]...;
av = aver( a );
a.
数组名作函数参数,两个数组分别定义。
b.
实参数组和形参数组类型保持一致。
c.
形参数组大小不起任何作用,因为C
语言不对形参数组大小作检查,只是将实参数组的地址传递给了形参数组名,
即在空间上为形参数组分配了一个指针大小空间。形参数组和实参数组共用存储单元,a[2]
和b[2]
指的同一个元素。
数组形式:
double fun(double b[5]);
地址形式:
double fun(double *b );
d.
形参数组可以不指定大小,定义时保留空方括号即可。
float aver(float b[]);
e.
实参数组大小可以用另一个形参进行传递。
float aver(float b[], int n);
3)
多维数组名作参数
a.
函数调用时只需要传递数组名。
b.
形参数组的一维可以省略,
括号不可以省略。二维不可省略,因为二维数组在内存中是按照行存放的,必须指定列数。
int array[3][10]
int array[ ][10]
c.
C
语言不检查第一维大小,在第二维数组相同的情况下,形参一维可以与实参大小不同。
实参:
int marks[5][10];
形参:
int array[2][10];
练习:对二维数组
a[4][3]
分析,求出最大值。
2.
指针函数
整型函数是返回一个整型值的函数;
指针函数是返回一个地址(
指针)
值的函数。
1)
定义形式:
<
数据类型
> *<
函数名称
> (<
参数说明
>) {...}
char *mystring (void) {}
int * fun(int x, int y);
函数名先和优先级高的()
结合组成函数。
3.
函数指针
函数地址是函数的入口地址。函数指针变量是用来存放函数地址的指针变量。
函数名代表函数的地址。
PS
:
函数可以通过函数名
(
表示函数地址
)
调用;也可以通过函数指针调用。
当一个整型指针指向一个整型变量,则可以通过指针去访问整型变量;
当一个函数指针指向一个函数,则可以通过这个指针调用函数。
1)
函数指针形式:
<
数据类型
> (*<
函数指针名
>) (<
参数列表
>);
数据类型是其指向函数的返回值类型。
int (*p)(int x, int y);
p
先和
*
结合,组成指针变量,然后和
()
结合组成指向函数的指针变量,
p
指向函数入口处,不能指向函数中的某一条指令,不能用
*(p+1)
表示函数下一条指令。
2)
函数指针的赋值:
p = max; //
直接给出函数名,不用给出参数。(
因为是把函数地址赋值给p,
与参数无关)
。
3)
函数指针调用函数:
调用时,
用(*p)
代替函数即可,
且要在(*p)
加上实参。
c = max(a, b);
c = (*p)(a, b);
Ps:
函数指针指向函数入口地址,
p+n, p++,p--
等没有意义。
4)
函数指针作为函数参数
void sub(int (*x1)(int), int (*x2)(int , int ))
{
int a, b, i, j;
a = (*x1)(i);
b = (*x2)(j);
}
4.
函数指针数组
函数指针数组是包含多个函数地址的数组;
1)
定义形式:
<
数据类型
> (*<
函数指针数组名
> [<
大小
>]) (<
参数列表
>);
int (*pFunc[2]) (int a, int b);
2)
赋值:
pFunc[1] = fun1;
pFunc[2] = fun2;
3)
调用:
a = (*pFunc[i])(6, 7)
一、
结构体
1.
结构体是数据类型
数据类型可以分为系统定义的类型(int/char/float...)
和用户定义类型。
当多个信息由不同的类型组合在一起的来描述一个事物的时候,开发者会根据自己的要求构造一个数据类型----
结构体(structure)/
结构。
结构体是用户自己定义的一种数据类型。
5.
定义结构体
struct
结构体名 //
用户自己决定类型名
{
.......//
成员列表
}
; //
用分号
;作为结束符,
且不能省略。
Ø
结构体类型是用户自定义的一种数据类型。
Ø
由不同基本数据类型的数据构成。
Ø
定义类型不分配空间,声明变量才分配空间。
6.
结构体类型变量定义
定义一个变量,先要有数据类型,然后再定义变量
定义结构体类型的变量有三种方式:
①
先定义结构体类型,再定义
struct
结构体名/
数据类型名 struct Mytype
{ {
成员列表; int id; char name[N]; char sex;
}
; }
;
struct
结构体名
变量名; struct Mytype man1, man2;
man1
和man2
是变量,它们的类型是 struct Mytype
类型。
1.
//Mac头部,总长度14字节 TCP/IP协议头部结构体
2.
typedef
struct
_eth_hdr
3.
{
4.
unsigned
char
dstmac[6];
//目标mac地址
5.
unsigned
char
srcmac[6];
//源mac地址
6.
unsigned
short
eth_type;
//以太网类型
7.
}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;//书写简单, 移植性增强 |
②
定义类型同时定义变量
struct
结构体名
{
成员列表;
}
变量名;
③
直接定义结构体变量
struct
{
成员列表;
}
变量名;
7.
引用、初始化、赋值
1)
引用
结构体变量名.成员名
//“ . ”
是分量运算符(
成员运算符),
优先级最高。
Ø
直接引用单个成员student1.id = 121; //
不能整体引用。
Ø
成员又是一个结构体类型
student2.birthday.month
Ø
成员可以同普通变量一样进行运算。
student2.age++
;//age
先和studen2
结合。
Ø
可以引用
结构体变量成员
地址,也可以引用
结构体变量
地址。但不能整体引用结构体变量。
scanf(“%d”, &student2.id);
printf(“%p”, &student2);
scanf(“%d,%s,%f,%s...”, &student1);
2)
初始化
定义同时初始化
3)
赋值
相同结构体类型的结构体变量可以相互赋值,
不同类型不可以。(
数组完全不可以相互赋值)
。
8.
结构体的大小
9.
结构体数组
具有相同结构体类型的结构体变量组成的数组。
定义:和结构体变量定义方法相仿,要说明是数组。
(
旧标准中只能对全局和静态存储类别结构体初始化
)
。
成员引用:stu[1].name
相同类型的结构体可以相互赋值,结构体数组元素可以直接对同类型元素赋值。
同样不能对整个结构体操作。
举例:
10.
结构体指针
指向结构体变量的指针变量称为结构体指针。
定义形式:
struct
结构体名
*
结构体变量名
struct storage *p; //
系统为指针本身分配内存空间。
成员引用:
struct message
{
uint8_t type; //
数据类型
uint8_t slave_address;
uint8_t machine_num
;
}infor1;
struce message *p = &infor1;
(*p).type = char //
每次使用括号为编写带来不便,C
给出了另一种方法:
p->type
。->
为指向运算符。
和分量运算符 .
拥有较高的优先级。
小结: 结构体成员引用方式: stu.name (*p).name p->name //p为结构体指针变量。 |
struct usr { char name[10]; int num; flaot score; }; struct usr staff[100], *p; p = staff; p++或p = staff+1指向哪里? |
11.
结构体变量作参数
返回结构体类型值的函数
结构体类型名
函数名
(
形参
...){...}
struct staff func(int x, char name[N]){...};
举例:求学生成绩总分和平均分
(
分别用结构体变量作为参数和结构体指针做参数
)<
结构体作参数
.c>
二、
共用体
不同数据类型使用同一段空间的构造类型称为共用体。(
省空间)
共用体(union)
在定义、说明和使用形式和结构体相似。
union foo
{
int i
;
char c;
};
i = 5;
c = ‘a’;
printf(“%d %c”, i, c);
① union
用同一个内存空间存储不同数据类型,
即不能同时存下每个成员的数据,
同时只有一个成员。
② union
变量中的数据时最后一次存放进去的数据,
之前的数据会失去作用。
③ union
变量地址和其他成员的地址是同一地址
不能对共用体变量名赋值,也不能企图引用变量名来得到一个值,并且,不能在定义共用体变量时对它进行初始化(
可以
,
仅仅对第一个成员初始化
,
后面的成员会覆盖前面的数据)
。
共用体变量的初始化
[1]
。
(
1
)
union data a=b; //
把共用体变量初始化为另一个共用体
(
2
)
union data a={123}; //
初始化共用体为第一个成员
(
3
)
union data a={.ch='a'}; //
指定初始化项目,按照
C99
标准
与结构体的比较: 存储空间的区别 结构体变量可以作为函数参数,函数也可返回一个结构体指针变量。联合体不可以作为函数参数。 |
例1
:
a
的大小为结构体大小,x,y,z
分别为4,5,6.
对k
赋值,k
要共享内存,union
从首地址开始存放数据,x
的位置。