函数
通俗理解就是一堆代码的集合,用一个标签来描述它,用于需要的地方复用。一般具有承上启下的作用,输入一些东西操作之后再输出一些东西。
函数一般包括三要素:1、函数名(函数地址标签)2、输入参数 3、返回值
由于函数名为一块特殊地址的标签,则可以用指针描述函数
int (*p)(int, int, char);//右边()告诉指针P是函数类型的指针,输出参数为int int char 类型的,左边告诉指针P返回值为int类型的。以例子可以实现printf的功能。
函数的参数的传递
函数的调用一般有调用者和被调者。
调用者(使用函数的地方)
方式:
函数名(传递的数据) //要传递的数据为实参
被调者(函数实现的地方)
方式:
函数返回值类型 函数名(要接受的数据) //接收的数据为形参
{
函数代码具体实现XXXX
xXXXXX
}
实参传递给形参传递的形式:按位拷贝赋值 以下例子结果为34
由于实参传递给形参是拷贝的方式,所以直接传值不会改变实参的大小,可以理解为我传递的参数是原来的备份不会对我原来的空间的值照成影响,但使用地址传递可以改变别的空间的变量值,像结构体、数组这样大的连续空间的传递一般为地址传递,减少内存占用,以下例子是对地址传递改变原有空间的值:
在函数实现的时候为了传递地址提示程序员不能修改,一般加上const修饰,如下下不可以对P进行更改:
以下例子会发生段错误:
对于字符空间地操作一般注意是否能修改,即是否需要要const修饰,若用const修饰一般使用“xxx”来初始化,char *p 一般使用buf来初始化,结束一般判断是否为‘\0’
对于非字符空间一般传递连续空间时,一般需要再传首地址的同时传空间的大小
Void * :非字符空间的标识符 ,没有结束标志,一般跟传递数据大小。一般使用方法
一般地址传递参数为void*代表对地址的修改,而传递指定类型的如:int *
代表对值的修改
到这函数的参数传递告一段落了,可以看一下下面这个例子检测是否理解
以下例子P不会改变:
形参拷贝P的值(p指向的一个地址),无论对p指向的地址的副本怎么操作,p指向的地址和p本身的地址都不会改变,但P指向的地址的值可能被改变。
函数的返回值
返回值和参数传递类似,也是逐一拷贝的原理,可以接收值也可以接收地址。
需要注意的是:
1、以下函数是返回指针的地址:
2、在C语言函数中不能对数组的空间,只能通过指针返回数组的首地址,
3、指针是空间返回的唯一数据类型
4、地址:指向的合法性
作为函数的设计者,必须保证函数返回的地址所指向的空间是合法。不是局部变量。
三个函数对比理解: