【问题标题】:increase size of array增加数组的大小
【发布时间】:2020-04-18 19:09:30
【问题描述】:

你能帮我做这个练习吗?

编写一个 C 程序,从键盘读取 6 个整数,并在数组的前 5 个位置分配前 5 个值;将第六个值存储在变量 N 中。编写一个函数,给定输入用键盘的前 5 个值和整数 N 初始化的数组,返回调整大小以包含 5 + N 个元素的数组,这样每个新的N 个元素对应于数组中它之前的数字的总和。 在 main 中,打印函数返回的数组的内容。

main 函数也可以。

当我必须使用函数 realloc 将数组从 size = 5 增加到 5 + N 时,我遇到了问题。

这是我的代码:

int N, a, i;
int *ptr;
int arr[6];

for (i = 0; i < 5; i++) {
    printf("Insert number in array, position(%d): ", i);
    scanf("%d", &arr[i]);
}

N = arr[4];

a = 5 + N;

ptr = (int *)realloc(arr, sizeof(int) * a);

for (i = 4; i < a; i++) {
    ptr + i = N * N; //<--- **problem!!**
}

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

free(ptr);

【问题讨论】:

  • 您不能reallocate 数组的大小。衰减为指针的数组标识符不是从malloc获取的。
  • 循环使用scanf读取前5个数字。然后你需要一个scanf 在循环之后读取N。然后还有更多的事情需要解决,但一次只做一件事。我发现读取用户的输入,然后打印出来是很有帮助的,只是为了证明所有的输入都被正确读取了。
  • 无法编译指示的ptr + i = N*N;。你的意思是*(ptr + i) = N*N
  • 代替ptr + i = N * N;,作为WeatherVane 建议[可行] 的替代方案,您可以使用ptr[i] = N * N;,它等效,但更紧凑。

标签: c memory-management sum malloc realloc


【解决方案1】:

您不能重新分配在函数中本地定义或全局定义的数组。您只能在先前使用malloc()calloc()realloc()NULL 指针分配的对象上调用realloc。所以你必须在main()中分配5个元素的初始数组,并在函数中重新分配。

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

int *extend_array(int *arr, int N) {
    int a = 5 + N;
    arr = realloc(arr, a * sizeof(int));
    if (arr != NULL) {
        int sum = 0;
        for (int i = 0; i < 5; i++) {
            sum += arr[i];
        }
        for (int i = 5; i < a; i++) {
            arr[i] = sum;
            sum += sum;
        }
    }
    return arr;
}

int main() {
    int N;

    int *arr = malloc(5 * sizeof(int));
    if (arr == NULL) {
        printf("allocation failed\n");
        return 1;
    }
    for (int i = 0; i < 5; i++) {
        printf("Insert number in array, position(%d): ", i);
        if (scanf("%d", &arr[i]) != 1) {
            printf("invalid input\n");
            return 1;
        }
    }

    printf("Insert the value of N: ");
    if (scanf("%d", &N) != 1) {
        printf("invalid input\n");
        return 1;
    }

    int *ptr = extend_array(arr, N);
    if (ptr == NULL) {
        printf("reallocation failed\n");
    } else {
        arr = ptr;
        for (int i = 0; i < 5 + N; i++) {
            printf("%d\n", arr[i]);
        }
    }
    free(arr);
    return 0;
}

赋值指定函数应该将数组和数字N 作为参数,但最好将初始大小设置为变量并将其传递给函数以使代码更通用、更简单进行扩展,并且由于常量5 出现在许多地方,因此不易出错。

【讨论】:

    【解决方案2】:

    如果您需要重新分配一个数组,那么它最初必须是动态分配的。 所以这段代码

    int arr[6];
    //...
    ptr = (int *)realloc(arr, sizeof(int) * a);
    

    无效。

    注意根据赋值需要写一个重新分配数组的函数。

    请记住,使用像5 这样的“幻数”是一种非常糟糕的编程风格。而是使用命名常量或将此类数字分配给变量并使用它们。

    程序可以如下所示。

    #include <stdio.h>
    #include <stdlib.h>
    
    int * resize( int *a, size_t n, size_t m )
    {
        int *tmp = realloc( a, ( n + m ) * sizeof( int ) );
    
        if ( tmp != NULL )
        {
            int sum = 0;
            size_t i = 0;
    
            while ( i < n ) sum += tmp[i++];
            while ( i < n + m )
            {
                tmp[i] = sum;
                sum += tmp[i++];
            }
        }
    
        return tmp;
    }
    
    int main(void) 
    {
        size_t n = 5;
        int *a = malloc( n * sizeof( int ) );
        size_t m = 0;
    
        printf( "Enter %zu numbers. The last number shall be greater than 0: ", n + 1 );
    
        for ( size_t i = 0; i < n; i++ )
        {
            scanf( "%d", a + i );
        }
    
        scanf( "%zu", &m );
    
        int *tmp  = resize( a, n, m );
    
        if ( tmp != NULL )
        {
            a = tmp;
        }
        else
        {
            m = 0;
        }
    
        for ( size_t i = 0; i < n + m; i++ )
        {
            printf( "%d ", a[i] );
        }
    
        putchar( '\n' );
    
        free( a );
    
        return 0;
    }
    

    程序输出可能看起来像

    Enter 6 numbers. The last number shall be greater than 0: 1 2 3 4 5 6
    1 2 3 4 5 15 30 60 120 240 480 960 1920 3840 7680 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-14
      • 2016-02-02
      • 1970-01-01
      • 2015-08-22
      • 2016-07-31
      • 2013-02-22
      相关资源
      最近更新 更多