解析C/C++值传递和址传递的区别

 更新时间:2021年10月27日 11:51:18   作者:Z小旋  
今天通过本文给大家介绍C/C++值传递和址传递的区别讲解,本文通过实例代码图文相结合给大家介绍的非常详细,需要的朋友参考下吧

C/C++的按值传递和按地址传递有明显不同,下面对他们作个区别:

按值传递:在调用函数中将原函数的值拷贝一份过去被调用的函数,在被调用函数中对该值的修改不会影响原函数的值。

按地址传递:在调用函数的时候将原函数的值所在的地址拷贝一份过去,被调用函数对这个地址所作的修改会影响原来的值。

概述:

首先我们要知道 a的地址”和“a地址中的内容”的区别,数据是存放在内存中的,每一个变量都有一个内存地址, 变量的内容存放在对应内存地址的空间中

比方说定义

int a = 10;

那么a在内存中的地址是0x1100,在这个地址中存储的数据是10

在这里插入图片描述

假设创建指针p,把a的地址赋值给p,就是把a的首地址0x1100赋值给指针p,这个时候p的值就是变量a在内存中的首地址

int a =10;
int*p;
p=&a; //把a的首地址赋值给P

在这里插入图片描述

简单点的理解就好比你去图书馆借书,每本书都会有他的一个编号(地址),记录它所在的位置,而这个书,就是这个地址对应的内容
如果你用指针,得到的是这个书所对应的编号(地址) ,存储内容就是地址
如果你是变量赋值,值传递,那么就相当于复印了一遍这个书(地址对应的内容),然后用一个新的编号(地址),去存储你复印的这本书

在这里插入图片描述

从命名来理解

所以我们就会发现:

值传递,或者变量赋值,修改变量的值,修改的是新的新的编号(地址)中的内容(复印的书),不会影响到原来编号(地址)中的数据。

也就是形参是实参内容的拷贝,并不是地址的拷贝,所以改变形参的值并不会影响实参的值

在这里插入图片描述

使用址传递,用指针修改变量的值,就是把原编号(地址)中的书给修改了,换了一本新的书,就相当于对实参本身进行的操作。

声明Declaration:描述在其他地方创建的对象,并不分配内存。(可以出现在多个地方)

定义Definition:产生一个新的对象,并分配内存。(只能出现一次)

值传递

新开辟一个内存空间,存储原来变量的值,修改变量修改的是新的内存空间中的值。所以,原始的参数不会被函数修改。

值传递的优点: 通过值来传递的参数可以是数字,变量,表达式。原本参数的值不会被修改。

值传递的缺点: 不能修改原参数的值。

#include <stdio.h>
 
void swap (int x, int y)
{
	int temp;
	temp = x;
	x = y;
	y = temp;
//	printf ("x = %d, y = %d\n", x, y);
}
 
int main (void)
{
	int a = 4, b = 6;
	printf ("交换前:\n a = %d, b = %d\n", a, b);
	swap (a, b);
	printf ("交换后:\n a = %d, b = %d\n", a, b);
	return 0;
}

输出:

在这里插入图片描述

址传递

址传递就是指针传递,形参实际是指向实参地址的指针,当对形参的进行操作时,就相当于对实参本身进行的操作,可以改变指针指向内容的值,但是不能改变指针本身的地址。

#include <stdio.h>
void swap (int *x, int *y)
{
	int temp=*x;
	*x=*y;
	*y=temp;
	//printf("x = %d, y = %d\n", *x, *y);
}
 
int main(void)
{
	int a=4;
	int b=6;
    printf("交换前:\n a = %d, b = %d\n", a, b);
	swap (&a,&b);  //传递的是地址 
	printf("交换后:\n a = %d, b = %d\n", a, b);
	return 0;
}

**加粗样式**

在你了解了什么是值传递和址传递之后,我们来看一个面试题:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void GetMemory( char *p ) {
	p = (char *) malloc( 100 );
}


int main (void) {
	char *str = NULL;
	GetMemory( str );
	strcpy( str, "hello world" );
	printf( str );
	return 0;
}

请问运行会有什么样的结果? 会输出hello world吗?

答:程序崩溃,没有输出

因为 GetMemory 并不能传递动态内存,Test 函数中的 str 一直都是 NULL。strcpy(str, “hello world”);将使程序崩溃
函数中的p其实是实参str的一份拷贝,函数中的操作都是对q进行的,str仍然是NULL,所以输出*str的值产生崩溃

也就是:传递给形参的指针仍然是实参指针的一份拷贝

在这里插入图片描述

这一点需要注意

解决的话可以把形参改为二重指针,程序便可以按预想中的情形进行:

二重指针指向一重指针的地址 也就是传递过来的实际是*str的参数本身

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void GetMemory( char **p ) {
	*p = (char *) malloc( 100 );
}

int main (void) {
	

	char *str = NULL;
	GetMemory(&str);
	strcpy( str, "hello world" );
	printf( str );
	return 0;
}

到此这篇关于解析C/C++值传递和址传递的区别的文章就介绍到这了,更多相关C/C++值传递和址传递内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • c语言字符数组与字符串的使用详解

    c语言字符数组与字符串的使用详解

    本篇文章是对c语言中字符数组与字符串的使用进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • QT使用canon sdk拍照并保存到本机的方法示例

    QT使用canon sdk拍照并保存到本机的方法示例

    这篇文章主要介绍了QT使用canon sdk拍照并保存到本机的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • C++ 系统String类详解

    C++ 系统String类详解

    这篇文章主要介绍了C++的系统String类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-11-11
  • C++ 函数指针详细总结

    C++ 函数指针详细总结

    这篇文章主要介绍了C++ 函数指针内容,下面文章围绕C++ 函数指针的相关资料展开详细内容,包括函数指针的进阶内容,需要的朋友可以参考一下,希望对大家有所帮助
    2021-11-11
  • 教你分辨C++堆与栈的区别

    教你分辨C++堆与栈的区别

    堆与栈的区别有:1、栈由系统自动分配,而堆是人为申请开辟;2、栈获得的空间较小,而堆获得的空间较大;3、栈由系统自动分配,速度较快,而堆一般速度比较慢;4、栈是连续的空间,而堆是不连续的空间
    2021-06-06
  • 用C语言实现通讯录

    用C语言实现通讯录

    这篇文章主要为大家详细介绍了用C语言实现通讯录,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06
  • VC随机函数srand和rand用法

    VC随机函数srand和rand用法

    VC中随机函数最常用就是srand和rand(实际上是属于标准C函数),其中srand负责设置随机种子,rand则负责生成随机数。使用此二随机函数需要包含<stdlib.h>头文件
    2016-11-11
  • 浅谈C++对象的内存分布和虚函数表

    浅谈C++对象的内存分布和虚函数表

    下面小编就为大家带来一篇浅谈C++对象的内存分布和虚函数表。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • C++ 内存泄漏调试方式

    C++ 内存泄漏调试方式

    这篇文章主要介绍了C++ 内存泄漏调试方式,C++和其他高级语言不同,需要自行管理内存,项目大调用多,下文我们就来看看C++ 内存泄漏调试方式分享,需要的小伙伴可以参考一下
    2022-04-04
  • C/C++ Qt MdiArea 多窗体组件应用教程

    C/C++ Qt MdiArea 多窗体组件应用教程

    MDI窗体控件类似于画布,该控件只具备展示窗体的功能,无法实现生成窗体,所以我们需要在项目中手动增加自定义的Dialog对话框,并对该对话框进行一定的定制,这篇文章主要介绍了C/C++ Qt MdiArea 多窗体组件应用,需要的朋友可以参考下
    2021-12-12

最新评论