Structures

A structure is a data type that can contain unlimited numbers of NAMED sub categories (or fields). For example, a student record may contain the students, name, age, gpa, etc. Each category of information is defined by its name and type (e.g., name is a string, age is an integer). By placing all this information into a "structure" the computer is able to utilize it as a single "entity". In C, the fields and types must be defined before the structure is used.

Structures

Structures are very similar to Matlab, but must (like every other TYPE in C) be predefined.

A structure type is the Name of a "grouping" of related pieces of "named" information about a single entity.

The Syntax to DECLARE a structure TYPE is:

        
        struct TYPE_NAME
        {
          TYPE_1   field_1_name;
          TYPE_2   field_2_name;
          TYPE_3   field_3_name[100]; //  an array of 'TYPE_3'
        };

        //  WARNING!!! don't forget the ;
        
      

Here is an actual structure:

        
        struct Student
        {
          char     name[100]; //  string of up to 100 characters
          int      age;       // name of field is "age". type is "int"
          float    gpa;       // name of field is "gpa". type is "float"
        };
        
      

Remember, when creating a structure, every "field" (the named sub-categories) must have a type!

Using a Structure

Once a structure has been defined, it can be used any place a standard TYPE can be used. Again, consider the structure Student defined above. To create it we use:

        
        Student student_1; // here we declare a single variable
                           //  of type "Student".  The name of the variable is "student_1"

        Student students[100]; // here we declare an array of students
                               //  of type "Array of Student".  The name: "students"
        
      

Here is an example Program

        
       int
       main()
       {
         Student the_student;  // declare a variable

         the_student.age = 5;
         sprintf(the_student.name, "Jim"); // remember the_student.anme = "jim"
                                           // does not work.
         the_student.gpa = 3.32;

         print_student(the_student);
         
         the_student = improve_gpa_of(the_student); // Note: we can return
                                                    // structures from functions.
       }
        
      

Remember, the type "Student" must be declared either at the top of the .C file, or in a special .h (header) file.


Example Program 2

Lets write a program to represent fractions in C.

  1. First we define the structure type in fractions.h

                
                struct Fraction
                {
                  int numer; // fields         
                  int denom; 
                };
                
              
  2. Then we define prototypes for all the functions we will write (still in fractions.h)

                
                void     print_fraction(Fraction f);               // prototypes
                Fraction add_fractions(Fraction f1, Fraction f2);
                Fraction simplify_fraction(Fraction fraction);
                
              

    Notice the use of the Fraction key word which because of the structure defintion above is a valid TYPE for C.

  3. Now we start writing the fractions.C file with our actual code.

    First we comment and then include fractions.h

                
    
               /*
                * Author: H. James de St. Germain
                * Date:   Spring 2007
                *
                *
                * This file contains the fraction library code, including:
                *
                *  add_fractions
                *  print_fraction
                *  simplify_fraction
                *
                */
    
                #include <stdio.h>
                #include "fractions.h"
                
    
              
  4. The first function is add_fractions .

                
    
    /*
     * Given two fractions, add them and return the result
     *
     * Inputs: f1, f2 (both fractions)
     * Output: fraction (the result of adding f1 and f2)
     *
     */
    
    Fraction
    add_fractions(Fraction f1, Fraction f2)
    {
      Fraction result;
    
      if (f1.denom == f2.denom)
        {
          result.numer = f1.numer + f2.numer;
          result.denom = f1.denom;
          return result;
        }
    
    
      // Questionable code
      result.numer = f1.numer + f2.numer;
      result.denom = f1.denom + f2.denom;
    
      return result;   // Can return structures!!!
    }
                
              
  5. Perhaps the most difficult function to write is "simplify_fraction".

    The algorithm we need is: 1) find the greatest common divisor of the numerator and denominator. Then 2) create a new fraction that is equal to the old fraction divided by the GCD. 3) return this result.

    Thus first we need to write a function to find the greatest common divisor of two numbers.

                
    /**
     * Find the greatest common divisor between two number
     *
     * Return either the GCD, or 0 meaning there is no greatest common divisor
     */
    int
    greatest_common_divisor( int number_1, int number_2 )
    {
      int gcd = number_1;
      
      if ( gcd > number_2 )  // assume the GCD starts at the smallest of the two numbers
        {
          gcd = number_2;
        }
    
      while ( gcd > 0 )
        {
          if ( number_1 % gcd == 0 && number_2 % gdc == 0)
            {
              return gcd;
            }
    
          gcd--;
        }
    
      return 0; // no solution
      
    }
                
              

    Once we have that function we can use it to simplify a fraction.

                
                
    
    /*
     * Simplify a fraction
     *
     * Inputs: f1 (a fractions)
     * Output: f1 in simplified form (still a fraction)
     *
     * Note: this only works with positive fractions
     */
    
    Fraction
    simplify_fraction( const Fraction frac )
    {
      // Declare and Initialize the result
      Fraction result = frac;  // notice that assignment words for structures
      
      // find the GCD
      int gcd = greatest_common_divisor( frac.numer, frac.denom );
      
      while ( gcd != 0 )  // while a GCD exists
        {
          result.numer /= gcd;  // divide both the numerator and denominator
          result.denom /= gcd;  //  by the GCD
    
          gcd = greatest_common_divisor( result.numer, result.denom ); // check for a new GCD
    
        }
    
      return result;  // you can return a fraction because it is a structure
      
    }
                
              

Back to Topics List