为什么此数组不保存扫描的数字?

Why doesn't this array save the scanned numbers?

提问人:Coder 提问时间:4/5/2023 最后编辑:Vlad from MoscowCoder 更新时间:4/5/2023 访问量:100

问:

这是我的代码。它应该扫描数字,直到输入 0。然后它应该打印数字。但它打印的只是零。

#include <stdio.h>

int main()
{
    int x[100];
    int n;
    int i;
    for(i = 0; ; i++)
    {
        while(x[i] != 0)
        {
            scanf("%d", &x[i]);
            n++;
        }
        if(x[i] == 0)
            {
                break;
            }
    }
    for(i = 0; i < n;i++)
    {
        printf("%d\n", x[i]);
    }

}

我期待看到我输入的确切数字。

数组 C 循环 while 循环

评论

4赞 Jason 4/5/2023
while(x[i] != 0): 从什么开始?它可能是 0。x[i]
3赞 Some programmer dude 4/5/2023
与任何其他局部非静态变量一样,开始时未初始化且值不确定。不要使用未初始化的变量。x
1赞 Jason 4/5/2023
@Coder我的意思是。它到底是什么。不是你想做什么。如果该语句在第一次通过时是错误的,则它永远不会到达 .scanf
1赞 Some programmer dude 4/5/2023
@Coder 完全跳过内部循环。它不是必需的。并添加一个检查(在循环条件下),使其不会等于或大于循环内部。whilefori100
1赞 Some programmer dude 4/5/2023
始终检查返回的内容scanf

答:

1赞 Jason 4/5/2023 #1

提前退出的原因是因为这里:如果未初始化的值()为0,则可能会失败。虽然它可能不是 0。但这种逻辑在其他几个方面存在严重缺陷。while(x[i] != 0)x[i]

  • 实际上没有必要执行 while 循环,因为 for 循环已经在遍历数组。

  • 你实际上应该在循环中有一个终止条件,因为你可以迭代传递的 100 并在数组的边界之外写入。

  • n未初始化,因此它实际上可以以任何数字开始计数,例如 12456 或其他 =]

这是我认为你想要的:

#include <stdio.h>

int main()
{
    int x[100];
    int n = 0;  // init this!
    int i;
    for(i = 0; i < 100; i++) // added terminating condition here
    {    
       scanf("%d", &x[i]);
       n++;
       if(x[i] == 0)
       {
           break;
       }
    }
    for(i = 0; i < n;i++)
    {
        printf("%d\n", x[i]);
    }
}

另外,您确实应该检查 的返回值。我会把那个留给你=]。scanf

评论

0赞 Steve Summit 4/5/2023
检查 的返回值也是一个好主意。scanf
0赞 0___________ 4/5/2023
这是行不通的
0赞 Chris 4/5/2023
真的没有任何理由不能在本地限定为这些循环。i
0赞 Jason 4/5/2023
@Chris 也许他正在使用 C89 ;)
1赞 Chris 4/5/2023
@Jason,我和任何人一样喜欢怀旧,但这是有限制的。
-1赞 NoUserNoName 4/5/2023 #2

您的号码从未输入过,因为默认情况下所有 x[i] 都是 0

 while(x[i] != 0)

在你的 while 循环中,你从未增加过 i。

For input {1, 2, 0}
x[0] = 1
x[0] = 2
x[0] = 0

代码如下

#include <stdio.h>

const int POOL_SIZE = 100;

int main(){
    int x[POOL_SIZE];
    int n = 0;
    
    do {
        scanf("%d", &x[n]);
    } while(n < POOL_SIZE && x[n++] != 0);
    
    for(int i = 0; i < n; i++)
        printf("%d\n", x[i]);
    
    return 0;
}

评论

0赞 Chris 4/5/2023
的内容不保证全部是 .也许他们是,但不确定。x0
0赞 Bob__ 4/5/2023
第一个循环可能会越界访问。x
0赞 Jason 4/5/2023
这将创建一个与 Flad 版本不同的 VLA。enum
0赞 Vlad from Moscow 4/5/2023 #3

在程序中,数组和变量都不会初始化xn

int main()
{
    int x[100];
    int n;
    //...

它们具有不确定的值。

因此,在while循环中评估条件

while(x[i] != 0)
{
//...

并增加变量n

n++;

调用未定义的行为。

此外,嵌套循环,即 for 循环中的 while 循环,也是多余的。

只使用一个循环就足够了。

例如

#include <stdio.h>

int main( void )
{
    enum { SIZE = 100 };
    int x[SIZE];

    int n = 0;

    for ( int value; n < SIZE && scanf( "%d", &value ) == 1 && value != 0; )
    {
        x[n++] = value;
    }

    for ( int i = 0; i < n; i++ )
    {
        printf( "%d\n", x[i] );
    }
}

请注意,您应该在使用变量的最小范围内声明变量。而不是像这样的幻数,你应该使用命名常量。100

此外,您应该检查调用是否成功。scanf