编译 ANSI C 书“链接列表”章节中的示例时出错
我正在从一本旧的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我无法重现第一个警告;您确定您粘贴到此处的代码是向您发出警告的代码吗?
错误
未知类型名称'tele_typ'
很容易修复:您已经声明了类型struct tele_typ
,但没有struct
在该行前面:如果将其更改为:
它将编译而不会出现错误。 (并且在我的 gcc-4.5.real (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2 中也没有警告。)
如果您想完全按原样编译函数体,那么您还需要添加:
立即在
struct 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 typestruct tele_typ
, but don't have thestruct
in front of the line:If you change this to:
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:
immediately after the
struct tele_typ
definition: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[])
orint 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.您的代码存在以下错误,其中一些是轻微错误。
main()
需要是int main(void)
。main()
形式是旧式定义;从 1989 年 ANSI C 标准开始,它已被弃用,并且在 1999 年 ISO C 标准中完全无效,该标准放弃了“隐式 int”规则。使用(void)
而不是()
可以明确表明main
没有参数;()
形式仍然有效,但自 1989 年以来已被弃用。为了向后兼容,许多 C 编译器会接受这样的旧式功能,但至少会在一致模式下发出警告。您应该了解如何为您的编译器启用此类警告。tele_typ *first;
需要是struct tele_typ *first;
。这是主要问题。 (添加typedef
是解决此问题的另一种方法,但绝对没有必要。代码已将类型引用为struct tele_typ
;您只需保持一致即可。 )请注意,在 C++ 中,您可以将类型称为struct tele_typ
或直接称为tele_typ
——当然,C++ 是一种具有不同规则的不同语言。在打印的字符串的末尾应该有一个
\n
;一开始你不需要它。printf("%s %s %s\n",first->名称,t1.nextaddr->名称,t2.nextaddr->名称);
你应该有一个
main
函数中结束}
之前的return 0;
。从 1989 年 ANSI C 标准(或等效的 1990 年 ISO C 标准)开始,脱离main
末尾而不返回值会向调用环境返回未定义的结果。根据 1999 年标准,从main
末尾脱落会隐式返回 0;,但明确地说明这一点并没有什么坏处。启用警告后,某些编译器可能会抱怨
t1
、t2
和t3
声明中缺少初始值设定项,因为您没有提供值对于nextaddr
成员。这是可以的,因为 (a) 只要你有一个初始化器,任何未指定的成员都会被初始化为零(在指针的情况下,初始化为空指针),并且 (b) 你稍后显式地为这些成员赋值。我看到你正在使用 gcc。要获得一组好的警告,您可以使用以下命令:
将
-ansi
更改为-std=c99
或-std=c1x
(如果您想要针对新版本的 C 标准进行测试。请注意,使用-ansi
或-std=...
选项之一可能会禁用某些非标准扩展。有时您需要编写不可移植的代码;在这种情况下,您可以删除该选项,也可以删除-pedantic
。但这个程序不使用任何扩展,也不需要。Your code has the following errors, some of them minor.
main()
needs to beint main(void)
. Themain()
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 thatmain
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.tele_typ *first;
needs to bestruct tele_typ *first;
. This is the main problem. (Adding atypedef
is another way to work around this, but it's absolutely unnecessary. The code already refers to the type asstruct tele_typ
; you just need to do so consistently.) Note that in C++ you can refer to the type either asstruct tele_typ
or just astele_typ
-- of course, C++ is a different language with different rules.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);
You should have a
return 0;
before the closing}
in yourmain
function. As of the 1989 ANSI C standard (or the equivalent 1990 ISO C standard), falling off the end ofmain
without returning a value returns an undefined result to the calling environment. As of the 1999 standard, falling off the end ofmain
does an implicitreturn 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
, andt3
, since you didn't provide values for thenextaddr
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:
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.您缺少 main 函数第四行开头的“结构”。它应该是这样的:
这在 C++ 中可以很好地工作,因为“struct”关键字是可选的,但在 C 中它是必需的。
You're missing the 'struct' at the beginning of the 4th line of function main. It should read
That would have worked fine in C++, since the 'struct' keyword is optional, but in C it's required.
这行是错误的:
您忘记了 struct 关键字。
另外,
main
实际上应该声明为返回int
,并以return
结尾。This line is wrong:
You forgot the
struct
keyword.Also,
main
should really be declared as returning anint
, and end with areturn
.使用 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!
您必须更改指针结构声明,如下所示:
为什么,因为您尚未将结构
tele_type
定义为直接类型,所以您仍然必须使用struct tele_typ 指向它
。如果你在另一边做了这样的事情:
你将能够调用之前定义的类型,如果你写了:
长话短说,这本书是错误的:P
You have to change the pointer structure declaration for something like this:
Why, because you haven't already defined the structure
tele_type
as a direct type, you still have to point at it usingstruct tele_typ
.If you on the other side had done something like this:
You would have been able to call for the previously defined type and it would have been ok if you had written:
Long story short, the book is wrong :P