函数的声明和定义
声明和定义函数语法:
返回值的数据类型 函数名(参数一的数据类型 参数一,参数二的数据类型 参数二,......)
{
实现函数功能的代码
return 返回值;
}
例子:
#include <iostream> //包含头文件
using namespace std; //指定缺省的命名空间
//写一个函数,给它两个整数,让它比较两个整数的大小,返回较大的那个整数。
int max(int a, int b)
{
int c;
if (a > b)c = a;
else c = b;
return c;
}
注:
- 函数的声明和定义可以书写在一起,也可以分开,如果书写在一起,一般放在main函数的上面,如果分开,一般在main函数的上面声明,在main函数的下面定义。
- 如果函数的声明和定义分开书写,函数的声明后面一定要有分号,函数的定义后面一定不能写分号。
- 在同一个程序中,函数只需要声明和定义一次,也可以多次声明,但只能定义一次。
- 函数的声明必须和函数的定义一致(返回值的数据类型、函数名、参数列表)。
- return语句返回值的数据类型必须与函数的声明一致。
- 如果函数的重点是功能实现,不关心返回值,返回值的数据填void,return语句后面就空着。
- 函数可以没有任何参数。
#include <iostream> //包含头文件
using namespace std; //指定缺省的命名空间
//写一个函数,给它两个整数,让它比较两个整数的大小,返回较大的那个整数。
int max(int a, int b);
int main()
{
}
int max(int a, int b)
{
int c;
if (a > b)c = a;
else c = b;
return c;
}
函数的调用
语法:函数名(参数一,参数二,......)
//写一个函数,给它两个整数,让它比较两个整数的大小,返回较大的那个整数。
int max(int a, int b);
int main()
{
cout << "max(5,8)=" << max(5, 8) << endl;
}
int max(int a, int b)
{
int c;
if (a > b)c = a;
else c = b;
return c;
}
注:
- 声明函数的代码必须放在调用之前,定义函数的代码可以放在调用之后。
- 调用函数的时候,参数列表必须与函数的声明一致。
- 函数中可以调用除main函数外的其它函数。
- 调用函数的代码可以独占一条语句,也可以用于表达式(赋值运算、算术运算、关系运算、函数的参数)。
- 如果函数用于表达式中,返回值的数据类型要匹配(否则可能会被隐式转换或者编译错误)。
- 如果函数有返回值,可以不关心它,忽视它。
变量的作用域
变量的作用域是变量存在的区域,超过该区域就不能被访问。
变量分为全局变量和局部变量。
全局变量
**全局变量:**定义在全部函数外或者头文件中。
全局变量例子:aa就是全局变量
int aa;
void func1();
void func2();
int main()
{
aa = 10;
func1();
func2();
cout << "main aa" << aa << endl;
}
void func1()
{
cout << "func1 aa=" << aa++ << endl;
}
void func2()
{
cout << "func2 aa=" << aa++ << endl;
}//运行的结果是10,11,12
注:
- 在整个程序生命周期内都有定义,定义之后都能访问,在主程序退出时收回内存。
- 一般把全局变量定义在全部函数的定义最上面,让全部函数可以访问。
局部变量
局部变量: 函数{}
内部或者语句块内部,在函数或语句块外部都是不可用的。语句块内就是大括号内
局部变量例子:xx是局部变量,在语句块中定义的
void func3()
{
if (true)
{
int xx = 19;
cout << "xx=" << xx << endl;
}//xx在大括号里面是可以使用的,大括号外不能使用,只要大括号里的都是语句块
cout << "func3 aa=" << aa++ << endl;
}
注:
- 局部变量在函数返回或语句块结束时由系统收回内存空间
静态局部变量
**静态局部变量:**用static修饰的局部变量,其生命周期和程序相同,并且只会初始化一次。
静态局部变量例子:
void func2();
int main()
{
func2();
func2();
func2();
}
void func2()
{
int aa = 10;
int bb = 10;
cout << "func2 aa=" << aa++ << endl;
cout << "func2 bb=" << bb++ << endl;
}//aa和bb都是局部变量,函数结束后aa和bb生命周期结束,所以func2调用三次的结果都为10
void func2();
int main()
{
func2();
func2();
func2();
}
void func2()
{
int aa = 10;
static int bb = 10;
cout << "func2 aa=" << aa++ << endl;
cout << "func2 bb=" << bb++ << endl;
}//bb是静态局部变量,其生命周期和程序相同,并且只会初始化一次
运行结果:
注:
- 静态局部变量的作用域为局部,当定义它的函数或语句块结束时,作用域也就结束了。
- 如果全局变量和静态变量都能满足程序需求时应该首先考虑使用static(考虑到数据安全性)。
- 全局变量和静态变量自动初始化为0,但局部变量在程序中不会,所以应在程序中有初始化语句,否则可能会报错。
- 局部变量和全局变量可以重名,但在局部中会自动认为是局部变量,若想使用全局变量需在变量名前加
::
函数参数的传递
实参:调用者程序中书写在函数名括号中的参数。
形参:函数的参数列表。
在函数定义中修改形参值,不会影响实参。
函数分文件编写
头文件(*.h): 需要包含的头文件、指定命名空间、生命全局变量、函数的声明、数据结构和类的声明等。
源文件(*.cpp): 函数的定义、类的定义。
主程序: main函数,程序的核心流程,需要用#include "头文件名"
把头文件包含进来。
函数分文件编写例子:
//未分文件编写时
#include <iostream> //包含头文件
using namespace std; //指定缺省的命名空间
int max(int a, int b);
int min(int a, int b);
void print(int no, string str);
int main()
{
int a = 5;
int b = 8;
max(a, b);
min(a, b);
print(3, "hello");
}
int max(int a, int b)
{
return a > b ? a : b;
}
int min(int a, int b)
{
return a < b ? a : b;
}
void print(int no, string str)
{
cout << "亲爱的" << no << "号:" << str << endl;
}
//分文件编写
//主程序文件
#include "tools.h" //包含头文件
#include "girls.h"
int main()
{
int a = 5;
int b = 8;
cout << max(a, b) << endl;
cout << min(a, b) << endl;
print(3, "hello");
}
//函数头文件tools.h
#include <iostream> //包含头文件
using namespace std; //指定缺省的命名空间
int max(int a, int b);
int min(int a, int b);
//函数源文件tools.cpp
#include "tools.h"
int max(int a, int b)
{
return a > b ? a : b;
}
int min(int a, int b)
{
return a < b ? a : b;
}
//函数头文件girls.h
#include <iostream> //包含头文件
using namespace std; //指定缺省的命名空间
void print(int no, string str);
//函数源文件girls.cpp
#include "girls.h"
void print(int no, string str)
{
cout << "亲爱的" << no << "号:" << str << endl;
}
在VS中调试程序
递归函数
在函数体中调用了自己,有递归终止的条件判断。
递归和循环不一样,进入的过程叫递去,函数返回的过程叫归来。