C 双字符指针声明和初始化
我总是认为该声明
char *c = "line";
相同
char c[] = "line";
与and so I did
char **choices = { "New Game", "Continue Game", "Exit" };
,其中给出了不兼容的指针类型,而
char *choices[] = { "New Game", "Continue Game", "Exit" };
没有。对理解这一点有帮助吗?
I always though that declaring
char *c = "line";
was the same as
char c[] = "line";
and so I did
char **choices = { "New Game", "Continue Game", "Exit" };
Which gives me an incompatible pointer type, where
char *choices[] = { "New Game", "Continue Game", "Exit" };
doesn't. Any help on understanding this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在线 C 标准(草案 n1256):
添加了强调。
char **
是标量类型,而不是聚合,因此与初始化器{"New Game", "Continue Game", "Exit"}
不兼容。相比之下,char *[]
是聚合(数组)类型。同样,您不能编写类似的内容
,因为
int *
不是数组类型。你对
和 的
理解略有偏差;它们不相同。第一种形式将字符串文字的地址复制到指针值
c
。第二种形式将数组表达式"line"
的内容复制到c
指定的缓冲区。Online C standard (draft n1256):
Emphasis added.
char **
is a scalar type, not an aggregate, and so is not compatible with the initializer{"New Game", "Continue Game", "Exit"}
. By contrast,char *[]
is an aggregate (array) type.Similarly, you couldn't write something like
because
int *
isn't an array type.Your understanding of
and
is slightly off; they are not the same. The first form copies the address of the string literal to the pointer value
c
. The second form copies the contents of the array expression"line"
to the buffer designated byc
.与
实际上相同,
只是变量
hidden_C0
不可直接访问。但是,如果转储生成的汇编语言,您就会看到它(它通常具有不是有效 C 标识符的名称,例如.LC0
)。在字符串常量数组示例中,发生了同样的事情:现在
,这是一种特殊情况行为,仅适用于字符串常量。你不能写,
你必须写
,这就是为什么你也不能写
。
(您的困惑是常见误解的一个特例,即数组与 C 中的指针“相同”。它们不是。数组就是数组。当它们被使用(几乎在所有上下文中),但不是在定义它们时使用。)
is not the same as
it's really the same as
except that the variable
hidden_C0
is not directly accessible. But you'll see it if you dump out generated assembly language (it will usually have a name that isn't a valid C identifier, like.LC0
). And in your array-of-string-constants example, the same thing is going on:becomes
Now, this is a special case behavior that is available only for string constants. You cannot write
you must write
and that's why you can't write
either.
(Your confusion is a special case of the common misconception that arrays are "the same as" pointers in C. They are not. Arrays are arrays. Variables with array types suffer type decay to a pointer type when they are used (in almost every context), but not when they are defined.)
嗯,他们不一样。对于大多数人来说,更容易认为它们是相同的,所以每个人都开始这样思考,直到他们遇到像上面这样的问题:-)
我本来打算写一些长篇大论的东西,但后来我想...一定有人已经这样做了。他们确实做到了。这是一个很好的解释:
http://www.lysator。 liu.se/c/c-faq/c-2.html
最简单的思考方法是,当您执行以下操作时:
您实际上正在执行以下操作:
现在...这并不是真正的准确的图片(尽管我不是编译器专家)。它至少让你以稍微更正确的方式思考事情。
所以,回到你的问题,如果我理解正确(这永远不能保证),你就不能用C语言做你的示例行#3。你是对的,有人可以编写一个编译器在这里会做正确的事情,但 gcc 不会。然而,第四个示例做了“正确的事情”,并为您提供了“一个指针数组,每个指针都指向一个 const char 数组本身”。
我曾经遇到过一个网页,可以将复杂的 C 类型翻译成英文。那可能是在 90 年代初,但我敢打赌,如果你用谷歌搜索得足够多,它会给你一个比我刚刚写的更准确的措辞描述。
Well, they're not the same. It's just easier for most people to think of them as being the same so everyone starts to think that way until they run into a problem like the above :-)
I was going to write something long and winded, but then I figured... Someone else must have done this already. And they have. This is a pretty good explanation:
http://www.lysator.liu.se/c/c-faq/c-2.html
The easiest way to think about it is that when you do something like:
You're really doing something like:
Now... that's not really an accurate picture (though I'm not a compiler expert). It at least lets you think about things in a slightly more correct fashion.
So, back to your problem, if I understand things right (which is never guaranteed), you can't do your example line #3 in C. You're right that someone could write a compiler that would do the right thing here, but gcc doesn't. The 4th example, however, does the "right thing" and gives you "an array of pointers that are each pointing to a const char array themselves".
I once ran across a web page that would translate a complex C type into English. That was probably in the early 90s though but I bet if you google enough it would give you a more accurate wording description than the one I just whipped up.
没关系,只要写
char **choices = (char *[]){ "New Game", "Continue Game", "Exit" };
不过,
choices
可以仅用于线性寻址。例如:printf ("%s", &(*choices)[0]);
输出:新游戏
printf ("%s", &(*choices)[1]);
输出:ew Game
printf ("%s", &(*choices)[9]);
输出:Continue Game
所以这不是一个笑话,它是一个有效的初始化。只是另一种用法。
您还可以在此处找到一个非常接近的示例,解释复合文字概念。
It's ok, just write
char **choices = (char *[]){ "New Game", "Continue Game", "Exit" };
However,
choices
can be used only for linear addressing. For example:printf ("%s", &(*choices)[0]);
outputs:New Game
printf ("%s", &(*choices)[1]);
outputs:ew Game
printf ("%s", &(*choices)[9]);
outputs:Continue Game
So it's not a joke, it's a valid initialization. Just another kind of usage.
You can also find a very close example here, explaining Compound Literals notion.