编译 ANSI C 书“链接列表”章节中的示例时出错

发布于 2025-01-04 09:09:18 字数 1249 浏览 1 评论 0原文

我正在从一本旧的 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 的输出code>:

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 版本 4.6.2 20120120(预发布) 中发生了一些变化?谢谢你!

I am doing some examples out of an older C book [A First Book of ANSI C] and am getting an error while trying to compile this example code:

#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);
}

..and the output from 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

It's chapter 10.4 on Linked Lists. Is there an error in the book? or has something changed in the standards/gcc version 4.6.2 20120120 (prerelease)? Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

凡尘雨 2025-01-11 09:09:18

我无法重现第一个警告;您确定您粘贴到此处的代码是向您发出警告的代码吗?

错误未知类型名称'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 编程语言是一本好书;由于其清晰性和正确性,很难对其进行改进。考虑切换到原来的。

I couldn't reproduce the first warning; are you sure the code you've pasted here is the code that gives you the warning?

The error unknown type name 'tele_typ' is easy to fix: you've declared a type struct tele_typ, but don't have the struct in front of the line:

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

If you change this to:

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

It'll compile without error. (And also without warnings in my gcc-4.5.real (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2.)

If you wanted to compile the function body exactly as-is, then you'd also want to add:

typedef struct tele_typ tele_typ;

immediately after the struct tele_typ definition:

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

typedef struct tele_typ tele_typ;

But I'm a little worried about a C book that doesn't give the main() function a return type or typed parameters. int main(int argc, char* argv[]) or int main(int argc, char** argv) is usual, and any book that deviates from these two options strikes me as a little strange. The C Programming Language is a fine book; it is hard to improve upon it for its clarity and correctness. Consider switching to the original.

总攻大人 2025-01-11 09:09:18

您的代码存在以下错误,其中一些是轻微错误。

  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->名称,t1.nextaddr->名称,t2.nextaddr->名称);

  4. 你应该有一个main 函数中结束 } 之前的 return 0;。从 1989 年 ANSI C 标准(或等效的 1990 年 ISO C 标准)开始,脱离 main 末尾而不返回值会向调用环境返回未定义的结果。根据 1999 年标准,从 main 末尾脱落会隐式返回 0;,但明确地说明这一点并没有什么坏处。

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

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

gcc -ansi -pedantic -Wall -Wextra

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

Your code has the following errors, some of them minor.

  1. main() needs to be int main(void). The main() form is an old-style definition; it's deprecated as of the 1989 ANSI C standard, and flat-out invalid under the 1999 ISO C standard, which dropped the "implicit int" rule. Using (void) rather than () makes it explicit that main has no parameters; the () form is still valid, but has been deprecated since 1989. Many C compilers will accept old-style features like this for the sake of backward compatibility, but will at least warn about them in conforming mode. You should find out how to enable such warnings for your compiler.

  2. tele_typ *first; needs to be struct tele_typ *first;. This is the main problem. (Adding a typedef is another way to work around this, but it's absolutely unnecessary. The code already refers to the type as struct tele_typ; you just need to do so consistently.) Note that in C++ you can refer to the type either as struct tele_typ or just as tele_typ -- of course, C++ is a different language with different rules.

  3. You should have a \n at the end of the string you print; you don't need it at the beginning.

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

  4. You should have a return 0; before the closing } in your main function. As of the 1989 ANSI C standard (or the equivalent 1990 ISO C standard), falling off the end of main without returning a value returns an undefined result to the calling environment. As of the 1999 standard, falling off the end of main does an implicit return 0;, but there's no harm in being explicit about it.

With warnings enabled, some compilers may complain about missing initializers on the declarations of t1, t2, and t3, since you didn't provide values for the nextaddr member. This is ok, since (a) as long as you have an initializer, any unspecified members are initialized to zero (in the case of a pointer, to a null pointer), and (b) you explicitly assign values to these members later on.

I see that you're using gcc. To get a good set of warnings, you can use this:

gcc -ansi -pedantic -Wall -Wextra

Change the -ansi to -std=c99 or -std=c1x if you want to test against a newer version of the C standard. Note that using -ansi or one of the -std=... options may disable some non-standard extensions. Sometimes you need to write non-portable code; in that case, you can drop that option, and probably the -pedantic as well. But this program doesn't use any extensions, and doesn't need to.

策马西风 2025-01-11 09:09:18

您缺少 main 函数第四行开头的“结构”。它应该是这样的:

struct tele_typ *first;

这在 C++ 中可以很好地工作,因为“struct”关键字是可选的,但在 C 中它是必需的。

You're missing the 'struct' at the beginning of the 4th line of function main. It should read

struct tele_typ *first;

That would have worked fine in C++, since the 'struct' keyword is optional, but in C it's required.

嘿嘿嘿 2025-01-11 09:09:18

这行是错误的:

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

您忘记了 struct 关键字。

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

This line is wrong:

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

You forgot the struct keyword.

Also, main should really be declared as returning an int, and end with a return.

别挽留 2025-01-11 09:09:18

使用 typedef 绝对是最佳选择。

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

克纳汉和Ritche 的书《C 编程语言》是最好的书,没有之一。然而,这对于初学者来说是一个艰难的过程。提出问题的人所拥有的书显然是错误的!

Using the typedef is definitely the way to go.

Just a quibble: Leading double underscores are reserved; they should NOT be used by application programmers because they could cause namespace problems.

The Kernahan & Ritche book "The C Programming Language" is the best book bar none. It is a hard slog for the beginner, however. The book the person who Posted the question has is obviously wrong!

冷月断魂刀 2025-01-11 09:09:18

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

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

You have to change the pointer structure declaration for something like this:

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

Why, because you haven't already defined the structure tele_type as a direct type, you still have to point at it using struct tele_typ.

If you on the other side had done something like this:

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

You would have been able to call for the previously defined type and it would have been ok if you had written:

tele_typ *first;

Long story short, the book is wrong :P

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文