[英]Declaring variables in functions that are called more than once in int main() (in C)
[英]Declaring functions as variables in c
我目前正在为我的大学准备考试,并且遇到了一些有关链接列表的令人困惑的代码示例。 在Steven S. Skiena撰写的《算法设计手册》中,他使用了一些我不太了解的有趣语法。
delete_list (list **l, item_type x)
{
list *p;
list *pred;
list *search_list(), *predicessor_list();
p = seach_list(*l, x);
if (p != NULL)
{
pred = predecessor_list(*l, x);
if (pred == NULL)
*l = p-> next;
else
pred->next = p->next;
free (p);
}
}
声明search_list()和predicessor_list()函数而不是显式调用它们是否有特定的优点或理由? 我假设它与维护指针有关,但是我在此上找不到任何参考资料。
这些是函数声明。 我认为有两件事对他们不利:
他们缺乏原型:
list *search_list(list *, item_type), *predecessor_list(list *, item_type);
原型(此处为每个函数的list *, item_type
)告诉编译器该函数期望什么类型的参数(以及多少个参数)。 没有理由不在函数声明中提供该信息。
如果仅说list *search_list()
,则编译器无法检查search_list
调用是否传递正确的参数。
它们在函数内部。
在块内声明一个函数没有意义。 那不会使函数成为本地函数; 在标准C中,所有功能都是全局的。 它只是使声明具有局部作用域,这是毫无用处的。
一个更标准的方法是
list *search_list(list *, item_type);
list *predecessor_list(list *, item_type);
void delete_list (list **l, item_type x)
{
...
}
请注意,由于delete_list
不返回任何值,因此添加了一个void
返回类型。 省略1999 C之前版本允许的返回类型,但默认为int
,而不是void
。
鉴于函数原型在1989年ANSI C的发布中成为标准,并且在1999年删除了“ implicit int
”(使用ISO 9899:1999),因此,我对算法设计手册 (载于2008年)中的技术内容保持警惕版权声明)。
它们肯定是在某处声明的。示例:
#include <stdio.h>
#include <stdlib.h>
typedef struct list {
} list;
void foo() {
//Forward Declaration:
list* search_list(), *predecessor_list();
//Function call:
list* search_results = search_list(/*whatever arguments here*/);
list* predecessor_results = predecessor_list(/*whatever arguments here*/);
//Printing Pointers or whatever..
printf("%p\n", search_results);
printf("%p\n", predecessor_results);
}
list* search_list(/*whatever arguments here*/) {
return NULL; //return a list pointer or node..
}
list* predecessor_list(/*whatever arguments here*/) {
return NULL; //return a list pointer or node..
}
int main() {
foo();
return 0;
}
如果您注释掉:
/*list* search_list() {
return malloc(sizeof(list));
}
list* predecessor_list() {
return malloc(sizeof(list));
}*/
您将收到错误:
/ usr / bin / ld:/home/J3v1L7/cc02GJDL.o:在函数
foo': prog.c:(.text+0x9): undefined reference to
search_list的foo': prog.c:(.text+0x9): undefined reference to
/ usr / bin / ld:prog.c :(。 text + 0x13):未定义对`predecessor_list'的引用collect2:错误:ld返回1退出状态
为什么? 因为list* search_list(), *predecessor_list();
是两个函数search_list
和其predecessor
的前向声明: https : search_list
list *search_list(), *predicessor_list();
是2个函数的局部声明,这些函数采用未指定数量的参数并返回一个指针以list
可能的内容。
在一个块范围声明函数是高度灰心。 在没有适当原型的情况下声明函数也是草率的。 定义没有返回类型的delete_list
也是过时的。
从发布的代码来看,这本书似乎已经过时,并为新手提供了糟糕的建议。
正确的代码应为:
#include <stdlib.h>
typedef int item_type;
typedef struct list {
item_type value;
struct list *next;
} list;
list *search_list(list *l, item_type x);
list *predecessor_list(list *l, item_type x);
void delete_list(list **l, item_type x) {
list *p;
list *pred;
p = search_list(*l, x);
if (p != NULL) {
pred = predecessor_list(*l, x);
if (pred == NULL)
*l = p->next;
else
pred->next = p->next;
free (p);
}
}
当然,更好的delete_list
版本可以避免双重扫描:
#include <stdlib.h>
/* delete the first node with value x, return 1 if found, else return 0 */
int delete_list(list **pp, item_type x) {
for (list *p = *pp; p != NULL; pp = &p->next, p = p->next) {
if (p->value == x) {
*pp = p->next;
free(p);
return 1;
}
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.