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 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!
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"
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.
Lets write a program to represent fractions in C.
First we define the structure type in fractions.h
struct Fraction
{
int numer; // fields
int denom;
};
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.
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"
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!!!
}
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
}