函数的声明与定义-嵌套调用
函数的声明与定义
main函数
//main.c
#include "func.h"
//函数的声明与定义
int main() {
int a = 10;
a = print_star(a);
print_message();//调用
print_star(5);
return 0;
}
//输出
************
print_star 10
how do you do
************
print_star 6
************
print_star 5
func函数
//
// Created by Halcyon on 2024/7/14.
//
# include "func.h"
int print_star(int i){
printf("************\n");
printf("print_star %d\n",i);
return i+3;
}
//可以调用print_star,这就是嵌套调用
void print_message(){
printf("how do you do\n");
print_star(6);
}
func.h头文件
//
// Created by Halcyon on 2024/7/14.
//
#ifndef UNTITLED5_FUNC_H
#define UNTITLED5_FUNC_H
#include <stdio.h>
void print_message();//print_message函数的声明
int print_star(int i);//print_star函数声明,有形参,有返回值
#endif //UNTITLED5_FUNC_H
👩💻 C语言的编译和执行的特点
- 一个C程序由一个或多个程序模块组成,每个程序模块作为一个源程序文件。这样处理便于分别编写、分别编译,进而提高调试效率。
- 一个源程序文件由一个或多个函数及其他有关内容(如命令行、数据定义等)组成。一个源程序文件是一个编译单位,在程序编译时是以源程序文件为单位而不是以函数为单位进行编译的。
- C程序的执行是从main函数开始的,如果在main函数中调用其他函数,那么在调用后会返回到main函数中,从main函数中结束整个程序的运行。
- 所有函数都是平行的,即在定义函数时是分别进行的,并且是互相独立的。函数不能嵌套定义。
❗隐式声明:函数如果不显式的声明返回值的类型,那么它默认返回整型。
函数的分类与调用
从用户角度
- 标准函数:printf函数、scanf函数等
- 用户自己定义的函数:用以解决用户的专门需要。
从函数角度
- 无参函数:一般用来执行指定的一组操作。在调用无参函数时,主调函数不向被调用函数传递数据。
- 有参函数
函数的递归调用
- 递归函数:函数自身调用自身的操作。
- 使用递归在解决一些问题时,可以让问题变得简单,降低编程的难度。
数字n的阶乘
❓ 求数字n的阶乘
✅ f(n) = n * f(n - 1)
#include <stdio.h>
int f(int n){
if(n == 1){
return 1;
}
return n * f(n - 1);
}
int main() {
int n;
scanf("%d",&n);
printf("f(%d) = %d\n",n,f(n));
return 0;
}
走台阶问题
❓ 假设有n个台阶,一次只能上1个台阶或2个台阶,请问走到第n个台阶有几种走法?
✅ 思路:到达第n个台阶,要么从n-1个台阶,要么从n-2个台阶。所以step(n) = step(n-1) + step(n-2)
//到第n个台阶,一共有多少种走法?
int step(int n){
if(1 == n || 2 == n){//当台阶有1个或者2个的时候递归结束
return n;
}
return step(n - 1)+step(n - 2);//公式是关键
}
int main() {
int n;
scanf("%d",&n);
printf("step(%d)=%d\n",n,step(n));
return 0;
}
局部变量与全局变量
全局变量-形参-实参
🐧 在不同的函数之间传递数据时,可以使用的方法:
- 参数:通过形式参数和实际参数
- 返回值:用return语句返回计算结果
- 全局变量:外部变量
#include <stdio.h>
int i = 10;//全局变量
void print(int a){
printf("I am print i = %d\n",i);
}
int main() {
printf("main i = %d\n",i);
i = 5;
print(5);
return 0;
}
//输出
main i = 10
I am print i = 5
⚠️ 如果局部变量与全局变量重名,那么将采取就近原则,即实际获取和修改的值是局部变量的值。
🐧 关于形参、实参的说明
- 定义函数中指定的形参,如果没有函数调用,那么它们并不占用内存中的存储单元。在调用结束后,形参所占的内存单元也会被释放。
- 实参可以是变量、常量或表达式,但要求它们有确切的值,
- 在被定义的函数中,必须指定形参的类型,实参与形参的个数应相等,类型应匹配,且实参与形参应按顺序对应,一一传递数据。
- 实参与形参的类型应相同或赋值应兼容。
- 实参向形参的数据传递是单项“值传递”,只能由实参传给形参。
- 形参相当于局部变量,因此不能再定义局部变量与形参同名,否则会造成编译不通。
全局变量与局部变量
全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元。
C语言一般要求把程序中的函数做成一个封闭体,除可以通过“实参→形参”的渠道与外界发生联系外,没有其他渠道。