"FILE *fp, *fopen();" 的作用是什么?

4
在《UNIX编程环境》第182页上,efopen的代码如下所示:(链接)
FILE *efopen(file, mode)    /* fopen file, die if can't */
    char *file, *mode;
{
    FILE *fp, *fopen();
    extern char *progname;

    if ((fp = fopen(file, mode)) != NULL)
        return fp;
    fprintf(stderr, "%s: can't open file %s mode %s\n",
        progname, file, mode);
    exit(1);
}

这一行代码 FILE *fp, *fopen(); 是干什么用的呢?

我的理解是,它声明了一个指向 FILE 类型的变量 fp ,并且声明了一个返回 FILE 指针的函数 fopen

如果是这样的话:为什么要在函数体内部提前声明 fopen 呢?为什么不声明它的参数呢?


3
这本书(在很多方面都非常出色)是在1984年写成的,比第一个C标准早五年。有趣的是,它并没有使用只在标准C中才有的特性,比如函数原型。现在所有的C语言都过时了——在计算机领域,很少有书籍可以经受30多年的变化而不受损失。要充分利用它,您需要了解预标准(K&R第一版)的C语言。有一些地方可能会难以将代码与现代C语言相协调——但这种情况并不多见。 - Jonathan Leffler
2
如果您在书中的某些代码转换方面遇到了困难,请通过电子邮件与我联系-请参阅我的个人资料。 - Jonathan Leffler
1个回答

8
它创建了一个名为fp的本地变量(类型为FILE *),并且前向声明一个名为fopen的外部函数(带有FILE *fopen()签名)
在C中,fopen函数声明中缺少参数并不意味着该函数不带参数(该函数签名将是FILE *fopen(void))。相反,缺少参数意味着该函数具有未指定的参数(参数数量和类型未指定)。
这是一种非常古老的C形式,在现代C中更符合惯用法的写法是:
#include <stdio.h>   // fopen() and fprintf()
#include <stdlib.h>  // exit()
#include <string.h>  // strerror()
#include <errno.h>   // errno

extern char *progname;

FILE *efopen(const char *file, const char *mode) {
    FILE *fp = fopen(file, mode);
    if (fp) return fp;

    fprintf(stderr, "%s: can't open file %s in mode %s: %s\n",
            progname, file, mode, strerror(errno));
    exit(1);
}

我从未见过C代码库中函数定义的左花括号放在行尾,就像你现在这样做的那样。JavaScript可以,但C从来没有。你是从哪里学来的? - zwol
1
@zwol: Google。或许可以通过编写Objective-C来加强这一点(尽管这是一种不同的语言,但有些代码库将大括号放在方法选择器的同一行,为了保持一致性,在Objective-C文件中也会对普通C函数采用相同的方式;苹果的代码(我提供的链接)没有展示这一点,但其他一些代码库确实这样做)。 - Cornstalks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接