structs and unions


structs

Struct syntax

Storing/access to struct fields

Example: student records

#include <cstdio>
#include <cstring>

const int Size = 81;
typedef char text[Size];

struct StudentRecord {
   long int studentnumber;
   text surname, givenname;
   float  fees;
} ;

int main()
{
   StudentRecord  student1, student2;
   
   printf("Enter your student number\n");
   scanf("%ld", &(student1.studentnumber));

   printf("Enter your surname (family name)\n");
   fgets(student1.surname, Size-1, stdin);

   printf("Enter your given name\n");
   fgets(student1.givenname, Size-1, stdin);

   printf("Enter your fees owed\n");
   scanf("%f", &(student1.fees));

   // copy student1 to student2
   student2.studentnumber = student1.studentnumber;
   strcpy(student2.surname, student1.surname);
   strcpy(student2.givenname, student1.givenname);
   student2.fees = student1.fees;

   // print out student 2
   printf("%ld: ", student2.studentnumber);
   printf("%s %s", student2.givenname, student2.surname);
   printf("%f\n", student2.fees);
}

Arrays and structs

Heirarchical structs

Example: class list

const int MaxClassSize = 300;
const int StringSize = 81;
typedef char text[StringSize];

struct StudentRecord {
   int studentnumber;
   text surname, givenname;
   float fees;
   float tutorialmarks[12];
} ;

struct Subject {
   text subjectname;
   text lecturer;
   int year;
   int numstudents;
   StudentRecord students[MaxClassSize];
} ;

int main()
{
   Subject csci160;
  
   // initialise subject
   strcpy(csci160.subjectname, "Intro to Computer Science");
   strcpy(csci160.lecturer, "Wessels");
   csci160.year = 1998;
   csci160.numstudents = 120;

   // initialise each student in the subject
   for (int indx = 0; indx < csci160.numstudents; indx++) {
       csci160.students[indx].studentnumber = 0;
       csci160.students[indx].fees = 0.0;
       strcpy(csci160.students[indx].surname, " ");
       strcpy(csci160.students[indx].givenname, " ");

       // initialise each tutorial mark for the student
       for (int tut = 0; tut < 12; tut++) {
            csci160.students[index].tutorialmarks[tut] = 0.0;
       }
   }
}

Structs as parameters

Unions

Unions and structs

Enumerated types

Often it is useful to create a data type whose value is any one of a fixed set of things, e.g.

C++ allows us to define these as enumerated types, and use the named list of values within a program:

enum WeekDay {
   Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
} ;

int main()
{
   Weekday day1, day2;
   day1 = Wednesday;
   if ((day1 != Saturday) && (day1 != Sunday)) 
      printf("The day is not a weekend...\n");
}
Internally, the values are stored as integers 0, 1, ...etc.
In the WeekDay example, Sunday == 0, Monday == 1, Tuesday == 2, etc, so the following two statements would be functionally equivalent:
day1 = Tuesday;
day1 = 2;
We can explicitly declare which integer values we want to equate to which enumerated types:
enum MonthName {
   January = 1, February = 2, March = 3, ...
} ;
Example: showing enumerated types, passing structs by value, passing structs by reference, assigning one struct to another, and returning structs from functions.
#include <cstdio>

// set up an enumerated type for days of the week
// (will default to values 0..6)
enum DayType { 
  Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday 
} ;

// set up an enumerated type for months of the year
//   and assign integer values 1..12
//   (rather than the defaults, which would have been 0..11)
enum MonthType {
  January = 1, February = 2, March = 3, April = 4, 
  May = 5, June = 6, July = 7, August = 8,
  September = 9, October = 10, November = 11, December = 12
} ;

// set up a struct that stores a date as the
//     day of the week (0-6 or Sunday-Saturday),
//     month (1-12 or January-December),
//     date (any int, no range checking here),
//     year (any int, again no range checking)
struct DateType {
   DayType day;
   MonthType month ;
   int date;
   int year;
} ;
 
// demonstrate that a function can return an entire struct
DateType GetDate(DateType d)
{
   return d;
}

// demonstrate pass-by-reference on a struct
void setdate(DateType& d)
{
   d.day = Wednesday;
   d.month = November;
   d.date = 22;
   d.year = 2000;
}
  
// demonstrate pass-by-value on a struct
void printdate(DateType d)
{
   switch (d.day) {
      case 0: printf("Sunday, "); break;
      case 1: printf("Monday, "); break;
      case 2: printf("Tuesday, "); break;
      case 3: printf("Wednesday, "); break;
      case 4: printf("Thursday, "); break;
      case 5: printf("Friday, "); break;
      case 6: printf("Saturday, "); break;
   }
   switch(d.month) {
      case 0: printf( "January %d, %d\n", d.date, d.year);  
      case 1: printf( "February %d, %d\n", d.date, d.year);  
      case 2: printf( "March %d, %d\n", d.date, d.year);  
      case 3: printf( "April %d, %d\n", d.date, d.year);   
      case 4: printf( "May %d, %d\n", d.date, d.year);  
      case 5: printf( "June %d, %d\n", d.date, d.year);  
      case 6: printf( "July %d, %d\n", d.date, d.year);   
      case 7: printf( "August %d, %d\n", d.date, d.year);  
      case 8: printf( "September %d, %d\n", d.date, d.year);
      case 9: printf( "October %d, %d\n", d.date, d.year);  
      case 10: printf( "November %d, %d\n", d.date, d.year); 
      case 11: printf( "December %d, %d\n", d.date, d.year);  
   }
}

// create three dates and experiment with function calls
int main()
{
   DateType day1, day2, day3;
   setdate(day1);
   printdate(day1); 
   day2 = GetDate(day1);
   printdate(day2); 
   day3 = day1;
   printdate(day3);
}

The output from this program will be
Wednesday, November 22, 2000
Wednesday, November 22, 2000
Wednesday, November 22, 2000