C语言函数传值的相关问题

(本文年代久远,请谨慎阅读)现有如下程序段:

void getmem(char **p,int n){
	*p=(char *)malloc(n);
}
int main(void) {
	// your code goes here
	char *str;
	getmem(&str,100);
	strcpy(str,"hello");
	printf("%s",str);free(str);
	return 0;
}

执行无误,输出hello,没有问题; 修改之后如下:

void getmem(char *p,int n){ //一开始认为是多余的
	p=(char *)malloc(n);
}
int main(void) {
	// your code goes here
	char *str;
	getmem(str,100); //相应改为str
	strcpy(str,"hello");
	printf("%s",str);free(str);
	return 0;
}

代码分析

上述输出为null,其实不小心犯了个低级错误,那就是: 调用getmem时是值传递,str本身在getmem之后并没有获得相应空间,原因即getmem中的*p 作为局部变量并不能将p返回到main函数,即它只让局部的p指向了一段空间,没有意义。

而如果形参改为开始的

1

getmem(char **p,int n)

调用时使用

1

getmem(&str,100);

其意思是:char *p即指向指针的指针,意为“p指向一个变量,此变量存放的不是具体数据,而是一个指针的地址”,p 即表示其所指的地址变量,显然,此处被指向的指针即str,那么getmem中的

1

*p=(char *)malloc(n);

即表示此“被指向的指针”,即str指向一段空间,而区别于值传递的是此处实参为&str,其结束调用后会改变其指向。

此处会改变的原因:本质仍为值传递,但是传递的不是此指针(不同于前面的getmem(str,100)),而是指针所存放的地址,其被 p所指向,然后在函数中通过p修改了p指向内容的值,即修改了str的地址,即调用后str指向发生改变。

注意

char *str中,str是一个地址,printf(str)中str也是个地址,只不过格式控制类型为%s,这样的print即从str地址开始一直输出,直到’\0’为止(终结符是系统自动加上的),这样便实现打印字符串的工作,好像str真作为一个变量存放了这个串,其实不然。

另外,不用函数的方式来开辟空间确实就不需要**p这么麻烦:

int main(void) {
	// your code goes here
	char *str;
	str=(char *)malloc(100);
	strcpy(str,"hello");
	printf("%s",str);free(str);
	return 0;
}

上述即可以完成对char *str开辟空间的工作,此外,除了用malloc手动申请空间,也可以用数组赋值的方式:

int main(void) {
	// your code goes here
	char *str;
	char a[100];//利用系统自动为数组分配空间的特点
	str=a; //这样也可以实现str指向一片连续空间
	//str=(char *)malloc(100);
	strcpy(str,"hello");
	printf("%s",str);free(str);
	return 0;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券