Search code examples
arrayscinitializationdeclarationvariable-length-array

Can anyone tell how can I get this done: code of relation of array with pointers


#include<stdio.h>
    
int main(void){
    const int size=5;
    int grades[size]={34,23,67,89,68};
    double sum=0.0;
    double *ptr_to_sum=&sum;
    int i;
    printf("\n my grades are:\n");
    for(i=0;i<size;i++){
        printf("%d\t",grades[i]);}
        printf("\n\n");
        for(i=0;i<size;i++){
            sum+=grades[i];
        }
        printf("my average grade is %.2f\n\n",sum/size);
        printf("\n\n");
        printf("sum is at %p, or %luandis%lf\n",ptr_to_sum,ptr_to_sum,*ptr_to_sum);
        printf("grades are at %lu to %lu\n",grades,grades+5);
    }

Even though being a simple code , I am unable to figure out the error ,the code is correct but I just don't know why this error is coming. Please can anyone help me in this? What I can just pretend after much thinking is that it is occurring due to the datatype long that is being used for the sum.

ERROR:pointers.c: In function 'main':
pointers.c:7:5: error: variable-sized object may not be initialized
    7 |     int grades[size]={34,23,67,89,68};
      |     ^~~
pointers.c:7:23: warning: excess elements in array initializer
    7 |     int grades[size]={34,23,67,89,68};
      |                       ^~
pointers.c:7:23: note: (near initialization for 'grades')    
pointers.c:7:26: warning: excess elements in array initializer
    7 |     int grades[size]={34,23,67,89,68};
      |                          ^~
pointers.c:7:26: note: (near initialization for 'grades')    
pointers.c:7:29: warning: excess elements in array initializer
    7 |     int grades[size]={34,23,67,89,68};
      |                             ^~
pointers.c:7:29: note: (near initialization for 'grades')    
pointers.c:7:32: warning: excess elements in array initializer
    7 |     int grades[size]={34,23,67,89,68};
      |                                ^~
pointers.c:7:32: note: (near initialization for 'grades')    
pointers.c:7:35: warning: excess elements in array initializer
    7 |     int grades[size]={34,23,67,89,68};
      |                                   ^~
pointers.c:7:35: note: (near initialization for 'grades') 

Solution

  • From the C Standard (6.7.6.2 Array declarators):

    1. ... If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.

    and (6.6 Constant expressions)

    6 An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator.

    That is in these declarations

    const int size=5;
    int grades[size]={34,23,67,89,68};
    

    the variable size is not an integer constant expression. Thus the array grades is a variable length array. And according to the C Standard (6.7.9 Initialization)

    3 The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.

    So you may mot initialize the array grades when it is declared as a variable length array.

    Instead of the constant variable size you could use an integer constant expression as for example an enumeration constant:

    enum {  size = 5 };
    int grades[size]={34,23,67,89,68};
    

    Pay attention to that as you already have the integer constant size then instead of the magic number 5 in this statement

    printf("grades are at %lu to %lu\n",grades,grades+5);
    

    it will be better to write

    printf( "grades are at %p to %p\n", 
            ( void * )grades, ( void * )( grades + size ) );
    

    To output pointers you have to use the conversion specifier %p.

    Another approach is to declare the array grades without specifying the number of elements. For example

    int grades[] = { 34, 23, 67, 89, 68 };
    

    and then to declare a variable that stores the number of elements in the array like

    const size_t size = sizeof( grades ) / sizeof( *grades );