【问题标题】:redeclaration of a functoin as int K&R 6.3将函数重新声明为 int K&R 6.3
【发布时间】:2019-10-14 10:37:34
【问题描述】:

在 K&R 的第 6.3 章中,函数 getword() 定义如下:

int getword(char *word, int lim)
{
    int c, getch(void);
    void ungetch(int);
    char *w = words;

    while(isspace(c=getch()))
        ;
        if(c!= EOF)
            *w++; = c;
        if(isalpha(c)) {
            *w = '\0';
            return c;
        }

        for(;--lim > 0; w++)
            if(!isalnum(*w)getch()){
                ungetch(*w);
                break;
            }
        *w = '\0';
        return word[0];
}

我不明白该行的语法

int c, getch(void);

这是我第一次看到这个。为什么将函数声明为 int?在调用函数之前插入函数原型还不够吗?

【问题讨论】:

  • K&R 的原始代码完全是垃圾,不会像这样编写现代 C 程序。除了坏习惯,这里没有什么可学的。我强烈建议你买一本更好的书。
  • @Lundin 你能推荐一些适合初学者和高级水平的现代 C 书籍吗?
  • K&R 书和有问题的代码片段都不是“完全垃圾”。 @Lundin 在这里有不合理的偏见。
  • @EsmaeelE Stack Overflow 有一个 book list
  • @SteveSummit 1) 从来没有理由在函数内部声明原型,2) 特别是与变量不在同一行。 3)控制语句内部的赋值是不好的做法。 4) 将 ++ 与赋值混合在一起是不好的做法。 5) 此处多次返回或中断跳转,无法读取。 6) 没有理由使用lim 作为迭代器而不是(i=0; i<lim; i++),就像在正常代码中所做的那样。 7)*w = '\0';是代码重复。大约 15 个 LoC 中有 7 个问题。摘要:完全垃圾。

标签: c kernighan-and-ritchie


【解决方案1】:

想一想

int c, getch(void);

相当于

int c;
int getch(void);

也就是说,它是一个名为 cint 变量的声明,然后是一个名为 getch 的函数的原型,它不带参数并返回 int

如本例所示,C 中的“声明”和“函数原型”之间没有硬性界限。函数原型只是一个声明,它声明了一个函数类型,包括其参数的类型。

像这样声明一个具有局部作用域的函数原型有点不寻常,但也没有错。通常,函数原型被声明在源文件的“顶部”,具有全局范围,位于任何函数之外。 (实际上,函数原型通常是在头文件中声明的。)

为什么将函数声明为 int?

好吧,因为getch 函数确实返回int

在调用函数之前插入函数原型还不够吗?

是的,这正是 this like 所做的——这一行确实包含一个函数原型,它在调用 getch 函数之前声明它。

底线是 C 中的每个函数声明都是“外部的”,无论它出现在函数内部还是外部,是否包含存储类说明符 extern

【讨论】:

  • 我从未见过在函数内声明原型但总是在函数外声明
  • @MichaelangeloMeucci 这有点不寻常,但并没有错。
  • 在局部范围内声明函数原型是非常错误的,句号。
  • @Lundin “非常错误”?不,我认为这太强了。
猜你喜欢
  • 2011-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
  • 2018-02-12
  • 2021-10-17
相关资源
最近更新 更多