【问题标题】:Compiling issue in C very basic program在 C 非常基本的程序中编译问题
【发布时间】:2014-02-05 01:33:59
【问题描述】:

以下是错误:

mario.c:23:25: error: expected identifier or ‘(’ before ‘int’
for (int levelCounter, int usrHeight, int paddIt = usrHeight - 1, char hashMaker, int hashCounter;(levelCounter <= usrHeight);)

                      ^


mario.c:25:39: error: expected ‘)’ before ‘paddIt’
printf("%'' * paddIt %c*hashCounter"paddIt,hashMaker,hashCounter);
                                    ^

^ 标识编译器指出错误发生的位置。

#include <cs50.h>
#include <stdio.h>

int main(void)
{
int usrHeight = 0;
int levelCounter = 0;
int paddIt = 0;
int hashCounter = 2;
char hashMaker = "#";

do 
{
    printf("How high?\n");
    int usrHeight = GetInt();
}
while ( usrHeight > 23 || usrHeight < 0);
if ( usrHeight >= 0 && usrHeight <= 23);
{
    printf("constructing...\n");

}
for (int levelCounter, int usrHeight, int paddIt = usrHeight - 1, char hashMaker, int hashCounter;(levelCounter <= usrHeight);)
                 *^ This is where the first error is occuring*
{
    printf("%'' * paddIt %c*hashCounter"paddIt,hashMaker,hashCounter);
                                                *^ And here is where the second is* 
    paddIt = paddIt - 1;
    levelCounter = levelCounter + 1;
    hashCounter = hashCounter + 1;
}
}

我到底做错了什么?

【问题讨论】:

  • 哇,一团糟。甚至不知道从哪里开始。您为什么不删除代码并慢慢将其添加回来。

标签: c cs50


【解决方案1】:

在 C99 及更高版本中,for 循环的初始位置只能有一个声明:

for (int levelCounter, usrHeight, paddIt = usrHeight - 1, hashMaker, hashCounter;
     ...condition...; ...increment...
    )

但是,您有问题; usrHeight 未初始化,因此 paddIt 是一个不确定的值。我不得不将hashMaker 的类型更改为int。您只能使用一种类型。

坦率地说,在循环控制中声明许多变量是错误的。如果你这样做,它们都应该被初始化。否则,您可以使用:

for (int levelCounter; ...condition...; ...increment...)
{
    int usrHeight = -1, paddIt = usrHeight - 1, hashCounter = 0;
    char hashMaker;
    ...loop body...
}

这解决了一些问题。如果您需要在循环的迭代中保留变量的值(这会在每次迭代中定义并初始化它们),那么应该在循环之外定义额外的变量。您很少会在for 循环中声明多个变量,甚至很少声明两个以上的变量。我几乎可以证明:

for (int i = min, j = max; i < j; i++, j--)

其中一个变量向上计数,而另一个变量向下计数,尽管您可以在循环体中计算 j,尤其是当 min 为 0 时。

向我提供(固定版本)原始代码以供代码审查的人会受到我的冷遇——更清楚地重写代码。


第二个问题是缺少逗号,编译器说它需要)

printf("%'' * paddIt %c*hashCounter"paddIt,hashMaker,hashCounter);

应该是:

printf("%'' * paddIt %c*hashCounter", paddIt, hashMaker, hashCounter);

第一部分实际上是格式错误的转换规范;您可能指的是"%%''...",或者您可能指的是完全不同的东西,例如:

printf("%' *.*c", paddIt, hashMaker, hashCounter);

单引号仍然与 %c 转换说明符无关(因此行为未定义),但它是 printf() 的 POSIX 2008 的一部分——它在必要时为大数字添加了数千个分隔符。


我没有注意到您已经声明了您在for 循环中提到的所有变量。看起来您可以将该循环简化为:

for (levelCounter = 0; levelCounter <= usrHeight; levelCounter++)
{
    printf("%.*s", paddIt, "");
    for (int i = 0; i < hashCounter; i++)
        putchar('#'); 
    paddIt = paddIt - 1;
    hashCounter = hashCounter + 1;
}

这使用来自原始问题中不清楚的预期格式的评论信息。

【讨论】:

  • 我使用 %c 打印哈希标记,单引号表示一个空格 n 次 n=paddIt,我将如何让 printf 打印 n 个空格,然后和 x 个 # 标记?
  • 你可以做的空间,碰巧,有一种作弊:printf("'%.*s'", paddIt, "");。这将打印由paddIt 指定的最小宽度的字符串,使用空格作为(右对齐)空字符串的填充符。但是,printf() 不支持将单个非空白字符打印指定次数。您可以指定最小和最大宽度,但不能指定重复计数(并且“作弊”使用宽度作为重复计数)。我会使用for (int i = 0; i &lt; hashCounter; i++) putchar('#');,如果它是一个会多次出现的习语,可能会被包装成一个小函数。
  • 在您上次的编辑中,您在另一个 for 语句中有一个 for 语句,第二个 for 需要 {}?
  • @user3273247:当循环体中只有一条语句时,不需要在它周围使用大括号。它们是允许的;它们不是强制性的。有人说“到处加大括号”;我不是那个学校的。但是,如果循环体是 if 语句(有或没有自己的 else)或 switch,那么我会使用大括号(尽管它们仍然是官方可选的)。
  • @Jonathan 在printf("%.*s", paddIt, ""); 语句中("%.*s", paddIt, "") 到底在做什么?据我所知%spaddIt 字符串?但我不确定.*对它做了什么。当"" 被声明时,声明中的内容是什么,或者更好的措辞是什么?
【解决方案2】:

为什么不能将此 for 循环转换为 while 循环?这会做同样的事情

while(levelCounter <= usrHeight)

{
 printf("%'' * paddIt %c*hashCounter",paddIt,hashMaker,hashCounter);

 paddIt = paddIt - 1;
 levelCounter = levelCounter + 1;
 hashCounter = hashCounter + 1;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-19
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多