C 指针变量值和地址传递

//指针变量进行值传递,实参赋值给形参,会在栈区申请一个局部的指针变量,和外面实参是两个变量
void getmemory(char *p)
{ 
	 p=(char *) malloc(100); 
 	 strcpy(p, "hello world");
}
int main()
{
	char *str=NULL; 
 	getmemory(str); 
 	printf("%s",str);  //一直未NULL,多次调用会造成内存空间泄漏,无法释放
 	free(str); 
	 return 0; 
} 

这样操作每调用函数一次都会泄露一块内存,str一直为NULL;
在这里插入图片描述

//要想改变实参的值,则需传递实参的地址,通过解指针来改变实参的值
void getmemory(char **p)
{ 
 	*p=(char *) malloc(100); 
 	strcpy(*p,"hello world"); 
}
int main()
{
 	char *str=NULL; 
 	getmemory(&str); 
 	printf("%s",str); 
 	free(str); 
 	return 0; 
} 

使用指针变量的地址作为参数传入函数,函数中申请的空间的地址会赋值str和临时变量*p,释放时会释放同一块内存空间;
在这里插入图片描述

<think> 首先,用户的问题是关于C语言中函数传递指针值传递地址传递的区别。我需要基于提供的引用内容来回答。 回顾引用: - 引用[1]提到值传递地址传递的例子:值传递如传入x=4,y=7,地址传递如传入&x,&y,通过指针操作变量值。 - 引用[2]说明调用子函数时栈的处理:值传递不影响主函数参数值,地址传递改变参数地址指向的值。 - 引用[3]讨论指针做传参时值传递地址传递的区别,但具体内容未详述。 - 引用[4]展示了传递结构体指针的例子,解决了一个问题。 - 引用[5]是一个C语言代码示例,涉及指针操作函数调用。 用户的问题焦点是“传递指针时”的值传递地址传递。在C语言中,所有参数传递都是值传递(pass by value),但当传递指针时,本质上是传递地址的值,从而允许函数修改指针指向的数据。这通常被称为“传递地址”或“通过指针传递”,但技术上是值传递地址值。 关键点: - **值传递(Pass by Value)**:函数接收参数的副本,修改副本不影响原值。 - **地址传递(Pass by Address)**:这通常指的是传递指针地址值),函数使用指针间接访问并可能修改原数据。 在C语言中,没有真正的“地址传递”机制;所有传递都是值传递。但当传递指针时,效果类似于地址传递。 从引用中提取相关信息: - 引用[1][2]明确区分了值传递地址传递值传递不改变原值,地址传递通过指针改变。 - 引用[4][5]展示了实际代码示例。 回答结构: 1. **解释基本概念**:先定义值传递地址传递。 2. **指针传递中的应用**:讨论当传递指针时,如何体现值传递地址传递的区别。 3. **区别**:强调值传递指针本身不影响原指针,但可以影响指向的数据;地址传递通常指传递指针本身。 4. **代码示例**:从引用中引用或创建简单示例说明。 5. **引用来源**:在回答末尾添加引用标识如[^1], [^2]。 使用中文回答,确保LaTeX语法正确。用户问题中没有数学表达式,但如果有变量,用$...$格式。 生成相关问题:基于用户问题,生成1-3个相关问题。 最终回答结构: - 清晰介绍 - 逐步解释 - 示例代码(如果需要) - 相关问题 </think> ### C语言函数传递指针值传递地址传递的区别 在C语言中,函数参数传递本质上是**值传递**(pass by value),但当传递指针(即内存地址)时,可以通过指针间接操作内存数据,实现类似“地址传递”(pass by address)的效果。两者的核心区别在于**是否允许函数修改原始数据**。下面逐步解释: 1. **值传递(Pass by Value)**: - 当函数参数以值传递方式传递时,函数接收的是实参的**副本**,而非原始数据本身。 - 在函数内修改参数值,不会影响调用函数(如`main`函数)中的原始变量。 - **传递指针时的值传递示例**: - 如果传递一个指针(如`int *p`),函数接收的是指针变量的副本(即地址值的副本)。 - 修改指针副本本身(如改变指针指向的地址)不会影响原始指针,但可以通过指针副本间接修改指针指向的数据。 - 示例代码(基于引用[1][2]): ```c void modifyPointer(int *p) { p = NULL; // 修改指针副本的指向,不影响原始指针 } int main() { int x = 10; int *ptr = &x; modifyPointer(ptr); // 值传递指针副本 printf("%p\n", ptr); // 输出不变(如0x7ffee3),因为ptr未被修改 } ``` - 此处`modifyPointer`函数接收`ptr`的副本,修改副本不影响`main`中的`ptr`[^1][^2]。 2. **地址传递(Pass by Address)**: - **术语说明**:C语言没有真正的“地址传递”语法,但通过传递指针(即地址值),函数可以**直接操作原始数据的内存**,实现类似地址传递的效果。 - 当函数参数以指针形式传递时,函数接收的是原始变量的地址值副本。 - 函数内通过**解引用指针**(如`*p`)可以修改原始数据,因为指针指向的内存地址是共享的。 - **关键区别**值传递保护原始指针变量不被修改,而地址传递(通过指针)允许修改指针指向的数据。 - **传递指针时的地址传递示例**: - 传递指针后,函数通过指针操作内存,改变原始变量值。 - 示例代码(基于引用[4][5]): ```c void swap(int *a, int *b) { int temp = *a; // 解引用指针,操作原始数据 *a = *b; *b = temp; } int main() { int x = 4, y = 7; swap(&x, &y); // 传递变量地址 printf("x=%d, y=%d\n", x, y); // 输出x=7, y=4,原始数据被修改 } ``` - 这里`swap`函数通过指针解引用修改了`main`函数中的`x``y`值,体现了地址传递的效果[^1][^4]。 3. **核心区别总结**: - **值传递指针**传递指针的副本,函数无法改变原始指针变量本身(如指向的地址),但可以修改指针指向的数据(如果未限制)。 - **地址传递(通过指针**传递指针副本,但通过解引用操作原始数据,实现数据的“传递引用”效果。 - **内存影响**: - 值传递时,函数调用创建新栈帧存储副本,调用结束栈销毁,不影响原始变量[^2]。 - 地址传递时,函数通过指针修改共享内存,影响原始数据。 - **使用场景**: - 值传递:适合保护数据不被意外修改(如只读操作)。 - 地址传递:需函数修改原始数据时(如结构体、数组操作,见引用[4])。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值