C和C++中函数传参方式

本文介绍了C和C++中函数参数的传递方式。C语言有传值和传址两种,传值单向传递不影响实参,传址可改变实参;C++在此基础上增加传引用,效果如传址、使用如传值。还给出传参建议,并提及内存分配的三种方式。

c中函数参数传递方式为传值,传地址两种

C++中函数参数传递方式为传值,传地址和传引用三种

C语言

(1)传值

传值的过程:

(1)行参与实参各占一个独立的存储空间。

(2)行参的存储空间是函数被调用时才分配的。调用开始,系统为行参开辟一个临时

存储区,然后将各实参之值传递给行参,这时行参就得到了实参的值。

(3)函数返回时,临时存储区也被撤销。

传值的特点:单向传递,即函数中对行参变量的操作不会影响到调用函数中的实参变量。

例1:

#include<stdio.h>

void myswap(int x, int y)

{

int t;

t=x;

x=y;

y=t;

}

int main()

{

int a, b;

printf("请输入待交换的两个整数:");

scanf("%d %d", &a, &b);

myswap(a,b); //作为对比,直接交换两个整数,显然不行

printf("调用交换函数后的结果是:%d 和 %d\n", a, b);

return 0;

}

结果:

输入2 3,输出2 3

解析:

传值不成功的原因是指在形参上改变了数值,没有在实参上改变数值。

(2)传址

就是传变量的地址赋给函数里形式参数的指针,使指针指向真实的变量的地址,因为对指针所指地址的内容的改变能反映到函数外,也就是能改变函数外的变量的值。

例2:

#include<stdio.h>

void myswap(int *p1, int *p2)

{

int t;

t=*p1;

p1=p2;

*p2=t;

}

int main()

{

int a, b;

printf("请输入待交换的两个整数:");

scanf("%d %d", &a, &b);

myswap(&a,&b); //交换两个整数的地址

printf("调用交换函数后的结果是:%d 和 %d\n", a, b);

return 0;

}

结果:

输入2 3,输出3 2

解析:

传地址成功的原因利用指针改变了原来的地址,所以实参就交换了。

 

C++

(1)传值:同上

(2)传地址:同上

(3)传引用

实际是通过指针来实现的,能达到使用的效果如传址,可是使用方式如传值。

例3:

#include<stdio.h>

void myswap(int &x, int &y)

{

int t;

t=x;

x=y;

y=t;

}

int main()

{

int a, b;

printf("请输入待交换的两个整数:");

scanf("%d %d", &a, &b);

myswap(a,b); //直接以变量a和b作为实参交换

printf("调用交换函数后的结果是:%d 和 %d\n", a, b);

return 0;

}

结果:

输入2 3,输出3 2

解析:

引用是直接改变两个实参变量a,b的值,所以就交换了。

建议:

如果传值的话,会生成新的对象,花费时间和空间,而在退出函数的时候,又会销毁该对象,花费时间和空间。

因而如果int,char等固有类型,而是你自己定义的类或结构等,都建议传指针或引用,因为他们不会创建新的对象。

内存分配方式:

此外还应注意内存的分配方式,内存分配方式有三种:

(1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的

整个运行期间都存在。例如全局变量,static 变量。

(2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函

数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集

中,效率很高,但是分配的内存容量有限。

(3) 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc 或new 申请任意

多少的内存,程序员自己负责在何时用free 或delete 释放内存。动态内存的生存

期由我们决定,使用非常灵活,但问题也最多。

<think> 我们正在讨论C++中的默认参数。根据引用[1][2],默认参数允许在定义函数时为形参指定默认值。调用函数时,如果省略了某个有默认值的参数,则使用默认值;如果提供了实参,则使用实参的值。 引用[2]还提到了一些规则: 1. 默认参数必须从右向左设置,即如果某个参数有默认值,那么它右边的所有参数都必须有默认值。 2. 函数的声明实现只能有一个地方指定默认参数(通常放在声明中)。 3. 调用函数时,实参按从左到右的顺序匹配形参,所以不能跳过左边的参数而直接给右边的参数赋值(除非使用C++11的指定参数初始化,但默认参数不支持跳过,只能从左边开始省略)。 引用[3][4]提到了数组作为函数参数的情况,但这不是默认参数的重点,默认参数主要针对的是普通参数。 因此,我们可以总结如下: 1. 默认参数的定义:在函数声明或定义中,为参数指定一个默认值。 2. 使用规则: - 默认参数必须从右向左连续设置,不能间隔。 - 调用函数时,实参按位置从左向右匹配,所以只能省略尾部(右边)的参数。 - 同一个参数的默认值只能在函数声明或定义中的一处指定(通常放在头文件的函数声明中)。 示例: 下面是一个正确使用默认参数的函数声明: void func(int a, int b=10, int c=20); // 正确:默认参数从右向左 调用示例: func(1); // 相当于 func(1,10,20) func(1,2); // 相当于 func(1,2,20) func(1,2,3); // 相当于 func(1,2,3) 错误示例: void func(int a=10, int b, int c=20); // 错误:a有默认值,但b没有(默认参数必须从右向左连续) 另外,关于数组作为函数参数,引用[3]展示了三种传递数组的方法(普通传递、引用传递、指针传递),但默认参数并不直接用于数组参数(因为数组作为参数时实际上是传递指针,而默认参数可以是数组的大小?)。不过,我们可以为指针型的参数设置默认值,例如: void printArray(int *arr, int size=10); 但是,引用[4]提到,有时我们可以通过重载函数来避免使用默认参数(但重载默认参数的使用场景不同)。 因此,针对用户的问题,我们主要回答默认参数的用法,并给出示例。 注意:引用[3][4]的内容虽然与默认参数不直接相关,但提到了函数参数传递的其他方面,我们可以在相关问题中提及。 根据要求,我们将生成相关问题。 </think> ### C++默认函数参数的用法详解 #### 1. **基本概念** 在C++中,可以为函数参数指定默认值。当调用函数时,如果没有提供对应位置的实参,则自动使用默认值;若提供了实参,则使用传入的值[^1]。例如: ```cpp int sum(int a, int b = 5) { return a + b; } // 调用示例 sum(3); // 返回 3+5=8 sum(3, 7); // 返回 3+7=10 ``` #### 2. **核心规则** - **从右向左设置** 默认参数必须从右向左连续指定,左侧参数无默认值时右侧不能有默认值[^2]: ✅ 合法:`void f(int a, int b=10, int c=20)` ❌ 非法:`void f(int a=5, int b, int c=20)` - **调用匹配顺序** 实参按从左向右的顺序匹配形参,只能省略尾部参数[^2]: ```cpp void print(int x=1, int y=2, int z=3); print(10); // x=10, y=2, z=3 print(10, 20); // x=10, y=20, z=3 ``` - **单一定义原则** 默认参数只能在函数声明或定义中的**一处**指定(通常在头文件的声明中)[^2]。 #### 3. **复合型用法** - **数组参数** 数组作为参数时,可配合默认指针或引用使用[^3]: ```cpp // 默认指针参数 void initArray(int* arr = nullptr, int size=10) { if(arr) for(int i=0; i<size; ++i) arr[i]=i; } // 数组引用(需固定大小) void printArray(int (&arr)[5] = {0,0,0,0,0}) { for(int val : arr) cout << val << " "; } ``` - **函数重载替代** 需谨慎使用函数重载替代默认参数(易导致代码冗余)[^4]: ```cpp // 不推荐的重载方式 double power(double base) { return base*base; } double power(double base, int exp) { ... } ``` #### 4. **使用场景** 1. 简化高频使用的参数(如日志级别、容器初始容量) 2. 扩展函数功能时保持向后兼容 3. 减少重复的参数传递(如数学计算中的精度参数) #### 5. **注意事项** - 默认值必须是常量表达式或全局变量 - 虚函数的默认参数在派生中不会重写基设置 - 默认参数不算函数签名的一部分,不能用于区分重载函数
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值