Home > front end >  I wanna know if can i redeclaring an array variable in C
I wanna know if can i redeclaring an array variable in C

Time:12-10

Is it possible to redeclare a variable in C? Or at least do it with pointers I want to redeclare the size of a variable in an array, what I want to try is not to ask the user the size of the array variable. I did an example which i don't even know if it's good Anyone know the answer?

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]);
    }   
}

Know if I can redeclare the size of a variable in a loop automatically while the user is placing values.

CodePudding user response:

If you are trying to have an array that can grow at runtime, you can use dynamic memory allocation with malloc and realloc. The following features no error-checking, which is left as an exercise for the reader.

To avoid having to reallocate too often, when necessary, we double the size of the array. In the below I have started with a count of 1, but that would just as easily be a larger number like 64, in which case a reallocation might never occur for trivial test input.

#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;
}

CodePudding user response:

In C, you cannot redeclare a variable with the same name in the same scope. However, you can change the value of a variable using the assignment operator (=).

One way to solve this problem is to use dynamic memory allocation to allocate memory for your array at runtime. This can be done using the malloc or realloc function, which allocates memory on the heap and returns a pointer to the allocated memory.

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

int main() {
    int i = 0;
    int *aUniverso = malloc(sizeof(int));

    printf("Put your numbers, if you want to leave put a number - to '0' \n");

    do {
        printf("Posicion[%d]: ", i);
        scanf("%d", &aUniverso[i]);
        i  ;

        // Reallocate memory for the array to make room for the new element.
        aUniverso = realloc(aUniverso, (i   1) * sizeof(int));
    } while (aUniverso[i - 1] >= 0);

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

    // Free the memory allocated for the array.
    free(aUniverso);

    return 0;
}

Note that this approach is inefficient.

You should ask the user for the size of the array and allocate it when needed.

You also checked whether the value of aUniverso[i], which is not initialized and leads to undefined behavior. What you meant was checking the last user input - aUniverso[i-1]

CodePudding user response:

In the spirit of the OP, another offering:

#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;
}

Practically speaking, incrementally growing the stored value array from zero, in this instance, is a minor consideration, imho... Here we see that passing a NULL pointer to realloc() initially causes it to function as if it were 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

CodePudding user response:

In C, it is not possible to simply resize an array. However, there are several other options for solving the problem:

Solution #1: Define an upper-bound of how many numbers you will need, and make the array that size.

Example:

#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] );
    }
}

This program has the following behavior:

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

However, the disadvantages of this solution are that

  • you have a hard limit on how many numbers you can have, and
  • setting this limit very high may cause you to waste a lot of memory.

If you don't want these disadvantages, then an alterantive would be:

Solution #2: Use a dynamically allocated array and resize it as necessary.

#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 );
}

This solution has the same behavior:

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

This solution has the advantage that you are only limited by available memory. However, a disadvantage of this solution is that realloc may have to copy the entire array to a new memory location, every time you call that function. If you only have a few numbers, then this should not be a problem. However, if you have thousands or even millions of numbers, then it probably will be a problem.

One way of solving this problem would be to not only increase the size of the array by a single element in every loop iteration, but to instead double the size of the array whenever more capacity is needed. That way it is guaranteed that, on average, every number will not have to be copied more than twice by realloc.

Here is an example:

#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 );
}
  •  Tags:  
  • c
  • Related