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

时间:2012-02-10 01:45:18

标签: c gcc linked-list ansi

我正在使用较旧的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)中有什么变化?谢谢!

6 个答案:

答案 0 :(得分:3)

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

错误unknown type name '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)是常见的,任何偏离这两个选项的书都会让我觉得有些奇怪。 The C Programming Language是一本好书;它的清晰度和正确性很难改进。考虑切换到原始版本。

答案 1 :(得分:2)

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

struct tele_typ *first;

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

答案 2 :(得分:2)

这一行错了:

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

您忘记了struct关键字。

此外,main应该真正声明为返回int,并以return结尾。

答案 3 :(得分:2)

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

  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. 您打印的字符串的 end 应该有一个\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;,但明确它是没有害处的。

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

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

    nextaddr

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:1)

使用typedef绝对是最佳选择。

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

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