(本文年代久远,请谨慎阅读)现有如下程序段:
1 | void getmem(char **p,int n){ |
执行无误,输出hello,没有问题;
修改之后如下:
1 | void getmem(char *p,int n){ //一开始认为是多余的 |
代码分析
上述输出为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指向发生改变。
<< 更多精彩尽在『程序萌部落』>>
<< https://www.cxmoe.com >>
注意
char *str中,str是一个地址,printf(str)中str也是个地址,只不过格式控制类型为%s,这样的print即从str地址开始一直输出,直到’\0’为止(终结符是系统自动加上的),这样便实现打印字符串的工作,好像str真作为一个变量存放了这个串,其实不然。
另外,不用函数的方式来开辟空间确实就不需要**p这么麻烦:
1 | int main(void) { |
上述即可以完成对char *str开辟空间的工作,此外,除了用malloc手动申请空间,也可以用数组赋值的方式:
1 | int main(void) { |
😒 留下您对该文章的评价 😄