C语言函数指针,结构体阶段总结

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 的位置。
 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值