C++ 函数与函数调用(传值、指针、引用调用)

8人阅读 评论(0) 收藏 举报
分类:

        函数是一组一起执行一个任务的语句。每个 C++ 程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。

        您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。

        函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。

        C++ 标准库提供了大量的程序可以调用的内置函数。例如,函数 strcat() 用来连接两个字符串,函数 memcpy() 用来复制内存到另一个位置。

        函数还有很多叫法,比如方法、子例程或程序,等等。

定义函数

C++ 中的函数定义的一般形式如下:

return_type function_name( parameter list ){ body of the function}

在 C++ 中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分:

  • 返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void
  • 函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名。
  • 参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。
  • 函数主体:函数主体包含一组定义函数执行任务的语句。

实例

以下是 max() 函数的源代码。该函数有两个参数 num1 和 num2,会返回这两个数中较大的那个数:

// 函数返回两个数中较大的那个数 
int max(int num1, int num2)
{
 // 局部变量声明 
 int result;
 if (num1 > num2) result = num1;
 else result = num2;
 return result;
}

函数声明

函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。

函数声明包括以下几个部分:

return_type function_name( parameter list );

针对上面定义的函数 max(),以下是函数声明:

int max(int num1, int num2);

在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明:

int max(int, int);

当您在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。在这种情况下,您应该在调用函数的文件顶部声明函数。

调用函数

创建 C++ 函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务。

当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。

调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。例如:

实例

#include <iostream>
using namespace std; 
// 函数声明
int max(int num1, int num2); 
int main()
{ // 局部变量声明
	int a = 100; int b = 200; int ret;
	// 调用函数来获取最大值 
	ret = max(a, b);
	cout << "Max value is : " << ret << endl;
	return 0;
}
// 函数返回两个数中较大的那个数
int max(int num1, int num2)
{
	// 局部变量声明 
	int result;
	if (num1 > num2) result = num1;
	else result = num2;
	return result;
}

把 max() 函数和 main() 函数放一块,编译源代码。当运行最后的可执行文件时,会产生下列结果:

Max value is : 200

函数参数

如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数

形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。

当调用函数时,有两种向函数传递参数的方式:

调用类型描述
传值调用该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数对实际参数没有影响。
指针调用该方法把参数的地址复制给形式参数。在函数内,该地址用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。
引用调用该方法把参数的引用复制给形式参数。在函数内,该引用用于访问调用中要用到的实际参数。这意味着,修改形式参数会影响实际参数。

默认情况下,C++ 使用传值调用来传递参数。一般来说,这意味着函数内的代码不能改变用于调用函数的参数。之前提到的实例,调用 max() 函数时,使用了相同的方法。

参数的默认值

当您定义一个函数,您可以为参数列表中后边的每一个参数指定默认值。当调用函数时,如果实际参数的值留空,则使用这个默认值。

这是通过在函数定义中使用赋值运算符来为参数赋值的。调用函数时,如果未传递参数的值,则会使用默认值,如果指定了值,则会忽略默认值,使用传递的值。请看下面的实例:

实例

#include <iostream>
using namespace std; 
int sum(int a, int b = 20)
{
	int result; result = a + b;
	return (result);
}
int main()
{ // 局部变量声明 
	int a = 100; int b = 200; int result;
	// 调用函数来添加值 
	result = sum(a, b);
	cout << "Total value is :" << result << endl;
	// 再次调用函数 
	result = sum(a);
	cout << "Total value is :" << result << endl;
	return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Total value is :300
Total value is :120

Lambda 函数与表达式

C++11 提供了对匿名函数的支持,称为 Lambda 函数(也叫 Lambda 表达式)。

Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。

Lambda 表达式本质上与函数声明非常类似。Lambda 表达式具体形式如下:

[capture](parameters)->return-type{body}

例如:

[](int x, int y){ return x < y ; }

如果没有返回值可以表示为:

[capture](parameters){body}

例如:

[]{ ++global_x; } 

在一个更为复杂的例子中,返回类型可以被明确的指定如下:

[](int x, int y) -> int { int z = x + y; return z + x; }

本例中,一个临时的参数 z 被创建用来存储中间结果。如同一般的函数,z 的值不会保留到下一次该不具名函数再次被调用时。

如果 lambda 函数没有传回值(例如 void),其返回类型可被完全忽略。

在Lambda表达式内可以访问当前作用域的变量,这是Lambda表达式的闭包(Closure)行为。 与JavaScript闭包不同,C++变量传递有传值和传引用的区别。可以通过前面的[]来指定:

[]      // 沒有定义任何变量。使用未定义变量会引发错误。
[x, &y] // x以传值方式传入(默认),y以引用方式传入。
[&]     // 任何被使用到的外部变量都隐式地以引用方式加以引用。
[=]     // 任何被使用到的外部变量都隐式地以传值方式加以引用。
[&, x]  // x显式地以传值方式加以引用。其余变量以引用方式加以引用。
[=, &z] // z显式地以引用方式加以引用。其余变量以传值方式加以引用。

另外有一点需要注意。对于[=]或[&]的形式,lambda 表达式可以直接使用 this 指针。但是,对于[]的形式,如果要使用 this 指针,必须显式传入:

[this]() { this->someFunc(); }();
查看评论

C++中搭建Lua脚本系统开发框架,并实现OpenGL调用

1.如何编译lua 2.C++ 中调用lua函数 3.lua中如何调用C++函数 4.深入的介绍lua栈(lua的灵魂) 5.lua闭包和上值的使用 6.lua元表的使用(lua的精髓) 7.实现导出C++类给lua 8.实现自动化导出类给lua 9.导出OpenGL函数库给lua 10.游戏循环中调用lua,实现OpenGL绘制.
  • 2017年03月20日 22:41

C/C++语言函数参数传递:传值,传指针,传引用

前面我们介绍了函数的调用约定,明白了函数调用者与被调用者之间传递参数的顺序与如何进行栈恢复的。 实际上,函数调用者如何将参数传递给被调用者也是有讲究的。 总的来说,函数参数传递分为3种情况:传值,传指...
  • u012713968
  • u012713968
  • 2016-01-08 14:50:51
  • 636

函数调用三种方式:传值&传引用&传指针

相关概念 c++三种传递参数方式 传参数的值(称值传递,简称传值),传参数的地址(称地址传递,简称为传址),和引用传递(称为传引用),相应的函数传值调用,传址调用和传引用调...
  • smallgyy
  • smallgyy
  • 2012-12-01 19:32:21
  • 1894

二级指针和指针引用函数传参(C++)

在函数的使用过程中,我们都明白传值和传引用会使实参的值发生改变。那么能够通过传指针改变指针所指向的地址吗?在解决这个问题之前,也许我们应该先了解指针非常容易混淆的三个属性: ①.指针变量地址(...
  • qq_32483145
  • qq_32483145
  • 2016-10-23 13:18:18
  • 2008

传值和传引用、传指针的区别

c语言中所有传递给函数的参数
  • a15994269853
  • a15994269853
  • 2014-04-18 09:50:51
  • 11121

函数的传值调用,传址调用和引用调用分析

函数的传值调用和传址调用在C和C++中都是合法的语法,但是引用调用就只是在C++中合法的。1.传值调用:程序:#includevoid swap(int x, int y){ int tmp = x;...
  • yanxiaolx
  • yanxiaolx
  • 2016-05-29 13:43:19
  • 513

C/C++的值传递,指针传值和引用传值的区别

首先让我们来看下面几个代码:
  • zhushh
  • zhushh
  • 2014-11-03 12:07:15
  • 2300

传值,传指针和传引用区别和联系

C++写了很多年,有一天,写着写着代码。竟然自己发现对传值,传指针,传引用这个每天都在用的传递方式的区别还不是很清楚。以为自己懂了,其实还理解得还不够深入,基础还需要花时间琢磨。今天参考了很多篇博客和...
  • zx3517288
  • zx3517288
  • 2016-11-27 12:15:28
  • 1823

c++const指针与函数调用

在我的博客http://blog.csdn.net/caoyan_12727/article/details/52064958中,已经讨论了动态绑定和静态绑定,以及在缺省参数情况下虚函数的绑定情况。一...
  • caoyan_12727
  • caoyan_12727
  • 2016-09-10 10:50:01
  • 618

C++传值&传指针&传引用

我同学看见我的电脑都说我浏览器开太多了,忍不住要帮我关掉,但是宝宝一个窗口是写博客,一个窗口写javascript,一个窗口写算法,虽然每个都开了十几个,但是条理很清晰啊,没毛病!C++传参数的三种方...
  • tingyugetc11
  • tingyugetc11
  • 2017-03-23 14:27:21
  • 926
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 997
    排名: 5万+
    最新评论