elements which are accessed through header files. We have used some of these already: the sqrt() functiondefined in, the rand() function defined in and the time() function defined in. Our first example illustrates the use of one of these mathematical functions. Show The square root of a given positive number is the number whose square is the given number. The square root of 9 is 3 because the square of 3 is 9. We can think of the square root function as a “black box.” When you put in a 9, out comes a 3. When the number 2 is input, the number 1.41421 is output. This function has the same input-process-output nature that complete programs have. However, the processing step is hidden: we do not need to know what the function does to 2 to produce 1.41421. All we need to know is that the output 1.41421 does have the square root property: its square is the input 2. Here is a simple program that uses the predefined square root function:
This program prints the square roots of the numbers 0 through 5. Each time the expression sqrt(x) is evaluated in the for loop, the sqrt() function is executed. Its actual code is hidden away within the Standard C++ Library. In using it, we may confidently assume that the expression sqrt(x) will be replaced by the actual square root of whatever value x has at that moment. Notice the directive #includeon the first line of the program. This is necessary for the compiler to find the definition of the sqrt() function. It tells the compiler that the function is declared in theheader file. A function like sqrt() is executed by using its name as a variable in a statement, like this: This is called invoking or calling the function. Thus in the Example , the code sqrt(x) calls the sqrt() function. The expression x in the parentheses is called the argument or actual parameter of the function call, and we say that it is passed by value to the function. So when x is 3, the value 3 is passed to the sqrt() function by the call sqrt(x). Function values may be used like ordinary variables in an expression. Thus we can write We can even “nest” function calls, like this:
Some Functions Defined in theHeader Function Description Exampleacos(x) isupper(x) tolower(x) inverse sine of x (in radians) inverse tangent of x (in radians) ceiling of x (rounds up) cosine of x (in radians) exponential of x (base e) absolute value of x floor of x (rounds down) natural logarithm of x (base e) common logarithm of x (base 10) x to the power p sine of x (in radians) square root of x tangent of x (in radians) Returns true if x is a lowercase letter; otherwise, it returns false; Returns true if x is a uppercase letter; otherwise, it returns false; Returns the lowercase value of x Returns the uppercase value of xacos(0.2) returns 1.36944 asin(0.2) returns 0.201358 atan(0.2) returns 0.197396 ceil(3.141593) returns 4.0 cos(2) returns -0.416147 exp(2) returns 7.38906 fabs(-2) returns 2.0 floor(3.141593) returns 3.0 log(2) returns 0.693147 log10(2) returns 0.30103 pow(2,3) returns 8.0 sin(2) returns 0.909297 sqrt(2) returns 1.41421 tan(2) returns -2.18504 islower('h') is true isupper('K') is true tolower('Z') returns z Notice that every mathematical function returns a double type. If an integer is passed to the function, it is promoted to a double before the function processes it. The table below lists some of the more useful header files in the Standard C++ Library. Some of the Header Files in the Standard C++ Library
These are derived from the Standard C Library. They are used the same way that Standard C++ header files such asare used. For example, if you want to use the random number function rand() from theheader file, include the following preprocessor directive at the beginning of your main program file: The great variety of functions provided by the Standard C++ Library is still not sufficient for most programming tasks. Programmers also need to be able to define their own functions. Because C++ does not provide every function that you will ever need and designers cannot possibly know a user’s specific needs, you must learn to write your own functions. User-defined functions in C++ are classified into two categories: • Value-returning functions—functions that have a return type. These functions return a value of a specific data type using the return statement, which we will explain shortly. Value-Returning Functions The previous section introduced some predefined C++ functions such as pow, abs, islower, and toupper. These are examples of value-returning functions. To use these functions in your programs, you must know the name of the header file that contains the functions’ specification. You need to include this header file in your program using the include statement and know the following items:
Because the value returned by a value-returning function is unique, the natural thing for you to do is to use the value in one of three ways:
This suggests that a value-returning function is used:
That is, a value-returning function is used (called) in an expression. Before we look at the syntax of a user-defined, value-returning function, let us consider the things associated with such functions. In addition to the four properties described previously, one more thing is associated with functions (both value-returning and void):
The first four properties form what is called the heading of the function (also called the function header); the fifth property is called the body of the function. Together, these five properties form what is called the definition of the function. For example, for the function cube, the heading might look like: Similarly, the function cube might have the following definition: The variable declared in the heading of the function cube is called the formal parameter of the function cube. Thus, the formal parameter of cube is x. Consider the following statements: The variable or expression listed in a call to a function is called the actual parameter of the function. Thus, the actual parameter of cube is v and 1.342 from the above statements.
A user-defined function has two parts: its head and its body. The syntax for the head of a function
This specifies for the compiler the function’s return type, its name, and its parameter list. In the e xample , the function’s return type is int, its name is cube, and its parameter list is int x. The body of a function is the block of code that follows its head. It contains the code that performs the function’s action, including the return statement that specifies the value that the function sends back to the place where it was called. The body of the cube function is
Below is another example of User-defined example with complete labels. } For predefined functions, you need to be concerned only with the first four properties.
The C++ code that describes what a function does is called the function definition. Its Everything before the first brace makes up the header of the function definition, and everything between the braces makes up the body of the function definition. In its simplest form, the syntax of a function header is
in which statements are usually declaration statements and/or executable statements. In this syntax, functionType is the type of the value that the function returns. The functionType is also called the data type or the return type of the value-returning function. Moreover, statements enclosed between curly braces form the body of the The syntax of the formal parameter list is:
Parameters are syntactically identifiers, and they can be used within the body of the function. The parameters in a function definition are called formal parameters to emphasize their role as placeholders for the values that are passed to the function when it is called. When the function is invoked, the value of the argument corresponding to a formal parameter is used within the body of the executing function. These parameters are call-by-value, meaning that only the values from the calling environment are passed, and not the variables themselves. This implies that if the called function changes the value of its formal parameters, the variables in the calling environment C++ functions can have declarations at the head of the block or elsewhere, as long as the variable is declared before its use. This differs from C, where variable declarations must be at the head of a block. In ANSI C++, the empty parameter list is always equivalent to using void. Thus, main() is equivalent to main(void). The function main() implicitly returns the integer value 0 if no explicit return expression statement is executed. The syntax to call a function is:
The syntax of the actual parameter list is:
(In this syntax, expression can be a single constant value.) Thus, to call a value-returning function, you use its name, with the actual parameters (if any) in parentheses A function’s formal parameter list can be empty. However, if the formal parameter list is empty, the parentheses () are still needed. The function heading of the value-returning function thus takes, if the formal parameter list is empty, the following form:
Thus, a call to a value-returning function with an empty formal parameter list is: In a function call, the number of actual parameters, together with their data types, must match with the formal parameters in the order given. That is, actual and formal parameters have a one-to-one correspondence. As stated previously, a value-returning function is called in an expression. The expression can be part of either an assignment statement or an output statement, or a parameter in a function call. A function call in a program causes the body of the called function to The variables that are listed in the function’s parameter list are called parameters. They are local variables that exist only during the execution of the function. Their listing in the parameter list constitutes their declaration. In the example below, x and y are the function's parameter.
variable in the main program, they must be declared before they are used in the call. In the example below, the function's arguments are firstnum and secnum.
The return statement is a flow of control statement. When a return statement is executed, the current function terminates, and program control is immediately passed back to the place where the function was invoked. In addition, if an expression follows the keyword return, the value of the expression is returned to the calling point as well. This value must be assignment-convertible to the return type of the function definition header. Once a value-returning function computes the value, the function returns this value via the return statement. In other words, it passes this value outside the function via the A return statement has one of the following two forms: in which expression is a variable, constant value, or expression. The expression is evaluated, and its value is returned. The data type of the value that expression computes must match the function type.In C++, return is a reserved word. Using parentheses in the return expression is optional, a stylistic device that some programmers use to enhance readability. A function’s return statement serves two purposes: it terminates the execution of the function, and it returns a value to the calling program. Its return expression is any expression whose value could be assigned to a variable whose type is the same as the function’s return type. When a return statement executes in a function, the function immediately terminates and the control goes back to the caller. Moreover, the function call statement is replaced by the value returned by the return statement. When a return statement executes in the function main, the program terminates. In creating C++ functions, you must be concerned with the function itself and how it interacts with other functions, such as main(). Interaction with a function includes passing data to a function correctly when it’s called and returning values from a function when it ceases operation. This section describes the first part of the interface, passing data to a function and having the function receive, store, and process the transmitted data correctly. As you have already seen with mathematical functions, a function is called, or used, by giving the function’s name and passing any data to it, as arguments, in the parentheses following the function name. The called function must be able to accept the data passed to it by the function doing the calling. Only after the called function receives the data successfully can the data be manipulated to produce a useful result. To clarify the process of sending and receiving data, take a look at Program below, which calls a function named findMax(). The program, as shown, consisting of the functions main() and findMax(), can be compiled and executed.
A function declaration (also known as a function prototype) should specify the data type of the value the function returns, the name of the function, and the data type of each of its arguments. A function declaration is like a variable declaration; its purpose is simply to provide the compiler with all the information it needs to compile the rest of the file. The compiler does not need to know how the function works (its body). It only needs to know the function’s name, the number and types of its parameters, and its return type. This is precisely the information contained in the function’s head. Also like a variable declaration, a function declaration must appear above any use of the function’s name. But the function definition, when listed separately from the declaration, may appear anywhere outside the main() function and is usually listed after it or in a separate file. Before a function can be called, it must be declared to the function that will do the calling. The declaration statement for a function is referred to as a function prototype. The function prototype tells the calling function the type of value that will be formally returned, if any, and the data type and order of the values the calling function should transmit to the called function. For example, the function prototype used in previous program example . declares that the function findMax() expects two integer values to be sent to it and that this function formally returns no value (void). Function prototypes can be placed with the variable declaration statements of the calling function, above the calling function name (as in Program example above), or in a separate header file specified with an #include preprocessor statement. The function prototype for findMax() could have been placed before or after the statement #include, before main(), or within main(). The reasons for the choice of placement are explained later. The use of function prototypes permits the compiler to error-check data types. If the function prototype doesn’t agree with data types defined when the function is written, a compiler warning occurs. The prototype also serves another task: It ensures that all arguments passed to the function are converted to the declared data type when the function is called. Now that you have some idea of how to write and use functions in a program, the nextquestion relates to the order in which user-defined functions should appear in a program. For example, do you place the function findmax before or after the function main? Following the rule that you must declare an identifier before you can use it and knowing that the function main uses the identifier findmax, logically you must place findmax before main. In reality, C++ programmers customarily place the function main before all other user defined functions. However, this organization could produce a compilation error because functions are compiled in the order in which they appear in the program. For example, if the function main is placed before the function fndmax, the identifier findmax is undefined when the function main is compiled. To work around this problem of undeclared identifiers, we place function prototypes before any function definition (including the definition of main).
The general syntax of the function prototype of a value-returning function is:
(Note that the function prototype ends with a semicolon.) From our last example, the function findmax has its prototype shown below. When writing the function prototype, you do may specify the variable name in the parameter list. However, you must also specify the data type of each parameter. You can rewrite the function prototype of the function findmax as follows:
The variable names are provided for good documentation, they are ignored by the compiler. However, always provide good names for the parameters. Why? Consider the scenario where the prototype for a calctax() function whose purpose is to calculate the sales tax depending upon the state code. A reasonable prototype might be
Call-By-Value (Pass-By-Value) Functions are invoked by writing their name and an appropriate list of arguments within parentheses. These arguments match in number and type (or compatible type) the parameters in the parameter list in the function definition. The compiler enforces type compatibility. The basic argument-passing mechanism inherited from the C language is call-by-value. That is, each argument is evaluated and its value is used locally in place of the corresponding formal parameter. Thus, if a variable is passed to a function, the stored value of that variable in the calling environment will not be changed. Here is an example that clearly illustrates the concept of call-by-value:
firstnum = firstnum*firstnum; secnum = secnum*secnum*secnum; cout << "The Square of firstnum in sqcub is : " << firstnum << endl;cout << "The Cube of secnum in sqcub is : " << secnum << endl; double firstnum = 5.5, secnum = 3.33; cout << "The value stored in firstnum is: " << firstnum << endl; cout << "The value stored in secnum is: "<< secnum << "\n\n"; sqcub(firstnum, secnum); // call the function - pass by VALUE cout << "The Square of firstnum in main() is : " << firstnum << endl; return 0; In the discussion below, remember that Variable Names are simply Memory Locations that hold data.Even though our variable names firstnum and secnum in the main() funtion are defined to be the same variable names in the user-defined function sqcub(double firstnum, double secnum) their memory locations are quite different, meaning they hold their own data and are different from each other. When the main() function initialized its variable name firstnum to 5.5 and secnum to 3.33, the memory location of the variable firstnum in the main() will be holding or storing the value of 5.5 and the memory location of the variable secnum is holding or storing the value of 3.33. BUT...the memory locations for the variables firstnum and secnum in the sqcub() function will not be affected by this initialization of the same variable names in the main(), SINCE they are not the same memory locations. Meaning. during the initilization the data in the variable firstnum and secnum of the sqcub() function will not be affected and will hold a different set of values in their own memory locations. When the function sqcub() is called or invoke in the main() function by the the statement sqcub(firstnum, secnum); At this point, the values in the variables firstnum and secnum of the main() function are passed to the variables firstnum and secnum of the sqcub() function and here their values will be the same since the passed values will be stored the memory location of the variables firstnum and secnum of the sqcub() function. In other words, after the function sqcub() is invoke, the values passed from the main() function will set the values of firstnum and secnum of the sqcub() function to be the same as of the main() function since their values were passed to these parameters of the sqcub() function. In the sqcub() funtion, the variables firsnum and secnum were both manipulated where the value of firstnum was squared (firstnum * firstnum) and the value ob secnum was cubed (secnum * secnum * secnum). This time only the memory location of the variables firstnum and secnum of the sqcub() function will be affected and that of the main() function will not be affected as these variables have different memory locations. We can verify all these by running the program above. Even though firstnum and secnum are passed to sqcub() and the values of firstnum and secnum in the body of sqcub() function are changed, the values of firstnum and secnum in the calling main() environment remains unchanged. It is the value of the arguments that are being passed, not the arguments firstnum and secnum itself. Function invocation with call-by-value means: 1. Each expression in the argument list is evaluated. 2. The value of the expression is converted, if necessary, to the type of the formal parameter, and that value is assigned to its corresponding formal parameter at the beginning of the body of the function. This means a local copy is 3. The body of the function is executed using the local copy of the parameter. 4. If a return statement is executed, then control is passed back to the calling 5. If the return statement includes an expression, then the value of the expression is converted, if necessary, to the type given by the type specifier of the function, and that value is passed back to the calling environment, too. 6. If the return statement does not include an expression, then no useful value is returned to the calling environment. 7. If no return statement is present, then control is passed back to the calling environment when the end of the body of the function is reached. No useful 8. All arguments are passed call-by-value. A change in the value of the local copy does not affect the passed in arguments value. Reference declarations, a C++ feature not available in C, declare the identifier to be an alternative name, or alias, for an object specified in an initialization of the reference. Reference declarations allow a simpler form of call-by-reference parameters. Some int& nn = n; // nn is alternative name for n double& last = a[9]; // last is an alias for a[9] Declarations of references that are definitions must be initialized and are usually initialized to simple variables. The initializer is an lvalue expression, which gives the variable’s location in memory. In these examples, the names n and nn are aliases for each other; that is, they refer to the same object. Modifying nn is equivalent to modifying n, and vice versa. The name last is an alternative to the single array element a[9]. These names, once initialized, cannot be changed. When a variable i is declared, it has an address and memory associated with it. When a pointer variable p is declared and initialized to &i, it has an identity separate from i. The pointer p has memory associated with it that is initialized to the address of i. When a reference variable r is declared and initialized to i, it is identical to i. It does not have an identity separate from the other names for the same object. In effect, r is just another name for i, that is, an alias. The following definitions are used to demonstrate the use of dereferencing and aliasing. The definitions assume that memory at location 1004 is used for integer variable a and that memory at 1008 is used for pointer variable p.
Notice in the preceding figure of pointer declarations that any change to the value of a is equivalent to changing ref_a. Such a change affects the dereferenced value of p. The pointer p can be assigned another address and lose its association with a. However, a and ref_a are aliases and within scope must refer to the same object. These declarations can be used for call-by-reference arguments, which allows C++ to have Pointer-Based Call-By-Reference As in C, the dereferencing, or indirection, operator * is unary and has the same precedence and right-to-left associativity as the other unary operators. If p is a pointer, *p is the value of the variable that p points to. The direct value of p is a memory location, whereas *p is the indirect value of p—namely, the value at the memory location stored in p. In a certain sense, * is the inverse operator to &. Here is code showing some of
The addresses of variables can be used as arguments to functions so that the stored values of the variables can be modified. call-by-reference, pointers must be used in the parameter list in the function definition. Then, when the function is called, addresses of variables must be passed as arguments. Using our previous program example, let's do a Pointer-Based Call-By-Reference.
*firstnum = *firstnum*(*firstnum); *secnum = *secnum*(*secnum)*(*secnum);
In the above program example the arguments passed to the functions are the addresses of the variables firstnum and secnum as shown when the function is invoke. sqcub(&firstnum, &secnum); //Pass by Reference using the Address &firstnum is the address of variable firstnum in the main() &secnum is the address of variable secnum in the main() The user-defined function void sqcub(double* firstnum, double* secnum) stored these addresses using pointers. double* firstnum is a pointer that points to the address &firstnum double *secnum is a pointer that points to the address &secnum In this program, the values stored in the address location of &firstnum and &secnum will be affected by the parameters of the user-defined function void sqcub(double* firstnum, double* secnum) since the pointer variables (double* firstnum, double* secnum) has the memory or point to the addresses of the arguments &firstnum and &secnum. Hence in this program the values of the arguments and parameters in main() and sqcun() will be the same. We can verify by running this program. The result is shown below. Call-By-Reference Using Pointers
call-by-reference using reference declarations. The call-by-value mechanism is in contrast to that of call-by-reference. In Section Pointer-Based Call-By-Reference, we explain how to accomplish callby- reference using pointers. In Reference Declarations, we will show how to achieve call-by-reference using reference declarations. Call-by-reference is a way of passing addresses (references) of variables to a function that then allows the body of the function to make changes to the values of variables in the calling environment. Again using the same program example we now do a call-by-reference using reference declarations.
void sqcub(double& firstnum, double& secnum) { cout << "The Square of firstnum in sqcub is : " << firstnum << endl; int main(){ cout << "The value stored in firstnum is: " << firstnum << endl; sqcub(firstnum, secnum); // call the function with references cout << "The Square of firstnum in main() is : " << firstnum << endl; return 0; Here in this program, you will notice that the calling function in main() simply pass its arguments to the user-defined function sqcub() using only the variable names firstnum and secnum just like in the Pass-By-Value. The only difference is the Data Types specified in the Parameters of the user-defined function where the Reference Addresses of the variables firstnum and secnum are specifed respectivelly as (double& firstnum, double& secnum).
So this means that whatever changes or computation done in these parameter in user-defined function sqcub() will have the same effect on the corresponding arguments in the calling environment main(). Let us again run and verify this process. The placement of the USER-DEFINED() function after the main() function in Program example is a matter of choice. Usually, main() is listed first because it’s the driver function that gives anyone reading the program an idea of what the complete program is about before encountering the details of each function. In no case, however, can the definition of USER DEFINED() function be placed inside main(). This rule applies to all C++ functions, which must be defined by themselves outside any other function. Each C++ function is a separate and independent entity with its own parameters and variables; nesting functions is never permitted. C++ doesn’t impose a rigid statement-ordering structure on programmers. The general rule for placing statements in a C++ program is simply that all preprocessor directives, named constants, variables, and functions must be declared or defined before they can be used. As noted previously, although this rule permits placing both preprocessor directives and declaration statements throughout a program, doing so results in poor program structure. As a matter of good programming form, the following statement ordering should form the basic structure around which all C++ programs are constructed:
As always, comment statements can be intermixed anywhere in this basic structure. The above approach is also known as the Top-Down Approach. We have used this structure in our first program function Some programmers prefer the Bottom-Up Approach, where all the function definitions are specified first which is followed on the very last or bottom by the main() function. In addition, there is no need to specify or declare the function prototypes, as shown below.
We have used this structure in our last 3 examples in Pass-By-Value and Pass-By-Reference function call. Which one to use ? The only advice is when you are dealing with a very huge program that contains several hundreds of function definitions, then the Top-Down Approach is best suitable since the function prototypes will serve as a list of all functions defined in your program. In a way, it serves like a table of contents for your defined functions plus the fact it will provide error-checking of all data types of all your functions and to ensure that all arguments passed to the function are converted to the declared data type when the function is called.While on the other hand, for small programs with a few function definition, the Bottom-Up approach maybe easier to follow. There are two categories of a User-Defined Function.
Value-Returning Functions As mentioned before, The return statement is a flow of control statement. When a return statement is executed, the current function terminates, and program control is immediately passed back to the place where the function was invoked. In addition, if an expression follows the keyword return, the value of the expression is returned to the calling point as well. This value must be assignment-convertible to the return type of the function definition header. Once a value-returning function computes the value, the function returns this value via the return statement. In other words, it passes this value outside the function via the A return statement has one of the following two forms: For a Value-Returning Function, it will always have a "return expression" when the function is terminated. Also it may only return 1 and only 1 value back to the calling function which is usually the main(). And lastly, the Data Type of the returning value should be the same as the Function-Type in the Function Prototype and Function Definition. Let us have another example using a Pass-By-Value function call with a return value.
From the above example, there are 2 User-Defined Functions and both are Value-Returning Functions, since both are returning a value. For the function int maximum(int value1, int value2, int value3) The return expression is return max where max has a Data Type int so the Function Type is int in the function definition as shown above. There is no Function Prototype as we are using the Bottom-Up Structure. For the function int minimum(int value1, int value2, int value3) The return expression is return min where min has a Data Type int so the Function Type is int in the function definition as shown above. There is no Function Prototype as we are using the Bottom-Up Structure. Also notice, that there is only 1 return value that a Value-Returning Function could handle. A void function does not have a data type. Therefore, functionType—that is, the return type—in the heading part and the return statement in the body of the void functions are meaningless. However, in a void function, you can use the return statement without any value; it is typically used to exit the function early. Like value-returning functions, void functions may or may not have formal parameters. Because void functions do not have a data type, they are not used (called) in an
in which statements are usually declaration and/or executable statements. The formal When do I use void functions ? We usually used void functions if we want certain tasks to be performed outside the main() function in order to break our main program into pieces of modules which will make it easier for us to revise and debug our programs. Here is a case of making a file copy or duplicating our file for a backup. In this program, we separated the file process for our input file and output file where they are both opened outside the main() function. This will also facilitate our revisions to our program where we can easily add or insert other tasks besides making a file copy, for instance computing the grades or the wages, which we can carry out by making another function. And in case after adding a new function you encounter some problems, you are assured that the problems only exist in the new function and hence we could also say that programs with function modules are easy to debug since we could ISOLATE the problems easily that might arise in any function modules of our whole program. Below is an example of program using 2 function modules to process separately their input file and output file.
In this program, we both input the filenames of our input file and output file via keyboard. The input file must be an existing file, while the output file may or may not exist. If the output file does not exist, then the program will create one for you. What is a void function with parameter?When used as a function return type, the void keyword specifies that the function doesn't return a value. When used for a function's parameter list, void specifies that the function takes no parameters. When used in the declaration of a pointer, void specifies that the pointer is "universal."
What is the parameters in function declaration?The function declarator includes the list of parameters that can be passed to the function when it is called by another function, or by itself. In C++, the parameter list of a function is referred to as its signature. The name and signature of a function uniquely identify it.
When a void function is called it is known as?When a void function is called, it is known as. an executable statement.
What is void X?The literal meaning of void is empty or blank. In C, void can be used as a data type that represents no data.
|