函数
函数概述
【函数概述】复用化,一堆代码的集合,用一个标签(函数名)去描述它,访问他
函数三要素,函数名 (地址)输入参数,返回值
使用指针保存函数地址?
定义函数和调用函数的区别?
标签就是地址,但由于访问方式的不同,得到的结果也不同fun(1)###fun(21)
输入参数
【承上启下】的功能
1.调用者
函数名(要传递的数据) 实参
2.被调者 -函数的具体实现
函数的返回值 函数名(接收的数据) 形参
{
xxxx
具体实现
}
实参传递给形参
传递的形式:【拷贝】
值传递
交换函数swap()
传递的是备份,原有的空间不会有任何改变
上层调用者,保护自己的空间【不被修改】的能力
地址传递
门牌号
上层调用者,让下层子函数【修改】自己空间值的方式
空间的读写
只读空间:const char *p;
char *p;该空间可以修改
举例:
sprintf();格式化字符串处理
int sprintf(char *str,const char *format,...);
int a=12;
char buf[10];
sprintf(buf,"%d",a);
连续空间的传递
连续空间的只读性
结构体变量-建议地址传递
struct abc{int a;int b;};
struct abc buf;
实参:fun(buf); fun(&buf);
形参:void fun(struct abc a); void fun(struct struct abc *a);
连续空间的传递【数组】-考虑地址传递
数组名,数组标签,标签就是地址
实参:int abc[10];
fun(abc);
形参:void fun(int *p);
字符空间和非字符空间最大的区别:结束标志的不同
字符空间:
空间首地址,结束标志
结束标志:内存中存放了0x00(1B),字符空间
非字符空间0x00,不能当成结束标志
void fun(char *p)//const char *p
{
int i=0;
while(p[i]){
//p[i]操作...
i++;
}
}
举例:编写一个strlen()函数,具体的实现可根据CPU决定
分析:1.对连续空间读内存,传递首地址
2.只读字符串 const char *p;
int strlen(const cahr *p)
{
int i=0;
/*错误处理,判断输入参数是否合法*/
if(p==NULL){
//return...
}
/*内存处理,遍历*/
while(p[i]){//结束条件
**********
i++;
}
}
编写一个strcpy()函数
void strcpy(char *dest,const char *src);
""--->初始化const char *
char buf[10] --->初始化char *
非字符空间
int *p;
unsigned char *p;
....
0不能作为结束标志,结束标志:数量
void fun(unsigned char *p,int len)
{
int i;
for(i=0;i<len;i++)
{
....
}
}
void *:在形参中,数据空间的标识符,可以接收任何类型传入,子函数反向修改上层空间的内容
大小:len
举例:void *memcpy(void *dest,const void *src,size_t n);
int fun(void *buf,int len)
{
unsigned char *tem=(unsigned char *)buf;
for(int i=0;i<len;i++)
{
tem[i]...
}
}
返回值
基本语法
调用者
a=fun();
被调者 实现
int fun()
{
return num;
}
【拷贝】
返回基本数据类型
函数承上启下的作用,修改上层函数的值
int fun1(void); main:int a=0;a=fun1();
void fun2(int *p); main:int a=0;fun2(&a);//传递的是a的地址,a的值可以被下层函数修改
【应用】当一个函数需要两个int返回值时:
int fun(int *p);
指向一个新的地方:
int *fun1(void);
int main()
{
int *p;
p=fun1();
}
定义成*p是想修改p指向的值,定义成**p是想修改p指向的地址
void fun2(int **P);
int main()
{
int *p;
fun2(&p);
}
返回连续空间类型
指针作为空间返回的唯一的数据类型
地址操作:指向的合法性【不是局部空间】
不合法的举例:在fun函数中开辟的空间 buf ,随着被调用函数的结束,空间即被回收释放,主函数中的指针相当于指向了一片已经消失了的空间
char *fun(void)
{
char buf[]="hello world!";
return buf;
}
int mian()
{
char *p;
p=fun();
printf("the p is %s\n",p);
return 0;
}
---》
1.只读区
char *fun(void)
{
return "hello world!";//字符串常量就是一个地址值,存放在常量区中
}
2.静态区
添加static关键字
3.堆区
char *s=(char *)malloc(100);//申请
strcpy(s,"hello world");//初始化
main:free(p);//释放
使用者:
int *fun();
int *p=fun();
函数内部实现
基本数据类型 fun(void)
{
基本数据类型 ret;
......
ret=xxx;
return ret;
}