【问题标题】:Why does this program show something else even though the code is correct? [closed]为什么即使代码正确,该程序也会显示其他内容? [关闭]
【发布时间】:2020-09-25 16:39:18
【问题描述】:
#include <stdio.h>

int main(void)
{
    int a = 4;
    char alpha[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    for (int i = 0; i < 6; i++);
    {
        for (int b = 5; b > a; b--)
        {
             printf("%c", alpha[b]);
        }
        a--;
        printf("\n");
        printf("%d\n", a);
    }
    return 0;
}

我希望这段代码像这样打印:

F
FE
FED
FEDC
FEDCB
FEDCBA

但它当前显示的输出是这样的:

F
3

我不知道是否有任何拼写错误,因为我检查了很多我做过的事情 否则错误。如果是拼写错误,请告诉我这是因为拼写错误,如果不是,请帮助我,因为我是 c 编程语言的新手。

【问题讨论】:

  • 如果它不能解决您打算解决的问题,说“代码是正确的”可能意味着什么?你的问题的标题没有意义。也许您只是意味着代码可以编译。所以呢?世界上到处都是编译错误的代码。此类代码不应被描述为“正确”。
  • 阅读Modern C 并考虑使用Frama-C 来说服您您的程序是正确的。您可以使用 ACSL 指定程序的行为

标签: c arrays for-loop


【解决方案1】:

这个循环的末尾有;。没有身体。它什么都不做。

    for(int i = 0; i < 6; i++);
                              ^

【讨论】:

    【解决方案2】:

    要获得预期的输出,请在第一个循环结束时删除 ; 并删除最后一个 printf

    for(int i = 0; i < 6; i++) { 
        for(int b = 5; b > a; b--) { 
            printf("%c", alpha[b]); 
         } 
         a--; 
         printf("\n"); 
    }
    

    【讨论】:

      【解决方案3】:

      删除你错误放置的第一个循环末尾的分号

      【讨论】:

        【解决方案4】:

        正如其他人所指出的,您的外部 for 循环末尾有一个 ;,因此它的主体是空的:

        for(int i = 0; i < 6; i++);
        

        请注意,您应该始终在启用警告的情况下进行编译(例如):

        gcc -c -Wall -Wextra -Werror foobar.c
        

        如果你有,编译器会标记这个语句。


        gcc:

        foobar.c: In function ‘main’:
        foobar.c:7:9: warning: this ‘for’ clause does not guard... [-Wmisleading-indentation]
                 for(int i = 0; i < 6; i++);
                 ^~~
        foobar.c:8:9: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘for’
                 {
                 ^
        

        叮当声:

        foobar.c:7:35: warning: for loop has empty body [-Wempty-body]
                for(int i = 0; i < 6; i++);
                                          ^
        foobar.c:7:35: note: put the semicolon on a separate line to silence this warning
        1 warning generated.
        

        请注意,较新版本的gcc 不需要-Wextra

        clang 将仅使用 clang -c foobar.c 标记该语句。

        而且,最初,gcc 产生了与 clang 类似的“空体”警告

        【讨论】:

        • 对我来说这不是第一次看到这很有趣,默认情况下,clang 似乎更明智(没有额外的编译器标志/选项)。我已经在其他问题上积累了经验。
        • 作为初学者的建议,我也想建议-Werror,因为没有逃避/忽略警告的方法。
        • @RobertSsupportsMonicaCellio 是的,绝对--已编辑。 -Werror 应该完成,即使对于有经验的程序员也是如此。我总是这样做。仅当现有代码库生成的代码库将其关闭(例如 linux 内核)时,我才将其关闭,在这种情况下,人们必须修复上游维护者应自行修复的一系列警告。
        • @RobertSsupportsMonicaCellio 脚注:我无意中将这样一个空正文错误(在if 上)引入了 1000 行文件。我使用的是gcc -Wall -Werror,但不知道-Wextra。经过三重检查后,我“确信”编译器生成了不正确的代码。我用clang 重建并收到警告。然后,我试验并发现-Wextra [打开-Wempty-body] 为gcc
        【解决方案5】:

        为什么即使代码是正确的,程序也会显示其他内容?

        因为你在第一个 for 循环的头部末尾有一个分号 ;

        for(int i = 0; i < 6; i++);
        

        这将导致假定的循环体不被视为循环体。它被视为复合语句第一个循环已经完成。

        这就是你得到这个输出的原因。


        删除分号,您的程序将打印:

        F
        3
        FE
        2
        FED
        1
        FEDC
        0
        FEDCB
        -1
        FEDCBA
        -2
        

        此外,删除 printf("%d\n", a); 以获得预期的输出:

        F
        FE
        FED
        FEDC
        FEDCB
        FEDCBA
        

        我还真的建议您阅读Craig´s answer 中有关编译器标志的线索,并且永远不要忽略编译器警告,因为这是编译器可以的代码问题,并且默认情况下也依赖于编译器,会警告您。

        【讨论】:

          【解决方案6】:

          有一个小错字导致您的代码出现重大问题:

          • 在外部for 语句的末尾有一个虚假的;; 是一个空语句,导致 for 循环使用空主体进行迭代,并且其预期主体在循环后无条件执行一次。

          我建议使用 Kernighan 和 Ritchie 支撑样式,这样就不太可能出现这种错误:

          #include <stdio.h>
          
          int main(void) {
              int a = 4;
              char alpha[26] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
          
              for (int i = 0; i < 6; i++) {
                  for (int b = 5; b > a; b--) {
                       printf("%c", alpha[b]);
                  }
                  a--;
                  printf("\n");
                  printf("%d\n", a);
              }
              return 0;
          }
          

          【讨论】:

            猜你喜欢
            • 2016-01-24
            • 1970-01-01
            • 1970-01-01
            • 2021-01-22
            • 2017-08-09
            • 1970-01-01
            • 2022-09-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多