概念
用一个标签去代表一堆代码,为了复用化 标签–>函数名
返回值 函数名(输入参数){}
- 函数指针
char *p;
char (*p)[10];
int (*p)(int ,int,char);
函数三要素
函数名 (地址)
定义调用函数
获取函数地址直接调用
int (*myshow)(const char *,...);
printf("HI");
myshow = printf;
myshow("===");
存函数地址的数组
int (*p[7])(int,int);
p[0]=fun0;//注册
p[1]=fun1;
...
//回调
p[day](10,20);
输入参数
承上启下,有输入输出
调用者:
函数名(要传递的数据)//实参
被调者:
函数具体实现
函数返回值 函数名(接收数据)//形参
{xxx}
值传递-普通类型
上层调用者保护自己空间不被修改的能力
int a = 1;
fun(a);
a ?= 1; //true
实参传递给形参
- 传递的形式:拷贝
地址传递-普通类型
int a = 1;
fun(&a);
a ?= 1://未知
如果想要直接修改原数据则应该传入地址
[!NOTE] eg:
int a; scanf(%d,a);//有误 scanf(%d,&a);//要对a修改,所以应该这样写,否则a执行完前后不变
作用
- 值修改 int * short * long *
- 空间传递
- 方便子函数直接修改上层空间 const *
- 空间传递 char * void *
连续空间的传递-嵌入式中常用
两大因素
- 数组
- 数组名标签
- 结构体
- 结构体变量
数组
地址传递
int abc[10];
//实参
fun(abc[10]);
fun(abc);//这样写
//形参
void fun(int *p)
void fun(int p[10])//同上
结构体
类似结构体这样的空间,函数与函数之间的调用方式最好用指针,省空间
struct abc{int a;int b;int c;}
struct abc buf;
//实参
fun(buf);
fun(&buf);
//形参
void fun(struct abc a1)
void fun(struct abc *a2)//节约空间
读写问题
既要避免拷贝浪费内存,又要避免改变传入值可以使用const传入地址
const *p; //只读
//上下二选一
char *p;//可能修改
void fun(const char *p){}
空间分类
结束标志不同,
字符空间
结束标志:内存存放了 0x00(1B),
[!空间操作函数示例]
void fun(char *p){ int i = 0; while(p[i]){ p[i]... i++; } }
[!strlen函数实现]
int strlen(const char *p)
{
int i = 0;
/*错误处理,判断输入是否合法*/
if(p == NULL){
//return...
}
/*内存处理,从头到尾,逐一处理*/
while(p[i]){
//功能
}
}
非字符空间
结束标志:0x00,不能当作结束标志
void fun(unsigned char *p,int len){
int i;
for(i=0;i< len;i++){
p[i]=;a=p[i];//++++++++++
}
//...
}
- 对于接收的数据定义为
unsigned char
- 字符以0结尾,若有0则显示不全
- 使用void表示无类型
send(int sockfd, const void *buf,size_t len,int flags);
recv(int sockfd,void *buf,size_t len,int flags);
对于void传入的数据,使用数组读可能会报错,在函数内部定义一个unsigned char的指针来区出传入的值然后再操作
int fun(void *buf,int len){
unsigned char *tmp = (unsigned char *)buf;
tmp[i]//....
}
返回值
基本语法
返回类型 函数名称(输入列表)
{
return
}
返回类型
基本数据类型 可以返回结构体,但是工程中不建议,返回是拷贝过程,结构体太大费内存,可以返回指针 指针(空间) 不能返回数组
返回基本数据类型
//直接返回值
int fun1(void);
int a=0;
a=fun();
//传入地址返回值
void fun2(int *p);
int a=0;
fun2(&a);a
//直接返回地址
int *fun3(void);
int *p;
p=fun3()
//传入地址返回地址
void fun4(int **p)
int *p;
fun4(&p);
返回连续空间类型
指针作为空间返回的唯一类型 int *fun(); 地址: 指向的合法性 => 不是局部变量
函数内部实现
- 静态区,static
- 只读区,字符串啥的,基本不用
- 堆区,malloc申请的