之前的代码我们用的都是main()函数,这是入口函数,今天把C++关于函数的知识大概总结下。
(一)函数的定义
函数的定义由函数头和其后的包含函数代码的代码块组成,下面是函数定义模板:
返回类型 函数名( 参数列表 )
{
函数中的代码块...
}
//返回值为int类型,该函数需要传递两个参数
int Add(int a, int b)
{
int result = a + b;
return result; //有返回值的函数最终一定要有return语句,返回相应的返回值类型
}
- 返回类型:函数执行完完毕时返回的值的类型。函数可以返回任意类型的数据,包括基本类型、类类型、指针类型、引用类型等,也可以什么都不返回,此时的返回类型为void;
- 函数名:与定义变量一样,最好确保你的函数名能概括这段函数的功能;
- 参数列表:在你调用该这个函数时传送给该函数的数据项的个数和类型,如果你没有在定义函数时就给形参设定默认值,那在后续的调用该函数时就必须对其传递对应类型的参数。
下面是函数的一些常规定义:
#include<iostream>
#include<string>
using namespace std;
int Add(int a, int b); //如果你声明的函数在main函数之后就需要在之前进行函数原型声明
void MyHello(string); //函数的原型声明中可以不写形参的变量名,但最好写下,好方便了解更多的关于该函数的信息
string UsageOfReturn(int a);
void main()
{
int sum = Add(15, 24);
cout << sum << endl;
MyHello("Hello World!!!"); //直接
string strResult = UsageOfReturn(1);
cout << strResult << endl;
}
//返回值为int类型,该函数需要传递两个参数
int Add(int a, int b)
{
int result = a + b;
return result; //有返回值的函数最终一定要有return语句,返回相应的返回值类型
}
string UsageOfReturn(int a)
{
if (a == 0)
return "a=0,我直接跳出去了"; //return可以直接跳出该函数,不再执行下方的代码
cout << "只要a不是0,我就可以显示" << endl;
return "你输入的不是0";
}
//返回类型为void的函数时特例,不需要return,当你也可以写,但return后为空
void MyHello(string myStr)
{
cout << myStr << endl;
}
在函数中的定义的变量为局部变量,只在函数体中有效。
(二)给函数传值
1、按值传送机制
#include<iostream>
using namespace std;
void TryToChangeValue(float a, int b);
void main()
{
float myValue = 20.5f;
int index = 10;
TryToChangeValue(myValue, index); //将我们定义的变量传入函数
cout << "现在的myValue = " << myValue << " ,index = " << index << endl; //作为函数参数的变量并没有改变
}
void TryToChangeValue(float a, int b)
{
a += 100;
b *= 35;
cout << "函数中的a = " << a << " ,b = " << b << endl;
}
在没有调用函数之前,内存不会为函数的形参分配空间,直到你调用该函数,我们的编译器会将实参的值交给形参,这时形参有了临时的内存空间,之后这个形参在函数体的内部就可以当实参用,但当该函数执行完后,形参的空间自然就会被废弃,所以我们传递进去的实参值并没有被函数改变,函数只是借用了我们给的实参的值,完成他体内的工作。
2、给函数传递指针
#include<iostream>
using namespace std;
void ChangeValue(int* a, int* b)
{
*a += 300;
*b *= 100;
}
void main()
{
int a = 21, b = 45;
int* pValueA = &a;
int* pValueB = &b;
cout << "调用函数之前a = " << *pValueA << " b = " << *pValueB << endl;
ChangeValue(pValueA, pValueB);
cout << "调用函数之后a = " << *pValueA << " b = " << *pValueB << endl;
}
可以看到指针中值已经变了,这是因为传递的指针参数就是传递我们定义变量的地址,于是在函数中直接对这个地址中的值进行了操作,自然最终会改变指针指向地址中的值。
#include<iostream>
using namespace std;
void ChangeArray(int a[],int count)
{
for (int i = 0; i < count; i++)
{
a[i] = i * 10;
}
}
void main()
{
int myArray[7]; //这里只定义了一个空的数组
ChangeArray(myArray, 7);
for (int i = 0; i < 7; i++)
{
cout << myArray[i] << " "; //现在数组中已经有了相应的值
}
}
数组变量也属于指针,所以调用函数后自然会改变。
3、按引用传送
#include<iostream>
using namespace std;
void TransmitReference(int& a,float& b)
{
a += 1000; //对引用变量进行修改
b *= 100;
}
void main()
{
int myValueA = 56;
float myValueB = 24.6f;
int& r_age = myValueA; //定义引用
float& r_price = myValueB;
cout << "调用函数之前的 myValueA = " << myValueA << " myValueB = " << myValueB << endl;
TransmitReference(r_age, r_price);
cout << "调用函数之后的 myValueA = " << myValueA << " myValueB = " << myValueB << endl; //值已经改变了
}
引用只是另一个变量的别名,在其他地方对引用变量进行操作就等价于对那另一个变量进行操作,现在引用在函数中修改就是直接对其对应的变量进行修改。
关于有指针和引用形参的函数的注意点和操作方式有很多,这些就只能自己去研究,最好能在实际项目中总结经验和细节。
(三)函数重载
我们经常需要一个函数去完成多种任务,但每次传递给这个函数的参数列表有不一样,这是函数重载就是解决这类问题方法。
定义两个同名函数的要求:
- 至少有一对对应参数的类型不同
- 函数的返回类型要相同
#include<iostream>
using namespace std;
int MyAdd(int a,int b)
{
return a + b;
}
int MyAdd(int a, int b, int c)
{
return a + b + c;
}
int MyAdd()
{
return 0;
}
void main()
{
int a = 20, b = 30, c = 60;
int result1 = MyAdd(a, b);
int result2 = MyAdd(a, b, c);
int result3 = MyAdd();
cout << "result1 = " << result1 << " result2 = " << result2 << " result3 = " << result3 << endl;
}
关于函数重载在指针、引用等相关的参数进行重载时又有注意点,同时又在函数重载的基础上衍生的函数模板也很重要,内容也比较多,这些大家自行去学习吧。