【问题标题】:Clarification on why this C code works澄清为什么这个 C 代码有效
【发布时间】:2011-07-03 20:23:50
【问题描述】:

我今天正在学习 C。一段时间以来,我一直在使用托管语言(Java、C#、Python 等)进行编码。我以为我了解了指针的细节,但后来我编写了以下代码,按预期工作,但生成了“不兼容的指针类型”警告。

void setText(char* output) {
    //code to set output to whatever, no problems here.
}

int main(int argc, const char* argv[]) {
    char output[10];

    setText(&output);

    //[EDITED] ...other test code which printf's and further manipulates output.

    return 0;
}

所以我用谷歌搜索,最后换行了

setText(&output);

到

setText(output);

摆脱了警告。但现在我不知道为什么第一个工作在所有。据我所知,我正在发送地址的地址(因为 char* x; 本质上与 char x[]; 相同)。我有什么误解,为什么这两种方法都有效?

【问题讨论】:

  • 很难告诉你为什么setText 在没有看到它的实现的情况下工作。虽然,如果所有setText 都设置了一个变量,然后程序退出,你怎么能真正判断程序是否在做你想做的事?
  • T * 与T [K]不相同。参见例如c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr
  • @Cameron:现在不适合我——也许你遇到了短暂的中断。你能再试一次吗?
  • @delnan:一定是这样,现在也对我有用 :-)

标签: c pointers


【解决方案1】:

output 的类型是char [10],它在函数调用的上下文中衰减为char *(这就是第二个变体起作用的原因)。

&output 的类型是char (*)[10],即指向数组的指针。这不是一回事,因此会发出编译器警告。但是,&output(地址)的 值 等于 output 的值(一旦它衰减为 char *),因此最终结果“如预期”。

这听起来像是迂腐,但有一个相当重要的区别。请尝试以下操作:

void foo(const char *p)
{
    printf("%s\n", p);
}

int main(void)
{
    char output[][6] = { "Hello", "world" };

    foo(output[0] + 1);
    foo(&output[0] + 1);
}

推荐阅读是the C FAQ on arrays and pointers,特别是问题6.3和6.12。

【讨论】:

  • 尽管有警告,它仍然“有效”,因为它们最终都指向同一个地方。
  • 很好的例子。它确实有助于说明这里实际发生的情况。
  • 是的,这个例子确实有帮助。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
  • 1970-01-01
  • 2014-02-02
相关资源
最近更新 更多