FUNCTIONS
and USING MENUS
C
Functions
|
Allow for the functional separation of a C program
into “logical modules.” |
|
Good Software Engineering |
|
The function “main” should be implemented as a
group of calls to functions that perform the bulk of the program’s work. |
|
Each function should be limited to performing
a single task. |
|
If you can’t choose a name for a function that
describes what it does then you may be trying to do to much with the single
function. |
|
Example: |
#include <stdio.h>
float Hours_worked(void);
float Pay_rate(void);
float Salary(float, float);
void Output(float);
main() {
float hours, rate,
check;
hours = Hours_worked();
rate = Pay_rate();
check = Salary(hours, rate);
Output(check);
}
float Hours_worked(){
float h;
printf("Please enter
the number of hours worked this week: ");
scanf("%f", &h);
return(h);
}
float Pay_rate(){
float r;
printf("Please enter your pay rate per hour: ");
scanf("%f", &r);
return(r);
}
float Salary (float Number_of_Hours,
float Hourly_Rate){
float Pay_Check;
Pay_Check = Number_of_Hours * Hourly_Rate;
return Pay_Check;
}
void Output(float Pay_Check){
printf("Your pay
for this week will be $%4.2f
before taxes and other deductions.", Pay_Check);
}
main() {
float hours, rate,
check;
hours = Hours_worked();
rate = Pay_rate();
check = Salary(hours, rate);
Output(check);
}
float Hours_worked(){
float h;
printf("Please enter
the number of hours worked this week: ");
scanf("%f", &h);
return(h);
}
float Pay_rate(){
float r;
printf("Please enter your pay rate per hour: ");
scanf("%f", &r);
return(r);
}
float Salary (float Number_of_Hours,
float Hourly_Rate){
float Pay_Check;
Pay_Check = Number_of_Hours * Hourly_Rate;
return Pay_Check;
}
void Output(float Pay_Check){
printf("Your pay
for this week will be $%4.2f
before taxes and other deductions.", Pay_Check);
}
|
Function
Calls
Call
by Value and Call by Reference
|
Two methods of invoking functions. |
|
When “arguments” are passed by value, a copy of the argument’s value is made and
passed to the called function. |
|
Changes to the copy in the function do not
affect the original variable’s value in the caller. |
|
When an argument is passed call by reference the
caller allows the called function to actually modify the original variable’s
value. |
|
Call by value should be used whenever the called
function does not need to modify the original variable’s value. |
|
Prevents accidental side effects. |
|
In “C”, all calls are call by
value. |
We will learn later how to simulate call by
reference which will allow the called functions to modify the original
variable’s value. (pointers)
Each standard library has corresponding “header”
file containing the function prototypes for all the functions in that library
and definitions of various data types and constants needed by those functions.
The
Common Header Files
<assert.h>
<setjmp.h>
<ctype.h>
<signal.h>
<errno.h>
<stdarg.h>
<float.h>
<stddef.h>
<limits.h>
<stdlib.h>
<locale.h>
<string.h>
<math.h>
<time.h>
|
Storage
Classes
When creating “identifiers” in “C” they are associated
with a
storage class.
In “C” there are four classes of storage class
specifiers:
|
auto
|
|
register
|
|
extern
|
|
static
|
Storage class determines:
|
Storage duration
period of time that an identifier exists in memory.
|
|
Scope where an
identifier can be referenced throughout a program.
|
|
Linkage is used
in multiple source files programs to determine where the identifier is
known.
|
Auto
& Register
|
The auto
and register
key words are used to declare variables of automatic storage duration. |
|
Variables are created when the block they are
declared in is entered, they exist while the block is active, and
are destroyed when the block is exited. |
|
Auto is the default
and does not have to be explicitly stated. |
|
Register causes the
memory allocation to be made to a hardware register. |
static
& extern
|
Used to declare variables and functions
of static storage
duration. |
|
Variables - storage is allocated and initialized
once the program begins execution. |
|
Functions - the name of the function exists from
the start of program execution. |
|
Global Variables and function names are of storage
class extern by
default. |
|
Global variables are created by placing variable
declarations outside any function definition and they retain their values
throughout the execution of the program. |
|
Global variables and functions can be referenced
by any function that follows their declarations or definitions in the file. |
|
One reason for using function prototypes. |
|
#include <stdio.h> used at the beginning of
the program -- known throughout the program. |
|
(i.e. printf, scanf) |
Static
|
Local variables declared with the keyword static
are still known only in the function |
|
in which they are defined. |
|
BUT, they retain their value when the function
is exited. The next time the function |
|
is called, the static local variable will contain
the value that existed when the function last exited. |
#include <stdio.h>
float Hours(void);
void Output(float, int);
extern int Big = 1000;
int Small = 10;
main() {
float hours;
int j;
for(j=0;j<3;j++){
hours = Hours();
Output(hours,j);
}
printf("Main: Big = %4d
Small = %2d\n", Big, Small);
}
float Hours ( ) {
static float
h=0;
h = h+ 10;
if (h< 11)
printf("Hours: Big = %4d Small = %2d\n", Big, Small);
return (h);}
void Output (float hours, int j) {
printf ("The value of hours
for iteration %d is %f.\n", j, hours);
if (j<1)
printf("Output: Big = %4d Small = %2d\n", Big, Small);
} |
|
In the logic of solving some problems it may be
necessary for a function to call itself. |
|
A function that calls itself is called a
recursive function. |
|
Iteration and Recursion are similar concepts. |
Recursion is a complex topic that is discussed
in much more detail in upper-level computer science courses.
|
#include <stdio.h>
int Func1(int);
main(){
int Num2=2;
Num2 = Func1(Num2);
printf("The result is %d\n",
Num2);
}
int Func1(int Num3){
Num3 = Num3 * Num3;
if (Num3 > 32){
printf("Coming
back!\n");
return(Num3);
}
else {
printf("Num3
= %d Going recursive!\n", Num3);
Num3 = Func1(Num3);
/*** Recursive Function Call ***/
}
} |
Data
Validation & Menus
Data
Validation
|
Programs that interact with people should be “user
friendly”. |
|
Programs should catch and handle errors. |
|
Data Validation is the process of checking
input for errors and allowing |
|
the user to correct the mistake. |
|
Always check for errors when programming
in the real world. |
Range
Checks
|
A range check determines if the data is reasonable
and lies within a given range of values. |
while((choice > 0 ) || (choice < 4)) {
statements;
}
Code/Value
Checks
|
A code/value check is used to determine if the
data matches a predefined code or value. |
if (state == “Florida”) {
statements;
}
Cross-Reference
Checks
|
A cross-reference check is used to ensure that
the relationship between two or more |
|
data items is consistent. |
if (price < cost) {
printf(“How do expect to make any $$$!”);
}
Menus
in Programs
|
Many user interfaces require that the user make
some choices about what it is that they want to do. |
|
The development of menu’s to capture the user’s
choice is an important skill. |
Guidelines
|
Make the menu easy to read. |
|
Use large enough text to make it readable. |
|
Use white space. |
|
Center the menu |
|
Keep it simple. |
|
Don’t clutter the screen with info. |
|
Make the choice clear. |
|
Don’t make the user guess what option he needs
to choose. |
Example
Menu
My Menu
1. Enter Your Name
2. Enter Your Age
3. Calculate Your Age in Days
4. Exit
Enter your Choice: ___
|
Menu
Selection
|
After the user selects an option the program must
evaluate the choice and execute the proper sequence of instructions. |
|
We can implement this evaluation with either nested
if/else logic or through the use of switch/case logic. |
Nested
if/else Statements
if
(choice == 1)
get_name();
else
if (choice == 2)
get_age();
else
if (choice == 3)
Calc_age();
esle
if (choice == 4)
Quit;
else
printf("That is not a good choice!");
The
getch() Function
|
Purpose: To input a single character from
the keyboard. As soon as the character is pressed it is passed to
the identifier. Does not display the character to the screen. Does not
wait for the “enter” key to be pressed. |
|
Format: |
identifier = getch();
Note: Using this, the enter key itself can be used as input.
Example
of getch()
printf(“Enter a grade (A-F) for the mid term and final”);
midterm = getch();
final = getch();
…..
Using
the switch Statement
|
When creating menu’s the switch statement is extremely
useful in determining which menu option was chosen. |
|
The switch statement used in conjunction with
a looping structure can provide the necessary controls for using your menu’s
efficiently. |
Menu
Example
While (!End) {
Display_Menu();
choice = getch();
Switch(choice)
{
case 1:
Get_Name();
break;
case 2:
Get_Age();
break;
case 3:
Calc_Age();
break;
case 4:
End = True;
break;
}
}
Dragon compliments Image Planet.
|