[其他] C语言的参数传递

[复制链接]
 楼主| modesty3jonah 发表于 2023-1-29 18:30 | 显示全部楼层 |阅读模式
有一道C语言的题可以引用来解释我们今天的问题,我们一起来看一下


v2-281212e4eeb7248fc5797ff6f5ded74d_720w.jpg
上面这个代码有好几处错误,它的目的很简单,就是想把字符串hello world拷贝给str,但是它能拷贝成功吗?


v2-451bd9781f7c3ae6678294585d5c5828_720w.jpg
很显然是不可以的。
为了使大家看的更清楚,代码简单修改一下
#include
#include
#include

void getmemory(char *p)
{
p = (char *) malloc(100);
strcpy(p,"http://www.zhiguoxin.cn");
printf("*p:%s &(*p):0x%x\r\n",p,&p);
}
int main()
{
char *str="http://www.baidu.cn";
getmemory(str);
printf("str:%s &str:0x%x\r\n",str,&str);
free(str);
return 0;
}
按照我们一般人的的想法,结果应该是:
p :http://www.zhiguoxin.cn &p :xxxxxxx
str:http://www.zhiguoxin.cn &str:xxxxxxx
但是实际上结果是多少?


v2-c276aabb92f09bbee1552cb3e03f9c63_720w.jpg
完全没有变化,为了彻底解决这个问题,画了一个图,希望大家能够看的更加清楚一点。


v2-de41a921591e094499bb860fadc0b654_720w.jpg
从这里可以看出来,在分配内存后,str与p就分道扬镳了,而str也还是指向http://www.baidu.cn
如何修改呢?正确的是啥样的?
#include
#include
#include

void getmemory(char **p)
{
*p = (char *) malloc(100);
strcpy(*p,"http://www.zhiguoxin.cn");
printf("*p:%s &(*p):0x%x\r\n",*p,&(*p));
}
int main()
{
char *str="http://www.baidu.cn";
getmemory(&str);
printf("str:%s &str:0x%x\r\n",str,&str);
free(str);
return 0;
}
编译运行,发现没问题。


v2-825aae901c7bb2850745fb957a9319be_720w.jpg
达到了我们想要的目的,字符串也得到了正常的拷贝。
如何解释?
函数中参数都是传值,传指针本质上也是传值,只不过它的值是指针类型罢了。如果想要改变入参内容,则需要传该入参的地址,通过解引用修改其指向的内容。
这里的str的值就是*p的值,是多少?它们都是一个指针,就是保存的是一个地址,地址是多少?地址就是使用动态分配内存malloc函数分配的100字节的首地址。然后又使用strcpy()函数将hello world拷贝到*p里面。
这里面就涉及到了二级指针,首先str毫无疑问是一个指针变量对吧?那么&str是啥?理所当然就是一个指针的指针吧,就是地址的地址。
所以,我如果在某个地方申请了一块内存,如果想得到这块内存的首地址,而此时我们又定义了一个指针变量,想让这个指针来保存我们申请内存你的首地址,就必须要传入这个指针的地址,即指针的指针(二级指针)而不是传入这个指针。
至于原因上面的例子已经非常清楚的讲解了原因。
下面接着回到我们最开始的创建函数的任务句柄。在开始之前我们再把上面的函数封装一下。


v2-5f0f5dcd99e7c060e1a5db4e25aa9e74_720w.jpg
#include
#include
#include

typedef char* TaskHandle_t;

void getmemory(TaskHandle_t *p)
{
*p = (char *) malloc(100);
strcpy(*p,"http://www.zhiguoxin.cn");
printf("*p:%s &(*p):0x%x\r\n",*p,&(*p));
}
int main()
{
TaskHandle_t str;
getmemory(&str);
printf("str:%s &str:0x%x\r\n",str,&str);
free(str);
return 0;
}
没啥大不了的,就是就是给char*起了一个别名而已,让下面的代码看起来更加顺畅一写。


v2-12f20b65a1536dcc42ff75a7d9ccd2cc_720w.jpg
这样对比一下是不是很清楚了呢?这样一来我们创建任务时候这个任务句柄就保存的是我们TCB控制块这个结构体的首地址了,知道了一个任务的TCB控制块首地址的话,那么这个任务的所有信息我是不是都知道了。是的,就是这么奇妙。通过指针的指针,二级指针来转换一下。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

32

主题

1726

帖子

2

粉丝
快速回复 返回顶部 返回列表