在C中的while循环或for循环之后没有代码执行[重复]

Posted

技术标签:

【中文标题】在C中的while循环或for循环之后没有代码执行[重复]【英文标题】:no code execution after while- or for-loop in C [duplicate] 【发布时间】:2017-06-14 08:22:20 【问题描述】:

我正在使用 Xcode 8 学习 C,编译器在执行 while 或 for 循环后不会运行任何代码。这是一个错误吗?我该如何解决?

在下面提供的示例中,printf("code executed after while-loop"); 永远不会执行

#include <stdio.h>

int getTheLine(char string[]);

int getTheLine(char string[]) 

  char character;
  int index;
  index = 0;

  while ((character = getchar()) >= EOF) 

    string[index] = character;
    ++index;
  

  printf("code executed after while-loop");
  return index;


int main(int argc, const char * argv[]) 

  char string[100];
  int length = getTheLine(string);
  printf("length %d\n", length);

  return 0;

【问题讨论】:

你可以开始向我们展示你的代码了。 编译器根本不应该运行任何代码。它应该将translation units 编译成目标文件,然后链接到可执行文件中。然后 IDE 可以启动一个进程来运行可执行文件。 更重要的是,请read about how to ask good questions 并了解如何创建Minimal, Complete, and Verifiable Example。 请编辑您的问题以包含代码,不要将其发布为 cmets。并请使其完整,尤其是变量声明(在这种情况下,我认为这非常重要)。 请注意getchar() 返回int,因为EOF 不适合char 【参考方案1】:

getchar 返回一个int 而不是char,与EOF 的比较应该使用!= 运算符而不是&gt;= 运算符来完成。

...
int character;   // int instead of char
int index;
index = 0;

while ((character = getchar()) != EOF)   // != instead of >=
...

【讨论】:

我最初按照您的建议编写了代码。同样的问题 @CristianLăpuşan 你的代码和我的修复程序在这里可以正常工作。你的输入到底是什么?你的平台是什么?请记住:在 Linux 上 EOF 使用 Ctrl+D 完成,在 Windows 上使用 Ctrl+Z 完成。 我正在使用 Xcode,macOS Sierra。 @CristianLăpuşan 好的;你到底在输入什么键? 问题是while循环永远不会结束!正如我已经提到的,我没有使用 C 的经验。感谢大家提供的帮助!【参考方案2】:

&gt;= EOF,它将让条件始终为true。原因是getchar() 的“有效”结果将是一个正整数,而像文件结尾这样的“无效”结果将是EOF,这是负数(参见getchar()):

EOF ... int 类型和负值的整数常量表达式

因此,来自getchar 的任何有效结果都将为&gt;EOF,而文件结尾结果将为==EOF,这样&gt;= EOF 将始终匹配。

改为写!= EOF

进一步注意,您不会通过字符串终止字符'\0' 来终止您的字符串,这样使用string 就像一个字符串(例如在printf("%s",string)) 中会产生未定义的行为(崩溃或其他可能不需要的东西) )。 所以至少写:

while ((character = getchar()) != EOF) 
    string[index] = character;
    ++index;

string[index]='\0';

那么还有一个问题是你可能写的越界,例如如果在您的示例中输入超过 100 个字符。但现在检查这一点超出了实际问题,即关于无限循环的问题。

【讨论】:

如果我提前退出函数,说我在循环“if (character == 47) return index;”之后立即插入,那么代码运行良好 @Cristian Lăpuşan:我想你的意思是“在循环内部”,因为你的循环永远不会结束;所以“while-loop 之后执行的代码”永远不会被打印出来,对吧?【参考方案3】:

符号常量EOF 是一个整数 常量,类型为int。它(通常)被定义为-1 的宏。

问题在于,作为(32 位)int 的值 -1 具有值 0xffffffff,而作为(8 位)char,相同的值将是 0xff。这两个值不相等。这反过来意味着您的循环条件将永远为假,从而导致无限循环。

这个问题的解决方案是所有读取字符的标准函数都将它们返回为int。这意味着您的变量 character 也需要属于该类型。

重要提示:如果plain char 是有符号或无符号类型,这是编译器实现细节。如果它已签名,那么在比较中提升char 值时,与int 的比较将导致符号扩展。这意味着带有值0xffsigned char 将扩展为int0xffffffff。这意味着如果 char 已签名,则比较将起作用。

这意味着您的编译将char 设置为unsigned char。所以升级为int 后的unsigned char0xff 将是0x000000ff


至于为什么-1变成0xffffffff是因为负数通常在计算机上表示,称为two's complement


您的代码中还有另外几个缺陷。

首先,由于循环是无限的,您将方式超出string数组的范围,导致未定义的行为(并可能更快地崩溃或以后)。对此的解决方案是添加一个条件以确保 index 永远不会达到 100(在您的数组的特定情况下,实际上应该作为参数传递)。

第二个问题是,如果您打算将string 数组用作实际字符串,则需要终止它。 C 中的字符串实际上称为 null terminated strings。该终止符是字符'\0'(等于整数0),并且需要放在要传递给处理此类字符串的标准函数的每个字符串的末尾。拥有这个终结符意味着100 字符数组只能包含 99 个字符,以便能够适应终结符。这对解决上述问题有影响。至于如何添加终止符,只需在循环后做string[index] = '\0';即可(如果index当然在范围内)。

【讨论】:

它不起作用.. @CristianLăpuşan what 如何“不起作用”?您是否将character 的类型更改为int?你在做其他你没有向我们展示的事情吗?您是否尝试过在调试器中单步执行代码?您是否尝试过在循环后打印的字符串中添加(尾随)换行符(因为输出到 stdout 是默认行缓冲的)? 赞成你带来的所有细节。但只是为了让我理解:(char)-1 == (int)-1 中的整体推广不确保(char)-1 实际上扩展到0xffffffff @StephanLechner 这取决于。我可能应该补充一点,char 可以是signed unsigned(取决于编译器),如果是signed,那么是的,会有符号扩展。当charunsigned 时并非如此(这里似乎就是这种情况,或者它应该可以工作)。 感谢您的意见。非常感谢!问题是,如果之前有一个while循环,即使是学习书中的代码也不会被执行

以上是关于在C中的while循环或for循环之后没有代码执行[重复]的主要内容,如果未能解决你的问题,请参考以下文章

python循环语句

vb中的循环语句

Python break 语句

C语言while执行不了,代码见图?

在while循环中没有第二次执行for循环

第八讲,循环结构,for循环,while循环