我很难在C中掌握一些概念,并对Greg Perry的“C编程绝对初学者指南”中的一些内容感到困惑。
在本书的最后,作者提到了函数gets()的工作方式。他说它返回一个字符指针,指向用户输入的字符串的开头。如果是这样的话(原谅我的话)无知。我真的很擅长这一点)它是如何返回字符串的其余部分的? 我的猜测是它将一个字符数组存储为完整,并将它存储为第一个元素:
char * names[5] = {"name1","name2","name3"};
从那里我们可以做类似
的事情printf("%s\n",*(names));
这将打印“name1”,因为它实际上是返回数组的第一个位置。 但是如下:
gets(names);
printf("%s\n",*(names));
上面的例子编译得很好,但是当我运行它时会出现分段错误,如果我。
我确信我可能没有正确地解释这本书,但在我看来,好像作者说要分配(在上面的例子中)用户输入的任何内容(名称)作为第一个数组元素整个不是部分,我能做的最多就是打印我输入的任何名字的第一个字母。
我一直对这些小事情着迷,因为我觉得它们帮助我更好地理解C编程(以及整个编程),所以我非常感谢任何可以指出我正确方向的人。
答案 0 :(得分:1)
C中的字符串只是内存中连续的字符序列。该函数返回指向第一个字符的指针,并且通过指针算术,您可以查看其余字符。没有“返回字符串的其余部分”:基本上,它返回的内容是“嘿,这是指向字符串开头的指针。您可以从该位置开始阅读”。
例如,如果p
是指向第一个字符的指针,p+1
是指向下一个字符的指针,依此类推。字符串以空值终止,因此您知道何时停止。
旁注:gets()
非常危险,因为它容易受到缓冲区溢出的影响;它已经过时了。没有人应该再使用它了。请改为阅读fgets()
。
gets()
名称无效,即时类型不匹配。 names
衰减为char **
,而gets()
期待char *
。此外,您必须提供指向有效内存位置的指针。
如果你这样声明names
:
char names[128];
然后gets(names)
有效。请注意,gets()
无法知道names
最多可以容纳128个字符,这就是您应该使用fgets()
的原因,{{1}}接收缓冲区的大小作为附加参数,它知道它的极限。
答案 1 :(得分:0)
在C中,数组是连续内存块的列表。因为这些块在内存中是连续的,如果你有第一个的地址,你就拥有了所有这些块的地址。 例如,使用char c [3],以下等式为真:
c[0] == *c
c[1] == *(c + sizeof(char));
c[2] == *(c + sizeof(char) * 2);