【问题标题】:Stuck in a for loop entering values to an array in C language卡在 for 循环中,用 C 语言将值输入到数组中
【发布时间】:2019-04-17 09:41:57
【问题描述】:

我正在尝试通过制作一个冒泡排序程序来练习 C 语言。到目前为止的问题似乎是,在不再满足条件后,为数组的单元格赋值的 for 循环被卡住了,但它似乎没有执行循环中的命令。我不知道到底发生了什么,我添加了一些额外的行来看看发生了什么,这些是我的结论。代码如下:

#include <stdio.h>
#include <stdlib.h>

void swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int *sort(int *array)
{
    int finish = 1;
    while (finish = 1)
    {
        finish = 0;
        for (int i = 0; i <= sizeof(array); i++)
        {
            if ((array + i) > (array + i + 1))
            {
                swap(array + i, array + i + 1);
                finish = 1;
            }
        }
    }
    return array;
}
int main()
{
    int s, res;
    printf("Give me the size of the array being sorted(larger than 1) : ");
    do
    {
        res = scanf("%d", &s);
        if (res != 1)
        {
            printf("Wrong Input!\n");
            exit(1);
        }
        if (s < 2)
            printf("Only numbers equal or larger than 2\n");

    } while (s < 2);
    int array[s];
    for (int i = 0; i < s; i += 1)
    {
        scanf("%d", array + i);
        printf("%d %d %d\n\n", *(array + i), i, i < s); // I used this to check if my values were ok
    }
    printf("end of reading the array"); //I added this line to see if I would exit the for loop. I am not seeing this message
    sort(array);
    printf("\n");
    for (int i = 0; i < sizeof(array); i++)
        printf("%d\n\n", array + i);
    printf("Array has been sorted! Have a nice day!\n\n************************************************************");
    return 0;
}

【问题讨论】:

  • sizeof(array) 不会像您认为的那样做。查找“数组到指针衰减”。
  • 还有while (finish = 1)-->while (finish == 1)
  • @Swordfish 我认为int array[s]; 应该是一个数组....对吗?
  • 请始终在编译器中启用警告。 while (finish = 1) 行应该引起一些关于条件中的赋值的警告。
  • sizeof(array) 两次都被误用。在sort() 函数中,sizeof(array) 返回构成指针 int *array 的字节数。在main 中,sizeof(array) 返回数组int array[s]; 中的字节 数,而不是数组中的元素数。

标签: c arrays loops for-loop scanf


【解决方案1】:

在排序函数sizeof(array)中返回指针的大小。 (您可以使用printf("%d", sizeof(array)自行检查。

解决方案是将您的功能更改为:

int sort(int* array, size_t size) { ... }

并使用正确的数组大小调用它:

sort(array, s);

【讨论】:

  • “返回与 sizeof(int) 相同”不。
  • "printf("%s", sizeof(array))" 不,不。
  • sizeof不返回指针类型的大小吗?这一直是我对它的理解。
  • 好的,我应该在回答之前自己测试过,它返回的是指针类型的大小。
  • 应该使用%zu 而不是%d 打印出sizeof 的东西
【解决方案2】:

查看代码中的注释:

#include <stddef.h>  // size_t  1)
#include <stdio.h>
#include <stdlib.h>

void swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int *sort(int *array, size_t size)  // needs an extra parameter to know the size of the array
{
    int finish = 1;
    while (finish /* = 1 * you don't want assignment, you want comparison: */ == 1)
    {
        finish = 0;
        for (int i = 0; i /* <= sizeof(array) */ < size - 1; i++)  // i should be of type size_t
        {
            // if ((array + i) > (array + i + 1)) you are not dereferencing:
            if(array[i] > array[i + 1]) 
            {
                // swap(array + i, array + i + 1);  // easier to read imho:
                swap(&array[i], &array[i + 1]);
                finish = 1;
            }
        }
    }
    return array;  // why does this function return anything? it is never used.
}
int main()
{
    int s; /* , res;  no need for an extra variable res */
    printf("Give me the size of the array being sorted(larger than 1) : ");
    do
    {
        // res = scanf("%d", &s);
        // if (res != 1)
        if (scanf("%d", &s) != 1)
        {
            printf("Wrong Input!\n");
            // exit(1);  // should be EXIT_FAILURE. Use return instead of exit() when in main().
            return EXIT_FAILURE;
        }
        if (s < 2)
            printf("Only numbers equal or larger than 2\n");

    } while (s < 2);
    int array[s];
    for (int i = 0; i < s; /* i += 1* idiomatic: */ ++i)  // size_t would be the correct type for s and i.
    {
        scanf("%d", /* array + i  use indexes: */ &array[i]);
        printf("%d %d %d\n\n", array[i], i, i < s);  // again: indexes. i < s is allready ensured by the condition of the for-loop
    }
    printf("end of reading the array");
    // sort(array);  // sort will have no idea about the size of array use
    sort(array, s); // instead.

    printf("\n");
    for (int i = 0; i < /* sizeof(array) 2) */ s; i++)
        printf("%d\n\n", /* array + i * again you don't dereference */ array[i]);
    printf("Array has been sorted! Have a nice day!\n\n************************************************************");
    return 0;
}

1) size_t 是保证足够大以在内存中保存所有大小的对象并对其进行索引的类型。 scanf() 的转换说明符是 "%zu"

2) main() 中的 sizeof(array) 将产生 array 中的字节数,但您需要元素数,因此您必须使用 sizeof(array) / sizeof(*array)。但这不是必需的,因为您已经知道它的大小。是s

【讨论】:

  • 您无法想象这对您有多大帮助,非常感谢!!我从中学到了很多东西,你扩展了我对 C 的理解,谢谢!
  • “你无法想象有多大帮助” 是的,我可以。我在 DOS 6.22 上使用 Borland C++ 3.1 在没有 Internet 访问和 q+a 站点或论坛的情况下非常艰难地学习了 C++^^
  • i +1 &lt; size 处理size == 0 的角落情况。它比i &lt; size - 1 更好,因为它实际上是i &lt; SIZE_MAX
【解决方案3】:

这一行

printf("end of reading the array");

字符串末尾没有换行符。这是一个问题,因为printf 是称为“缓冲 IO”的函数系列的一部分。 C 库维护您要打印的内容的缓冲区,并且仅当缓冲区已满或在字符流中遇到\n 时才将它们发送到终端。在打印换行符之前,您不会在屏幕上看到end of reading the array。您只能在调用sort() 之后 执行此操作。所以你只知道你的程序在sort结束之前的某个时间点进入了一个无限循环。

所以实际上有三个循环可能是无限的:您确定的 for 循环、sort 中的 while 循环和 while 循环内的 for 循环。正如其他答案所指出的,您犯了在while 条件中使用赋值的经典错误

while (finish = 1)
//            ^ not enough equals signs

除非您的 C 编译器非常旧,否则它可能会在该行输出警告。你应该注意警告。

此外,您应该尽早学会使用调试器。相信我,它会为您节省大量查找错误的时间。

【讨论】:

    猜你喜欢
    • 2014-02-09
    • 2021-03-06
    • 2016-02-24
    • 2020-02-27
    • 2017-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    相关资源
    最近更新 更多