传参(转)

函数传参有三种传参方式:传值、传址、传引用。

1、按值传递

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

(2)形参的存储空间是函数被调用时才分配的,调用开始,系统为形参开辟一个临时的存储区,然后将各实参传递给形参,这是形参就得到了实参的值。

#include<stdio.h>
void swap1(int x, int y)//定义中的x,y变量是swap函数的两个形参
{
	int tmp;
	tmp = x;
	x = y;
	y = tmp;
	printf("x=%d,y=%d\n", x, y);
}
int main()
{
	int a = 2;
	int b = 3;
	swap1(a, b);//a,b变量为swap函数的实际参数
	printf("a=%d,b=%d", a, b);
	return 0;
}

输出结果为:x=3,y=2; a=2,b=3

代码分析:你也许会疑惑,a和b的值明明在函数swap中交换,为什么输出值却没变呢?

那是因为你还没理解形参和实参的关系。

为了解释这个问题,我先给出如下代码:

int a=2;

int x;

x=a;

x=x+3;

最终的结果是不是a=2,x=5

这段代码我们需要理解a虽然赋值给x,但是a的值并没有改变,对x的任何修改都不会改变a的值。

而代码中值传递方式如下:

main函数中调用了swap函数;swap中包含了以下代码

int x=a;
int y=b;/*前两行代码是函数的隐含操作不可写在代码之中,
是为了方便大家理解我自己加上的*/
int tmp;
	tmp = x;
	x = y;
	y = tmp;
	printf("x=%d,y=%d\n", x, y);

以上的分析中我们可以看出函数是通过赋值把a,b赋给x,y,这是一个隐含操作,我们不能把它显式的写出来,进行函数中变量的值进行交换时只是形参x,y的交换,并没有对实参进行真正交换,所以a,b值不变。

2、地址传递

地址传递与值传递的不同在于,它把实参的存储地址传送给形参,使得形参指针和实参指针指向同一块地址。因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。

示例代码:


void swap2(int *px, int *py)
{
	int tmp;
	tmp = *px;
	*px = *py;
	*py = tmp;
	printf("px=%d,py=%d\n", *px, *py);
}
int main()
{
	int a = 2;
	int b = 3;
	swap2(&a, &b);/*调用了swap函数,同样也有隐含动作px=&a;py=&b;*/
	printf("a=%d,b=%d", a, b);
	return 0;
}

运行结果为*px=3,py=2 a=3,b=2;

代码分析:有了两行隐含赋值操作,我们可以清晰的看出指针px,*py是对变量a,b的值操作。函数里面对a和b的值进行了交换。这就是传址。

3、引用传递

引用传递是以引用为参数,则既可以使得对形参的任何操作都能改变相应数据,又使函数调用方便。引用传递是在形参调用前加入引用运算符“&”。引用为实参的别名,和实参是同一个变量,则他们的值也相同,该引用改变则它的实参也改变。

代码示例:

#include<stdio.h>
void  swap3(int &x,int &y)
{
	int tmp = x;
	x = y;
	y = tmp;
	printf("x=%d,y=%d\n", x, y);
}
int main()
{
	int a = 2;
	int b = 3;
	swap3(a, b);//调用方式与传值一样
	printf("a=%d,b=%d", a, b);
	system("pause");
	return 0;
}

输出结果:x=3,y=2; a=3,b=2;

代码分析:我们看到该代码只与传值中swap函数定义不同,swap3中参数都加了取地址符号&,有了这个函数会将a,b分别替代了x,y,这样函数里面操作就是a,b本身了。

4、对于值传递和引用传递的比较:

在C语言中,并没有引用的概念,引用是C++的概念。

在C++的函数参数中,有两种形式,其中 TYPE & var的形式,称为传引用方式; TYPE var的形式,称为传值。

二者的区别为,当传引用时,实际传到函数中的形参,是实际参数的一个引用,而不是仅传递值到函数中。具体的表现有以下几条:

1 传引用时,形参和实参是同一个变量,即使用相同的内存空间,二者有相同的地址。而传值时二者地址不同;

2 传引用时,由于没有新建变量,所以对于类对象参数,不会产生构造和析构。而如果是传值调用,调用时会进行构造,退出函数时会进行析构;

3 由于传引用使用的是原本实参的地址,所以对引用参数值的修改,会在退出函数后体现在主调函数中,而传值调用对参数的修改不会影响到主调函数。

---------------------

本文来自 番茄都是西红柿 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/qq_39539470/article/details/79519156?utm_source=copy

原文地址:https://www.cnblogs.com/zxy-lya/p/9716587.html

时间: 2024-10-14 07:36:41

传参(转)的相关文章

jQuery与django传参

Get方式传参 Django中的代码如下: urls.py代码: from django.conf.urls import url from django.contrib import admin import AjaxTest.views urlpatterns = [ url(r'^admin/', admin.site.urls), url(r"^index/$",AjaxTest.views.index), ] views.py代码: from django.http impo

spring jdbc传参及处理查询

传参有两种传参方式,一种直接传,一种通过对象传. 查询返回值,可以直接封进对象. public class springJdbcTest { private static JdbcTemplate jdbcTemplate; private static String uuid; @BeforeClass public static void init(){ ApplicationContext context = new ClassPathXmlApplicationContext("/spr

Azure sql database 监控存储过程的传参情况

背景 实施开发的同事找到我,反馈说项目中使用Azure sql database 之后,无法使用Profiler来监控自己开发的存储过程的参数传参情况.确实profiler这些实例级别的工具在Azure sql database下是不支持的,那我们有没有办法,变相实现监控参数情况,特写一篇博客记录一下. 测试环境 Microsoft SQL Azure (RTM) - 12.0.2000.8 Mar 30 2017 01:30:03 Copyright (C) 2016 Microsoft Co

webpack2使用ch4-向根目录index.html文件传参并使用参数 使用线上资源 压缩html

1 webpack.config.js const webpack = require('webpack'), htmlWebpackPlugin = require('html-webpack-plugin'), path = require('path'); module.exports = { entry: { main: './src/script/main.js', a: './src/script/a.js' }, output: { path: path.resolve(__dir

JS完成页面跳转并传参的方法|附加:循环遍历对象

此方法只能传递较少参数 方法如下: <a href='page/index.html'>跳转</a> 以上是正常写法,如果要传参按一下写法: <!--参数写在?后面,多个参数用&隔开,下面传的参数为name=lemon,age=18--> <a href='page/index.html?name=lemon&age=18'></a> 当跳转到页面的时候这个页面的地址栏就会跟你写的那个一样,这时候你只需要获取地址栏的内容并进行采取

Less-minxin传参

//mixin传参 --简单传参,example: .border-radius(@radius) { -webkit-border-radius: @radius; -moz-border-radius: @radius; border-radius: @radius; } .callUse{ .border-radius(5px); } --带默认值传参,参数为可选,example: .border-radius(@radius:5px) { -webkit-border-radius: @

js 日期对象Date以及传参

创建一个日期对象,日期对象可传参new Date() 创建日期对象getFullYear() 获取年份 getMonth() 获取月份 返回值是 0(一月) 到 11(十二月) 之间的一个整数 getDate() 获取日期(多少号) getDay() 获取星期数 返回值是 0(周日) 到 6(周六) 之间的一个整数. getHours() 获取小时 返回值是 0 (午夜) 到 23 (晚上 11 点)之间的一个整数 getMinutes() 获取分钟数 返回值是 0 ~ 59 之间的一个整数 g

【MYSQL】在脚本中使用变量-执行脚本时传参

在shell脚本里可以定义变量,并在执行脚本时任意传参. #!/bin/bashdb_name=$1 #将第一个值赋给db_name变量sql_name=$2 #将第二个值赋给sql_name变量mysql -uroot -p123456 -h192.168.227.129 $db_name < $sql_name 在执行shell脚本时,在执行命令后面直接传参即可 ./sqlrecovery jinqy jinqy.sql

关于url传参中文乱码问题

之前都一直很不了解中文编码得问题,之前在做项目中没碰到那么头痛的问题.所以一直没有了解中文乱码的问题. 问题描述: 地址: http://localhost:8080/sun-government/contest/get_teams_by_type_with_page?typeName=新材料 当在windows 跑 myeclipse的命令台  能正确打印出typeName的参数,而且持久层并没有问题. 当在 linux 跑catalina模式  打印出乱码,持久层也是乱码. 百度了好几个好几

url传参

A页面的某些参数需要传递给B页面 window.location.href = 'competition_console.html?compName='+encodeURI(compName)+'&compStyle='+compStyle+'&roundNum='+roundNum; 跳转到B页面时,传递参数. B页面从url上获取参数: function url_param(){ var url = location.search; var str = url.substr(1); v