ES101 - Lesson 9 : Structures

From Embedded Systems Learning Academy
Jump to: navigation, search

Objective

You will learn how to create structures.

Structures can help you group information together. For example, if you wish to ask for student age, ID, and name, you can group this data into a single structure that represents one student.

Video Demonstration :

Type Define Structure

/* It is recommended to define your structure
 * before function declarations (outside main)
 */
typedef struct {   /* Syntax of struct type-define */
    int age;
    int id;        /* Put variables separated by semicolon */
    char name[32];
} student_t;       /* Name of the structure read as "student type" */

void main()
{
    /* Your main() code here */
}

Structure is declared using typedef struct. You enclose the "members" inside the curly braces. These members are then accessed using the dot operator as demonstrated below. The name of the structure, or "your variable type" appears after the closing } curly brace.

Declare and use structure

#include <stdio.h>


typedef struct {
    int age;
    int id;
    char name[32];
} student_t;


int main(void)
{
   /* One student declared */
   student_t student;

   /* Access the "members" of the struct using the "dot" . operator. */
   printf("Enter student name: "); scanf("%s", &student.name[0]);
   printf("Enter student age: ");  scanf("%i", &student.age);
   printf("Enter student id: ");   scanf("%i", &student.id);

   /* Declare 100 students */
   student_t students[100];
   for (int i=0; i<100; i++) {
       /* Ask for data for 100 students */
       printf("Enter ID of student #%i\n", (i+1));
 
       /* Access student array element by index, then the dot to access member */
       scanf("%i", &student[i].id);
   }
}

In this example, we declare one structure instance called "student", and then access the members using the dot operator. We can similarly declare array of students and access each member of the array using the [ ] (index) operator, followed by the dot operator.

Passing structure to a function

Structure(s) can be passed to a function just like a variable. It is recommended that you pass a pointer instead of a copy because passing a very large structure to a function as a copy can consume a lot of memory.

In the example below, we have a function that populates a single student information, and then return it. In the main() function, we then use this function to capture the returned structure into the array. This demonstrates one way to populate the student array, which "returns" the entire structure back that is copied (less efficient) into the array.

#include <stdio.h>


typedef struct {
    int age;
    int id;
    char name[32];
} student_t;

/* This function returns a structure back */
student_t get_student_info(void);

int main(void)
{
   /* Declare 100 students */
   student_t students[100];

   for (int i=0; i<100; i++) {
       students[i] = get_student_info();
   }
}

student_t get_student_info(void)
{
   student_t student;

   printf("Enter student name: "); scanf("%s", &student.name[0]);
   printf("Enter student age: ");  scanf("%i", &student.age);
   printf("Enter student id: ");   scanf("%i", &student.id);

   return student;
}


In this example, we use a pointer to the structure. Unlike a pointer to a variable, we have to access the members of the structure using the -> operator. This operator means "pointer to the member" of the structure. It is similar to using the dot operator. If we had used a non-pointer version and the dot operator, it would've only modified the "copy of the structure" rather than the "memory of the structure".

#include <stdio.h>

typedef struct {
    int age;
    int id;
    char name[32];
} student_t;

/* User will pass in the memory location of their structure.
 * We will directly store the information there
 */
void get_student_info(student_t *student);

int main(void)
{
   /* Declare 100 students */
   student_t students[100];

   /* This method is more efficient */
   for (int i=0; i<100; i++) {
       get_student_info(&student[i]);
   }
}

void get_student_info(student_t *student)
{
   /* Access the members of the structure using -> operator
    * because student is now a pointer.
    * No need to return anything because we directly modify
    * structure's memory since pointer tells us where it is.
    */
   printf("Enter student name: "); scanf("%s", &student->name[0]);
   printf("Enter student age: ");  scanf("%i", &student->age);
   printf("Enter student id: ");   scanf("%i", &student->id);
}


Summary

In the first example, the get_student_info() populates its internal structure and returns it. This returned structure is then copied into the student array. In the second example, the get_student_info() directly writes the memory of the given structure pointer, and hence large amount of structure data is not returned or copied therefore improving performance.

Assignment

  1. Declare a student structure that contains :
    • Student's first and last name
    • Student ID
  2. Create the following functions:
    • getStudentInfo(void)
      Declares a single student, uses printf()/scanf() to get input
      Returns the single student back
    • printStudentInfo(student_t *st_ptr)
      Takes the pointer to a student (to avoid making a copy)
      Prints out all of the student information
  3. Declare an array of five students
  4. Using a for loop and getStudentInfo() function, get input of all the students
  5. Using a for loop and printStudentInfo() function, print all the output of all students.