我有一个以上的疑问所以请耐心等待。 有人能告诉我为什么这段代码会失败吗?
#include<stdio.h>
void main(int argc,char **argv) /*assume program called with arguments aaa bbb ccc*/
{
char **list={"aaa","bbb","ccc"};
printf("%s",argv[1]);/*prints aaa*/
printf("%s",list[1]); /*fails*/
}
我认为它与指针内容的指针有关,我不明白这一点。所以我试过了:
#include<stdio.h>
void main()
{
char **list={"aaa","bbb","ccc"};
char *ptr;
ptr=list;
printf("%s",ptr);/*this prints the first string aaa*/
/* My second question is how do i increment the value
of ptr so that it points to the second string bbb*/
}
char *list[]
和char **list
之间有什么区别?在什么情况下使用它们都是理想的?
令我困惑的另一件事是argv特别?当我将char **list
传递给另一个函数时假设它允许我以argv
的方式访问内容,它也失败了。
我意识到过去曾经问过类似的问题,但我似乎无法找到我需要的东西。若有人可以发布相关链接。
答案 0 :(得分:12)
您应该使用char *list[]={"aaa","bbb","ccc"};
代替char **list={"aaa","bbb","ccc"};
。您使用char* list[] = {...};
声明指针数组,但是使用char**
将指针传递给指向函数的一个或多个指针。
T* x[]
=指针数组T** x
=指向指针的指针 P.S。响应ejohn:我只能想到一个用于创建指针指针的用法(作为实际声明的变量,而不是作为函数参数或由一元&
运算符创建的临时变量):a {{ 3}}。简而言之,句柄是指向指针的指针,其中handl; e由用户拥有,但它指向的指针可以根据操作系统或库的需要进行更改。
在旧的Mac OS中广泛使用了句柄。由于Mac OS是在没有虚拟内存技术的情况下开发的,因此保持堆快速碎片化的唯一方法是在几乎所有内存分配中使用句柄。这让操作系统根据需要移动内存来压缩堆并打开更大,连续的可用内存块。
事实是,这种策略充其量只是“少吸”。有一大堆缺点:
memcpy()
工作的批次。我忘记了可能还有几个。请记住,所有这些缺点仍然比仅使用指针和快速分割堆更加可口,特别是在第一台只有128K RAM的Mac上。这也让我们深入了解为什么Apple完全放弃了这一切并转向BSD,然后他们有机会,一旦他们的整个产品线都有内存管理单元。
答案 1 :(得分:3)
答案 2 :(得分:2)
char ** x指向一个char指针数组,但这可能不是你的编译器在内存中存储{“aaa”,“bbb”,“ccc”}的方式。无论编译器如何存储指针数组,char * x []都将生成正确的代码。
答案 3 :(得分:1)
学习C复杂性的最佳来源是Peter van der Linden的专家C编程(http://www.amazon.co.uk/Expert-Programming-Peter-van-Linden/dp/0131774298)。
这本书的名称具有误导性,因为我认为它很容易被初学者阅读。
答案 4 :(得分:0)
“......假设它有事可做 用指针指针的东西, 我不明白。“