这段 1988 年的 C 代码有什么问题?

2024-04-09

我正在尝试编译《C 编程语言》(K & R)一书中的这段代码。它是 UNIX 程序的基本版本wc:

#include <stdio.h>

#define IN   1;     /* inside a word */
#define OUT  0;     /* outside a word */

/* count lines, words and characters in input */
main()
{
    int c, nl, nw, nc, state;

    state = OUT;
    nl = nw = nc = 0;
    while ((c = getchar()) != EOF) {
        ++nc;
        if (c == '\n')
            ++nl;
        if (c == ' ' || c == '\n' || c == '\t')
            state = OUT;
        else if (state == OUT) {
            state = IN;
            ++nw;
        }
    }
    printf("%d %d %d\n", nl, nw, nc);
}

我收到以下错误:

$ gcc wc.c 
wc.c: In function ‘main’:
wc.c:18: error: ‘else’ without a previous ‘if’
wc.c:18: error: expected ‘)’ before ‘;’ token

这本书的第二版是 1988 年的,我对 C 还很陌生。也许这与编译器版本有关,或者也许我只是在胡说八道。

我在现代 C 代码中看到了不同的用法main功能:

int main()
{
    /* code */
    return 0;
}

这是一个新标准还是我仍然可以使用无类型主干?


你的问题在于你的预处理器定义IN and OUT:

#define IN   1;     /* inside a word */
#define OUT  0;     /* outside a word */

请注意每一个中都有一个尾随分号。当预处理器展开它们时,您的代码将大致如下所示:

    if (c == ' ' || c == '\n' || c == '\t')
        state = 0;; /* <--PROBLEM #1 */
    else if (state == 0;) { /* <--PROBLEM #2 */
        state = 1;;

第二个分号导致else没有以前的if作为匹配,因为您没有使用大括号。因此,从预处理器定义中删除分号IN and OUT.

这里学到的教训是预处理器语句不必以分号结尾。

另外,您应该始终使用牙套!

    if (c == ' ' || c == '\n' || c == '\t') {
        state = OUT;
    } else if (state == OUT) {
        state = IN;
        ++nw;
    }

没有悬挂-else上面的代码有歧义。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这段 1988 年的 C 代码有什么问题? 的相关文章

随机推荐

  • 使用 javascript 关闭窗口时注销

    我在我的 javascript 代码上使用了 window onbeforeunload 但显然它只适用于 FireFox 我需要这个来关闭至少 5 个知名浏览器 firefox IE opera safari 和 chrome 谁能帮我吗
  • 将 input=file 转换为字节数组

    我尝试将通过输入文件获得的文件转换为字节 我尝试使用 FileReader 但我一定错过了一些东西 var bytes var reader new FileReader reader onload function bytes reade
  • 如何在 SQLite for Android rawQuery 中获取最接近当前时间的行#

    专家们 我想从 MyColumn 列中获取值 其中 Judge 列为 true 并且 DateTime 列最接近当前时间 如何处理这个问题 谢谢 我开发如下代码似乎可行 然而 当表仅包含行 Judge false 由于我的其中条件之一是 J
  • 如何通过 SSL 使用 Play WS?

    我的 Java 客户端应用程序需要执行 REST 调用 我被指示使用 Play 的 WS 实现 目前 我有这个 AsyncHttpClientConfig Builder builder new com ning http client A
  • 如何在 apache.poi 中为数据栏制作纯色

    我正在尝试创建一个带有进度条的工作表 它将代表一些进度 我正在使用这些库 org apache poi poi 4 1 0 org apache poi poi ooxml 4 1 0 org apache poi poi ooxml sc
  • 如何更改 selectize.js 下拉列表的占位符?

    当父下拉列表更改其选择以加载要更改占位符的下拉列表的选项时 我想更改由 selectize js 创建的下拉列表的占位符 文档中没有提供执行此操作的方法 您可以指定一个placeholder初始化时将 key 作为选项对象的一部分 我在文档
  • C: main 未找到,但它在那里 |编译错误

    当我编译两个 c 文件 如下所示 时 我收到一个非常奇怪的错误 终端编译代码 gcc I o main c matrix c lblas lgfortran Error usr bin ld usr lib debug usr lib i3
  • 使用活动管理配置设置活动管理命名空间

    我正在使用带有设计的活动管理 并且尝试为所有活动管理路由设置命名空间 在 active admin rb 中 我将 default namespace 设置为 config default namespace abc 123 在我的路线中
  • 设置 ~/.conda/pkgs 目录的路径

    在主目录空间非常有限的集群上工作 因此我想将 conda pkgs 文件夹的主目录默认设置为另一个目录 但我似乎不知道如何执行此操作 我尝试过将 condarc 文件与 pkg dirs 一起使用 channels conda forge
  • 停止服务后如何从传感器取消注册侦听器?

    我正在创建一个应用程序 该应用程序在按下 开始 按钮时启动服务 并在按下 停止 按钮时停止服务 在服务中 我为传感器 ACCELEROMETER 注册了一个侦听器 以便获得 x y z 轴的加速计值 但是当我停止应用程序并从传感器取消注册侦
  • 如何使用 boost::log::BOOST_TRIVIAL_LOG 更改默认格式?

    boost log 看起来真的很强大 它提供了一个用于简单日志记录的 BOOST LOG TRIVIAL 宏 但如何更改默认格式呢 它默认打印时间戳 但我不想要它 你有什么主意吗 似乎唯一的方法是重新定义一个新的接收器并将其添加到核心 然后
  • 使用 if 语句时,当前上下文中不存在该名称[重复]

    这个问题在这里已经有答案了 我想用用户给出的小数位数来计算 Pi 当输入为 0 时 变量 piNumber 应设置为 3 而不是 3 以便输出没有无用的逗号 这有效 static string PiNumberFinder int amou
  • 如何在 PySpark Pipeline 中使用 XGboost

    我想更新我的 pyspark 代码 在pyspark中 它必须将基础模型放入管道中 即办公室演示 http spark apache org docs latest ml pipeline html管道使用逻辑回归作为基本模型 但是 似乎无
  • CLion:调试由 python 生成的 C++ 子进程

    CLion 有没有办法调试从 Python 脚本运行的 C 程序subprocess Popen 我可以设置断点并调试Python程序 如果直接运行C 程序 我可以设置断点并调试它 但是当程序从Popen启动时 我无法触发C 断点 我尝试在
  • 如何在unix中查找字符串之间包含多个空格的行?

    我有像这样的行 1 Harry says hi 2 Ron says bye 3 Her mi oh ne is silent 4 The above sentence is weird 我需要一个 grep 命令来检测第三行 这就是我正在
  • 矩阵求逆 R

    我想求逆方形对称正定矩阵 我知道有两个功能solve and chol2inv 在 R 中 但他们的结果是不同的 我需要知道为什么会发生这种情况 谢谢 以下是计算矩阵逆的几种方法 包括solve and chol2inv gt A lt m
  • 默认情况下启用或禁用菜单项。为什么?

    我有一些遗留代码 由于某种原因 菜单项在启动时被启用或禁用 我的问题是 如何 有没有办法在不调用 EnableMenuItem 函数的情况下执行此操作 MFC 有没有办法做与资源设置所说相反的事情 我也不明白为什么当最后一个子窗口关闭时 当
  • 页面上或 .js 脚本中是否可以有多个 jQuery 就绪事件?

    我注意到 jQuery 就绪事件和函数在我的大部分 JavaScript 中只使用了一次 但是 我想知道是否可以多次使用就绪事件 例如 是否可以在我的主 html 代码中的就绪事件函数调用中调用函数 然后在 js 文件中的另一个就绪事件函数
  • 在 Woocommerce 中下订单后,将值插入自定义表中

    我需要插入到我的自定义表中许可证表 username order id Quantity This needs to be populated when an order is placed Username customer s emai
  • 这段 1988 年的 C 代码有什么问题?

    我正在尝试编译 C 编程语言 K R 一书中的这段代码 它是 UNIX 程序的基本版本wc include