![](/img/trans.png)
[英]Is there an error in the example code in chapter 1.9 in the classic book “The C Programming Language”?
[英]Errors compiling example from ANSI C book, Linked Lists chapter
我正在做一些较旧的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
的输出:
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
前面没有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编程语言是一本很好的书; 它的清晰度和正确性很难改进。 考虑切换到原始。
你错过了函数main第4行开头的'struct'。 它应该读
struct tele_typ *first;
这在C ++中运行良好,因为'struct'关键字是可选的,但在C中它是必需的。
这条线错了:
tele_typ *first; /* create a pointer to a structure */
你忘了struct
关键字了。
另外, main
应该被声明为返回一个int
,并以return
结束。
您的代码有以下错误,其中一些是次要的。
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->name,t1.nextaddr->name,t2.nextaddr->name);
你应该有一个return 0;
在main
函数中关闭之前}
。 从1989年ANSI C标准(或等效的1990 ISO C标准)开始,在不返回值的情况下从main
结束处掉落会向调用环境返回未定义的结果。 截至1999年的标准,从main
结束下跌确实隐含return 0;
,但明确它是没有害处的。
启用警告后,某些编译器可能会抱怨在t1
, t2
和t3
的声明上缺少初始值设定项,因为您没有为nextaddr
成员提供值。 这没关系,因为(a)只要你有一个初始化器,任何未指定的成员都被初始化为零(在指针的情况下,指向空指针),以及(b)你稍后明确地为这些成员赋值。
我看到你正在使用gcc。 要获得一组好的警告,您可以使用:
gcc -ansi -pedantic -Wall -Wextra
如果要针对较新版本的C标准进行测试,请将-ansi
更改为-std=c99
或-std=c1x
。 请注意,使用-ansi
或其中一个-std=...
选项可能会禁用某些非标准扩展。 有时您需要编写不可移植的代码; 在这种情况下,您可以删除该选项,也可能是-pedantic
。 但是这个程序不使用任何扩展,也不需要。
您必须更改指针结构声明,如下所示:
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
使用typedef肯定是要走的路。
只是一个狡辩:保留领先的双下划线; 应用程序员不应该使用它们,因为它们可能会导致命名空间问题。
Kernahan&Ritche的书“The C Programming Language”是最好的书吧。 然而,这对初学者来说是一个艰难的过程。 发布问题的人有这本书显然是错的!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.