我想知道我是否可以用C重新声明一个数组变量

pn9klfpd  于 2022-12-17  发布在  其他
关注(0)|答案(3)|浏览(118)

在C语言中可以重新声明一个变量吗,或者至少可以用指针来做,我想重新声明一个数组中变量的大小,我想尝试的是不要问用户数组变量的大小,我做了一个例子,我甚至不知道它好不好,有人知道答案吗?

int i;

int main() {
    int aUniverso[i];
    int ii = 0;
    
    printf("Put your numbers, if u wanna leave put a number - to '0' \n");
    
    do{
        printf("Posicion[%d]: ", i);
        scanf("%d", &aUniverso[i]);
        i++;
    }
    while (aUniverso[i] >= 0);

    printf("U = {");
    for (ii = 0; ii < i; ii++) {
       printf("%d, ", aUniverso[ii]);
    }   
}

知道我是否可以在用户放置值时自动重新声明循环中变量的大小。

ecr0jaav

ecr0jaav1#

在C语言中,简单地调整数组大小是不可能的。然而,有几个其他的选项可以解决这个问题:

溶液#1:定义所需数字的上限,并使数组达到该大小。

示例:

#include <stdio.h>

#define MAX_NUMBERS 100

int main( void )
{
    int numbers[MAX_NUMBERS];
    int i;

    for ( i = 0; i < MAX_NUMBERS; i++ )
    {
        printf( "Please enter #%d, or -1 to stop: ", i + 1 );

        if ( scanf( "%d", &numbers[i] ) != 1 || numbers[i] == -1 )
            break;
    }

    printf( "\nYou entered the following numbers:\n" );

    for ( int j = 0; j < i; j++ )
    {
        printf( "#%d: %d\n", j + 1, numbers[j] );
    }
}

此程序具有以下行为:

Please enter #1, or -1 to stop: 7
Please enter #2, or -1 to stop: 3
Please enter #3, or -1 to stop: 5
Please enter #4, or -1 to stop: 8
Please enter #5, or -1 to stop: 3
Please enter #6, or -1 to stop: -1

You entered the following numbers:
#1: 7
#2: 3
#3: 5
#4: 8
#5: 3

然而,这种解决方案的缺点是

  • 你有一个硬限制你可以有多少个号码,
  • 将这个限制设置得很高可能会导致你浪费大量的内存。

如果你不希望这些缺点,那么一个备选方案将是:

溶液#2:使用动态分配的数组并根据需要调整其大小。

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

int main( void )
{
    int *numbers = NULL;
    int i;

    for ( i = 0; ; i++ ) //infinite loop
    {
        //attempt to create/resize buffer to desired capacity
        //NOTE: calling realloc with a NULL argument is equivalent
        //      to calling malloc
        numbers = realloc( numbers, (i+1) * sizeof(int) );
        if ( numbers == NULL )
        {
            fprintf( stderr, "Memory allocation error!\n" );
            exit( EXIT_FAILURE );
        }

        printf( "Please enter #%d, or -1 to stop: ", i + 1 );

        if ( scanf( "%d", &numbers[i] ) != 1 || numbers[i] == -1 )
            break;
    }

    printf( "\nYou entered the following numbers:\n" );

    for ( int j = 0; j < i; j++ )
    {
        printf( "#%d: %d\n", j + 1, numbers[j] );
    }

    //cleanup
    free( numbers );
}

此解决方案具有相同的行为:

Please enter #1, or -1 to stop: 7
Please enter #2, or -1 to stop: 3
Please enter #3, or -1 to stop: 5
Please enter #4, or -1 to stop: 8
Please enter #5, or -1 to stop: 3
Please enter #6, or -1 to stop: -1

You entered the following numbers:
#1: 7
#2: 3
#3: 5
#4: 8
#5: 3

这种解决方案的优点是只受可用内存的限制。然而,这种解决方案的缺点是每次调用该函数时,realloc可能必须将整个数组复制到新的内存位置。如果只有几个数字,则这应该不是问题。但是,如果有数千个甚至数百万个数字,则可能会出现问题。
解决这个问题的一个方法是不仅在每次循环迭代中增加一个元素,而且在需要更多容量时将数组的大小增加一倍,这样就可以保证平均每个数字复制的次数不会超过realloc的两倍。
下面是一个例子:

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

int main( void )
{
    int capacity = 100;
    int *numbers;
    int i;

    //allocate initial array
    numbers = malloc( capacity * sizeof(int) );
    if ( numbers == NULL )
    {
        fprintf( stderr, "Memory allocation error!\n" );
        exit( EXIT_FAILURE );
    }

    for ( i = 0; ; i++ ) //infinite loop
    {
        //double the capacity of the array, if necessary
        if ( i == capacity )
        {
            capacity *= 2;

            numbers = realloc( numbers, capacity * sizeof(int) );
            if ( numbers == NULL )
            {
                fprintf( stderr, "Memory allocation error!\n" );
                exit( EXIT_FAILURE );
            }
        }

        printf( "Please enter #%d, or -1 to stop: ", i + 1 );

        if ( scanf( "%d", &numbers[i] ) != 1 || numbers[i] == -1 )
            break;
    }

    printf( "\nYou entered the following numbers:\n" );

    for ( int j = 0; j < i; j++ )
    {
        printf( "#%d: %d\n", j + 1, numbers[j] );
    }

    //cleanup
    free( numbers );
}
tquggr8v

tquggr8v2#

如果你想要一个可以在运行时增长的数组,你可以使用mallocrealloc的动态内存分配。下面的代码没有错误检查功能,这是留给读者的练习。
为了避免过于频繁地重新分配,在必要的时候,我们将数组的大小增加一倍,在下面的例子中,我从1的计数开始,但是这很容易成为一个更大的数字,比如64,在这种情况下,对于微不足道的测试输入,重新分配可能永远不会发生。

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

int main(void) {
    size_t count = 1;
    int *numbers = malloc(sizeof(int) * count);
    size_t i;

    for (i = 0; i < count; i++) {
        scanf("%d", &numbers[i]);

        if (numbers[i] < 0) break;

        if (i == count - 1) {
            count *= 2;
            numbers = realloc(numbers, sizeof(int) * count);
        }
    } 

    for (size_t c = 0; c < i; c++) {
        printf("%d\n", numbers[c]);
    }
    
    free(numbers);

    return 0;
}
bvpmtnay

bvpmtnay3#

本着业务方案的精神,另一项服务:

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

int main( void ) {
    int *vals = NULL; // starting out with nothing
    size_t nVals = 0;

    puts( "Enter as many counting numbers as you like. 0 to end input" );

    do {
        // note that sizeof doesn't presume an int
        // less maintenance when changing this to 'doubles'
        vals = realloc( vals, (nVals+1) * sizeof *vals );
        if( vals == NULL ) {
            printf( "Realloc failed\n" );
            return 1; // can't go on...
        }

        while( scanf( "%d", vals + nVals ) != 1 ) {
            scanf( "%*[^\n]" ); // discard whatever is waiting.
            printf( "Bad input\n" );
        }
    } while( vals[ nVals++ ] > 0 );

    puts( "\nHere are your numbers:" );
    for( size_t i = 0; i < nVals - 1; i++ )
        printf( "%d\n", vals[ i ] );
    
    free( vals );

    return 0;
}

实际上,在这种情况下,从零开始递增存储值数组是一个次要的考虑因素,imho...在这里,我们看到将NULL指针传递到realloc()最初会导致它像malloc()一样运行。

Enter as many counting numbers as you like. 0 to end input
9 8 7 6 5 4 3 2 1 0

Here are your numbers:
9
8
7
6
5
4
3
2
1

相关问题