C/C++中参数传递有两种方式,传值或传地址(传引用),通常我们要在被调用函数中改变一个变量的值就需要传地址调用方式,例如:

void swap_by_value(int a, int b)
{
int temp;
temp = a;
a = b;
b = temp;
}
void swap_by_ptr(int* pa, int* pb)
{
int temp;
temp = *pa;
*pa = *pb;
*pb = temp;
}
int main(int argc, char* argv[])
{
int a=5, b=6;
swap_by_value(a, b);//传值
printf("a=%d, b=%d\n", a, b);//a=5,b=6
swap_by_ptr(&a, &b);//传地址
printf("a=%d, b=%d\n", a, b);//a=6,b=5
return 0;
}

  很显然,通过传值调用并不能改变main函数中的a与b,要想改变a与b的值就必须通过传地址方式,然后在被调用函数中通过指针访问到主函数中的变量。

  可是通过传递变量指针就一定是传地址调用么?看下面一个例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h> void get_str(char* p); int main(int argc, char* argv[])
{
char* p = NULL;
get_str(p);//传递指针
printf("p=%p\n", p);
puts(p);
return 0;
}
void get_str(char* p)
{
p = (char*)malloc(sizeof("abcd"));
printf("%d\n", sizeof("abcd"));
strcpy(p, "abcd");
return;
}

  其中参数p是一个指针,程序想通过p来得到在get_str(char* p)中分配的一块内存。但是上面的代码并不能完成此功能。原因是程序需要在get_str(char* p)中修改main函数中的指针变量p,使其指向malloc返回的一块内存,要想在 get_str(char* p)中修改main函数中p的值就只有把p的地址传过去,在get_str中通过地址访问主函数中的变量p。正确的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h> void get_str(char** p); int main(int argc, char* argv[])
{
char* p = NULL;
get_str(&p);//传递地址(引用)
printf("p=%p\n", p);//abcd
puts(p);
return 0;
}
void get_str(char** p)
{
*p = (char*)malloc(sizeof("abcd"));
printf("%d\n", sizeof("abcd"));
strcpy(*p, "abcd");
return;
}

  引用是C++中的语法,结合了传地址和传值的优点,即传递的是一个地址,但在形式上又没有指针那个怪异的符合*,看上去舒服多了。

下面是一个传引用版的swap()函数

void swap_by_ref(int& a, int& b)
{
  int temp;
  temp = a;
  a = b;
  b = temp;
}
int main(int argc, char* argv[])
{
  int a=5, b=6;
  swap_by_ref(a, b);
  printf("a=%d,b=%d \n",a,b);//a=6,b=5
  return 0;
}

  总之,如果想在被调用函数中改变哪个变量的值就需要把那个变量的地址传给被调用函数,这样在被调用函数中通过地址就可以访问和修改这个变量。传值的时候会对参数进行拷贝,然后传给被调用函数,而传地址只是对地址进行一份拷贝,然后赋给形参,这样在C++中如果传递一个比较大的对象时效率就有所区别了。对于简单类型的变量来说传值和传地址在根本上是没有区别的,都是传递一个数给被调用函数,而怎样去解释和使用这个数是我们事先约定好的。

转自:http://blog.chinaunix.net/uid-21411227-id-1826826.html

 2015-03-14 10:44:10

C/C++中传值和传地址(引用)的更多相关文章

  1. python中传值和传地址问题

    在python中,还没有对这个知识点有一个详细的定义,很模糊的说明了,通过下面代码,可以观察出来,什么时候传的是值,什么时候传的是地址 有时候会发现自己的数据发生变化,可能就是这个原因,python的 ...

  2. c语言 参数传值和传地址

    static void TestCharP(char **p) { char *q = "ssssss"; *p=q; } static void TestCharP1(char ...

  3. Java中传值与传引用

    不管Java参数类型是什么,一律传递参数的副本. <Thinking In Java>:“When you're passing primitives into a method,you ...

  4. php传值,传地址,传引用的区别

    传值,   是把实参的值赋值给行参   那么对行参的修改,不会影响实参的值 传地址   是传值的一种特殊方式,只是他传递的是地址,不是普通的如int   那么传地址以后,实参和行参都指向同一个对象 传 ...

  5. java中函数传值和传地址的问题

    记录一下这个难过的双休,2019.3.16-2019.3.17,16号上午字节跳动笔试,四道题只做出1道半,输入输出搞的半死,第三题类似于leetcode上的分糖问题,数组初始化的时候全部赋为0了,要 ...

  6. JAVA的String的传值和传地址问题

    关于Java的String类型,可能你会碰到这种情况,将String类型的变量传到一个函数,在这个函数中修改变量的值,但是,实参的值并没有发生改变. Java中String的传值/传地址问题: 例子引 ...

  7. 一段代码让你秒懂java方法究竟是传值还是传地址

    先看看代码以及执行结果: 凝视写得非常清楚了.我就不多说了. 我说说我的结论.事实上在java中没有传值还是传址的概念,java仅仅有引用的概念.引用类似传址.只是是一个变量名中保存着对象的地址,地址 ...

  8. C语言:传值,传地址

    形参:形式参数实参:实际参数 传值: 把实参的值复制给形参, 修改函数内的形参,不会影响实参. 传地址: 指针传值,形参为指向实参地址的指针 当对形参的指向操作时,相当于对实参本身进行的操作 #inc ...

  9. php中传值与传引用的区别。什么时候传值什么时候传引用?

    值传递:   函数范围内对值的任何改变在函数外部都会被忽略; 引用传递: 函数范围内对值的任何改变在函数外部也能反映出这些修改: 优缺点:按值传递时,php必须复制值.特别是对于大型的字符串和对象来说 ...

随机推荐

  1. npoi的用法,动态的判断单元格的大小,设置列的宽度

    public MemoryStream GridToExcelByNPOI(DataTable dt, string strExcelFileName) { HSSFWorkbook wk = new ...

  2. POJ 1679 The Unique MST 【最小生成树/次小生成树模板】

    The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 22668   Accepted: 8038 D ...

  3. 洛谷P1120 小木棍 [搜索]

    题目传送门 题目描述乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍 ...

  4. 洛谷——P1618 三连击(升级版)

    P1618 三连击(升级版) 题目描述 将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数的比例是A:B:C,试求出所有满足条件的三个三位数,若无解,输出“No!!!”. //感谢 ...

  5. Linux命令之who

    who [选项] … [FILE | ARG1 ARG2] 打印有关当前登录用户的信息. (1).选项 -a,--all 同-b –d –login –p –r –t –T -u -b,--boot ...

  6. poj 1068(模拟题)

    Parencodings Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23545   Accepted: 13802 De ...

  7. BZOJ 4883 [Lydsy2017年5月月赛]棋盘上的守卫(最小生成环套树森林)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4883 [题目大意] 在一个n*m的棋盘上要放置若干个守卫. 对于n行来说,每行必须恰好 ...

  8. 中间件和auth模块

    中间件 1.什么是中间件 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用 ...

  9. 从源码入手,一文带你读懂Spring AOP面向切面编程

    之前<零基础带你看Spring源码--IOC控制反转>详细讲了Spring容器的初始化和加载的原理,后面<你真的完全了解Java动态代理吗?看这篇就够了>介绍了下JDK的动态代 ...

  10. Springcloud中的region和zone的使用

    一.背景 用户量比较大或者用户地理位置分布范围很广的项目,一般都会有多个机房.这个时候如果上线springCloud服务的话,我们希望一个机房内的服务优先调用同一个机房内的服务 ,当同一个机房的服务不 ...