Functions and Program Design

A function is simply a named block of code. A function is like a small program that performs a small, well-defined task. Like the larger program it is a part of, a function is usually fed data to process and can have its own variables.

There are two main types of functions, value-returning functions and void functions. A void function does not return any value.

A function call is a statement or expression that transfers control to a function so that the function can perform its designated task. A function call is executed by calling the name of the function immediately followed by parentheses. If we wish to supply values to the function, we place those values in order within the parentheses, separated by commas. These values constitute arguments to the function, that are passed over to the function’s parameters.

Value parameters are an integral part of functions. Value parameters are in essence a type of variable that a function uses to receive the data it will process. A value parameter has a life separate from the corresponding value sent into the function from the function’s caller; this is true even if that value is itself a variable. In other words, if we change the parameter in the function, the associated value in the rest of the program remains the same; in other words, parameters are a copy of the data, not the original data, and the scope of the parameter is limited to the length of the function.

Let’s start by practicing with some of the predefined mathematical functions from the library math.h. As our program will be using a function from a library file, we must have an include statement specifying that library file. We will be calling the log10() function, which takes a double as an argument and returns a double value. The log10() function finds the natural logarithm, AKA the base 10 algorithm, for a specified value. We recalled here that the logarithm of a number is simply the exponent to which another number, the base, must be raised to produce the number. Thus, log10(100) would return the value 2.

#include <stdio.h>
#include <math.h>

int main(void){

	double x = 100000;
	int y = 1000;

	printf("The base10 log of %f is %f\n", x, log10(x));
	//cast y into double to match parameter
	printf("The base10 log of %d is %f\n", y, log10((double)y));

	return 0;

}

We should remember here that any value a function call supplies to the function is called an argument of the function, whereas the result calculated and returned by the function is known as the return value.

A function expects the argument type to match the parameter type; we can see an example of this in the three functions abs(), labs(), and fabs(). Each of these three functions performs the same task, they return the absolute value of the argument provided. Where they differ is that each function accepts an argument of a different type, abs() accepts an argument of type int, labs() accepts an argument of type long, and fabs() accepts an argument of type double.

#include <stdio.h>
#include <math.h>

int main(void){

    int iX = 1999;
    double dY = -1.05;
    long lZ = 8675309;

    printf("The absolute value of %d is %d\n", iX, abs(iX));
    printf("The absolute value of %f is %f\n", dY, fabs(dY));
    printf("The absolute value of %ld is %ld\n", lZ, labs(lZ));

    return 0;

}

When writing a function, we normally split the function into two separate pieces, the declaration and the definition. A function declaration is placed before the main() function. The function declaration specifies what the function is supposed to do and what a programmer should known to call the function. The function definition includes the code that actually performs the task. The function definition includes before this code the function header, which matches the function declaration, except that the function declaration is followed by a semicolon.

#include <stdio.h>

//function declarations go here
void Greet();
void GreetByName(char nameParameter[]);

int main(void){

	char szName[256];

	//call function Greet()
	Greet();

	printf("What is your name? Please enter it here: ");
	scanf(" %s", szName);

	//call function GreetByName()
        //note the single argument
	GreetByName(szName);

	return 0;

}


//function definitions go here
void Greet(){
	printf("\nSaluton Mundo!\n");
}

void GreetByName(char nameParameter[]){
	printf("\nHello, %s\n", nameParameter);
}


As stated earlier, arguments and parameters must match each others data types. Arguments and parameters are matched in order from left to right, so that the first parameter is assigned the value specified in the first argument, etc. When writing a call to a function, we must therefore be careful to give the arguments in the same order as the parameters to which they will be paired.

#include <stdio.h>

//function declaration
//AddUpChange adds up the number of quarters, dimes, nickels and pennies and 
//returns the dollar amount as a double value
double AddUpChange(int quarters, int dimes, int nickels, int pennies);

int main(void){

	int iQuarters, iDimes, iNickels, iPennies;

	iQuarters = 3;
	iDimes = 9;
	iNickels = 4;
	iPennies = 3;

	printf("We have %d quarters, %d dimes, %d nickels, %d pennies.\n", iQuarters, iDimes, iNickels, iPennies);

	printf("That equals $%.2f\n", AddUpChange(iQuarters, iDimes, iNickels, iPennies));

	return 0;

}


double AddUpChange(int quarters, int dimes, int nickels, int pennies){
	double d = 0.0;
	d += quarters * .25;
	d += dimes * .10;
	d += nickels * .05;
	d += pennies * .01;

	return d;

}

In the program above, the double value d is a local variable; local variables are accessible only by statements within the function. Just as with parameters, the memory for local variables is allocated when the computer begins executing the function and is deleted when the function completes its execution.

Advertisements

Function Return Values and Prototypes In C

Let’s look at ways to write function return values so as to increase our program’s effectiveness.

Return values enable us to pass data back from a receiving function to its calling function. When we want to return a value from a function to its calling function we put the return value after the return statement.

Note that we must include a function prototype in our program. In C, a function prototype models the function so as to inform the compiler of each function’s parameter list and return type. Prototyping a function is easy; all we need to do is copy the function’s header to the top of our program. We ought to recall here that the function header contains the return type, the function name, and the type of each argument sent to the function.

#include <stdio.h>

double average(int nums[], int arraySize);

int main(void){

    int nums[3];

    int avg, i;

    for(i = 0; i < 3; i++){
        printf("Please enter a number: ");
        scanf(" %d", &nums[i]);
        printf("%d number entered.\n", i + 1);
    }

    printf("The average is: %f\n", average(nums, 4));

    return 0;

}


//function returns a double value
double average(int nums[], int arraySize){
    int total;
    double count = arraySize;
    while(arraySize >= 0){
        total += nums[arraySize--];    
    }
                        
    return total / count;
}

Note that the prototypes for library functions are contained in header files, such as stdio.h and string.h.

We must always precede a function name with its return data type. Because the variable returned from the average() function above is a double, the double return type was placed before the function’s name when we defined the function. Note that we can only return a single value to a calling function.

We can place a call to a function on the right side of an assignment operator since the program replaces a function call with its return value when the return takes place. In a sense, a function that returns a value becomes that value.

#include <stdio.h>

int SquareNum(int num);

int main(void){
    
    int num;
    
    int square;
    
    printf("What number do you want squared?\n");
    scanf(" %d", &num);
    
    //assign return value to
    //the int variable square
    square = SquareNum(num);
    
    printf("%d squared is %d\n", num, square);
    
    
    return 0;
    
}

int SquareNum(int num){
    return num * num;
}

It is possible to nest function calls within other function calls.

#include <stdio.h>

//function prototype
double linearFunction(int rise, int run, int x, int b);

int main(void){
    
    int rise, run, intercept;
    
    printf("Enter the rise: ");
    scanf(" %d", &rise);
    
    printf("Enter the run: ");
    scanf(" %d", &run);
    
    printf("Enter the y-intercept: ");
    scanf(" %d", &intercept);
    
    for(int i = 0; i < 10; i++){
        printf("f(%d) = ", i);
        printf("%f\n", linearFunction(rise, run, i, intercept));
    }
    
    
    return 0;

}

double linearFunction(int rise, int run, int x, int b){
    return ((double)rise/run)*x+b;
}

Note that sometimes it is clearer to call the function and assign its return value to a variable before using it.

Our next program finds the digit sum of a number given by the user. The digit sum is all of the whole numbers from one to a certain number added together. We will also call a user-defined function from within another user-defined function for the first time.

#include <stdio.h>

int DigitSum(int num);
void printNumber(int i, int num);

int main(void){
    int num;
    printf("Enter a number: ");
    scanf(" %d", &num);
    
    printf("The digit sum of %d is %d\n", num, DigitSum(num));

}

int DigitSum(int num){

    int i;
    int sum;

    if(num <= 0){
        return num;
    } else {
        for(i=1, sum=0;i<=num;i++){
            //call another user defined function
            printNumber(i, num);
            sum+=i;
        }
    }

    return sum;
} //end DigitSum()

//prints either number +
//or else just the number
void printNumber(int i, int num){
    if(i<num){
        printf("%d + ", i);
    } else {
        printf("%d\n", i);
    }
}// end printNumber()

Note that when we prototype a function that does not return a value we declare it to be of type void.

If you’d like to learn more about C, take a look at my book that contains 300 new incremental lessons on C:

http://www.amazon.com/Big-Als-C-Standard-ebook/dp/B00A4JGE0M

 

 

Introduction to C Functions

A function is a named block of code that performs a specific task and optionally returns a value. A function is named. Every function has a unique name; which can be used to call the function from within another function. This function may pass information back to the function that called it in the form of a return value.

#include <stdio.h>


void firstFunction(){
 
  prinf("\n - This is our first function. - \n");
 
}


int main(void){
 
  printf("Let's call the function we defined!\n");
 
  firstFunction();
 
  printf("Let's call it again!\n");
 
  firstFunction();
 
  return 0;
 
}

To pass arguments to a function, we list them in parentheses following the function name. Be aware that the number of arguments and the type of each argument must match the parameters in the function definition. If a function has multiple arguments, the arguments are listed in order.

#include <stdio.h>

int cube(int val){
  return val * val * val;
}

int main(void){
 
  int x = 2;
  int y = 6;
 
  printf("The value of %d cubed is %d\n", x, cube(x));
  printf("The value of %d cubed is %d\n", y, cube(y));
 
  return 0;
 
}

A function definition contains the code that will be executed. The first line of a function definition is called the function header. The function header gives the function’s name. The header also gives the function’s return type and describes its arguments. A function header shouldn’t end with a semicolon. Following the header is the function body, containing the statements that the function will execute. The function body begins with an opening curly brace and ends with a closing curly brace.

#include <stdio.h>


void function1(int arg1){
  printf("\nBegin function1()\n");
  printf("function1() received the argument %d\n", arg1);
  printf("End function1()\n\n");
}

void function2(double arg1, char arg2){
  printf("\nBegin function2()\n");
  printf("function2() received the arguments:\n");
  printf("%f and %c\n", arg1, arg2);
  printf("End function2()\n");
}


int main(void){
  printf("Begin function main()\n");
 
  function1(42);
  function2(802.11, 'n');
 
  printf("End function main()\n");
 
  return 0;
 
}

Although the two terms are often used interchangeably, a parameter and an argument are different. A parameter is an entry in the function header; it acts as a placeholder for an argument. An argument is an actual value passed to the function by the calling program.

A function should know what kind of argument to expect, this means that the function must know the data type of each argument. A value of any of C’s data types may be passed to a function. The argument type is specified in the parameter list part of the function header. For each argument passed to the function, the parameter list must contain one item.

 #include <stdio.h>

double functionA(int x, double y){
   return x * y;
}

long long functionB(int y, int z){
  return (y*y) + (z*z);
}

int main(void){
  int a = 1999;
  int b = 1138;
 
  double y = 1.618;
  double z = 2.718;
 
 
  printf("%d * %f = %f\n", a, y, functionA(a, y));
  printf("%d * %f = %f\n", b, z, functionA(b, z));
  printf("%d^2 + %d^2 = %lld\n", a, b, functionB(a, b));
 
  return 0;
    
}

A function prototype is a model for a function that will appear later in the program. A program should include a prototype for each function that it uses. The prototype for a function is the same as the function header, only with a semicolon added to the end. Like the function header, the function prototype contains information about the function’s return type, name, and parameters.

#include <stdio.h>

double byHalf(double a);

int main(void){
 
  printf("Half of 4.4 is %f\n", byHalf(4.4));
  printf("Half of 7 is %f\n", byHalf((double)7));
  printf("Half of 12 is %f\n", byHalf((double)12));
 
 
  return 0;
 
}


double byHalf(double a){
  return a / 2.0;
}

Function prototypes should be placed before the start of the first function. Typically, function prototypes are all grouped together in one location.