函数、指针、数组的组合 及结构体和共用体

1.数组与函数

1) 数组元素作参数

large(int x, int y){...};

large(a[2], a[3]);

 

1) 数组名作参数

计算数组中用户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);

2) 多维数组名作参数

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)表示函数下一条指令。

3) 函数指针的赋值:

p = max; //直接给出函数名,不用给出参数。(因为是把函数地址赋值给p,与参数无关)

4) 函数指针调用函数:

调用时,(*p)代替函数即可,且要在(*p)加上实参。

c = max(a, b);

c = (*p)(a, b);

Ps:

函数指针指向函数入口地址,p+n, p++,p--等没有意义。

5) 函数指针作为函数参数

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);

6) 赋值:

pFunc[1] = fun1;

pFunc[2] = fun2;

7) 调用:

a = (*pFunc[i])(6, 7)

 

 

 

 

一、结构体

结构体是数据类型

数据类型可以分为系统定义的类型(int/char/float...)和用户定义类型。

当多个信息由不同的类型组合在一起的来描述一个事物的时候,开发者会根据自己的要求构造一个数据类型----结构体(structure)/结构。

结构体是用户自己定义的一种数据类型。

5.定义结构体

struct  结构体名 //用户自己决定类型名

{

.......//成员列表

} ;  //用分号 ;作为结束符,且不能省略。

Ø 结构体类型是用户自定义的一种数据类型。

Ø 由不同基本数据类型的数据构成。

Ø 定义类型不分配空间,声明变量才分配空间。

6.结构体类型变量定义

定义一个变量,先要有数据类型,然后再定义变量

定义结构体类型的变量有三种方式:

① 先定义结构体类型,再定义

struct  结构体名/数据类型名 struct  Mytype

{ {

成员列表; int id;  char  name[N]; char sex;

} }

struct  结构体名   变量名; struct  Mytype   man1, man2;

man1man2是变量,它们的类型是 struct  Mytype 类型。

//Mac头部,总长度14字   TCP/IP协议头部结构体

typedef struct _eth_hdr  

{  

    unsigned char dstmac[6]; //目标mac地址  

    unsigned char srcmac[6]; //源mac地址  

    unsigned short eth_type; //以太网类型  

}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);

8) 初始化

定义同时初始化

 

9) 赋值

相同结构体类型的结构体变量可以相互赋值,不同类型不可以。(数组完全不可以相互赋值)

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]  

1union data a=b; //把共用体变量初始化为另一个共用体

2union data a={123}; //初始化共用体为第一个成员

3union data a={.ch='a'}; //指定初始化项目,按照C99标准

与结构体的比较:

存储空间的区别

结构体变量可以作为函数参数,函数也可返回一个结构体指针变量。联合体不可以作为函数参数。

 

1

 

a的大小为结构体大小,x,y,z分别为4,5,6. k赋值,k要共享内存,union从首地址开始存放数据,x的位置。

 

《格列佛游记》中把人类按照敲鸡蛋的方向分为两类人,计算机在数据存储的时候也有两种存储机制,分别为大小端。

编写代码测试系统大小端

<Endianness.c>

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值