2. A Quick Start Using the IDE

Chapter 8 - Writing and Using Functions

Visual C++ 6: The Complete Reference
Chris H. Pappas and William H. Murray, III
  Copyright 1998 The McGraw-Hill Companies

What Is Function Prototyping?
When the ANSI C standard was implemented for C, it was the C functions that underwent the greatest change. The ANSI C standard for functions is based upon the function prototype that has already been extensively used in C++.
At this point, the world of C programming is still in transition. As you read magazine articles and books that use C code, you will see many forms used to describe C functions. These may or may not conform to the new ANSI C standard as programmers attempt to bring themselves in line with this standard. The Visual C/C++ compiler uses the ANSI C standard for functions, but will also compile the earlier forms. The C programs in this book conform to the ANSI C standard. An attempt has been made to pattern C++ programs after the ANSI C standard for C since one has not yet been set for C++.
The Syntax for Prototypes
If you are not familiar with writing C functions, you probably have a few questions. What does a function look like? Where do functions go in a program? How are functions declared? What constitutes a function? Where is type checking performed?
With the new ANSI C standard, all functions must be prototyped. The prototyping can take place in the C or C++ program itself or in a header file. For the programs in this book, most function prototyping is contained within the program itself. Function declarations begin with the C and C++ function prototype. The function prototype is simple, and it is usually included at the start of program code to notify the compiler of the type and number of arguments that a function will use. Prototyping enforces stronger type checking than was previously possible when C standards were less strongly enforced.
Although other prototyping style variations are legal, this book recommends the function prototype form that is a replication of the function’s declaration line, with the addition of a semicolon at the end, whenever possible. For example:
return_type function_name(argument_type optional_argument_name
       [,...]);
The function can be of type void, int, float, and so on. The return_type gives this specification. The function_name( ) is any meaningful name you choose to describe the function. If any information is passed to the function, an argument_type followed by an optional_argument_name should also be given. Argument types can also be of type void, int, float, and so on. You can pass many values to a function by repeating the argument type and name separated by a comma. It is also correct to list just the argument type, but that prototype form is used specifically for library routine prototypes.
The function itself is actually an encapsulated piece of C or C++ program code that usually follows the main( ) function definition. A function can take the following form:
return_type function_name(argument_types and names)
{
 .
 .
 (
data declarations and body of function)
 .
 .
 return();
}
Notice that the first line of the actual function is identical to the prototype that is listed at the beginning of a program, with one important exception: it does not end with a semicolon. A function prototype and function used in a program are shown in the following application:
/*
*   proto.c
*   A C program to illustrate function prototyping.
*   Function adds two integers
*   and returns an integer result.
*   Copyright (c) Chris H. Pappas and William H. Murray, 1998
*/

#include <stdio.h>

int iadder(int ix,int iy);           /
* function prototype  */
int main()
{
 int ia=23;
 int ib=13;
 int ic;

 ic=iadder(ia,ib);
 printf(“The sum is: %d\n”, ic);

 return (0);
}

int iadder(int ix,int iy)           /
* function declaration */
{
 int iz;

 iz=ix+iy;
 return(iz);                       /
* function return      */
}
The function is called iadder( ). The prototype states that the function will accept two integer arguments and return an integer type. Actually, the ANSI C standard suggests that all functions be prototyped in a separate header file. This, as you might guess, is how header files are associated with their appropriate C libraries. For simple programs, as already mentioned, including the function prototype within the body of the program is acceptable.
The same function written for C++ takes on an almost identical appearance:
//  proto.cpp
//  C++ program to illustrate function prototyping.
//  Function adds two integers
//  and returns an integer result.
//  Copyright (c) Chris H. Pappas and William H. Murray, 1998
//

#include <iostream.h>

int iadder(int ix,int iy);            // function prototype

int main()
{
 int ia=23;
 int ib=13;
 int ic;

 ic=iadder(ia,ib);
 cout << “The sum is: ” << ic << endl;

 return (0);
}

int iadder(int ix,int iy)            // function declaration
{
 int iz;

 iz=ix+iy;
 return(iz);                        // function return
}
Ways to Pass Actual Arguments
In the previous two examples, arguments have been passed by value to the functions. When variables are passed by value, a copy of the variable’s actual contents is passed to the function. Since a copy of the variable is passed, the variable in the calling function itself is not altered. Calling a function by value is the most popular means of passing information to a function, and it is the default method in C and C++. The major restriction to the call-by-value method is that the function typically returns only one value.
When you use a call-by-reference, the address of the argument, rather than the actual value, is passed to the function. This approach also requires less program memory than a call-by-value. When you use call-by-reference, the variables in the calling function can be altered. Another advantage to a call-by-reference is that more than one value can be returned by the function.
The next example uses the iadder( ) function from the previous section. The arguments are now passed by a call-by-reference. In C, you accomplish a call-by-reference by using a pointer as an argument, as shown next. This same method can be used with C++.
/*
*   cbref.c
*   A C program to illustrate call by reference.
*   Copyright (c) Chris H. Pappas and William H. Murray, 1998
*/

#include <stdio.h>

int iadder(int
*pix,int *piy);

int main()
{
 int ia=23;
 int ib=13;
 int ic;
 ic=iadder(&ia,&ib);
 printf(“The sum is: %d\n”, ic);

 return (0);
}

int iadder(int
*pix,int *piy)
{
 int iz;

 iz=
*pix+*piy;
 return(iz);
}
You have learned in C that you can use variables and pointers as arguments in function declarations. C++ uses variables and pointers as arguments in function declarations and adds a third type. In C++, the third argument type is called a reference type. The reference type specifies a location but does not require a dereferencing operator. Many advanced C++ programs use this syntax to simplify the use of pointer variables within called subroutines. Examine the following syntax carefully and compare it with the previous example:
//
//  refrnc.cpp
//  C++ program to illustrate an equivalent
//  call-by-reference, using the C++ reference type.
//  Copyright (c) Chris H. Pappas and William H. Murray, 1998
//

#include <iostream.h>

int iadder(int &rix,int &riy);

int main()
{
 int ia=23;
 int ib=13;
 int ic;
 ic=iadder(ia,ib);
 cout << “The sum is: ” << ic << endl;

 return (0);
}

int iadder(int &rix,int &riy)
{
 int iz;

 iz=rix+riy;
 return(iz);
}
Did you notice the lack of pointers in the previous C++ program code? The reference types in this example are rix and riy. In C++, references to references, references to bit-fields, arrays of references, and pointers to references are not allowed. Regardless of whether you use call-by-reference or a reference type, C++ always uses the address of the argument.
Storage Classes
Storage classes can be affixed to data type declarations, as you saw earlier in Chapter 6. A variable might, for example, be declared as
static float fyourvariable;
Functions can also use extern and static storage class types. A function is declared with an extern storage class when it has been defined in another file, external to the present program. A function can be declared static when external access, apart from the present program, is not permitted.
Identifier Visibility Rules
The scope of a variable, when used in a function, refers to the range of effect that the variable has. The scope rules are similar for C and C++ variables used with functions. Variables can have a local, file, or class scope. (Class scope is discussed in Chapter 16.)
It is possible to use a local variable completely within a function definition. Its scope is then limited to the function itself. The variable is said to be accessible, or visible, within the function only and has a local scope.
Variables with a file scope are declared outside of individual functions or classes. These variables have visibility or accessibility throughout the file in which they are declared and are global in range.
A variable may be used with a file scope and later within a function definition with a local scope. When this is done, the local scope takes precedence over the file scope. C++ offers a new programming feature called the scope resolution operator (::). When the C++ resolution operator is used, a variable with local scope is changed to one with file scope. In this situation, the variable would possess the value of the “global” variable. The syntax for referencing the global variable is
::yourvariable
The scope rules allow unique programming errors to occur. Various scope rule errors are discussed at the end of this chapter.
Recursion
Recursion takes place in a program when a function calls itself. Initially, this might seem like an endless loop, but it is not. Both C and C++ support recursion. Recursive algorithms allow for creative, readable, and terse problem solutions. For example, the next program uses recursion to generate the factorial of a number. The factorial of a number is defined as the number multiplied by all successively lower integers. For example:
8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
 = 40320
Care must be taken when choosing data types since the product increases very rapidly. The factorial of 15 is 1,307,674,368,000.
/*
*   factr.c
*   A C program illustrating recursive function calls.
*   Calculation of the factorial of a number.
*   Example:  7! = 7 x 6 x 5 x 4 x 3 x 2 x 1 = 5040
*   Copyright (c) Chris H. Pappas and William H. Murray, 1998
*/

#include <stdio.h>

double dfactorial(double danswer);

int main()
{
 double dnumber=15.0;
 double dresult;
 dresult=dfactorial(dnumber);

 printf(“The factorial of %15.0lf is: %15.0lf\n”,
        dnumber,dresult);

 return (0);
}

double dfactorial(double danswer)
{
 if (danswer <= 1.0)
   return(1.0);
 else
   return(danswer
*dfactorial(danswer-1.0));
}
Recursion occurs because the function, dfactorial( ), has a call to itself within the function. Notice, too, that the printf( ) function uses a new format code for printing a double value: %...lf. Here, the “l” is a modifier to the “f” and specifies a double instead of a float.

Books24x7.com, Inc 2000 –  


Visual C++ 6(c) The Complete Reference
Visual Studio 6: The Complete Reference
ISBN: B00007FYGA
EAN: N/A
Year: 1998
Pages: 207

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net