繁体   English   中英

编译ANSI C book,Linked Lists章节中的错误

[英]Errors compiling example from ANSI C book, Linked Lists chapter

我正在做一些较旧的C书[ANSI C的第一本书]中的一些例子,并在尝试编译此示例代码时遇到错误:

#include <stdio.h>

struct tele_typ {
  char name[30];
  char phone_no[15];
  struct tele_typ *nextaddr;
};

main() {
  struct tele_typ t1 = {"Acme, Sam", "(201) 555-6678"};
  struct tele_typ t2 = {"Dolan, Edith", "(213) 682-3104"};
  struct tele_typ t3 = {"Lanfrank, John", "(415) 718-4581"};
  tele_typ *first;    /* create a pointer to a structure */

  first = &t1;          /* store t1's address in first */
  t1.nextaddr = &t2;    /* store t2's address in t1.nextaddr */
  t2.nextaddr = &t3;    /* store t3's address in t2.nextaddr */
  t3.nextaddr = NULL;   /* store the NULL address in t3.nextaddr */

  printf("\n%s %s %s",first->name,t1.nextaddr->name,t2.nextaddr->name);
}

..和gcc newstruct.c -o newstruct的输出:

newstruct.c: In function 'main':
newstruct.c:13:3: error: unknown type name 'tele_typ'
newstruct.c:15:9: warning: assignment from incompatible pointer type [enabled by default]
newstruct.c:20:28: error: request for member 'name' in something not a structure or union

这是关于链接列表的第10.4章。 书中有错误吗? 或者标准/ gcc version 4.6.2 20120120 (prerelease)有什么变化? 谢谢!

我无法重现第一个警告; 你确定你在这里粘贴的代码是给你警告的代码吗?

错误unknown type name 'tele_typ'很容易修复:您已声明类型struct tele_typ ,但struct tele_typ前面没有struct

  tele_typ *first;    /* create a pointer to a structure */

如果您将其更改为:

  struct tele_typ *first;    /* create a pointer to a structure */

它会编译没有错误。 (并且在我的gcc-4.5.real(Ubuntu / Linaro 4.5.2-8ubuntu4)4.5.2中也没有警告。)

如果你想完全按原样编译函数体,那么你还需要添加:

typedef struct tele_typ tele_typ;

struct tele_typ定义之后立即:

struct tele_typ {
  char name[30];
  char phone_no[15];
  struct tele_typ *nextaddr;
};

typedef struct tele_typ tele_typ;

但我有点担心一本不给main()函数提供返回类型类型参数的C书。 int main(int argc, char* argv[])int main(int argc, char** argv)是常见的,任何偏离这两个选项的书都让我觉得有些奇怪。 C编程语言是一本很好的书; 它的清晰度和正确性很难改进。 考虑切换到原始。

你错过了函数main第4行开头的'struct'。 它应该读

struct tele_typ *first;

这在C ++中运行良好,因为'struct'关键字是可选的,但在C中它是必需的。

这条线错了:

tele_typ *first;    /* create a pointer to a structure */

你忘了struct关键字了。

另外, main应该被声明为返回一个int ,并以return结束。

您的代码有以下错误,其中一些是次要的。

  1. main()需要是int main(void) main()形式是旧式定义; 它在1989 ANSI C标准中被弃用,并且根据1999 ISO C标准的平坦无效,它取消了“隐含int”规则。 使用(void)而不是()使得显式main没有参数; ()表单仍然有效,但自1989年以来一直被弃用。许多C编译器为了向后兼容性将接受这样的旧式功能,但至少会在符合模式下警告它们。 您应该了解如何为编译器启用此类警告。

  2. tele_typ *first; 需要首先是struct tele_typ *first; 这是主要问题。 (添加typedef是另一种解决此问题的方法,但它绝对没有必要。代码已经将类型称为struct tele_typ ;您只需要一致地这样做。)请注意,在C ++中,您可以将类型引用为struct tele_typ或者就像tele_typ - 当然,C ++是一种具有不同规则的不同语言。

  3. 你应该在你打印的字符串的末尾有一个\\n ; 你一开始就不需要它。

    printf("%s %s %s\\n",first->name,t1.nextaddr->name,t2.nextaddr->name);

  4. 你应该有一个return 0; main函数中关闭之前} 从1989年ANSI C标准(或等效的1990 ISO C标准)开始,在不返回值的情况下从main结束处掉落会向调用环境返回未定义的结果。 截至1999年的标准,从main结束下跌确实隐含return 0; ,但明确它是没有害处的。

启用警告后,某些编译器可能会抱怨在t1t2t3的声明上缺少初始值设定项,因为您没有为nextaddr成员提供值。 这没关系,因为(a)只要你有一个初始化器,任何未指定的成员都被初始化为零(在指针的情况下,指向空指针),以及(b)你稍后明确地为这些成员赋值。

我看到你正在使用gcc。 要获得一组好的警告,您可以使用:

gcc -ansi -pedantic -Wall -Wextra

如果要针对较新版本的C标准进行测试,请将-ansi更改为-std=c99-std=c1x 请注意,使用-ansi或其中一个-std=...选项可能会禁用某些非标准扩展。 有时您需要编写不可移植的代码; 在这种情况下,您可以删除该选项,也可能是-pedantic 但是这个程序不使用任何扩展,也不需要。

您必须更改指针结构声明,如下所示:

struct tele_typ *first;    /* create a pointer to a structure */

为什么,因为您尚未将结构tele_type定义为直接类型,您仍然必须使用struct tele_typ指向它。

如果你在另一边做过这样的事情:

typedef struct TELE_TYP {
  char name[30];
  char phone_no[15];
  struct TELE_TYP *nextaddr;
}tele_typ;

你本来可以调用以前定义的类型,如果你写了,那就没关系了:

tele_typ *first;

长话短说,这本书是错的:P

使用typedef肯定是要走的路。

只是一个狡辩:保留领先的双下划线; 应用程序员不应该使用它们,因为它们可能会导致命名空间问题。

Kernahan&Ritche的书“The C Programming Language”是最好的书吧。 然而,这对初学者来说是一个艰难的过程。 发布问题的人有这本书显然是错的!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM