/***************************************************************************
 *  Columbia University Introduction to Computer Programming in C COMS 1003
 *  Structs, Unions, Bit Fields, Enums
 *
 *  Copyright (C) 2005 Michael E. Locasto
 *
 *  All rights reserved.
 *
 * $Id: advancedata.c,v 1.2 2005/10/14 18:06:35 locasto Exp $
 **************************************************************************/

#include <stdio.h>

/* Define a named enumeration type. */
enum months { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec };

/* illustrate an unamed enum with the ability to assign values, not just
 * take the default ones. 
 */
enum {FOO='c', BAR='z'};

/* Define a new type 'struct student' that groups some related fields in
 * one logical record. This declaration defines a template for the type
 * but no instances.
 */
struct student
{
   int id;
   char name[81];
   enum months birth_month;
};

/* define a new type 'student_t' that is of type 'struct student'*/
typedef struct student student_t;

/*
 * This is an anonymous struct, and it causes the following warning:
[michael@xoren code]$ make advancedata
gcc -Wall -g -o advancedata advancedata.c
advancedata.c:29: warning: unnamed struct/union that defines no instances 
 */
struct{
   int k;
};

/* An example of a union. It can only be one thing at a time. */
union pet
{
   int dog;
   char cat;
   float turtle;
};

/* Define a bit-field structure that simulates a 32-bit instruction. */
struct instruction
{
   unsigned int opcode : 6;
   unsigned int oper1  : 5;
   unsigned int oper2  : 5;
   unsigned int immediate : 16;
};

/* Create an array of student structs...*/
student_t students[56];

/* Define a variable that can hold an instance of the enum value. */
enum months year = Jul;

/**
 * Show how to access 'members' of a struct and use a case statement
 * to switch on the value of a member, using the fields of the enum
 * as the constant case values.
 * 
 */
int main(int argc, char* argv[])
{
   int i=0;
   for(i=0;i<56;i++)
   {
      students[i].id = i;
   }

   students[0].name[0] = 'M';
   students[0].name[1] = 'I';
   students[0].name[2] = 'K';
   students[0].name[3] = 'E';
   students[0].name[4] = '\0';
   students[0].birth_month = Mar;

   switch(students[0].birth_month)
   {
   case Jan : printf("Jan\n");
      break;
   case Feb : printf("Feb\n");
      break;
   case Mar : printf("Mar\n");
      break;
   case Apr : printf("Apr\n");
      break;
   case May : printf("May\n");
      break;
   case Jun : printf("Jun\n");
      break;
   case Jul : printf("Jul\n");
      break;
   case Aug : printf("Aug\n");
      break;
   case Sep : printf("Sep\n");
      break;
   case Oct : printf("Oct\n");
      break;
   case Nov : printf("Nov\n");
      break;
   case Dec : printf("Dec\n");
      break;
   default:
      printf("illegal month value\n");
      break;
   }

   return 0;
}
