服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - 解析C/C++值传递和址传递的区别

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

2022-02-16 15:51Z小旋 C/C++

今天通过本文给大家介绍C/C++值传递和址传递的区别讲解,本文通过实例代码图文相结合给大家介绍的非常详细,需要的朋友参考下吧

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

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

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

 

概述:

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

比方说定义

int a = 10;

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

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

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

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

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

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

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

从命名来理解

所以我们就会发现:

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

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

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

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

声明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;
}

输出:

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

 

址传递

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

#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;
}

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

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

#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的值产生崩溃

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

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

这一点需要注意

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

二重指针指向一重指针的地址 也就是传递过来的实际是*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++值传递和址传递内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/as480133937/article/details/120876758

延伸 · 阅读

精彩推荐
  • C/C++C语言实现双人五子棋游戏

    C语言实现双人五子棋游戏

    这篇文章主要为大家详细介绍了C语言实现双人五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    两片空白7312021-11-12
  • C/C++深入C++拷贝构造函数的总结详解

    深入C++拷贝构造函数的总结详解

    本篇文章是对C++中拷贝构造函数进行了总结与介绍。需要的朋友参考下...

    C++教程网5182020-11-30
  • C/C++使用C++制作简单的web服务器(续)

    使用C++制作简单的web服务器(续)

    本文承接上文《使用C++制作简单的web服务器》,把web服务器做的功能稍微强大些,主要增加的功能是从文件中读取网页并返回给客户端,而不是把网页代码...

    C++教程网5492021-02-22
  • C/C++C语言main函数的三种形式实例详解

    C语言main函数的三种形式实例详解

    这篇文章主要介绍了 C语言main函数的三种形式实例详解的相关资料,需要的朋友可以参考下...

    ieearth6912021-05-16
  • C/C++OpenCV实现拼接图像的简单方法

    OpenCV实现拼接图像的简单方法

    这篇文章主要为大家详细介绍了OpenCV实现拼接图像的简单方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    iteye_183805102021-07-29
  • C/C++关于C语言中E-R图的详解

    关于C语言中E-R图的详解

    今天小编就为大家分享一篇关于关于C语言中E-R图的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看...

    Struggler095962021-07-12
  • C/C++c/c++实现获取域名的IP地址

    c/c++实现获取域名的IP地址

    本文给大家汇总介绍了使用c/c++实现获取域名的IP地址的几种方法以及这些方法的核心函数gethostbyname的详细用法,非常的实用,有需要的小伙伴可以参考下...

    C++教程网10262021-03-16
  • C/C++c/c++内存分配大小实例讲解

    c/c++内存分配大小实例讲解

    在本篇文章里小编给大家整理了一篇关于c/c++内存分配大小实例讲解内容,有需要的朋友们可以跟着学习参考下。...

    jihite5172022-02-22