写在前面:本章在教程视频的原有基础上,增加了对C++中“引用”部分的学习笔记。
6 函数
6.1 函数定义与调用
1.语法
/*********** 函数定义 ***********/
返回值类型 函数名 (形参列表)
{
函数体内容
……
return表达式
}
/*********** 函数调用 ***********/
函数名(传入实参)
2.实例
/************************** 实现角度与弧度制互换 ****************************/
#include<iostream>
using namespace std;
#define pi 3.1415926
/********** 弧度值--->角度值 **********/
float rad2angle(float rad)
{
return rad / pi * 180;
}
/********** 角度值--->弧度值 **********/
float angle2rad(float angle)
{
return angle / 180 * pi;
}
/************** 主函数 **************/
int main() {
float input_rad, input_angle;
cout << "请输入一个弧度:";
cin >> input_rad;
cout << "请输入一个角度:";
cin >> input_angle;
printf("%f = %f°\n", input_rad, rad2angle(input_rad));
printf("%f° = %f\n", input_angle, angle2rad(input_angle));
system("pause");
return 0;
}
3.注意:若函数无返回值,可将返回值类型写作 void ,且不写 return 表达式
6.2 值传递
/****************** 交换两数 *****************/
void my_swap(int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
/******************* 主函数 *****************/
int main() {
int num1 = 1, num2 = 2;
my_swap(num1, num2);
cout << "num1 = " << num1 << " , num2 = " << num2 << endl;
system("pause");
return 0;
}
/********** 输出结果 **********/
//num1 = 1 , num2 = 2
为什么使用数字交换函数后num1和num2并无变化?
因为函数调用在传入参数时是值传递,即将实参的值传递给函数的形参作为输入**而非地址**,函数内的执行语句是对形参的操作,形参与实参分属与不同的地址,自然对形参(a b)的操作不会对实参(num1 num2)造成任何影响。
为什么函数命名为 my_swap 而非 swap ?
这个问题出现在下面的函数声明中,最初设置的函数名为swap意为交换函数,在验证“函数定义在主函数之后必须在主函数前声明”时,发现无需声明也不会报错,但是实参(num1 num2)却被交换了(输出了num1 = 2 , num2 = 1)????前面不是说形参的行为对实参没有影响吗?
查阅资料之后发现,原来命名空间std内自带了一个swap函数,即std::swap函数,这就解释了为什么不需要声明也不会报错;但是为什么实参被交换了呢?是因为std::swap函数调用时,参数通过引用传递交换了原始变量,即实参的值。所以之后修改了函数名避免冲突。
怎样实现实参的交换呢?
有引用传递和指针传递两种方式:
/**************** 引用传递 ****************/
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
/**************** 指针传递 ****************/
void swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}
指针在后面会学到,下面重点介绍C++中的“引用”。
6.3 引用
6.3.1 引用的概念
在C++中,引用(reference)是一个变量的别名或另一个名字。通过引用,我们可以间接操作某个变量,就像直接操作它一样。引用的主要作用是提供一种简便的方式,允许函数或代码片段直接访问变量本身,而不是它的副本。
6.3.2 定义引用
1.定义方式:
int x = 10;
int& ref = x; // ref 是 x 的引用
2.特性:
- 引用并不是变量的副本,而是变量本身的另一个名字
- 通过引用进行的操作,实际上是对原始变量的操作
- 引用必须在定义时初始化
- 一旦一个引用被初始化,它就与某个变量绑定,不能重新绑定到其他变量
6.3.3 引用用途
-
作为别名修改变量
对引用的修改等价于对其引用对象的修改
int a = 5; int& ref = a; // ref 是 a 的引用 ref = 10; // 等价于 a = 10 cout << "a = " << a << endl; // 输出 a = 10 -
作为函数的输入参数
使得函数可以直接操作传入的变量,而非对副本进行操作
void my_swap(int& a, int& b) { int temp = a; a = b; b = temp; } int main(){ int num1 = 5,num2 = 10; my_swap(num1,num2); // 此时 num1 = 10,num2 = 5 } -
作为函数返回值
允许函数调用结果直接作为左值被修改
int& getMax(int& a, int& b) { return (a > b) ? a : b; // 返回较大值的引用 } int main() { int x = 10, y = 20; getMax(x, y) = 50; // 修改较大值的变量值为50 }
6.3 函数声明
若函数处于主函数之后,由于程序是顺序执行的,所以必须在主函数之前进行函数声明,以保证主函数可以正确识别该函数名。
float angle2rad(float angle); // 函数声明
int main(){
……
rad_value = angle2rad(input_angle); // 函数调用
……
}
float angle2rad(float angle) // 函数定义
{
……
}
注意:声明可以多次,定义只能有一次
6.4 函数的分文件编写
-
创建.h后缀的头文件
-
创建.cpp后缀的源文件
-
在头文件中写函数的声明
- 源文件中各函数需要的头文件
- 各个函数的声明
#include <iostream> // 包含源文件中需要的头文件 using namespace std; void my_swap(int& a,int& b); // 函数声明 -
在源文件中写函数的定义
- 该源文件对应的头文件
- 各个函数的定义
#include "my_include" // 包含已创建的头文件名 void my_swap(int& a, int& b) // 函数定义 { int temp = a; a = b; b = temp; } -
在主函数对应的源文件中包含自定义的头文件
#include <iostream> #include "my_include" ……
1152

被折叠的 条评论
为什么被折叠?



