【问题标题】:MIT OpenCourseWARE C/C++ Assignment 1 no output issueMIT OpenCourseWARE C/C++ 作业 1 无输出问题
【发布时间】:2014-01-27 02:44:34
【问题描述】:

我对 C/C++ 知之甚少,所以我决定在线学习 MIT 的 OpenCourseWare 课程。大约 8 年前,我学习了两年的 Java 课程,最近有大约 4 年的 MATLAB 经验。

在努力设置编译器后,我设法在 Eclipse IDE 中完成了第一个实验。我可以在 Eclipse 或 cmd 中运行这两个 Hello World 代码,它们将输出我在代码中的任何文本。我在“作业 1”中,我已经在 .C 文件的答案键中进行了修改。

这是作业的链接:http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-s096-introduction-to-c-and-c-january-iap-2013/lectures-and-assignments/compilation-pipeline/

它似乎可以编译并生成 .exe,但是当我进入命令提示符输入两个输入 (int argc, char *argv[]) 时,它运行但不生成任何输出。我正在使用网站上建议的命令:./fibeverse 6 '这真是一次旅行!'。 Eclipse 中只有一个警告,它在 fibverse.c 中,它显示“未使用的变量 'i'”,尽管在下面的两个 'if' 语句中使用了该变量。

我将这一行用于我的 makefile:gcc -Wall -std=c99 fibeverse.c reverse.c fibonacci.c -o fibeverse

有谁知道我是否做错了什么?我不确定错误是我调用 .exe 文件的方式,还是 .exe 生成不正确。

如果需要,我可以发布我的确切文字,除非有必要,否则我不想弄乱帖子。我已经多次检查了解决方案密钥,以确保我没有输入任何错误。

感谢您的宝贵时间,

伊恩

编辑:这是主要内容,它在 cmets 中的发布不是很好:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "fibonacci.h"
#include "reverse.h"

int main(int argc, char *argv[]) {
int i = 1;

#ifdef fibonacci
if (i < argc) {
    print_fib(atoi(argv[i]));
    i++;
}
#endif

#ifdef reverse
if (i < argc) {
    reverse(argv[i], strlen(argv[i]));
    i++;
}
#endif
printf("Press Enter to Exit\n");
getchar();

return 0;
}

添加 printf 只是为了确保它没有闪烁输出,没有它它的响应没有什么不同。此外,#ifdef 只是更改为小写,但这也没有改变任何内容。

感谢您的快速回复!

【问题讨论】:

  • 如果它说该变量未使用,它就是未使用。您可能正在使用来自另一个范围的同名变量;很难说没有看到你的代码。当然,未使用的变量只是警告,而不是错误,但通常是您应该注意的警告。奇怪的是,您对更改的应用并不完全符合预期的答案。
  • 你要我发布所有内容吗?我想知道变量问题是否是其中的一部分。看起来如果“i”有错误,它可能会提前退出 if 语句。答案键有确切的文字,我基本上只是复制和粘贴。所以我认为可能不会有任何解释问题。现在,这是我的主要内容 fibverse.c:

标签: c


【解决方案1】:

作业 1 有两个问题。问题1中,程序要用gcc -Wall -std=c99 fibeverse.c reverse.c fibonacci.c -o fibeverse进行编译,并修复导致程序无法编译的错误。

有两个错误:

  • fibonacci.creverse.c 中的每一个都不包括其对应的标头fibonacci.creverse.c。虽然源文件不需要包含其相应的头文件,但出于两个原因,这通常是一种很好的做法。一,头文件声明了源文件定义的例程,并且包含头文件允许编译器在同一个编译中看到声明和定义,这反过来又允许编译器报告两者之间的不一致。第二,源文件经常使用它们自己的一些例程作为子例程,并且包括头文件为这些例程提供声明,这些是在定义之前使用的例程所需要的。在fibonacci.c中,fib是在定义之前使用的,所以在使用之前应该有一个声明。包括fibonacci.h 提供此声明。
  • reverse.c 定义了一个名为 backwards 的例程,但旨在定义一个名为 reverse 的例程,因此应更改名称。

一旦这些错误得到修复,程序就会使用上面显示的命令编译,不会出错。

该命令用于作业的第 1 题,不应用于第 2 题。

在问题 2 中,您修改程序,使调用print_fibreverse 的两条代码可以分别启用或禁用。正如您在提供的解决方案中看到的,这可以通过插入诸如#ifdef FIBONACCI 之类的语句来完成。

完成此修改后,您可以通过在编译器命令行中包含开关-DFIBONACCI-DREVERSE 来启用每段代码。 一旦你做了这个修改,原来的命令行就不会毫无怨言地工作。不要使用它。

问题2的说明显示了程序修改后与命令一起使用的三个命令。

此命令构建程序,因此它只计算斐波那契数:

gcc -Wall -std=c99 -DFIBONACCI fibeverse.c reverse.c fibonacci.c -o fibonacci

此命令构建程序,因此它只反转字符串:

gcc -Wall -std=c99 -DREVERSE fibeverse.c reverse.c fibonacci.c -o reverse

这个命令构建程序,所以它同时做:

gcc -Wall -std=c99 -DFIBONACCI -DREVERSE fibeverse.c reverse.c fibonacci.c -o fibeverse

【讨论】:

  • 感谢您抽空 Eric。你是对的,这两个问题之间存在一些混淆。我相信你在理解任务的目的方面是正确的。仍然存在的主要问题是,如果我不手动更改 #ifDef 或 #ifnDef 语句,fibeverse.c 将无法识别编译命令中的 FIBONACCI 或 REVERSE 声明,它会忽略整个块。我在原始帖子中实际上是不正确的,我一直在使用 'gcc -Wall -std=c99 -DFIBONACCI -DREVERSE fibeverse.c reverse.c fibonacci.c -o fibeverse' 来构建程序但没有成功。
  • @IanM.:语句必须是#ifdef,而不是#ifDef,并且它们必须使用全部大写的标识符,如#ifdef FIBONACCI,完全匹配使用的-DFIBONACCI命令行。
  • 对,#ifdef。我最初确实尝试过使用所有大写字母,例如-DFIBONACCI。似乎 Eclipse 没有识别出我在命令行中使用了 -DFIBONACCI 语句(虽然我使用的是 makefile),所以当它编译时,它会单独处理 fibeverse.c 文件并且不运行#ifdef 块。绝对有可能我没有在 Eclipse 中正确编译它们,而不是文件本身的问题。
【解决方案2】:

这是说变量未使用,因为它是。您在使用变量 i 的两个代码块周围都有 ifdef,但您没有定义正在测试的宏。 在文件顶部添加:

#define fibonacci 1
#define reverse 1

您将看到警告消息消失。您还会发现 for 循环现在正在执行。

【讨论】:

  • 分配调用通过命令行定义FIBONACCI和REVERSE。在源代码中定义它们不是正确的解决方案。
  • 谢谢!这就是问题所在。他们为什么不在解决方案中添加它?我将开始学习宏的语法是如何工作的。现在看起来 Reverse 有问题。它只返回第一个字符:'什么埃里克,你认为什么是问题?我尝试使用 gcc -Wall -std=c99 -DFIBONACCI -DREVERSE fibeverse.c reverse.c fibonacci.c -o fibeverse 编译它们,但这似乎不起作用。
  • 好的,解决了最后一个问题。我需要使用 "not ' 输入字符串。谢谢您的帮助。
【解决方案3】:

我读了作业。您需要学习两个 C 预处理器结构。

#ifdef foo
// Compile everything in this block if flag "foo" is defined in the program 
// or in the make file.
#end

#ifndef foo
// Compile everything in this block if flag "foo" is NOT defined anywhere.
#end

您可以通过将#ifdef 替换为#ifndef 来修复编译时警告。当您继续分配的第二部分时,将这些结构与编译时标志混合并匹配。

【讨论】:

  • 你是对的,那是在讲座中。这些宏实际上有什么作用吗?我认为宏的目的是在其他地方使用该块并保存代码。
  • 在C预处理器中,宏也可以被测试并用于控制是否应该编译部分代码——这就是#ifdef ... #endif#ifndef ... #endif(和#if .. .#endif`) 做。这通常用于在编译时在多个替代解决方案中进行选择,例如,当不同的环境需要不同的解决方案或试验代码时。
  • 如果符号定义,则分配并没有说明要使任何代码工作。在这个作业中没有理由使用#ifndef。 OP 收到一条错误消息,因为他们在按照问题 2 的要求修改程序后使用了错误的命令(对于作业的问题 1)来编译程序。解决方案是使用作业中显示的正确命令问题 2。
猜你喜欢
  • 2011-04-14
  • 2011-07-29
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-04
  • 2014-08-08
  • 1970-01-01
相关资源
最近更新 更多