Skip to content

Using Struct

Once we have created a new type into the program, we can now create a variable of that particular type. Additionally, structure types also provide a way to access the members using the dot (i.e., .) operator. This operator can also be used to update the values of the members if it is used as <lvalue> similar to array update.

Structure Variables

The syntax is the same as variable declaration. The only thing that changes is that now we have more possibilities for <data type>.

Structure Variables

Uninitialised Structure Variable
1
<data type> <variable name>;
Initialised Structure Variable
1
<data type> <variable name> = {expr, expr, expr, ...};

  1. The syntyax for initialisation (i.e., c{expr, expr, expr, ...}) is similar to array initialisation.
  2. Each expression during initialisation (i.e., c{expr, expr, expr, ...}) must match the type of the member based on the order of declaration.

Structure Declaration

StructInit.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
typedef struct {
  int stuNum;
  float score;
  char grade;
} result_t;
typedef struct {
  int day, month, year;
} date_t;
typedef struct {
  int cardNum;
  date_t expiryDate;
} card_t;
:
result_t result = { 123321, 93.5, 'A' };
card_t card = {888888, {31, 12, 2020}};

Accessing and Updating Members

We can access the members of a structure as well as updating the values using the dot operator.

Access and Update

Access
1
<variable name> . <member name>;
Update
1
<variable name> . <member name> = <expr>;

To access values from nested structure, we simply have to do it slowly. In particular, if <variable name>.<member name> results in another structure, then an additional .<member name> can be done. The associativity is left-to-right.

StructDot.c

StructDot.c
1
2
3
4
5
6
7
result_t result;
result.stuNum = 456654;
result.score  = 62.0;
result.grade  = 'D';

card_t card = { 666666, {30, 6} };
card.expiryDate.year = 2021;

Initialising, Update and Accessing

StructureEg1.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

typedef struct  {
  int stuNum;
  float score;
  char grade;
} result_t;

int main(void) {
  result_t result1 = { 123321, 93.5, 'A' }, // initialisation
           result2;                         // declaration

  result2.stuNum = 456654; // update
  result2.score = 62.0;    // update
  result2.grade = 'D';     // update

  printf("result1: stuNum = %d; score = %.1f; grade = %c\n", 
          result1.stuNum, result1.score, result1.grade); // access
  printf("result2: stuNum = %d; score = %.1f; grade = %c\n", 
          result2.stuNum, result2.score, result2.grade); // access
  return 0;
}

Input/Output

To initialise a structure using user input via keyboard, there are two general ways to do this. The first is the easiest. We simply read user input into some temporary variable first and then we initialise a structure using these variables. The second way is a shortcut of this through bypassing the creation of a temporary variable. To bypass the creation of the temporary variable, we simply pass the address of the member directly into scanf().

StructInput.c

StructInput.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>

typedef struct  {
  int stuNum;
  float score;
  char grade;
} result_t;

int main(void) {
  result_t result1;
  printf("Enter student number, score and grade: ");
  scanf("%d %f %c", &result1.stuNum, // integer
                    &result1.score,  // float
                    &result1.grade); // character

  printf("result1: stuNum = %d; score = %.1f; grade = %c\n", 
          result1.stuNum, result1.score, result1.grade); // access
  return 0;
}

Assignment

Unlike array, we can actually do assignment to a structure variable. This will copy the values of all the members from one to the other. Hence, it is similar to updating individual member.

Structure Assignment

StructAssign.c
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>

typedef struct  {
  int stuNum;
  float score;
  char grade;
} result_t;

int main(void) {
  result_t result1 = {123321, 93.5, 'A'},
           result2 = {456654, 63.0, 'D'};

  print("Before\n");
  printf("result1: stuNum = %d; score = %.1f; grade = %c\n", 
          result1.stuNum, result1.score, result1.grade); // access
  printf("result2: stuNum = %d; score = %.1f; grade = %c\n", 
          result2.stuNum, result2.score, result2.grade); // access

  result2 = result1;

  print("After\n");
  printf("result1: stuNum = %d; score = %.1f; grade = %c\n", 
          result1.stuNum, result1.score, result1.grade); // access
  printf("result2: stuNum = %d; score = %.1f; grade = %c\n", 
          result2.stuNum, result2.score, result2.grade); // access
  return 0;
}

Here, the assignment result2 = result1; is equivalent to the following:

Equivalent Statements
1
2
3
result2.stuNum = result1.stuNum;
result2.score  = result1.score;
result2.grade  = result1.grade;

One important thing to note is that this is copying so there is no aliasing. We can visualise what is happening as follows:

Struct Assignment

Address of Structures

Since a structure is treated like a normal variable, we can also get the address of the structure using the address operator (i.e., &). This will be used in a similar way as address of variable to allow a function to modify the content of a structure.