函数需要提前声明:
#include
//函数的声明与定义
//这里是函数的定义
//void print_message()
//{
// printf("how do you do\n");
//}
//函数放在main函数下面需要提前声明
void print_message();//print_message函数的声明
int main()
{
print_message();//调用print_message()
return 0;
}
void print_message()//放在下面时提示函数未声明,函数未声明时返回int类型
{
printf("how do you do\n");
}
新建头文件:
#pragma once
#include //<>是在标准库里找头文件
#include
//在func.h中引用多个头文件,可以在源文件中直接引用func.h
void print_message();//print_message函数的声明
//在func.h中放入函数声明,源文件可通过引用func.h声明函数
即
#include "func.h"//""在当前目录下找自定义的头文件
在自定义头文件中引用多个头文件,可以在源文件中直接引用自定义头文件。
< >是在标准库里找头文件
" "在当前目录下找自定义的头文件
在自定义头文件中放入函数声明,源文件可通过引用自定义头文件声明函数。
func.h
#include
#include
void print_message();//print_message函数的声明
int print_star(int i);//printstar函数的声明,int i - 有形参,int - 有返回值
func.c
#include "func.h"
int print_star(int i)//i - 即为形式参数
{
printf("********************\n");
printf("printstar %d\n", i);
return i + 3;
}
void print_message() //可以调用printstar
{
printf("how do you do\n");
print_star(3);//3是实参
}
main.c
#include "func.h"
int main()
{
int a = 10;
a = print_star(a);//用一个变量接返回值
print_message();//调用print_message()
print_star(a);
return 0;
}
ctrl + 鼠标左键点击函数,就可以跳转到对应函数查看源码。
类型标识符 函数名()
{
声明部分
语句部分
}
类型标识符 函数名(形式参数表列)
{
声明部分
语句部分
}
死循环
!
调试递归时多画图
#include
//求n的阶乘
int f(int n)
{
//一定要有结束条件,一定是写在return之前的
if (1 == n)
{
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个台阶有几种走法?
举例说明如下:假如有3个台阶,那么总计就有3种走法:第一种为每次且1个台阶,上3次;第二种为先上2个台阶,再上1个台阶;第三种为先上1个台阶,再上2个台阶。
要点:找递归关系
s
t
e
p
(
n
)
=
s
t
e
p
(
n
−
1
)
+
s
t
e
p
(
n
−
2
)
step(n)=step(n-1)+step(n-2)
step(n)=step(n−1)+step(n−2)
要达到n个台阶,只能从n-1个台阶走1步,或从n-2个台阶走2步。
依次向前推。
#include
//上台阶,到第n个台阶,有多少种走法
int step(int n)
{
if (1 == n || 2 == n)//但台阶是1个,或者是2个时,递归结束
{
return n;//1个台阶1种走法,2个台阶2种走法
}
return step(n - 1) + step(n - 2);
}
int main()
{
int n;
scanf("%d", &n);
printf("step(%d) = %d\n", n, step(n));
return 0;
}
注意
- 找公式
- 编写结束条件
在不同的函数之间传递数据时,可使用的方法如下:
返回值:
如果b调用a函数
b称为调用函数
a称为被调函数
返回值只能是被调函数a返回给调用函数b
#include
int i = 10;//i是一个全局变量,不建议使用
void print(int a)
{
printf("I am print i = %d\n", i);
}
int main()
{
printf("main i = %d\n", i);
//i = 5;//接下来打印5
//int i = 5;//接下来打印10
print(5);
return 0;
}
有全局变量int i = 10;
在主函数中写
i = 5;改变的是全局变量i
int i = 5;是局部变量,与全局变量i重名,全局变量i不改变。
{
int j = 5;
}//局部变量的有效范围是离自己最近的花括号
printf("%d\n",j);//无法打印!!
for(int k = 0; k < -1)
{
}
printf("%d\n",k);//无法打印!!
把print(int a)改为print(int i),那么print函数的打印结果是多少?
int i = 10;
//把print(int a)改为print(int i),那么print函数的打印结果是多少?
void print(int i)//形参可以看成一个局部变量
{
printf("I am print i = %d\n", i);//输出3
}
int main()
{
{
int j = 5;
}//局部变量的有效范围是离自己最近的花括号
printf("main i = %d\n", i);
//i = 5;//接下来打印5
//int i = 5;//接下来打印10
print(3);
return 0;
}
将printf(int a)改为printf(int i),则不再打印全局变量10,而打印print(3)中的3。
定义函数中指定的形参,如果没有函数调用,那么它们并不占用内存中的存储单元。
发生函数调用时,形参分配内存单元。
在调用结束后,被释放。
实参可以是常量、变量或表达式,但要求它们有确定的值。
例如,print(i+3)在调用时将实参的值i+3赋给形参。
print函数可以有多个形参,如 print(int a,int b)
在被定义的函数中,必须指定形参的类型。
如果实参列表中包含多个实参,那么各参数间用逗号隔开。
实参与形参的个数应相等,类型匹配,且按顺序对应,一一传递数据。
实参与形参的类型应相同或赋值应兼容。
实参向形参的数据传递是单向“值传递”,只能由实参传给形参,而不能由形参传回给实参。
调用函数时,给形参分配存储单元,并将实参对应的值传递给形参;调用结束后,形参单元被释放,实参单元仍保留并维持原值。
形参相当于局部变量,因此不能再定义局部变量与形参同名,否则会造成编译不通。
在一个函数内部定义的变量称为内部变量。它只在本函数范围内有效,即只有在本函数内才能使用这些变量,故也称局部变量。
关于局部变量需要注意如下几点:
函数之外定义的变量称为外部变量。外部变量可以为本文件中的其他函数共用,它的有效范围是从定义变量的位置开始到本源文件结束,所以也称全局变量(全程变量)。
关于全局变量需要注意如下几点:
主函数调用其他函数,其他函数可以互相调用。
函数需要提前声明。
在自定义头文件中引用多个头文件,可以在源文件中直接引用自定义头文件。
在自定义头文件中放入函数声明,源文件可通过引用自定义头文件声明函数。
一个项目可以有多个模块 - 源文件,便于分别编写、分别编译,进而提高调试效率。
程序编译时以源程序文件为单位而不是以函数为单位进行编译的。
C程序的执行是从main函数开始的,如果在main函数中调用其他函数,那么在调用后会返回到main函数中,在main函数中结束整个程序的运行。
所有的函数的平行的,互相独立的,C语言中函数不能嵌套定义,可以互相调用。
函数的定义是指对函数功能的确立,包括指定函数名、函数值类型、形参及其类型、函数体等,它是一个完整的、独立的函数单位。
函数的声明的作用是把函数的名字、函数类型及形参的类型、个数和顺序通知编译系统,以便在调用该函数时编译系统能正确识别函数并检查调用是否合法。
无参函数:一般用来执行指定的一组操作。在调用无参函数时,主调函数不向被调用函数传递数据。
有参函数:主调函数在调用被调用函数时,通过参数向被调用函数传递数据。
死循环
!定义函数中指定的形参,如果没有函数调用,那么它们并不占用内存中的存储单元。
发生函数调用时,形参分配内存单元。
在调用结束后,被释放。
实参可以是常量、变量或表达式,但要求它们有确定的值。
例如,print(i+3)在调用时将实参的值i+3赋给形参。
print函数可以有多个形参,如 print(int a,int b)
在被定义的函数中,必须指定形参的类型。
如果实参列表中包含多个实参,那么各参数间用逗号隔开。
实参与形参的个数应相等,类型匹配,且按顺序对应,一一传递数据。
实参与形参的类型应相同或赋值应兼容。
实参向形参的数据传递是单向“值传递”,只能由实参传给形参,而不能由形参传回给实参。
调用函数时,给形参分配存储单元,并将实参对应的值传递给形参;调用结束后,形参单元被释放,实参单元仍保留并维持原值。
形参相当于局部变量,因此不能再定义局部变量与形参同名,否则会造成编译不通。