编译ANSI C手册“链表”一章中的示例时出错



我正在做一本旧的C书[ANSIC的第一本书]中的一些例子,在试图编译以下示例代码时遇到了错误:

#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 *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;

但我有点担心一本C书没有给main()函数一个返回类型类型的参数。int main(int argc, char* argv[])int main(int argc, char** argv)是常见的,任何偏离这两个选项的书都会让我觉得有点奇怪。《C程序设计语言》是一本很好的书;由于它的清晰性和正确性,很难对其进行改进。考虑切换到原始版本。

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

  1. CCD_ 10需要是CCD_。main()表单是一个旧式的定义;从1989年的ANSI C标准开始,它就被弃用了,在1999年的ISO C标准中,它完全无效,该标准删除了"隐式int"规则。使用CCD_ 13而不是CCD_ 14使得CCD_;()形式仍然有效,但自1989年以来一直被弃用。出于向后兼容性的考虑,许多C编译器会接受这样的旧式功能,但至少会在一致性模式下警告它们。您应该了解如何为编译器启用此类警告。

  2. CCD_ 17需要是CCD_。这是主要问题。(添加typedef是解决这一问题的另一种方法,但这是绝对没有必要的。代码已经将该类型称为struct tele_typ;您只需要一致地这样做。)请注意,在C++中,您可以将该类型称作struct tele_typ,也可以仅称作tele_typ——当然,C++是一种不同的语言,具有不同的规则。

  3. 您应该在打印字符串的结尾处有一个n;你一开始并不需要它。

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

  4. main函数中,在关闭}之前应该有一个return 0;。根据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。但是这个程序不使用任何扩展,也不需要。

您在函数main的第4行开头缺少"struct"。它应该读取

struct tele_typ *first;

这在C++中会很好,因为"struct"关键字是可选的,但在C中却是必需的。

此行错误:

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

您忘记了struct关键字。

此外,main实际上应该声明为返回int,并以return结束。

使用typedef肯定是一种方法。

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

Kernahan&里奇的书《C编程语言》是最好的书。然而,对于初学者来说,这是一项艰巨的任务。发帖人的书显然错了!

您必须更改指针结构声明,以获得以下内容:

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

相关内容

  • 没有找到相关文章

最新更新