大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C技巧 > 必须弄懂的495个C语言问题

必须弄懂的495个C语言问题(2)

关键词:弄懂语言  阅读(1579) 赞(17)

[摘要]本文是对必须弄懂的495个C语言问题的讲解,与大家分享。

它可以用作一种格式上的提示表明函数的定义可能在另一个源文件中, 但在extern int f();和int f();之间并没有实质的区别。


参考资料: [ISO, Sec. 6.1.2.2, Sec. 6.5.1]; [Rationale, Sec. 3.1.2.2]; [H&S,Secs. 4.3,4.3.1 pp. 75-6].


1.5 关键字auto 到底有什么用途?


毫无用途;它已经过时。参见问题20.32。


参考资料: [K&R1, Sec. A8.1 p. 193]; [ISO, Sec. 6.1.2.4, Sec. 6.5.1;]; [H&S,Sec. 4.3 p. 75, Sec. 4.3.1 p. 76].


1.6 我似乎不能成功定义一个链表。我试过typedef struct { char*item; NODEPTR next; } *NODEPTR; 但是编译器报了错误信息。难道在C语言中一个结构不能包含指向自己的指针吗?


C 语言中的结构当然可以包含指向自己的指针; [K&R2, 第6.5 节] 的讨论和例子表明了这点。NODEPTR 例子的问题是在声明next 域的时候typedef 还没有定义。为了解决这个问题, 首先赋予这个结构一个标签(“struct node”)。然后,声明“next” 域为“struct node *”, 或者分开typedef 定义和结构定义, 或者两者都采纳。以下是一个修改后的版本:
struct node {
char *item;
struct node *next;
};
typedef struct node *NODEPTR;


至少还有三种同样正确的方法解决这个问题。


在用typedef 定义互相引用的两个结构时也会产生类似的问题, 可以用同样的方法解决。


参见问题2.1。


参考资料: [K&R1, Sec. 6.5 p. 101]; [K&R2, Sec. 6.5 p. 139]; [ISO, Sec.6.5.2, Sec. 6.5.2.3]; [H&S, Sec. 5.6.1 pp. 132-3]。


1.7 怎样建立和理解非常复杂的声明?例如定义一个包含N 个指向返回指向字符的指针的函数的指针的数组?


这个问题至少有以下3 种答案:


1. char *(*(*a[N])())();


2. 用typedef 逐步完成声明:
typedef char *pc; /* 字符指针*/
typedef pc fpc(); /* 返回字符指针的函数*/
typedef fpc *pfpc; /* 上面函数的指针*/
typedef pfpc fpfpc(); /* 返回函数指针的函数*/
typedef fpfpc *pfpfpc; /* 上面函数的指针*/
pfpfpc a[N]; /* 上面指针的数组*/


3. 使用cdecl 程序, 它可以把英文翻译成C 或者把C 翻译成英文:
cdecl> declare a as array of pointer to function returning

pointer to function returning pointer to char

char *(*(*a[])())()
通过类型转换, cdecl 也可以用于解释复杂的声明, 指出参数应该进入哪一对括号(如同在上述的复杂函数定义中)。参见问题18.1。

一本好的C 语言书都会解释如何“从内到外” 解释和理解这样复杂的C 语言声明(“模拟声明使用”)。


上文的例子中的函数指针声明还没有包括参数类型信息。如果参数有复杂类型, 声明就会变得真正的混乱了。现代的cdecl 版本可以提供帮助。

参考资料: [K&R2, Sec. 5.12 p. 122]; [ISO, Sec. 6.5ff (esp. Sec. 6.5.4)]; [H&S,Sec. 4.5 pp. 85-92, Sec. 5.10.1 pp. 149-50]。


1.8 函数只定义了一次, 调用了一次, 但编译器提示非法重定义了。



相关评论