C语言指针作为函数参数传递学习(一)

1. 一维指针做函数参数

传入的指针为NULL

比如下面的例子,很多人都会理解错:

#include <stdio.h>

void test(char *string)
{
	string = "hello world";
}
int main()
{
	char *str = NULL;
	test(str);
	printf("str=%s\n",str);
	
	return 0;
	
}

是不是觉得输出应该是:str=hello world.事实上并不是
输出结果是(操作系统:win10):
在这里插入图片描述
具体过程如下:
在这里插入图片描述
开始str指针指向NULL,并将该地址作为形参传入函数test(),最开始string指针也是指向NULL,接着讲“hello world”地址传给了string,此时string的指针不再指向NULL,而是指向“hello world”这个字符串的地址。为了验证这个,可以在代码里加一些打印信息验证:

#include <stdio.h>

void test(char *string)
{
	printf("string未操作之前的的指针:%p\n",string);
	string = "hello world";
	printf("string未操作之后的的指针:%p\n",string);
}
int main()
{
	char *str = NULL;
	printf("传入test函数之前str的指针:%p\n",str);
	test(str);
	printf("str=%s\n",str);

	getchar();
	return 0;
	
}

结果:
在这里插入图片描述

2.那要实现在test函数中改变str的指针指向地址怎么办?

2.1 返回string指针,这个很好理解

#include <stdio.h>

char *test(char *string)
{
	string = "hello world";
	return string;
}
int main()
{
	char *str = NULL;
	str = test(str);
	printf("str=%s\n",str);

	getchar();
	return 0;
}

结果:
在这里插入图片描述
2.2 用二维指针

#include <stdio.h>

void test(char **string)
{
	*string = "hello world";
}
int main()
{
	char *str = NULL;
	test(&str);
	printf("str=%s\n",str);

	getchar();
	return 0;
}

结果:
在这里插入图片描述
具体分析如下图:
在这里插入图片描述
过程:
1.定义一个字符串指针str,str本身的地址是100,值为0(即NULL,一般的编译器NULL的地址是0)。
2.取str的地址100传给string,此时string的值是100,地址为200
3.这里假设“hello world”字符串的地址是300,接下来就是改变一级指针指向的内容的地址,由0变成300。

针对评论区的留言,再一起讨论学习下:
问题:为什么传入形参的是指针,在test函数调用后,main函数中str的内容没有改变?
先看几个例子:

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

void test(char *string)
{
	char *testString = "world";
	
	printf("111 string addr:%p,   testString addr:%p\n",string,testString);
	string = testString;
	printf("222 string addr:%p,   testString addr:%p\n",string,testString);
	
}
int main(void)
{
	char *str ="china";

	test(str);
	printf("333 str addr:%p,      str is:%s\n",str,str);
	
	return 0;
}

结果(因为用的是64位系统,所以地址是8位,这里地址显示的6位,因为前面两位是0,所以默认省略了):
在这里插入图片描述
形参都是值传递。但是这个值如果是指针的话,是可以改变指针指向内容的值,即实参的值。这个要弄清两个概念:指针和指针指向的数据。
这个例子中形参的值是实参的地址,并不是实参的值,所以形参的值的改变只是指针的改变,即指向数据的
地址
改变,并不是指针指向数据的改变。所以我们发现在main函数中,str的值没有改变。
我们先再看一个例子:

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

void test(char *string)
{
	printf("111 addr:%p, content:%s\n",string,string);
	strncpy(string,"world",6);//连带把字符串结尾复制过去
	printf("222 addr:%p, content:%s\n",string,string);
	
}
int main(void)
{
	char *str ="china";

	test(str);
	printf("333 addr:%p, content:%s\n",str,str);
	
	return 0;
}

结果:
在这里插入图片描述
编译没有任何问题。但是运行却崩溃了,为什么呢?
这个又是一个需要注意的点:指针指向的常量存储区是不允许修改的,这个实参和形参的地址都是指向字符串的地址,是const类型的,所以不能修改。
原来的程序稍作修改:

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

void test(char *string)
{
	printf("111 addr:%p, content:%s\n",string,string);
	strncpy(string,"world",6);//连带把字符串结尾复制过去
	printf("222 addr:%p, content:%s\n",string,string);
	
}
int main(void)
{
	char str[] ="china";//修改这里,用字符数组存储,这样指针就指向栈区的内容了

	test(str);
	printf("333 addr:%p, content:%s\n",str,str);
	
	return 0;
}

结果:
在这里插入图片描述
我们可以看到,地址没有改变,但是内容已经被修改了。

总结:
形参都是值传递
1.这个值是指针的话,在被调用的函数(test)中,如果指针的值,不会改变实参的值。
2.如果改变指针指向的内容时,会改变实参的值。
注意:在传递的过程中如果是const类型的指针是不允许修改的。

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值