今天回家路上在地铁上玩手机的时候,发现了一个有意思的C语言的面试题,于是自己也看了看,代码(代码并非原创,源自网络)如下:
#include <stdio.h>
#include <stdlib.h>
typedef char u1;
void Test(u1 *pu1)
{
pu1 = (u1*) malloc(100);
strcpy(pu1,"hello");
}
int main( )
{
u1 *pu1str = NULL;
Test(pu1str);
printf("%s/n",pu1str);
free(pu1str);
return 0x00;
}
这段代码需要怎样修改?
首先我们简单理解一下代码的逻辑,我们大致可以了解,是想输出字符串“hello”;但是最后打印出来的是我们想要的嘛?当然不是!打印出来的为NULL。 那么为什么会这样 如何修改才能打印出我们想要的字符串呢?
这段代码错误点在哪? 就是在对实参和形参的理解。其实我们通过打印地址的方式 我们可以发现 pu1和pu1str打印出来的地址全部都是0x00000000 但是并不代表着pu1=pu1str
其实最终将字符串拷贝时拷贝到了 0x00CF4EF8(也就是malloc申请的内存地址,由Test中的pu1指向),但是并未实现将指针pu1str也指向 0x00CF4EF8, 所以最后打印出来的依旧是NULL
那么如何使指针pu1str原本指向的空指针变成 0x00CF4EF8?这就是问题的关键了。也就意味着我们需要改变pu1str自身地址里面存储的地址(也就是pu1str指向的地址),既然要改变指针pu1str自身地址存储的值,我们必然要得到pu1str自身地址,也就是&pu1str,并且得到地址里面的值。也就需要用到二级指针了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char u1;
void Test(u1 **ppu1)
{
*ppu1 = (u1 *) malloc(100);
strcpy(*ppu1,"hello");
}
int main( )
{
char *pu1str= NULL;
Test(&pu1str);
printf("%s\n",pu1str);
free(pu1str);
return 0x00;
}
我们借助二级指针 使ppu1指向&pu1str ,ppu1即为pu1str存储的地址,给ppu1赋值,则修改了指针pu1str储存的地址,则间接修改了pu1str指向的地址。因此这样就可以打印出来,不过这么改是不是也可以?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char u1;
void Test(u1 *pu1)
{
strcpy(pu1,"hello");
}
int main( )
{
u1 *pu1str = (u1 *) malloc(100);
Test(pu1str);
printf("%s\n",pu1str);
free(pu1str);
return 0x00;
}
这样改应该就不是本应该考察的重点了吧 哈哈哈哈哈
如果觉得写的可以 或者有问题欢迎大家留言讨论
还可以关注一下公众号(初学嵌入式的栗子) 谢谢大家