C语言 为什么下面的代码会打印超过6个元素?

hgtggwj0  于 2023-08-03  发布在  其他
关注(0)|答案(4)|浏览(144)
#include <stdio.h>

int main() {
    int a[] = {10, 20, 30, 40, 50};
    int size = sizeof(a) / sizeof(a[0]);
    int num, pos;
    printf("Enter the number to insert in the array: ");
    scanf("%d", &num);
    printf("Enter the position to enter the element in the array: ");
    scanf("%d", &pos);

    if (pos < 0 || pos > size) {
        printf("Invalid position!");
    } else {
        // Move elements to make space for the new element
        for (int i = size - 1; i >= pos; i--) {
            a[i + 1] = a[i];
        }

        // Insert the new element
        a[pos] = num;

        // Update the size of the array
        size++;

        printf("The updated array is: ");
        for (int i = 0; i < size; i++) {
            printf("%d ", a[i]);
        }
    }
    return 0;
}

字符串
该代码的输出给出了数组中超过6个元素。前6个元素打印正确,但其余的是随机垃圾值。这是什么原因呢?

wgx48brx

wgx48brx1#

要修复此问题并防止打印垃圾值,您需要声明一个大小比原始数组大一个元素的新数组,然后执行插入。下面是代码的修改版本:

#include <stdio.h>

int main()
{
    int a[] = {10, 20, 30, 40, 50};
    int size = sizeof(a) / sizeof(a[0]);
    int num, pos;

    printf("Enter the number to insert in the array: ");
    scanf("%d", &num);
    printf("Enter the position to enter the element in the array: ");
    scanf("%d", &pos);

    if (pos < 0 || pos > size)
    {
        printf("Invalid position!");
    }
    else
    {
        // Create a new array with one extra element
        int updated_size = size + 1;
        int updated_array[updated_size];

        // Copy elements before the specified position
        for (int i = 0; i < pos; i++)
        {
            updated_array[i] = a[i];
        }

        // Insert the new element
        updated_array[pos] = num;

        // Copy elements after the specified position
        for (int i = pos; i < size; i++)
        {
            updated_array[i + 1] = a[i];
        }

        // Print the updated array
        printf("The updated array is: ");
        for (int i = 0; i < updated_size; i++)
        {
            printf("%d ", updated_array[i]);
        }
    }

    return 0;
}

字符串

92dk7w1h

92dk7w1h2#

当我们创建一个数组时:
int arr[] = {10, 20, 30, 40, 50};分配sizeof(arr)/sizeof(arr[0])个内存块。
所以当你执行size++时,它是逻辑上不正确的
数组为 * 静态 *,大小不能修改
如果你希望有一个动态数组,使用malloc()calloc()这些函数在堆中分配内存。如果你想增加(或减少)数组的大小,你可以通过调用函数realloc()来实现。记住:malloc()calloc()realloc()free()属于stdlib.h头文件。
另外,当你在 heap 中分配内存时,记得 de-allocate OR free()内存,否则可能会导致内存泄漏

e5njpo68

e5njpo683#

这条线

int a[] = {10, 20, 30, 40, 50};

字符串
定义一个由五个int组成的数组。有效的索引为0、1、2、3和4。
此行正确计算的大小为5。

int size = sizeof(a) / sizeof(a[0]);


这个片段

for (int i = size - 1; i >= pos; i--) {
            a[i + 1] = a[i];
        }


将数组中的所有数字从pos向上移动一个槽。这就是第一个问题。如果是pos == size,则不会发生任何事情,但是如果是pos < size,则首先发生的事情是将a[size-1]中的项目复制到a[size]。麻烦的是size是5,索引是0 ...包括4。a[size] * 不在数组中 *。这称为“缓冲区溢出”。a是一个缓冲区,您已经在其外部写入了一个值。这是C标准所称的未定义行为的一个示例。这意味着任何事情都有可能发生。
接下来的实际情况取决于编译器实现和底层机器体系结构。如果你幸运的话,数组后面的内存位置不会被任何东西占用,即使你的程序坏了,你最后的打印也会 * 看起来 * 工作正常。如果你运气不好,位置后的阵列正在被用于一些重要的和不可预测的行为可能会接踵而至。
根据您描述的症状(打印了6个以上的元素),我认为编译器在数组结束后立即存储了变量size。因此,来自a[size-1]的第一个副本将对其进行乱码,,如果您为pos输入5size将被num覆盖。无论哪种方式,对执行打印的for循环来说都是坏消息。
根据您的最终目标,您有两种选择来解决此问题。如果这只是一个练习,并且您只打算执行一次插入,请通过在初始化器的末尾添加一个伪赋值器使数组的大小为6,并调整size以解决此问题

int a[] = {10, 20, 30, 40, 50, 0};
    //                             ^--- Dummy value
    int size = sizeof(a) / sizeof(a[0]) - 1;
    //                                  ^^^- reduces size from 6 to 5


如果最终希望能够重复插入任意次数,则需要使用malloc()动态分配数组,并在每次插入之前使用realloc()调整数组大小。

sauutmhj

sauutmhj4#

代码打印6个以上元素的原因是,它正在访问和打印数组中未初始化的元素。数组a的大小为5个元素:

int a[] = {10, 20, 30, 40, 50};

字符串
然后,在数组中插入元素后,数组的大小会更新:

size++;


然而,数组a的大小实际上并不改变。在C语言中,数组一旦被声明就有一个固定的大小。变量size仅跟踪用于插入目的的元素数,但不调整数组本身的大小。
因此,当您循环以使用更新后的大小打印数组时,循环会超出数组中实际初始化的元素,并从内存中存取垃圾值。
若要修正这个问题,您应该只打印数组有效大小(储存在变数size中)以内的元素。按如下方式修改打印循环:

printf("The updated array is: ");
for (int i = 0; i < size; i++)
{
  printf("%d ", a[i]);
}


这样,您将只打印数组中直到插入新元素的位置为止的有效元素。

相关问题