一、函数的定义与使用
1.1 函数的定义
1.1.1 函数定义的语法形式
类型说明符 函数名(含类型说明的形参表)
{
语句序列
}
1.1.2 形式参数
形式参数(简称形参),内容如下:
type1 name1,type2 name2,type3 name3,...typen namen;
type1,type2是类型标识符,表示形参的类型。
name1,name2是形参名。
形参的作用是实现主调函数与被调函数之间的联系。
函数在没有被调用的时候是静止的,此时的形参只是一个符号,它标志着形参出现的位置应该有一个什么类型的数据。函数在被调用时才执行,也就是被调用时才由主调函数将实际参数(实参)赋予形参。
1.2 函数的调用
1.2.1 函数的调用形式
函数原型声明的形式如下:
类型说明符 函数名(含类型说明的形参表);
double power(doublex,int n)
//函数名:power
//返回值类型:double
//参数表:double x,int n
声明一个函数只是将函数的有关信息(函数名、参数表、返回值类型等)告诉编译器,此时并不产生任何代码。
声明了函数原型之后,便可在主函数中调用此函数。形式如下:
函数名(实参列表)
//1.
power(5,2)
//2.
int a,b;
cin>>a>>b>>endl;
power(a,b);
- 形参与实参
函数定义的时候,num1和num2并没有真实数据。
它只是形式上的参数,简称形参。
int add(int num1, int num2)//int num1和num2是形参
{
int sum = num1 + num2;
return sum;
}
int main()
{
int a, b;
a = 10;
b = 20;
a和b称为实际参数,简称实参。
当调用函数的时候,实参的值会传递给形参。
//a的值传递给num1,b的值传递给num2,在函数中计算出sum并返回,再将这个return值赋给c
int c=add(a, b);
cout << "c=" << c;
return 0;
}
1.2.2 嵌套调用
如果函数1调用了函数2,函数2调用了函数3,便形成了函数的嵌套调用。
eg:输入两个整数,求他们的平方和。
思路:函数1——求平方函数,函数2——求和函数
double power(double a)//函数1
{
double val = a * a;
return val;
}
double add(double x, double y)//函数2
{
double sum = power(x)+power(y);//嵌套调用
return sum;
}
int main()
{
double m, n;
cin >> m >> n;
cout << "The sum of square of a and b:" << add(m,n) << endl;
return 0;
}
1.3 函数的参数传递
1.3.1 值传递
//如果函数不需要返回值,声明的时候可以写void
void swap(int num1, int num2)
{
cout << "交换前:\n" << "num1=" << num1<<"\nnum2=" << num2 << endl;
int temp = num1;
num1 = num2;
num2 = temp;
cout << "交换后:\n" << "num1=" << num1<<"\nnum2="<< num2 << endl;
}
int main()
{
int a = 10;
int b = 20;
cout << "a=" << a << endl;
cout << "b=" << b << endl;
swap(a, b);
cout << "a=" << a << endl;
cout << "b=" << b << endl;
}
如果像这样写,结果如下:
发现a和b的值并没有发生变换。这是因为,此程序采用的是值传递。值传递中,当函数发生调用时,才给形参分配内存空间,并将实参的值传递给形参(初始化)。函数调用时传递实参的值,是单向传递过程。所谓单向传递过程,是指一旦形参获得值便与实参脱离了关系,此后无论形参发生了怎样的改变,都不会影响到实参。形参值的改变对实参不起作用。
1.3.2 引用传递
引用是一种特殊类型的变量,可以被认为是另一个变量的别名。
使用引用时需注意:
- 声明一个引用时,必须对它初始化,使它指向一个已存在的对象。
- 一旦一个引用被初始化以后,就不能改为指向其他对象。
使用引用传递改写上述程序:
void swap(int &num1, int &num2)//“&”是取地址符
{
cout << "交换前:\n" << "num1=" << num1<<"\nnum2=" << num2 << endl;
int temp = num1;
num1 = num2;
num2 = temp;
cout << "交换后:\n" << "num1=" << num1<<"\nnum2="<< num2 << endl;
}
因为引用涉及一些更深层次的内容,所以打算另起一篇博客。本篇对引用的讲解先到此为止。
二、函数的常见样式
常见的函数样式有4种:
- 无参无返
- 有参无返
- 无参有返
- 有参有返
//无参无返
void test01()
{
cout << "this is test01" << endl;
}
//有参无返
void test02(int a)
{
cout << "this is test02 a=" <<a<< endl;
}
//无参有返
int test03()
{
cout << "this is test 03" << endl;
return 1000;
}
//有参有返
int test04(int b)
{
cout << "this is test04 b=" << b << endl;
return b;
}
在主函数中调用时要遵循函数样式:
//无参无返函数调用
test01();
//有参无返函数调用
test02(100);
//无参有返函数调用
int num1=test03();//num1用于接受返回值
cout << "num1=" << num1 << endl;
//有参有返函数调用
int num2=test04(10000);
cout << "num2=" << num2 << endl;
三、内联函数
内联函数在调用时不发生控制转移,而是在编译时将函数体嵌入在每一个调用处。
与函数调用相比,内联函数没有参数传递、控制传递等开销,减少了程序在时间和空间方面的开销。因此,对于一些功能简单、规模较小又使用频繁的函数,可以设计为内联函数。
内联函数的定义与普通函数的定义方式几乎一样,只是需使用关键字inline。形式如下:
inline 类型说明符 函数名(含类型说明的形参表)
{
语句序列
}
注意,内联函数体内不能使用循环语句和switch语句。
四、总结与反思
本篇博客写完,深入理解了形参的概念和性质。通过图解的方式解读了函数调用值传递的单向传递性质,有助于抽象概念的理解。
对于递归调用,打算结合汉诺塔问题深入研究一下;对于引用传递,会安排在后续的博客中。