Submitted by Anonymous (not verified) on Sun, 03/10/2013 - 21:21

Arrays of Structures

In C, you can declare an array of a structure by preceding the array name with the structure name. For instance, given a structure with the tag name of x, the following statement

struct x array_of_structure[8];

declares an array, called array_of_structure, with the structure data type of x. The array has eight elements.

The program shown in Listing 19.5 demonstrates how to use an array of a structure by printing out two pieces of Japanese haiku and their authors' names.
 

TYPE
Listing 19.5. Using arrays of structures.


1:  /* 19L05.c Arrays of structures */
2:  #include <stdio.h>
3:
4:  struct haiku {
5:     int start_year;
6:     int end_year;
7:     char author[16];
8:     char str1[32];
9:     char str2[32];
10:    char str3[32];
11: };
12:
13: typedef struct haiku HK;
14:
15: void DataDisplay(HK *ptr_s);
16:
17: main(void)
18: {
19:    HK poem[2] = {
20:      { 1641,
21:        1716,
22:        "Sodo",
23:        "Leading me along",
24:        "my shadow goes back home",
25:        "from looking at the moon."
26:      },
27:      { 1729,
28:        1781,
29:        "Chora",
30:        "A storm wind blows",
31:        "out from among the grasses",
32:        "the full moon grows."
33:      }
34:    };
35:    int i;
36:
37:    for (i=0; i<2; i++)
38:       DataDisplay(&poem[i]);
39:
40:    return 0;
41: }
42: /* function definition */
43: void DataDisplay(HK *ptr_s)
44: {
45:    printf("%s\n", ptr_s->str1);
46:    printf("%s\n", ptr_s->str2);
47:    printf("%s\n", ptr_s->str3);
48:    printf("--- %s\n", ptr_s->author);
49:    printf("   (%d-%d)\n\n", ptr_s->start_year, ptr_s->end_year);
50: }


After running the executable (19L05.exe) of the program in Listing 19.5, I see the two pieces of Japanese haiku printed on the screen:

OUTPUT

C:\app>19L05
Leading me along
my shadow goes back home
from looking at the moon.
--- Sodo
   (1641-1716)

A storm wind blows
out from among the grasses
the full moon grows.
--- Chora
   (1729-1781)
C:\app>

ANALYSIS

In Listing 19.5, a structure data type, with the tag name of haiku, is declared in lines 4_11. The structure data type contains two int variables and four char arrays as its members. The statement in line 13 creates a synonym, HK, for the struct haiku data type.

Then, in lines 19_34, an array of two elements, poem, is declared and initialized with two pieces of haiku written by Sodo and Chora, respectively. The following is a copy of the two pieces of haiku from poem:

"Leading me along",
"my shadow goes back home",
"from looking at the moon."

and

"A storm wind blows",
"out from among the grasses",
"the full moon grows."

The initializer also includes the authors' names and the years of their births and deaths (refers to lines 20_22 and lines 27_29). Note that the poem array, declared with HK, is indeed an array of the haiku structure.

The DataDisplay() function is called twice in a for loop in lines 37 and 38. Each time, the address of an element of poem is passed to the DataDisplay() function. According to the definition of the function in lines 43_50, DataDisplay() prints out three strings of a haiku, the author's name, and the period of time in which he lived.

From the output, you can see that the contents stored in the poem array of the haiku structure are displayed on the screen properly.

 

Nested Structures

A structure is called a nested structure when one of the members of the structure is itself a structure. For instance, given a structure data type of x, the following statement

struct y {
   int i;
   char ch[8];
   struct x nested;
};


declares a nested structure with a tag name of y, because one of the members of the y structure is a structure with the variable name of nested that is defined by the structure data type of x.

Listing 19.6 contains an example of using a nested structure to receive and print out information about an employee.

TYPE
Listing 19.6. Using nested structures.


1:  /* 19L06.c Using nested structures */
2:  #include <stdio.h>
3:
4:  struct department {
5:     int  code;
6:     char name[32];
7:     char position[16];
8:  };
9:
10: typedef struct department DPT;
11:
12: struct employee {
13:    DPT d;
14:    int id;
15:    char name[32];
16: };
17:
18: typedef struct employee EMPLY;
19:
20: void InfoDisplay(EMPLY *ptr);
21: void InfoEnter(EMPLY *ptr);
22:
23: main(void)
24: {
25:    EMPLY info = {
26:       { 1,
27:         "Marketing",
28:         "Manager"
29:       },
30:       1,
31:       "B. Smith"
32:    };
33:
34:    printf("Here is a sample:\n");
35:    InfoDisplay(&info);
36:
37:    InfoEnter(&info);
38:
39:    printf("\nHere are what you entered:\n");
40:    InfoDisplay(&info);
41:
42:    return 0;
43: }
44: /* function definition */
45: void InfoDisplay(EMPLY *ptr)
46: {
47:    printf("Name: %s\n", ptr->name);
48:    printf("ID #: %04d\n", ptr->id);
49:    printf("Dept. name: %s\n", ptr->d.name);
50:    printf("Dept. code: %02d\n", ptr->d.code);
51:    printf("Your position: %s\n", ptr->d.position);
52: }
53: /* function definition */
54: void InfoEnter(EMPLY *ptr)
55: {
56:    printf("\nPlease enter your information:\n");
57:    printf("Your name:\n");
58:       gets(ptr->name);
59:    printf("Your position:\n");
60:       gets(ptr->d.position);
61:    printf("Dept. name:\n");
62:       gets(ptr->d.name);
63:    printf("Dept. code:\n");
64:       scanf("%d", &(ptr->d.code));
65:    printf("Your employee ID #:\n");
66:       scanf("%d", &(ptr->id));
67: }


When the executable, 19L06.exe, is running, the initial content of the nested structure is printed out first. Then, I enter my employment information, which is in bold in the following output and displayed back on the screen, too:

OUTPUT

C:\app>19L06
Here is a sample:
Name: B. Smith
ID #: 0001
Dept. name: Marketing
Dept. code: 01
Your position: Manager

Please enter your information:\n");
Your name:
T. Zhang
Your position:\n");
Engineer
Dept. name:
R&D
Dept. code:
3

Your employee ID #:
1234

Here are what you entered:
Name: T. Zhang
ID #: 1234
Dept. name: R&D
Dept. code: 03
Your position: Engineer
C:\app>

ANALYSIS

There are two structure data types in Listing 19.6. The first one, called department, is declared in lines 4_8. The second one, employee, declared in lines 12_16, contains a member of the department structure data type. Therefore, the employee structure data type is a nested structure data type.

Two synonyms, DPT for the struct department data type, and EMPLY for the struct employee data type, are created in two typedef statements, respectively, in lines 10 and 18. In the program, there are two functions, InfoDisplay() and InfoEnter(), whose prototypes are declared with a pointer of EMPLY as the argument (see lines 20 and 21).

The statement in 25_32 initializes a nested structure, which is called info and defined with EMPLY. Note that the nested braces ({ and }) in lines 26 and 29 enclose the initializers for the d structure of DPT that is nested inside the info structure.

Then, the statement in line 35 displays the initial contents held by the nested info structure by calling the InfoDisplay() function. Line 37 calls the InfoEnter() function to ask the user to enter his or her employment information and then save it into the info structure. The InfoDisplay() function is called again in line 40 to display the information that the user entered and is now stored in the nested structure.

The definitions for the two functions, InfoDisplay() and InfoEnter(), are listed in lines 45_52 and lines 54_67, respectively.
Forward-Referencing Structures

If one of the members of a structure is a pointer pointing to another structure that has not been declared yet, the structure is called a forward-referencing structure.

For example, the following statement declares a forward-referencing structure:

struct x {
   int i;
   char ch[8];
   struct y *ptr;
};


It is presumed that the structure y has not been declared yet.

If the pointer in a structure points to the structure itself, the structure is called a self-referencing structure. The following declaration is an example of a self-referencing structure:

struct x {
   int i;
   char ch[8];
   struct x *ptr;
};


Now, let's move to the program in Listing 19.7, which provides you with another example of declaring a forward-referencing structure.
 

TYPE
Listing 19.7. Using forward-referencing structures.


1:  /* 19L07.c Forward-referencing structures */
2:  #include <stdio.h>
3:  /* forward-referencing structure */
4:  struct resume {
5:     char name[16];
6:     struct date *u;
7:     struct date *g;
8:  };
9:  /* referenced structure */
10: struct date {
11:    int year;
12:    char school[32];
13:    char degree[8];
14: };
15:
16: typedef struct resume RSM;
17: typedef struct date DATE;
18:
19: void InfoDisplay(RSM *ptr);
20:
21: main(void)
22: {
23:    DATE under = {
24:        1985,
25:        "Rice University",
26:        "B.S."
27:        };
28:    DATE graduate = {
29:        1987,
30:        "UT Austin",
31:        "M.S."
32:        };
33:    RSM new_employee = {
34:        "Tony",
35:        &under,
36:        &graduate
37:        };
38:
39:    printf("Here is the new employee's resume:\n");
40:    InfoDisplay(&new_employee);
41:
42:    return 0;
43: }
44: /* function definition */
45: void InfoDisplay(RSM *ptr)
46: {
47:    printf("Name: %s\n", ptr->name);
48:    /* undergraduate */
49:    printf("School name: %s\n", ptr->u->school);
50:    printf("Graduation year: %d\n", ptr->u->year);
51:    printf("Degree: %s\n", ptr->u->degree);
52:    /* graduate */
53:    printf("School name: %s\n", ptr->g->school);
54:    printf("Graduation year: %d\n", ptr->g->year);
55:    printf("Degree: %s\n", ptr->g->degree);
56: }


I have the following output displayed on the screen after I run the executable, 19L07.exe, of the program in Listing 19.7:

OUTPUT

C:\app>19L07
Here is the new employee's resume:
Name: Tony
School name: Rice University
Graduation year: 1985
Degree: B.S.
School name: UT Austin
Graduation year: 1987
Degree: M.S.
C:\app>

ANALYSIS

The purpose of the program in Listing 19.7 is to show you how to declare and initialize a forward-referencing structure. As you can see, the forward-referencing structure data type, labeled with resume, is declared in lines 4_8. This structure data type has two members, u and g, which are pointers defined with the date structure data type. However, the date structure data type has not yet been declared at this moment. The structure data type of resume is thus called a forward-referencing structure data type.

The referenced date structure data type is declared in lines 10_14. Then, I make two synonyms, RSM and DATE, to represent struct resume and struct date, respectively, in lines 16 and 17.

Because there are two pointers inside the resume structure data type that reference the date structure data type, I define and initialize two structures with DATE in lines 23_32. under and graduate are the names of the two structures.

Then, in lines 33_37, a structure, called new_employee, is defined with RSM and initialized with the addresses of the two structures, under and graduate (see lines 35 and 36). In this way, the forward-referencing structure new_employee is assigned with access to the contents of the two referenced structures, under and graduate.

The statement in line 40, which calls the InfoDisplay() function, prints out all the contents held by the new_employee structure, as well as that of the under and graduate structures.

Lines 45_56 give the definition of the InfoDisplay() function, from which you can see that the expressions, such as ptr->u->school and ptr->g->school, are used to reference the members in the under and graduate structures. Since ptr, u, and g are all pointers, two arrows (->) are used in the expressions.

In exercise 5, later in this hour, you'll be asked to rewrite the program in Listing 19.7 with an array of pointers to replace the two pointers defined inside the forward-referencing structure of resume.

WARNING

    Don't include forward references in a typedef statement. It's not legal in C.

Related Items

মডুলার C প্রোগ্রামিং (Modular C Programming)

কেবল মাত্র একটি ফাংশন দিয়ে কোনো বড়ো জটিল সমস্যা সমাধানের চেষ্টা করা ভাল প্রোগ্রামিংয়ের পদ্ধতি নয়। সঠিক পদ্ধতি হ'ল সমস্যাটিকে কয়েকটি ছোট ছোট এবং সরল টুকরো করে ফেলা যাতে তা আরও বিশদে বোঝা যায় । তারপরে এই ছোট এবং সরল সমস্যাগুলি সমাধান করার জন্য ছোট ছোট ফাংশন ব্লক তৈরি করা এবং পরে সেগুলি নিয়মানুযায়ী সংযোজিত করা ।

Programming Style

Programming Style

In this section, I'd like to briefly highlight some points that will help you write clean programs that can easily be read, understood, and maintained.

Exercises : Answer the following Question

To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish the exercises provided in the Workshop before you move to the next lesson.

Question and Answer

    Q Is the C preprocessor part of the C compiler?

    A No. The C preprocessor is not part of the C compiler. With its own line-oriented grammar and syntax, the C preprocessor runs before the compiler in order to handle named constants, macros, and inclusion of files.

Compiling Your Code Under Conditions

Compiling Your Code Under Conditions

You can select portions of your C program that you want to compile by using a set of preprocessor directives. This is useful, especially when you're testing a piece of new code or debugging a portion of code.