ANSI C手册“链接列表”一章中的错误编译示例

6yoyoihd  于 2023-03-22  发布在  其他
关注(0)|答案(6)|浏览(89)

我正在从一本较旧的C书[A First Book of 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)中有什么变化?谢谢!

gywdnpxw

gywdnpxw1#

我无法重现第一次警告;你确定你粘贴在这里的代码是给你警告的代码吗?
错误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- 8 ubuntu 4)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)是常见的,任何偏离这两个选项的书都让我觉得有点奇怪。由于它的清晰性和正确性,很难在此基础上加以改进。考虑切换到原文。

ifsvaxew

ifsvaxew2#

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

  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_typtele_typ--当然,C是一种具有不同规则的不同语言。
    1.你应该在你打印的字符串的 * 结尾 * 有一个\n;一开始你不需要它。
    printf("%s %s %s\n",first->name,t1.nextaddr->name,t2.nextaddr->name);
    1.在main函数中,应该在结束}之前有一个return 0;。(或等效的1990 ISO C标准),从main的末尾脱落而不返回值,将向调用环境返回未定义的结果。从main的末尾掉下来会产生一个隐式的return 0;,但是显式地处理它并没有什么坏处。
    启用警告后,一些编译器可能会抱怨在t1t2t3的声明中缺少初始化器,因为您没有为nextaddr成员提供值。(a)只要你有一个初始化器,任何未指定的成员都被初始化为零(在指针的情况下,指向空指针),以及(B)稍后显式地为这些成员赋值。
    我看到你正在使用gcc。要获得一组良好的警告,你可以使用以下命令:
gcc -ansi -pedantic -Wall -Wextra

如果你想测试一个新版本的C标准,请将-ansi更改为-std=c99-std=c1x。请注意,使用-ansi-std=...选项之一可能会禁用一些非标准的扩展。有时你需要编写不可移植的代码;在这种情况下,您可以删除该选项,也可以删除-pedantic

olhwl3o2

olhwl3o23#

你在函数main的第4行的开头缺少了'struct'。它应该是

struct tele_typ *first;

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

u7up0aaq

u7up0aaq4#

这一行是错误的:

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

您忘记了struct关键字。
另外,main应该声明为返回int,并以return结束。

3okqufwl

3okqufwl5#

使用typedef绝对是正确的选择。
只是一个狡辩:保留前导双下划线;应用程序员不应该使用它们,因为它们可能会导致命名空间问题。
Kernahan & Ritche的书《C编程语言》是最好的书,但没有一本。然而,对于初学者来说,这是一个艰难的过程。发布问题的人所拥有的书显然是错误的!

hs1ihplo

hs1ihplo6#

你必须改变指针结构声明,如下所示:

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

相关问题