函数
1.概念
- 用来代表一组相对独立的语句
2.函数和变量之间的关系
- 不可以跨函数使用变量
- 不同函数里的变量可以重名
- 如果一个函数多次运行则它里面的变量每次运行都可能对应不同的存储区
- 使用volatile关键字声明的变量可以被其他程序修改内容
3.函数调用
- 函数调用过程中通常伴随着数据传递
- 数据传递既可以从调用函数到被调用函数也可以从被调用函数到调用函数
- 从调用函数向被调用函数只能传递一个数字,但是反过来可以传递多个数字
- 数据传递需要使用被调用函数提供的存储区
4.返回值
- 如果函数没有返回值就必须在函数前写void
- 被调函数不可以用数组记录返回值
5.参数
- 函数调用时可以从调用函数向被调用函数传递多个数剧
- 被调函数需要提供多个存储区来存放多个传递过来的数字,被调函数使用形式参数记录调用函数传递过来的数字(这就是形式参数的作用:从调用函数向被调用参数传递数字)
- 每个形式参数类型名称不能省略
- 函数调用调用语句里用实际参数表示希望传递的数字
- 能当做数字的内容都可以作为实际参数使用
- 如果一个函数没有形式参数就应该在编写的时候在小括号里写void
6.数组形式参数
- 数组做形式参数的时候实际上是使用调用函数的存储区(甚至是其他函数提供的)向被调用函数传递参数
- 声明数组形式参数的时候可以省略数组里存储区的个数
- 使用数组类型参数的时候需要另外提供一个整数类型参数来表示数组形式参数里的存储区个数
- 通过数组形式参数可以让被调函数使用其它函数的存储区(但一个函数不可以使用其它函数的变量)
- 数组形式参数可以实现双向数据传递,这个参数也叫输入输出参数
#include <stdio.h>
void neg(int arr[], int size) {
int num = 0;
for (num = 0; num <= size - 1; num++) {
arr[num] = 0 - arr[num];
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 6};
int num = 0;
neg(arr, 5);
for (num = 0; num <= 4; num++) {
printf("%d \n", arr[num]);
}
return 0;
}
/*
数组型参的双向传递效果:
主函数通过数组形参把1, 2, 3, 4, 5传递给了neg函数
neg函数同样通过数组形参将-1, -2, -3, -4, -5传递回给了主函数
两个函数改变的是同一个函数的存储区
*/
//数组做形参的本质,真正的形参就是一个指针,利用调用函数的存储区做数值传递
#include <stdio.h>
void neg(int *p_val, int size) {
int num = 0;
for (num = 0; num <= size -1; num++) {
*(p_val + num) = 0 - *(p_val + num);
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5};
int num = 0;
neg(arr, 5);
for (num = 0; num <= 4; num++) {
printf("%d \n", arr[num]);
}
return 0;
}
7.隐式声明
- 被调函数写在调用函数下面会发生隐身函数声明
- 如果被调函数的格式和隐式声明的格式不同,编译会出错
- 把函数声明语句写在文件开头叫函数的显式声明
- 函数显式声明可以避免隐式声明
- 除主函数以外的所有函数都应该进行显示声明
8.递归函数 递归解释的视频
- 概念: 会调用自己的函数
- 适用场景: 如果一个问题可以采用一种方法不断分解下去就可以采用递归函数解决这个问题
- 编写步骤:
- 编写语句问题处理分解后的每个小问题(假设递归函数已经完成,可以使用)即找到"公式"
- 在递归调用前编写分支处理不可分解的情况(分支必须保证函数可以结束)
显示1-10之间所有的整数(1:找公式, 2:找结束条件)
/*显示1-10之间所有的整数,第一步显示1-9之间所有的整数,然后再显示10本身,第一步又可以分为先显示1-8之间所有的整数,再显示9...,这个分解过程可以不断地进行下去*/
#include <stdio.h>
void print(int n) {
if (n == 1) {
printf("1 ");
return ;
}
print(n -1);
printf("%d ", n);
}
int main() {
print(10);
printf("\n");
return 0;
}
//ouptut: 1 2 3 4 5 6 7 8 9 10
- 递归函数验证方法,用参数去试
- 用递归函数解决问题叫递归, 用循环解决叫递推