C语言的指针
目录
指针作为参数传递
C语言中,当指针作为函数参数进行传递时,实际上形参和实参指向的是同一个地方,例如:
/*
* @Author: YaleXin
* @Date: 2020-06-19 18:02:53
* @LastEditTime: 2020-06-29 08:59:40
* @LastEditors: YaleXin
* @Description:
* @FilePath: \my_c_workspace\some_test\pointTest-copy.c
* @祈祷不出现BUG
*/
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
void test(int *p1) { printf("=== test p1 = %p ====\n", p1); }
int main() {
int *p;
printf("=== main p = %p ====\n", p);
test(p);
return 0;
}
输出的是:
=== main p = 0000000000000010 ====
=== test p1 = 0000000000000010 ====
可见二者的地址是相同的。
所以形参对其指向的内存区域进行修改,也会影响到实参指向的内存区域,因为二者指向的区域是同一个位置,例如:
/*
* @Author: YaleXin
* @Date: 2020-06-19 18:02:53
* @LastEditTime: 2020-06-29 09:08:30
* @LastEditors: YaleXin
* @Description:
* @FilePath: \my_c_workspace\some_test\pointTest-copy.c
* @祈祷不出现BUG
*/
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
void test(int *p1) { *p1 = 2; }
int main() {
int a = 1;
int *p = &a;
printf("before a = %d\n", a);
test(p);
printf("after a = %d\n", a);
return 0;
}
输出的是:
before a = 1
after a = 2
但是,我们再来看一个例子:
/*
* @Author: YaleXin
* @Date: 2020-06-19 18:02:53
* @LastEditTime: 2020-06-29 09:16:55
* @LastEditors: YaleXin
* @Description:
* @FilePath: \my_c_workspace\some_test\pointTest-copy.c
* @祈祷不出现BUG
*/
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
void test(char *p1) { p1 = "modified"; }
int main() {
char *p = NULL;
test(p);
printf("after p = %s\n", p);
return 0;
}
很容易让人以为输出的是
after p = modified
但是实际上输出的是
after p = (null)
下图给出这个过程中,指针的变化:
实际上是因为形参指向的区域已经与实参指向的不一致。
但是假如有在被调函数改变实参的地址的需求怎么办?
两种方法:
-
被调函数返回指针:
#include <malloc.h> #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <stdio.h> #include <stdlib.h> char *test(char *p1) { p1 = "modified"; } int main() { char *p = NULL; p = test(p); printf("after p = %s\n", p); return 0; }
但是使用该方法的时候,不推荐返回局部指针,返回局部指针很容易出现错误,详见这篇文章
下面的例子就是存在问题:
#include <malloc.h> #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <stdio.h> #include <stdlib.h> char *test(char *p1) { p1 = "modified"; char str[20] = ""; sprintf(str, "yalexin %s", p1); printf("str = %s\n",str); return str; } int main(void) { char *p = NULL; p = test(p); printf("after p = %s\n", p); return 0; }
输出的是:
str = yalexin modified after p = (null)
-
使用二级指针:
#include <malloc.h> #include <stdio.h> #include <stdlib.h> char test(char **p1) { *p1 = "modified"; } int main(void) { char *p = NULL; printf("调用函数之前p的地址是 %p\n", p); test(&p); printf("调用函数之后p的地址是 %p\n", p); printf("after p = %s\n", p); return 0; }
输出:
调用函数之前p的地址是 0000000000000000 调用函数之后p的地址是 0000000000404000 after p = modified
注意事项
- 当指针指向的是一个变量,例如
*int* *p = &a;
,是不能使用free(p)
进行释放资源,free()
只是针对使用了malloc()
,realloc()
函数进行申请的内存进行释放。 - 使用
free()
后,相应的指针就会变为“野指针”,如果对野指针进行引用,会造成不可预期的后果,所以一般使用free(p)
后,一般紧接着p = NULL
本文由「黄阿信」创作,创作不易,请多支持。
如果您觉得本文写得不错,那就点一下「赞赏」请我喝杯咖啡~
商业转载请联系作者获得授权,非商业转载请附上原文出处及本链接。
关注公众号,获取最新动态!
历史评论
开始评论