pixelfigure
pixelfigure

Reputation: 33

Initialising an array of structures in C

I'm doing a simple student database program exercise and I'm unsure of how to initialise an array of structures. I'm trying to initialize the first 3 elements of the array stdt[] with values known at compile-time, and then the next 3 students' information will be populated from user input. When I compile I get the error:

lab7.c: In function ‘main’:

lab7.c:16:9: error: expected expression before ‘{’ token
 stdt[0]={"John","Bishop","s1234","Inf",'m',18};
         ^

lab7.c:17:9: error: expected expression before ‘{’ token
 stdt[1]={"Lady","Cook","s2345","Eng",'f',21};
         ^

lab7.c:18:9: error: expected expression before ‘{’ token
 stdt[2]={"James","Jackson","s33456","Eng",'m',17};
         ^

How can I do this correctly?

Here is the code so far:

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

typedef struct {
    char *name;
    char *surname;
    char *UUN;
    char *department;
    char gender;
    int age;
} student_t;

int main() {
    int i;
    student_t stdt[6];
    stdt[0]={"John","Bishop","s1234","Inf",'m',18};
    stdt[1]={"Lady","Cook","s2345","Eng",'f',21};
    stdt[2]={"James","Jackson","s33456","Eng",'m',17};

    for(i=3;i<6;i++) {
        printf("First name: \n");
        scanf("%s",stdt[i].name);
        printf("Last name: \n");
        scanf("%s",stdt[i].surname);
        printf("UUN: \n");
        scanf("%s",stdt[i].UUN);
        printf("Department: \n");
        scanf("%s",stdt[i].department);
        printf("Gender (m/f): \n");
        scanf("%c",stdt[i].gender);
        printf("Age: \n");
        scanf("%d",stdt[i].age);
    }
    return 0;
}   

Upvotes: 3

Views: 138

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 755054

You can do almost what you wrote if you use C99 'compound literals':

stdt[0] = (student_t){ "John",  "Bishop",  "s1234",  "Inf", 'm', 18 };
stdt[1] = (student_t){ "Lady",  "Cook",    "s2345",  "Eng", 'f', 21 };
stdt[2] = (student_t){ "James", "Jackson", "s33456", "Eng", 'm', 17 };

However, this is assigning values to the array, not initializing the array. Further, since the array is local to main(), the values in the other three elements of the array are indeterminate; you cannot assume anything about them.

Upvotes: 2

Crowman
Crowman

Reputation: 25936

You're not "initializing" if you don't do it at the point of creation. You can do:

student_t stdt[2] = { {"John", "Bishop", "s1234", "Inf", 'm', 18},
                      {"Lady", "Cook", "s2345", "Eng", 'f', 21}
                    };

for as many as you have.

It's OK to not explicitly provide values for each member of the array. For the ones you don't explicitly initialize, pointer members will be implicitly initialized to NULL, and numeric members will be implicitly initialized to 0. In other words, this:

student_t stdt[4] = { {"John", "Bishop", "s1234", "Inf", 'm', 18},
                      {"Lady", "Cook", "s2345", "Eng", 'f', 21}
                    };

is equivalent to this:

student_t stdt[4] = { {"John", "Bishop", "s1234", "Inf", 'm', 18},
                      {"Lady", "Cook", "s2345", "Eng", 'f', 21},
                      {NULL, NULL, NULL, NULL, 0, 0},
                      {NULL, NULL, NULL, NULL, 0, 0}
                    };

For the curious, these rules derive from the C standard as follows.

From C11 Section 6.7.9.21:

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

and for "the same as objects that have static storage duration" we have Section 6.7.9.10:

If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static or thread storage duration is not initialized explicitly, then:

  • if it has pointer type, it is initialized to a null pointer;

  • if it has arithmetic type, it is initialized to (positive or unsigned) zero;

  • if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

  • if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;

A struct is an "aggregate" in the sense of the third bullet above.

Upvotes: 8

Related Questions