目录
1. 函数前言
1.1 函数的概念:
1.2 为什么要使用函数:
2. 标准库函数
2.1 什么是标准库:
2.2 库函数有哪些:
3. 自定义函数
3.1 函数的定义:
3.2 函数的声明:
3.4 函数的调用:
4. 实参 和 形参
4.1 实参:
4.2 形参:
4.3 实参和形参的关系
5. 数组传参
6. return语句
6.1 return语句作用:
6.2 常见的return问题:
7. 嵌套函数 和 链式访问
7.1 嵌套函数:
7.2 链式访问(例 - printf函数):
8. static修饰的函数 和 extern引入函数
8.1 生命周期 和 作用域:
8.2 static 修饰函数:
8.3 extern 引入函数:
1. 函数前言
1.1 函数的概念:
函数(子程序,过程)是完成特定任务的独立程序代码块。通常是用来打印信息,或者返回我们想要的值。
1.2 为什么要使用函数:
1.节省时间。对于重复无意义的代码,我们可以定义一个函数,包含重复语句。通过调用函数,我们就可以完成重复工作。
2.模块化工作。函数让程序更加模块化,提高了代码的可读性,方面后期的维护,完善。
2. 标准库函数
2.1 什么是标准库:
在C语言中,定义了各种语法,但它并不提供函数。C语言国际标准 ANSI C 定义了函数使用的规定。不同编译厂商根据C语言国际标准,在编译器上提供了各种函数的实现,这些函数就成称为库函数。
2.2 库函数有哪些:
库函数成千上万,如果说在这一一列举,那是不太可能地。我们大部分人并不可能全部学会记住,所以在需要的时候查到这些库函数如何使用是很重要的,这里博主提供C/C++库函数查询网站:/reference/
3. 自定义函数
3.1 函数的定义:
ret_type fun_name(形式参数)
{
}
●ret_type :函数返回类型(int ,float ,char.....),其中如果是 void,那么函数就是无返回值,只是完成特定工作。
●fun_name : 函数名,在主函数或是其他函数中,我们通过函数名来调用函数。有了函数名,我们可以非常方便的识别和完成某些工作。
●(形式参数):形参列表,作用是接受实参传来的值/址(在后期指针阶段我们会学习传址调用,本章全部基于传值调用)
●{ }:{ }包含的语句总称为函数体。我们就是在函数体重完成工作。
3.2 函数的声明:
ret_type fun_name(形式参数);
C语言是自上而下的读取语句(后期编译连接会接触到更为详细内容)。单文件中,如果函数定义在主函数后面,编译器可能会报错,而如果全部定义在主函数之前,又未免强人所难,这样我们可能连主函数都不知道在哪,做什么。所以我们通常会提前声明函数,告诉编译器这里有个函数,它的形参是什么,返回类型是什么。在主函数后面定义函数,告诉编译器,这个函数做些什么。
在 第 8 小讲中,将讲述多文件如何定义声明函数。
3.4 函数的调用:
fun_name(实际参数);
在主函数或是其他函数中,只要写出函数名,以及实参(也可以没有),就可以调用函数,完成特定工作。注意()是必须有的。
4. 实参 和 形参
4.1 实参:
实际参数就是真实传递给函数的参数。
4.2 形参:
形参,顾名思义就是形式上的参数。如果我们不去调用,那么形参就不回去创建。只有当我们调用函数的时候,形参才会向内存申请空间,这个过程就是形参的实例化。这块空间与实参所在空间时互补相同的两块空间。
4.3 实参和形参的关系
在没有学指针之前,我们可以简单地理解为 形参就是实参的临时拷贝。对形参的改变不会影响实参。
5. 数组传参
#include <>
void test(int arr[],sz); //函数的声明
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int sz = sizeof(arr)/sizeof(arr[0]);
test(arr,sz); //函数的调用——打印数组各元素
return 0
}
void test(int arr[],sz) //函数的调用
{
int i =0;
for(i=0;i<sz;i++)
{
printf("%d",arr[i]);
}
}
在数组传参的时候,我们要注意以下几点:
●形参 和 实参 所指向的是同一个数组,所以形参并不会创建新的数组,形参对数组的操作会影响实参。
●形参的[ ]中里面的数字可有可无。及时写错,也不会检查出错。
●形参个数 和 实参个数必须相同
●对于一维数组[ ]里面的数字可有可无,对于二维数组行[]里面的数字可有可无,列[ ]中必须要有。
6. return语句
6.1 return语句作用:
在函数中,return语句作用就是结束函数,返回后面的值。
6.2 常见的return问题:
● return语句后面可以是值,也可以是表达式。如果是表达式,先求值,再返回。若是 ; 则表明什么也不返回,函数返回类型为空(void)。
● 函数体中,如遇到return则函数直接结束,返回return后面的值,不执行后面的语句。
●若函数体中有if语句,则要保证每一种可能都有return,否则编译器会报警告。
●若return返回值与函数返回类型不一致时,则将返回值强制转换成函数返回类型。
7. 嵌套函数 和 链式访问
7.1 嵌套函数:
在函数中调用函数,就是嵌套函数。函数可以嵌套,但是函数不可以嵌套定义。
#include <>
void test(int arr[],sz); //函数的声明
void print(int arr[],int sz);
int main()
{
int arr[10] = {0};
int sz = sizeof(arr)/sizeof(arr[0]);
test(arr,sz); //函数的调用——打印数组各元素
return 0
}
void test(int arr[],sz) //函数的调用
{
int i =0;
for(i=0;i<sz;i++)
{
arr[i]=i; //数组元素赋值
}
print(arr,sz);
}
void print(int arr[],int sz)
{
for(i=0;i<sz;i++)
{
printf("%d ",arr[i]); //打印数组元素
}
}
7.2 链式访问(例 - printf函数):
#include <>
int main()
{
printf("%d\n", strlen("abcdef"));//链式访问
return 0;
}
printf函数的返回值是打印祖父的个数,所以上述代码的打印结果是 4321
8. static修饰的函数 和 extern引入函数
8.1 生命周期 和 作用域:
作用域(scope)是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
生命周期指的是变量的创建(申请内存)到变量的销毁(收回内存)之间的⼀个时间段。
8.2 static 修饰函数:
⼀个函数只想在所在的源文件内部使用,不想被其他源文件使用,就可以使用static修饰。
8.3 extern 引入函数:
相反,如果想要使用别的源文件的函数时,就要使用extern引入函数。