004.函数设计
一、函数概述
函数名的本质
函数名:程序员编写代码空间的名称,本质就是一个地址(常量)
int fun(int a,int b);//声明一个地址常量
fun(10, 20);//使用这个地址,访问代码空间
定义变量来保存不同的常量
可以将fun的地址存入指针中
int fun(int a, int b);
int (*p)(int, int);
也可以利用typedef便于程序员的阅读
二、函数地址
函数地址传递的含义
在函数中,如果在参数中直接传输值,这个值只是形参,对其更改后并不会影响到原始空间中的变量值。而传递地址则是让程序访问原始空间,并且直接对原始数据进行更改,这样做也不会再申请额外内存放置复制的数据,节约空间。
连续空间
数组,结构体是典型的连续空间,我们常常需要去进行查看和修改
| 基础数据类型 | 连续空间 | |
|---|---|---|
| 看 | 值拷贝 | const |
| 改 | 地址拷贝 | 地址和空间大小 |
//基础数据类型
int fun1(int);//看
int fun2(int *);//改
//连续空间
int fun3(const int *);//看
int fun4(int *, int num);
空间结束标志
字符空间 结束有标志 0 '\0' 可以不限定长度(尽量还是限定一下)
非字符串空间 没有结束标志 限定长度
任意空间的声明
在声明任意空间时,需要注意形参与实参类型的统一,考虑越界问题
如果使用str时需要复制,可以使用函数strcpy或strncpy
函数返回值
一个函数,只能返回一个信息体:基础数据类型(int,char,float,double)或自定义类型(多个数据类型)
函数返回地址:保证地址的有效性
如果我不想把返回的内容打印到屏幕上,而是传递到某一个内存中,我们可以使用sprintf或snprintf
char *fun1(int flags) {
snprintf(buf,sizeof(buf), "====%d====", flags);
return buf;
}
char *fun2(int flags) {
char *buf;
buf = (char *)malloc(32);
snprintf(buf, 32, "====%d====", flags);
return buf;
}
void release_fun(void *p) {
free(p);
}
当函数返回地址时,我们需要判断这个地址是在静态区还是堆区
如果只有fun1这样的一个函数,那么显然是静态区,数据不做改变
如果是同时有fun2和release_fun的释放函数,那么地址就在堆区(有创建有释放)
浙公网安备 33010602011771号