C++ Ripped Apart :: Section 8
Author: Mike Ware
Website: [warebiz] :: "The Programmer's Domain" - http://warebiz.tripod.com
Email: warebiz@yahoo.com
Copyright © 2003 Michael Shawn Ware, All Rights Reserved.


You are here --> [Section 8 :: User-Defined Types, Header Files, and Graphics Intro]

"Jump To Articles"
    --> Structures
    --> Enumerated Data Types
    --> Introduction To Graphics
    --> Creating User-Defined Header Files


Structures

A structure in C++ is similar to a record in Ada, Pascal, QBasic, and some other programming languages. A structure, like an array, is a collection of values but structures are different from arrays in that the values stored in an structure may be of different types, and a structure's stored values, called members, are individually named and typed, just like "ordinary" variables. In other words, a structure is a collection of related elements, possibly of different types, having a single referencing name. Each element (member) in a structure is called a field of the structure. All elements or data specified in a structure should be related to one object. Each element in a structure can be individually accessed by using the "dot" ( . ) operator.

The form for declaring a structure type is:


    struct type-id
    {
        type1 member1-name;
        type2 member2-name;
        type3 member3-name;
        .
        .
        typeN memberN-name;
    };


NOTE: The semi-colon placed after the closing bracket is required. The proper placement of a structure type is at the beginning of a program in the global area before the main ( ) function or in a user-defined header file.

The above structure type would create a data type, not a variable. To declare of variable of this type, simply declare it as follows:


    type-id var-id;

Suppose we need to store the following data for a student:


    id #
    name
    grade
    gpa

We could create a structure type to handle this situation as follows:


    const int nameLen = 25;

    struct tStudent
    {
    	int idNumber;
    	char name[nameLen];
    	char grade;
    	float gpa;
    };

To declare two variables of this type, simply:


    tStudent stu1, stu2;

We can then give values to each individual member as follows ( string.h required for strncpy ):


    stu1.idNumber = 111;
    strncpy(stu1.name, "studentname", nameLen);
    stu1.grade = 'A';
    stu1.gpa = 4.0;

You are allowed, but not advised, to combine a structure specifier with the declaration of a variable of that structure type. For example:


    const int nameLen = 25;

    struct tStudent
    {
    	int idNumber;
    	char name[nameLen];
    	char grade;
    	float gpa;
    } thisStudent;

This can be used instead of creating a structure type and then declaring a variable; in this case, thisStudent would be immediately associated with the structure type. Obviously, this is not recommended because there would be no way to declare multiple variables of that particular structure type. You can also initialize structures at compile time just like you can arrays. For example, with the earlier tStudent structure type, we could use:


    tStudent stu1 = { 111, "studentname", 'a', 4.0 };

Unlike arrays, you can directly assign one structure variable the value of another structure that is of the same type. For example, if we had another variable declared tStudent thisStu, we could simply use the assignment operator to assign thisStu the value of stu1:


    thisStu = stu1;

The above assignment statement would perform a data member by data member copy of stu1 to thisStu. You can also declare an array of structure types and are allowed to give structure types arrays as individual members (we actually have already done this with strings). For example:


    struct STUDENT
    {
        int idNum;
        int testScores[10];
        int finalExam;
    };

    STUDENT classStu[50];

In the above structure type, testScores[] is an array that holds ten values. classStu[] is an array that holds 50 STUDENT structure types. We can access and manipulate the contents of each element in the classStu[] array much like we do ordinary arrays. For example:


    classStu[5].testScores[1] = 88;

The above statement would assign the second test score of the sixth element in classStu[] a value of 88.

Structure Example:
The following program acts as a computerized ordering system for an automobile part store. Study the code before reading further in the tutorial.


//////////////////////////////////////// USING DEV C/C++ V.4 COMPILER /////////////////////////////////////////

#include <iostream.h>
#include <stdlib.h>
#include <iomanip.h>

struct tAutoPart
{
      int partNumber;
      int idNumber;
      double retailPrice;
      double wholesalePrice;
};

int main()
{
      int MAXORDERSIZE;

      cout << "Enter how many parts are to be ordered: ";
      cin >> MAXORDERSIZE;
      cout << endl;

      tAutoPart partOrder[MAXORDERSIZE];

      for (int k = 0; k < MAXORDERSIZE; k++)
      {
            cout << "Enter the part number for order " << k+1 << ": ";
            cin >> partOrder[k].partNumber;
            cout << "Enter the identification number for order " << k+1 << ": ";
            cin >> partOrder[k].idNumber;
            cout << "Enter the retail price for order " << k+1 << ": ";
            cin >> partOrder[k].retailPrice;
            cout << "Enter the wholesale price for order " << k+1 << ": ";
            cin >> partOrder[k].wholesalePrice;
            cout << endl;
      }

      cout << endl << endl;
      cout << "COMPLETE ORDER" << endl;
      cout << setfill('-') << setw(60) << "-" << setfill(' ') << endl;
      for (int j = 0; j < MAXORDERSIZE; j++)
      {
            cout << "Order " << j+1 << " --> ";
            cout << "Part Number: " << partOrder[j].partNumber << endl;
            cout << setw(12) << " " << "ID Number: " << partOrder[j].idNumber << endl;
            cout << setw(12) << " " << "Retail Price: $" << partOrder[j].retailPrice << endl;
            cout << setw(12) << " " << "Wholesale Price: $" << partOrder[j].wholesalePrice << endl << endl;
            cout << setfill('-') << setw(60) << "-" << setfill(' ') << endl << endl;
      }

      cout << endl << endl << endl;

      system("PAUSE");
      return EXIT_SUCCESS;
}

//////////////////////////////////////// USING DEV C/C++ V.4 COMPILER /////////////////////////////////////////

We can now move on to our next topic: enumerated data types, which simply allow programmers to give descriptive names to integers. Read on for more...

Enumerated Data Types

Enum is derived from the integer type and therefore enumerated data types are integral in nature. Each integer value is given an identifier called an enumeration constant. In other words, it allows programmers to give names (labels) to some particular list of integers. The purpose is to assign names to integers, which in turn makes more readable code. There are two forms: the enumerated constant and the enumerated type. The form of a enumerated constant is as follows:


    enum { enumeration constants };

The form of a enumeration type is as follows:


    enum type_name { enumeration constants };
    type_name var_name;

The list of constants is usually given a number of 0, 1, 2, 3, etc. By default, C++ assigns a value of 0 to the first constant and then equates each enumerated constant to the next higher integral number, which means you can initialize a constant to whatever integer value you choose. For example,


    enum tWeekDays { sunday, monday, tuesday, wednesday, thursday, friday, saturday };

would assign sunday = 0, monday = 1, tuesday = 2, and so on. However, you could also do something like this:


    enum tFruits { lemon, orange = 5, grape, apple = 4, pear, peach};

This would assign lemon = 0, orange = 5, grape = 6, apple = 4, pear = 5, and peach = 6. Consider the output from the following section of code:


    tFruits fruit;
    fruit = orange;
    cout << fruit << endl;
    fruit = pear;
    cout << fruit << endl;
    cout << ++fruit << endl;


This would produce:


    5
    5
    6

Enumerated data types are commonly used with switch statements. Since switch statements are also integral in nature, you could use the enumerated constant of a enum type as a switch "case" or "cases" in a switch statement. If you are not familiar with switch statements, [see Switch Statements (section 2)]. For example, consider the following switch statement:


    enum tWeekDays { sunday, monday, tuesday, wednesday, thursday, friday, saturday };

    tWeekDays dayOfWeek;
    .
    .
    .
    switch (dayOfWeek)
    {
        case sunday:
            cout << "Today is Sunday." << endl;
            break;
        case monday:
            cout << "Today is Monday." << endl;
            break;
        case tuesday:
            cout << "Today is Tuesday." << endl;
            break;
        case wednesday:
            cout << "Today is Wednesday." << endl;
            break;
        case thursday:
            cout << "Today is Thursday." << endl;
            break;
        case friday:
            cout << "Today is Friday." << endl;
            break;
        case saturday:
            cout << "Today is Saturday." << endl;
            break;
    }


The next section is an introduction to graphics. Read on for more...

Introduction To Graphics

Graphics is obviously a very important aspect of programming. A substantial amount of programs have some form of graphical interaction or GUI (graphical user interface). There is a need for graphical programs not only for visual appeal, but also in order to provide easy program interaction and execution when being operated by non-technical people. In this tutorial, I will only cover a few topics. It is important to note that everything I explain is geared toward Dev C/C++ V.4 compiler. I've found from my experiences that compilers are particularly different on how they set up their graphics functions so if you are using a different compiler, don't be surprised if these functions do not work for you. To make the Dev C/C++ V.4 compiler "recognize" the graphics function, you must first go to the options menu, choose "compiler options", and check the box which says "Add the following commands when calling compiler". Place the following in the input box:


    -lbgi -lgdi32

bgi in the above code stands for Borland Graphics Interface and gdi stands for graphical device interface (32 bit). The value of -l preceding the two commands most likely stands for link which tells the compiler to link or load these functions during compilation of a program. Why are we using Borland Graphics Interface? In order to let the DEV compiler incorporate graphics, a programmer a few years back created code based on Borland's graphical interface which would be compatible with DEV's compiler. Very slick programmer.

The Borland Graphics Interface (BGI) library of functions use the following coordinate system:

    Top-Left of window : (0, 0)
    Top-Right of window : (maxX, 0)
    Bottom-Left of window : (0, maxY)
    Bottom-Right of window : (maxX, maxY)

In "normal" VGA mode, maxX is 639 and maxY is 479 which provides for a (640 X 480) screen resolution. You must also specify the following #include statements when using graphics in a program:


    #include <stdlib.h>
    #include <winbgim.h>

The following is code which can be used as a graphics setup program when you need to begin coding a new graphics program. The purpose of the code is to initialize the graphics functions and make sure no errors were encountered during initialization. Instead of having to type the code in everytime you want to create a graphics program, you can save this and open it when you need it:


///////////////////////////////////////// USING DEV C/C++ V.4 COMPILER////////////////////////////////////////

#include <iostream.h>
#include <stdlib.h>
#include <winbgim.h>

int main()
{
      int graphDriver, graphMode, errorCode;

      // initialize graphic functions
      graphDriver = DETECT; // detects highest resolution possible (640 x 480)
      initgraph(&graphDriver, &graphMode, "");
      errorCode = graphresult();
      if (errorCode != grOk)
      {
            cout << "Error initializing graphics." << endl
                 << grapherrormsg(errorCode) << endl;
      }
      else
      {
            // begin creating graphics

      }
      getch();
      closegraph();
}

///////////////////////////////////////// USING DEV C/C++ V.4 COMPILER////////////////////////////////////////

I will begin by describing certain BGI functions that you can use in your programs.


    getmaxx( );
    getmaxy( );

These functions return the maximum pixel coordinates in the horizontal and vertical directions, respectively. So, ( getmaxx( ), getmaxy( ) ) refers to the lower right corner of the graphics window.


    getmaxcolor( )


This function returns the largest available color number. For example, consider the following segment of code which displays 3500 "random" pixels in the graphics window:


// initialize graphics first

int xMax = getmaxx();
int yMax = getmaxy();
int maxColor = getmaxcolor();
int pixel, x, y;

// seed random generator
srand((unsigned)time(NULL));

for (pixel = 0; pixel < 3500; pixel++)
{
     x = rand() % (xMax + 1);
     y = rand() % (yMax + 1);
     color = rand() % (maxColor + 1); // randon pixel color value
     putpixel(x,y,color);
     delay(15);
}

getch();
closegraph();


The     setviewport( )     function allows you to limit the drawing done to a specified rectangular portion of the graphics window. For example, consider the following code:


    setviewport(50, 100, 350, 300, 1);
    setcolor(WHITE);
    rectangle(0, 0, 299, 199);
    setcolor(RED);
    line(25, 50, 425, 50);

This would draw a white rectangle around the viewport coordinates and a red line from (25,50) to (299,50) in viewport coordinates or from (75,150) to (350,150) in absolute coordinates. After a viewport is defined, all coordinates used will be relative to the viewport settings. The following describes the functions used in the above code:

setviewport( x1,y1,x2,y2,1 )
    --> (x1,y1) = top left coordinate of viewport; (x2,y2) = bottom right coordinate of viewport; 1 = clipping is turned on (could also be 0 = clipping turned off)

setcolor( color )
    --> where color is a constant or value describing the color of choice. Not sure on this but I believe there are 16 possible colors.

rectangle( x1,y1,x2,y2 )
    --> (x1,y1) top left coordinate of rectangle; (x2,y2) bottom right coordinate of rectangle;

line( x1,y1,x2,y2 )
    --> (x1,y1) starting coordinate of line; (x2,y2) ending coordinate of line;

In order to clear all or part of the graphics window (display), you can use the following functions:

cleardevice( )
    --> clears the entire graphics window

clearviewport( )
    --> clears the currently active viewport

Lines
The following functions may be used to draw lines:

line( x1, y1, x2, y2 )
    --> draws a line from (x1, y1) to (x2, y2)

moveto( x,y )
    --> changes the current position to (x, y)

lineto( x,y )
    --> draws a line in the current style and color from the current position to the specified position (x,y) and also sets the current position to (x,y)

linerel( dX, dY )
    --> draws a line from the current position (CP) to (CP + dX, CP + dY)

moverel( dX, dY )
    --> changes the current position (CP) to (CP + dX, CP + dY)

Customizing Lines
By default, all lines are drawn using a solid line style, one pixel thick. You can change these settings by using the     setlinestyle( )     function, which has three parameters:

    1) int linestyle : can have one of the following values [ SOLID_LINE (0), DOTTED_LINE (1), CENTER_LINE (2), DASHED_LINE (3), USERBIT_LINE (4) ] (there are more than 5 linestyles; check compiler documentation).

    2) unsigned upattern : allows for a 16-bit user defined pattern; this value will be ignored if linestyle is not equal to 4.

    3) int thickness : can have one of the following values [ NORM_WIDTH (1) or THICK_WIDTH (3) ]

NOTE: When creating USERBIT_LINES, consider the following:

    if upattern = 0xAAAA, then every other pixel is "on"
    if upattern = 0xCCCC, then 2 on, 2 off, 2 on, 2 off, etc.

Remember that upattern must be created using a 16-bit pattern, which is basically evaluated at the binary level. 'A' in binary = 1010, 'C' in binary = 1100. NOTE: 1 means "turned on"; 0 means "turned off"

The setlinestyle( ) function has the following form:


    setlinestyle( int linestyle, unsigned pattern, int thickness );

For example, to set the linestyle to a dotted line format with thick width, use the following:


    setlinestyle( DASHED_LINE, 0, THICK_WIDTH );

Rectangles
The rectangle( ) function accepts four parameters: left, top, right, bottom. These parameters specify the upper left and bottom right corners of the rectangle to be drawn.


    rectangle( left, top, right, bottom );
    EX: rectangle( 0, 0, 100, 50 );

Circles
The circle( ) function accepts three parameters: xCenter, yCenter, radius. This is used to draw a circle with the center point being (xCenter, yCenter) and radius of radius.


    circle( xCenter, yCenter, radius );
    circle( 50, 50, 10 );

The rectangle( ) and circle( ) functions draw only the perimeter (outline) of the specified objects. This means that the objects are not filled with color when displayed. One way to fill an object or any closed region is to use the following function:


    floodfill( x, y, borderColor )

The floodfill( ) function has three parameters: the point (x, y), called the seed point, can be any point that is located inside the region to be filled; the borderColor value specifies the color of the border of the region to be filled --> filling will stop when borderColor is reached. The floodfill( ) function can possibly "leak" or "spill" outside the region, perhaps filling the entire graphics window, if the (x, y) point selected is inside a non-closed region.

There are also two other "fill" functions, which draw and fill an object simultaneously:


    fillellipse( xCenter, yCenter, xRadius, yRadius );

The fillellipse( ) function has four parameters: (xCenter, yCenter) specifies the center point of the ellipse; xRadius specifies the horizontal radius; yRadius specifies the vertical radius.


    fillpoly( numPoints, polyPoints );

The fillpoly( ) function and corresponding drawpoly( ) function have two parameters: polyPoints should be an array containing the points of the polygon (must pass the first point in again as the last point in the polygon); numPoints specifies how many actual points are in polyPoints. The following shows an example:


    int polyPoints[] = { 3, 5, 25, 33, 250, 76, 123, 123, 3, 5 };
    drawpoly(5, polyPoints);

Drawing ellipses involves using the following function:


    ellipse( x, y, startAngle, endAngle, xRadius, yRadius );

The ellipse( ) function has six parameters: the point (x, y) is the center point of the ellipse; using a startAngle and endAngle other than 0 and 360 allows you to draw a certain sector or portion of an ellipse; xRadius and yRadius are self-explanatory.

Specifying Colors
If you want to change or specify the color and/or pattern used for filling objects and regions, you can use the following function:


    setfillstyle( int pattern, int color );

NOTE: setcolor( ) will specify the color used for the border of objects and normal drawing functions; setfillstyle( ) specifies the color to be used for the interior of objects.

There are 13 different patterns defined for the pattern of filling, including:

    EMPTY_FILL (0)
    SOLID_FILL (1)
    SLASH_FILL (4)
    BK_SLASH_FILL (5)
    HATCH_FILL (7)
    XHATCH_FILL (8)

The following section of code will draw a rectangle with a border of white and interior of red:


setcolor(WHITE);
rectangle(20,20,120,100);
setfillstyle(SOLID_FILL, RED);
floodfill(21,21, WHITE);

Displaying Graphical Text
Text can be displayed on the graphics window using the following functions:


    outtext( string );
    outtextxy( x, y, string );

The outtext( ) function displays the given string using the font, direction, and the size set by the function     settextstyle( )    , which has three parameters; int font, int direction, and int size (1 - 10);


    settextstyle( int font, int direction, int size );
    DEFAULT: settextstyle( 0, 0, 1 );

Direction may be one of the following: HORIZ_DIR (0) or VERT_DIR (1)

You can use the default values, but the displayed text will be practically unreadable. You should experiment with various settings to see which values you prefer and looks best.

By default, outtext( ) positions the text such that the upper left corner of the first character is in the current position. outtextxy( ) is similar to outtext( ) except the upper left corner of the first character is in (x, y).

You can use     settextjustify( )     to control the horizontal and vertical position of the text relative to the current position or (x, y). It requires two parameters: horizontal and vertical with the following form:

    settextjustify( int horizontal, int vertical );

The horizontal parameter may be:

    LEFT_TEXT (0)
    CENTER_TEXT (1)
    RIGHT_TEXT (2)

The horizontal parameter determines whether the text starts at the current position, is centered at the current position, or ends at the current position.

The vertical parameter may be:

    BOTTOM_TEXT (0)
    CENTER_TEXT (1)
    TOP_TEXT (2)

The vertical parameter determines whether the text is displayed above the current position, centered at the current position, or below the current position. The default values of text justification are LEFT_TEXT and TOP_TEXT.

This wraps up all I have to say concerning graphics. The best way to become familiar with graphics is by experimenting with the functions covered until you have a firm grip on them. If you would like to view all possible graphics functions, explore the winbgim.h header file. The next section shows how to create header files. Read on for more...

Creating User-Defined Header Files

It is important to note that I am using Dev C/C++ V.4 as the compiler for all information depicted in this tutorial. Let me start this topic off by first explaining what a header file actually is. Everytime you write a program, you have to specify certain #include statements at the beginning of the program. Why is this? Basically, the #include statement is actually a link to a header file containing pre-defined elements that you will need to use for successful execution of the program. Header files are created so you can use the code contained in them in multiple programs without having to write the code everytime you want to use it in a program. It is all pre-defined in a separate header file so all you have to do is "include" it in a program that needs to use its routines or contents.

Consider the iostream.h header file. Load your compiler and open iostream.h. Peek at what it contains. Do you understand it? Probably not at this point, but you should be able to recognize certain function calls and declarations. What you see is actually code used to define the standard input/output streams. By using this header file in your programs, you have access to the input/output streams. Without this convenient header file, if you wanted to have access to the input/output streams, you would first have to define them. Very tedious and time consuming not to mention the extra effort of learning how to define them.

A user-defined header file is a header file that you, as the programmer, created. --> iostream.h and all other header files which are "included" using angle brackets are pre-defined and are provided for by the developers of the Dev C/C++ V.4 compiler. For example, #include <time.h> and #include <winbgim.h> (notice the brackets). When you create a header file, which I describe below, and "include" it in your program, you will use quotes instead of brackets. For example, suppose guess.h is a header file that you created for a program. You can include this header file in your program by using: #include "guess.h".

User-defined header files are used to define constants, user-defined types, and to list function prototypes to be used in a main file. NOTE: header files do not include function definitions --> they will normally be placed in a separate "auxiliary" source file that will have a (.cpp) extension. Also note that you shouldn't compile header files individually. The header files will be compiled when you compile the actual program which tries to link to it. Also, when you compile the actual program, the only elements in the header file which will be compiled are the elements in which the program will need to use.

The following explains how to create a header file using Dev-C++ V.4 compiler:

First, open a new document and clear it. Next, enter the following information (the elements are described further below):


    #ifndef __NAMEOFHEADER_H
       #define __NAMEOFHEADER_H

    // place constants here

    // place user-defined types here

    // place function prototypes here

    #endif

Notice the (#) symbol preceding commands in the above file. Anytime the (#) symbol is used, it is associated with the compiler directories. It tells the compiler to do something as in turning on/off some compiler setting. It is not an executable statement. It only functions during compilation. NOTE: in the above code, NAMEOFHEADER is the name of the header file; this name can be anything you want it to be, but it should be descriptive and reflect its contents.

The     #ifndef     command can be read as "if not defined" which means it checks to see if a given symbol is defined or not. If the symbol is not defined, compilation will move into the body of the header file and do necessary definitions. If the symbol is defined, the header fill will not need to perform the definitions. The     #define     is only performed if     #ifndef     returns a value of true, which means the symbol is not defined.     #define     literally does what it reads: it defines the elements contained in the header file for use in the program which called upon it. Basically, these two commands, especially     #ifndef    , gaurd against re-declaration errors if the header file is included in the calling program more than once. In a single application, you may be using multiple source files, and it is possible that more than one of the source files may try to #include the same header file.

Generally speaking, when you create a header file that contains the constants and prototypes for a program, you will also want to create an auxiliary file (will have a .cpp extension) that holds all of the function definitions to be used in the program. This means that the only function in the main program will be the main() function. The question may arise as to how the compiler will know how to link the auxiliary file to the actual main program file. This can be done through the use of a project file. It is important to note that the main program file, which contains the main() function, and the auxiliary file, which contains the function definitions, both have to include the user-defined header file and also any other compiler directives they use. When you include a user-defined header file, you have to use double quotes instead of using brackets. The brackets tell the compiler that it is dealing with pre-defined include files and the quotes tell the compiler it is dealing with a user-defined header file. For example, if I create a header file called myHeader.h, I can include it by using #include "myHeader.h".

Creating Project Files
In order for you to successfully link all of your source files (main file and auxiliary file), you will have to create a project and place the files in it. Project files are used to "tie together" multiple source files into a single executable application or program. Creating a project is extremely easy. The following explains how to create a project using Dev C/C++ V.4 compiler:

If the individual source files already exist, which means you have already created them, click the file menu and select new project. For DOS level programs (probably what you want), at the next prompt select console application and make sure C++ project is selected. At the dialog box, enter a descriptive name for the project, which will be given an extension of .dev. It is important to note that none of the source files can have the same base name as the project file. The base name of project will be used as the name of the executable file that is created after successful compilation. Next go to the project menu and select add to project. At the open prompt, select all of the source files to be included in the program (NOTE: do not include the header file itself). Now, you should see an "outline" form of the project on the left side pane. Now, you need to go to the options menu and select Compiler Options. Select directories and place either an "x" or mark the "Add the directory below to be searched for include files..." and enter the full path to the user-defined header file that you created in the text box. This only needs to be done if you didn't place your user-defined header file in the default "include" directory under the Dev-C++ directories. Then, go to the execute menu and select rebuild all. Assuming there are no errors, the executable file should be created (.exe extension with the base project name).

If you have not created any project files, simplY choose to create a "New Unit for Project..." instead of "Add unit to project...".

The following are two source files and one user-defined header file you can use as an example of setting up a project. The program is written for Dev C/C++ V.4 compiler.


/////////////////////////////////////////    user-defined header file    /////////////////////////////////////

#ifndef __STUGRADES_H
   #define __STUGRADES_H

// initialize constants
const int possiblePoints = 300;
const int NAMELEN = 25;

// function prototypes
void getStudentInfo(char name[NAMELEN], int& points);
char calculateGrade(int points);
void displayResults(char name[NAMELEN], char grade);

#endif

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\   end of user-defined header file    \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

/////////////////////////////////////////        main source file        /////////////////////////////////////

// PURPOSE: Uses a user-defined header file to calculate a student's letter grade
//          based on three test scores. POSSIBLE POINTS = 300

// PROGRAMMER: Mike Ware
// DATE LAST UPDATED:

int main()
{
      char stuName[NAMELEN], grade;
      int earnedPoints = 0;

      getStudentInfo(stuName, earnedPoints);
      grade = calculateGrade(earnedPoints);
      displayResults(stuName, grade);

      system("PAUSE");
      return EXIT_SUCCESS;
}


\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\    end of main source file     \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

/////////////////////////////////////////     auxiliary source file      /////////////////////////////////////

// auxiliary file for main file --> contains the function definitions

#include <iostream.h>
#include <stdlib.h>
#include <iomanip.h>
#include "STUGRADES.H"

// get student name and total points earned for student
void getStudentInfo(char name[NAMELEN], int& points)
{
      int test1, test2, test3;

      cout << "Enter name of the student: ";
      cin.getline(name, NAMELEN);

      cout << "Enter student's earned points for test 1: ";
      cin >> test1;
      cout << "Enter student's earned points for test 2: ";
      cin >> test2;
      cout << "Enter student's earned points for test 3: ";
      cin >> test3;

      points = test1 + test2 + test3;
}// end getStudentInfo()

// calculate letter grade for student based on numerical earned points
char calculateGrade(int points)
{
      char letterGrade;
      int percentage = (points / float(possiblePoints)) * 100;

      if (percentage >= 90)
            letterGrade = 'A';
      else if (percentage >= 80)
            letterGrade = 'B';
      else if (percentage >= 70)
            letterGrade = 'C';
      else if (percentage >= 60)
            letterGrade = 'D';
      else
            letterGrade = 'F';

      return letterGrade;
}// end calculateGrade()

// display student name and letter grade
void displayResults(char name[NAMELEN], char grade)
{
      cout << endl << endl;
      cout << "STUDENT NAME: " << name << endl;
      cout << setw(45) << setfill('-') << "-" << setfill(' ') << endl;
      cout << setw(14) << "GRADE: " << grade << endl << endl;
}// end displayResults()

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\  end of auxillary source file  \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

In the next section, you will be introduced to object oriented programming and classes. Read on for more...

Move on to next section: [Section 9] - OOP => Classes and Related Topics

Back to Top