简体   繁体   English

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

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

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: 我正在做一些较旧的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);
}

..and the output from gcc newstruct.c -o newstruct : ..和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. 这是关于链接列表的第10.4章。 Is there an error in the book? 书中有错误吗? or has something changed in the standards/ gcc version 4.6.2 20120120 (prerelease) ? 或者标准/ gcc version 4.6.2 20120120 (prerelease)有什么变化? Thank you! 谢谢!

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: 错误unknown type name 'tele_typ'很容易修复:您已声明类型struct tele_typ ,但struct tele_typ前面没有struct

  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.) (并且在我的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定义之后立即:

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. 但我有点担心一本不给main()函数提供返回类型类型参数的C书。 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. int main(int argc, char* argv[])int main(int argc, char** argv)是常见的,任何偏离这两个选项的书都让我觉得有些奇怪。 The C Programming Language is a fine book; C编程语言是一本很好的书; it is hard to improve upon it for its clarity and correctness. 它的清晰度和正确性很难改进。 Consider switching to the original. 考虑切换到原始。

You're missing the 'struct' at the beginning of the 4th line of function main. 你错过了函数main第4行开头的'struct'。 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. 这在C ++中运行良好,因为'struct'关键字是可选的,但在C中它是必需的。

This line is wrong: 这条线错了:

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

You forgot the struct keyword. 你忘了struct关键字了。

Also, main should really be declared as returning an int , and end with a return . 另外, main应该被声明为返回一个int ,并以return结束。

Your code has the following errors, some of them minor. 您的代码有以下错误,其中一些是次要的。

  1. main() needs to be int main(void) . main()需要是int main(void) The main() form is an old-style definition; main()形式是旧式定义; 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. 它在1989 ANSI C标准中被弃用,并且根据1999 ISO C标准的平坦无效,它取消了“隐含int”规则。 Using (void) rather than () makes it explicit that main has no parameters; 使用(void)而不是()使得显式main没有参数; 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. ()表单仍然有效,但自1989年以来一直被弃用。许多C编译器为了向后兼容性将接受这样的旧式功能,但至少会在符合模式下警告它们。 You should find out how to enable such warnings for your compiler. 您应该了解如何为编译器启用此类警告。

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

  3. You should have a \\n at the end of the string you print; 你应该在你打印的字符串的末尾有一个\\n ; 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; 你应该有一个return 0; before the closing } in your main function. main函数中关闭之前} 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. 从1989年ANSI C标准(或等效的1990 ISO C标准)开始,在不返回值的情况下从main结束处掉落会向调用环境返回未定义的结果。 As of the 1999 standard, falling off the end of main does an implicit return 0; 截至1999年的标准,从main结束下跌确实隐含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. 启用警告后,某些编译器可能会抱怨在t1t2t3的声明上缺少初始值设定项,因为您没有为nextaddr成员提供值。 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. 这没关系,因为(a)只要你有一个初始化器,任何未指定的成员都被初始化为零(在指针的情况下,指向空指针),以及(b)你稍后明确地为这些成员赋值。

I see that you're using gcc. 我看到你正在使用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. 如果要针对较新版本的C标准进行测试,请将-ansi更改为-std=c99-std=c1x Note that using -ansi or one of the -std=... options may disable some non-standard extensions. 请注意,使用-ansi或其中一个-std=...选项可能会禁用某些非标准扩展。 Sometimes you need to write non-portable code; 有时您需要编写不可移植的代码; in that case, you can drop that option, and probably the -pedantic as well. 在这种情况下,您可以删除该选项,也可能是-pedantic But this program doesn't use any extensions, and doesn't need to. 但是这个程序不使用任何扩展,也不需要。

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 . 为什么,因为您尚未将结构tele_type定义为直接类型,您仍然必须使用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 长话短说,这本书是错的:P

Using the typedef is definitely the way to go. 使用typedef肯定是要走的路。

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. Kernahan&Ritche的书“The C Programming Language”是最好的书吧。 It is a hard slog for the beginner, however. 然而,这对初学者来说是一个艰难的过程。 The book the person who Posted the question has is obviously wrong! 发布问题的人有这本书显然是错的!

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

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