C++第5章 函数

目录

5.1 函数声明与定义

5.2 函数参数及返回值

5.2.1:形参与实参

5.2.2:默认参数

5.2.3:可变参数

5.3 函数调用

5.3.1 传值调用

5.3.2 嵌套调用

5.3.3 递归调用

5.4 变量作用域

5.5 重载函数

5.6 内联函数

5.7 变量的存储类别

5.7.1:auto变量

5.7.2:静态变量

5.7.3:register变量

5.7.4:extern变量


5.1 函数声明与定义

函数声明可以写多次,但是定义只能有一次

函数语句声明:数据类型    函数名(参数列表);//参数列表可只写参数的数据类型

函数定义:数据类型    函数名(参数列表){函数体}

 例1:函数语句声明

#include<iostream>
using namespace std;

//函数的声明
//比较函数,实现两个整型数字进行比较,返回较大 的值
//函数声明可以写多次,但是定义只能有一次
//提前告诉编译器函数的存在,可以利用函数的声明
int max(int a, int b);

int main() {

	int a = 10, b = 20;
	cout << max(a, b) << endl;

	return 0;
}

//函数定义
int max(int a, int b) {
	return a > b ? a : b;
}

例2:先定义函数

#include<iostream>
using namespace std;

//函数的定义
//语法:
//返回值类型 函数名(参数列表) {函数体语句  return 表达式}

//加法函数,实现两个整型相加,并且将相加的结果进行返回
//函数定义时,num1和num2并没有真实数据,他只是一个形式上的参数,简称形参
int add(int num1, int num2) {
	return num1 + num2;
}

int main() {
	int a = 10, b = 20;
	//a和b为 实际参数,简称实参
	//当调用函数时候,实参会传递给形参
	int sum = add(a, b);
	cout << "sum=" << sum << endl;
	return 0;
}

5.2 函数参数及返回值

5.2.1:形参与实参

1.定义

形参:带参函数中的参数在函数声明和定义时被称为“形式参数”;

实参:在函数调用时被赋予具体值,具体的值被称为“实际参数”

2.形参与实参的区别:

(1)在定义函数中指定的形参,在没有调用时,不占用内存中的存储单元。只有在函数被调用的时候,函数的形参才被分配内存单元,在调用结束后,形参所占的内存单元也会被释放

(2)实参是确定的值。在调用时将实参的值赋值给形参,如果形参是指针类型,就将地址值传递给形参;

(3)实参和形参的类型应相同;

(4)实参与形参之间是单项传递,只能由实参传递给形参,而不能由形参传回来给实参。

5.2.2:默认参数

在定义函数默认值参数时,如果函数具有多个参数,应保证默认参数出现在参数列表的右方,如下所示:

int getMax(int x, int y, int z = 0) {

if (x < y) x = y;

if (x < z) x = z;

return x;

}

5.2.3:可变参数

省略号参数代表的含义是函数的参数是不固定的,可以传递一个或多个参数。

对于可变参数,可以使用va_list类型和va_start、va_arg、va_end 3个宏读取传递到函数中的参数值(需引用<STDARG.H> )。

例3:可变参数

#include <iostream>
#include <STDARG.H> //需要包含该头文件
using namespace std;
void OutputInfo(int num, ...)						//定义一个省略号参数的函数
{
	va_list arguments;							//定义va_list类型变量
	va_start(arguments, num);
	while (num--)								//读取所有参数的数据
	{
		char* pchData = va_arg(arguments, char*);	//获取字符串数据
		int iData = va_arg(arguments, int);			//获取整型数据
		cout << pchData << endl;					//输出字符串
		cout << iData << endl;						//输出整数
	}
	va_end(arguments);
}

void main()
{
	OutputInfo(2, "Beijing", 2022, "纯洁的冰雪激情的约会", 2022);	//调用OutputInfo函数
}

5.3 函数调用

5.3.1 传值调用

例4:若x<y,则交换x、y.

1.常见误区:传值只是复制变量,未赋值

#include <iostream>
using namespace std;
void swap(int a, int b)
{
	int tmp;
	tmp = a;
	a = b;
	b = tmp;

}
int main()
{
	int x, y;
	cout << "输入两个数" << endl;
	cin >> x;
	cin >> y;

	if (x < y)
		swap(x, y);
	cout << "x=" << x << endl;
	cout << "y=" << y << endl;
	return 0;
}

实际结果是x<y,调用函数却没有交换值,是因为swap函数复制了变量x和y的值,而非变量本身。 

2.如果将swap写在主函数中:

int main()
{
	int x, y;
	cout << "输入两个数" << endl;
	cin >> x;
	cin >> y;
	int tmp;
	if (x < y) {
		tmp = x;
		x = y;
		y = tmp;
	}
	cout << "x=" << x << endl;
	cout << "y=" << y << endl;
	return 0;
}

 实际结果交换了两个变量的值

3.使用指针:实际更改变量的值

#include <iostream>
using namespace std;
void swap(int *a, int *b)
{
	int tmp;
	tmp = *a;
	*a = *b;
	*b = tmp;

}
int main()
{
	int x, y;
	cout << "输入两个数" << endl;
	cin >> x;
	cin >> y;

	if (x < y)
		swap(x, y);
	cout << "x=" << x << endl;
	cout << "y=" << y << endl;
	return 0;
}

 

5.3.2 嵌套调用

一个函数中调用另外一个函数

例5:函数的嵌套调用

#include<iostream>
using namespace std;
void showMessage() {
	cout << "The ShowMessage function" << endl;
}

void Display() {
	showMessage();
}

int main() {
	Display();
	return 0;
}

5.3.3 递归调用

直接或间接调用自己的函数被称为递归函数(recursive function)。

缺点:递归的运行效率比较低,无论是从时间角度还是从空间角度都比非递归程序差。

 例6:汉诺塔问题

这是一个经典的数学问题:古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个盘子,盘子大小不等,大的在下,小的在上。有个老和尚想把这64个盘子从A座移到C座,但每次只允许移动一个盘子,且移动过程中在3个座上都始终保持大盘在下,小盘在上。在移动过程中可以利用B座,要求编程序打印出移动的步骤。

#include <iostream>
using namespace std;
long lCount;
void move(int n, char x, char y, char z)//将n个盘子从x针借助y针移到z针上。
{
	if (n == 1)
		cout << "Times:" << ++lCount << x << "->" << z << endl;
	else
	{
		move(n - 1, x, z, y);
		cout << "Times:" << ++lCount << x << "->" << z << endl;
		move(n - 1, y, x, z);
	}
}
int main()
{
	int n;
	lCount = 0;
	cout << "please input a number" << endl;
	cin >> n;
	move(n, 'a', 'b', 'c');
	return 0;
}

 例7:求n!

1.递归调用

#include <iostream>
using namespace std;
long Fac(int n)
{
	if (n == 0)
		return 1;
	else
		return n * Fac(n - 1);
}
int main()
{
	int n;
	long f;
	cout << "please input a number" << endl;
	cin >> n;
	f = Fac(n);
	cout << "Result :" << f << endl;
	return 0;
}

2.for循环

#include <iostream>
using namespace std;
typedef unsigned int UINT; 		//自定义类型
long Fac(const UINT n)		//定义函数
{
	long ret = 1;				//定义结果变量
	for (int i = 1; i <= n; i++)			//累计乘积
	{
		ret *= i;
	}
	return ret;					//返回结果
}

int main()
{
	int n;
	long f;
	cout << "please input a number" << endl;
	cin >> n;
	f = Fac(n);
	cout << "Result :" << f << endl;
	return 0;
}

5.4 变量作用域

全局变量和局部变量:

(1)全局变量:在函数体内定义的变量;全局变量:在函数体外定义的变量;

(2)全局变量在程序开始的时候,创建并分配空间,在程序结束的时候,释放内存并销毁;

局部变量是在函数调用的时候创建,并在栈中分配内存,在函数调用结束后销毁并释放。

#include<iostream>
using namespace std;
int iTotalCount;//全局变量
int getCount();

int main() {
	int iTotalCount = 100;//局部变量 
	cout << iTotalCount << endl;
	cout << getCount() << endl;
	return 0;
}
int getCount() {
	iTotalCount = 200;//给全局  
	return iTotalCount;
}

5.5 重载函数

函数的重载(函数名相同,参数类型或个数不同)

#include <iostream>
using namespace std;
int Add(int x, int y)				//定义第一个重载函数
{
	cout << "int add" << endl;	//输出信息
	return x + y;				//设置函数返回值
}
double Add(double x, double y)		//定义第二个重载函数
{
	cout << "double add" << endl;	//输出信息
	return x + y;				//设置函数返回值
}
int main()
{
	int ivar = Add(5, 2);			//调用第一个Add函数
	float fvar = Add(10.5, 11.4);	//调用第二个Add函数
	return 0;
}

例8:重载函数:fun(int a[], int n)fun(int *p, int n)为同一函数

#include<iostream>
using namespace std;

//函数1
void fun(int a, float x){
	cout << "函数1	fun(int a, float x)" << endl;
}

//函数2
void fun(int a, int x){
	cout << "函数2	fun(int a, int x)" << endl;
}

//函数3
void fun(float a, float x){
	cout << "函数3	fun(float a, float x)" << endl;
}

//函数4
void fun(float a, int x){
	cout << "函数4	fun(float a, int x)" << endl;
}

//函数5
void fun(int a[], int n){
	cout << "函数5	fun(int a[], int n)" << endl;
}

//函数6
void fun(int *p, int n){
	cout << "函数6	fun(int *p, int n)" << endl;
}

int main() {
	
	int a = 1,b=2;
	float f = 1.1f;
	int *p = &b;
	int c[] = { 1,2,3 };

	//选项A:函数1和函数2可以构成重载函数
	fun(a, f);//函数1
	fun(a, b);//函数2

	//选项B:函数1和函数4可以构成重载函数
	fun(f, a);//函数4

	//选项C:函数3和函数4可以构成重载函数
	fun(f, f);

	//选项D:函数5和函数6可以构成重载函数
	fun(c, a);//函数定义或声明中有错误;未调用函数
	fun(p, a);//函数定义或声明中有错误;未调用函数

	return 0;
}

5.6 内联函数

通过inline关键字可以把函数定义为内联函数,编译器会在每个调用该函数的地方展开一个函数的副本。

#include<iostream>
using namespace std;
inline int integerAdd(int x, int y);


int main() {
	int a, b;
	cin >> a >> b;
	cout << integerAdd(a, b) << endl;
	return 0;
}

int integerAdd(int x, int y) {
	return x + y;
}

5.7 变量的存储类别

5.7.1:auto变量

auto(自动)变量存储类型是C++语言程序中默认的存储类型。函数中未加存储类型的变量均视为自动变量。

自动变量的特点:

(1)自动变量的作用域,仅限于定义该变量的个体内。

(2)自动变量属于动态存储方式,变量分配的内存是栈中,当函数调用结束后,自动变量的值会被释放。

(3)由于自动变量的作用域和生命期都局限于定义它的个体内(函数或符合语句内),因此不同的个体中允许使用同名的变量而不会混淆

5.7.2:静态变量

1.在声明变量前加关键字static,可以将变量声明成静态变量。

静态局部变量的值在函数调用结束后不会消失;

静态全局变量的值在函数调用结束后不消失,静态全局变量只能在本源文件中使用。

2.静态变量属于静态存储方式,具有以下特定:

(1)静态变量的生命周期是整个源文件,即程序退出时才释放,整个运行期间都不释放;

(2)静态变量的作用域与自动变量相同;

(3)编译器会为静态局部变量赋予0值。

5.7.3:register变量

register变量(寄存器变量):当需要反复访问内存,花费大量的存取时间。此时使用寄存器变量,使用时不需要访问内存,直接从寄存器中读写。

寄存器变量的说明如下:

(1)寄存器变量属于动态存储方式。凡需要采用静态存储方式的量不能定义为寄存器变量;

(2)编译程序会自动决定哪个变量使用寄存器存储。register起到程序优化作用。

5.7.4:extern变量

在使用其他源文件的全局变量时,只需在本源文件使用extern关键字来声明这个变量就行。

例9:输出不同生命期的变量值

#include<iostream>
using namespace std;
int main()
{
	auto int i, j, k;
	cout << "input the number:" << endl;
	cin >> i >> j;
	k = i + j;
	if (i != 0 && j != 0)
	{
		auto int k;
		k = i - j;
		cout << "k :" << k << endl;//输出变量K的值
	}
	cout << "k :" << k << endl;//输出变量k的值
	return 0;
}

 

例10:使用静态变量实现累加,求1+2+3+...+n的值 

#include<iostream>
using namespace std;
int add(int x)
{
	static int n = 0;
	n = n + x;
	return n;
}
int main()
{
	int i, j, sum;
	cout << " input the number:" << endl;
	cin >> i;
	cout << "the result is:" << endl;
	for (j = 1; j <= i; j++)
	{
		sum = add(j);
		cout << j << ":" << sum << endl;
	}
	return 0;
}

 

  世间安得双全法,不负如来不负卿! 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Catherinemin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值