C++函数
参数传递
引用传递
③可以用表达式作为默认参数,只要表达式可以转换成形参所需的类型即可。但是,局部量不能作为默认参数值。
② 在定义和调用重载函数时,要注意它的二义性。
<!–hexoPostRenderEscape:
值传递
/* 使用值传递,当实参值过大或过多时,赋值给形参这个过程会大大降低程序运行的效率 */
void swap(int a, int b) {
// 很明显,使用值传递是无法实现x, y交换的目的的
int temp = a;
a = b;
b = temp;
}
x = 10;
y = 5;
swap1(x, y);
// x, y的值传给形参a, b
指针传递
void swap2(int *a, int *b) {
// 通过x, y的指针直接改变x, y指向的数据,函数内的操作可以影响外部
int temp = *a;
*a = *b;
*b = temp;
}
x = 10;
y = 5;
swap2(&x, &y);// 对数组进行操作一般使用指针传递
void sortArr(int arr[6]) { //这里的 6 只是一个期望值,实际上对形参并没有约束作用,即等价于int arr[]或int *arr
for (int i = 0; i < 6 - 1; i++) {
for (int j = 0; j < 6 - i - 1; j++) {
if (a[j] > a[j+1]) {
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
}
/*
要想确定数组的大小,还是得显示指定
数组尺寸 n,即sortArr(int a[], int n)
*/
void main() {
int b[] = { 21, 13, 4, 1, 7, 5 };
sortArr(b);
}引用传递
#include <iostream>
using namespace std;
void swap(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
void main() {
int x = 5, y = 10;
swap(x, y);
cout << "x = " << x << "\ty = " << y << endl;
}
/* 运行结果:
x = 10 y = 5
*/
// 由于传给函数形参的本质上是实参的地址,故不能向函数传入常数
int x = 5;
swap(3, 4); // error
swap(x, 9); // error
swap(6, x); // error
函数默认参数
#include <iostream>
using namespace std;
double sqrt(double f = 1.0);
void main() {
cout << sqrt() << endl; // 使用默认参数
cout << sqrt(5) << endl;
}
double sqrt(double f) {
return f * f;
}
使用默认参数要注意以下三点:
①在指定某个函数的默认值时,如果它有函数原型,就只能在函数原型中指定对应数的默认值,不能在定义函数时再重复指定参数默认值。当然,若函数是直接定义的,没有函频原型,若要指定参数默认值,在定义时指定就行了。
②在具有多个参数的函数中指定默认值时,所有默认参数都必须出现在无默认值参数的右边。即,一旦某个参数开始指定默认值,它右边的所有参数都必须指定默认值。
int f(int i1, int i2, int i3 = 0);
int g(int i1, int 12 = 0, int i3); // error,i3没有默认值
int h(int i1=0, int i2, int i3=0); // error,i1默认后,其右边的i2没有默认值③可以用表达式作为默认参数,只要表达式可以转换成形参所需的类型即可。但是,局部量不能作为默认参数值。
#include <iostream>
#include <string>
using namespace std;
// 定义全局变量
string name = "tom";
double h = 0.8, len = 1.1;
void dog(string dogname = name, double high = h, double length = len) {
cout << "Dogname: " << dogname << "\tHigh:" << h << "\tLength:" << len << endl;
}
int main() {
name = "Jake"; // 修改全局变量以改变参数name的默认值
double h = 2.1; // 重新定义一个局部变量h,与全局变量h无关,对参数high的默认值无影响
dog();
return 0;
}
/* 运行结果如下:
Dogname:Jake High:0.8 Length:1.1
*/
函数返回值
默认返回值和void的返回值
每个函数最后都是通过return语句来结束调用的(返回值为void的函数没有return语句,但系统会在该函数的最后一条语句的后面隐式地执行return语句)
int maxArr(int a[], int n) {
// 在最新的C++11中的标准中,函数没有默认返回值了(在C语言和早期的C++中,函数的默认返回值为int)
int max = a[0];
for (int i = 1; i < n; i++) {
if (max < a[i])
max = a[i];
}
return max;
}
void swap(int &a, int &b) {
if (a = b)
return;
else {
int t = a;
a = b;
b = t;
}
}
返回引用
<!–hexoPostRenderEscape:
#include <iostream>
using namespace std;
int temp;
int& f(int i1, int i2) {
temp = i1 + i2;
return temp; // 返回 temp的引用
}
void main() {
int t = f(1, 3);
cout << temp << " ";
f(2, 8)++;
cout << temp << " ";
f(2, 3) = 9;
cout << temp << endl;
}
/ 运行结果如下:
4 11 9
/
:hexoPostRenderEscape–>int &g(int i1, int i2) { // error
// 返回值为引用的函数应该return一个变量,而不能是表达式
return i1 + i2;
}const int &g(int i1, int i2) {
return i1 + i2;
}
// 函数返回值为常量引用值时可以return表达式
/* 函数返回表达式的隐式过程:
int temp = i1 + i2;
return temp;
一般情况下,函数返回temp的值后,temp就会被回收
但返回值为const type&时,temp会被保留,将temp的地址作为返回值,直到使用函数返回值的那个变量的作用域结束后才被回收
*/
函数重载
/* 重载函数必须具有不同的形参列表 */
#include <iostream>
using namespace std;
int Abs(int x) { return x > 0 ? x : -x; }
float Abs(float x) { return x > 0 ? x : -x }
double Abs(double x) { return x > 0 ? x : -x; }
void main() {
cout << Abs(-9) << endl;
cout << Abs(-9.9f) << endl;
cout << Abs(-9.8) << endl;
}
重载函数注意事项:
① 返回值不同并不能作为重载函数的依据。
// 重载函数
int f(int, int)
double f(int)
int f(char)
// 只有返回类型不同,而函数名和参数表都完全相同的函数只能看作是同一函数的重复声明
int f(int);
double f(int);② 在定义和调用重载函数时,要注意它的二义性。
<!–hexoPostRenderEscape:
int f(int& x) {…}
double f(int x) {…}
int a = 1;
f(a); // error,产生二义性,无法确定调用的是f(int& x)还是f(int x)
:hexoPostRenderEscape–>
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!