C++. Functions. Part 1. Function declaration. Actual and formal arguments. Passing arguments to a function by value and by reference. Function prototype




Functions. Part 1. Function declaration. Actual and formal arguments. Passing arguments to a function by value and by reference. Function prototype


Contents


Search other websites:

1. What is a function? Function definition. The advantages of using functions

When writing programs of the medium and high levels of complexity, there is a need for them to break up into parts. Splitting a large program into smaller parts reduces the risk of errors, improves readability of the program code.

Also, if some code is repeated several times (or is close in meaning), it is advisable to organize it as a function, which then can be called multiple times by using it’s name. Thus, there is a memory savings, reduction of the source code, etc.

Function – it’s part of the program, which has the following properties or characteristics:

  • function is a logically independent part of the program;
  • function has a name on the basis of which the function is called (function is executed). The function name must correspond to the rules for creating C++ language identifiers;

The function name must correspond to the rules for creating C++ language identifiers;

  • function can contain a list of parameters that are passed to it for processing or use. If the function does not contain a list of parameters, then this function is called a function without parameters;
  • function can return (not necessarily) some value. In case the function does not return any value, then the keyword void is specified;
  • function has its own program code, which is located between the curly braces { }. The program code solves the task assigned to this function. The program function code, implemented in curly braces, is called the “body of a function“.

Using functions in programs gives the following advantages:

  • compact organization of the program by conveniently calling the program code by its name, which in the program can occur several times;
  • saving of memory and the size of the source and execution code, etc.;
  • reducing the risk of errors for large sets of codes;
  • improving of the readability of the code.

2. What is the general form of the function definition?

The general form of the function definition is as follows:

type function_name(arguments_list or void)
{
    function_body
    [return] (expression);
}

where

  • type – type of the value returned by the function. If the keyword “void” is specified in the “type” field, the function does not return any value;
  • function_name – it is directly a function name. This name calls the code implemented in function_body. In addition, the function name is a pointer to the function. The value of the pointer is the address of the entry point to the function;
  • arguments_list – parameters that are passed to the function. A function can receive any number of arguments (parameters). If a function without parameters is described, the keyword void is indicated in parentheses;
  • function_body – a set of code statements that implement the calculation algorithm inside the function;
  • return (expression) – the return keyword indicates that the function returns the value specified in (expression). The word return can occur in several places in the body of the function, depending on the algorithm.

3. Examples of definition and using functions that do not return values

If the function does not return a value, then it must begin with the void keyword.

Example 1. Function MyFunc1() without parameters, which does not return a value.

If you describe a function in the body of a class or module:

// A definition of a function that does not receive or return parameters
void MyFunc1(void)
{
    // function body - text output on the form in label1 control
    label1->Text = "MyFunc1() is called";
    return; // return from function
}

Then you can call this function as follows:

...

// сall a function from another program code (for example, an event handler)
MyFunc1();

...

Example 2. Function MyFuncMult2(), which gets 1 parameter of integer type and does not return a value. The function multiplies the received parameter by 2 and outputs the result to the form in the label1 control.

// function that gets an integer, multiplies it by 2, and outputs the result
void MyFuncMult2(int x)
{
    int res;     // internal variable
    res = x * 2; // result calculation
    label1->Text = res.ToString(); // output of result to form
    return;
}

Calling a function from another program code:

// calling of function
MyFuncMult2(42); // 84 is displayed
MyFuncMult2(-8); // -16

Example 3. A function that receives 2 parameters of type double, finds their multiplication and outputs it to the form in the control label1.

// function that multiplies the parameter x by the parameter y and outputs the result to the form
void MyFuncMultDouble(double x, double y)
{
    double z;
    z = x*y;
    label1->Text = z.ToString();
    return;
}

Calling of function from another program code:

...

MyFuncMultDouble(2.5, -2.0); // Will be displayed -5
MyFuncMultDouble(1.85, -2.23); // Will be displayed -4.1255

...

4. Examples of definition and using functions that receive one parameter

Example 1. A function that receives one parameter of an integer type multiplies it by 5 and returns the result. The function does not output the result.

// Function that multiplies the parameter by 5
int Mult5(int d)
{
    int res;
    res = d * 5;
    return res; // Returning the result
}

Calling of function from another program code:

...

// calling the function from another program code:
int x, y;
x = 20;
y = Mult5(x);   // y = 100
y = Mult5(-15); // y = -75

...

Example 2. A function that calculates the value y = sign (x), which is determined according to the rule:

Implementation of the function:

int sign(float x)
{
    if (x<0) return -1;
    if (x==0) return 0;
    if (x>0) return 1;
}

Calling the function from another program code:

...

int res;

res = sign(-0.399f); // res = -1
res = sign(0.00f);   // res = 0
res = sign(2.39);    // res = 1

...

5. Examples of describing and using functions that receive two or more parameters

Example 1. An example of the function MaxFloat (), which gets 2 parameters of type float and returns the maximum of them.

// function that finds a maximum between two real numbers
float MaxFloat(float x, float y)
{
    if (x>y) return x;
    else return y;
}

It should be noted that the return statement is encountered twice in this function.

Calling the function from another program code:

// Calling the function from another program code
float Max; // the result variable
Max = MaxFloat(29.65f, (float)30); // Max = 30.0

double x = 10.99;
double y = 10.999;
Max = MaxFloat(x, y); // Max = 10.999
Max = MaxFloat((float)x, (float)y); // Max = 10.999

Example 2. The MaxInt3() function, which finds the maximum value between three integers.

// Function that finds a maximum between three integers
// The function gets 3 integer parameters a, b, c
int MaxInt3(int a, int b, int c)
{
    int max;
    max = a;
    if (max<b) max = b;
    if (max<c) max = c;
    return max;
}

Calling the function from another program code:

...

int a = 8, b = 5, c = -10;
int res;

res = MaxInt3(a, b, c);       // res = 8
res = MaxInt3(a, b+10, c+15); // res = 15
res = MaxInt3(11, 2, 18);     // res = 18

...

6. What methods exist for passing parameters to a function? Example

C++ provides 3 ways to pass a parameters to a function:

  • Parameter passing by value (Call-By-Value). This is a simple passing of copies of the variables in the function. In this case, changing the values of the parameters in the body of the function will not change the values that were passed to the function from the outside (when it was called);
  • Passing the parameter by the address of the variable. In this case, as parameters, not copies of variables but copies of addresses of variables are transferred to the function. A pointer to the variable is passed. Using this pointer the function accesses the necessary memory locations where the passed variable is located and can change its value. For general information about pointers, click here;
  • Passing the parameter by reference (Call-By-Reference). A reference (pointer) is passed to the object (variable), which allows you to syntactically use this reference as a pointer, and as a value. Changes made to a parameter that is passed by reference change the original copy of the parameter of the calling function.

Example. This example demonstrates the difference between passing parameters by value, passing parameters by an address and passing parameters by a reference. A function is described that takes three parameters. The first parameter (x) is passed by value. The second parameter (y) is passed by the address (as a pointer). Third parameter (z) is passed by the reference.

// function MyFunction()
// parameter x - passed by value (parameter-value)
// parameter y - passed by address
// parameter z - passed by reference
void MyFunction(int x, int* y, int& z)
{
    x = 8;   // parameter is changed only within a function body
    *y = 8; // parameter is also changed outside of the function
    z = 8; // parameter is also changed outside of the function
    return;
}

Demonstration of calling the function MyFunction() from another program code:

int a, b, c;

a = b = c = 5; 

// calling the function MyFunction()
// parameter a is passed by value a-> x
// parameter b is passed by the address b->y
// parameter c is passed by the reference c->z
MyFunction(a, &b, c); // a = 5; b = 8; c = 8;

As can be seen from the result, the value of the variable a has not changed. The variable a was passed to the function MyFunction() with the value passed (the first parameter).

However, the value of the variable b after the call to the MyFunction() function has changed. This is due to the fact that the value of the address of the variable b was passed to the function MyFunction(). Having the address of variable b in the computer’s memory, inside the function MyFunction(), you can change the values of this variable with the pointer y.

Similarly, the value of c after the function call has changed. The reference is the address of the object in memory. With this address can have access to the value of the object.

7. What are the formal and actual parameters of the function? Example

Formal parameters are variables, that takes the values of the arguments (parameters) of the function. If a function has several arguments (parameters), their type and names are separated by a comma ‘ , ‘.

When you call a function with parameters, the compiler copies the formal parameters to the stack.






Example 1. The MyAbs() function, which finds the number module, has one formal parameter x.

// A function that finds a module of a real number
float MyAbs(float x) // x - formal parameter
{
    if (x<0) return (float)(-x);
    else return x;
}

Calling a function from another program code (another function)

// сalling a function from another program code
float res, a;
a = -18.25f;
res = MyAbs(a); // res = 18.25f; variable a - actual parameter
res = MyAbs(-23); // res = 23; constant 23 - actual parameter

When you call a function from another program code, the actual parameter takes place. In this example, the actual parameter is the variable a and the constant 23.

When the function is called, the actual parameters are copied to special memory cells in the stack (stack is a part of the memory). These memory cells are reserved for formal parameters. Thus, the formal parameters (through the use of the stack) get the value of the actual parameters.

Since the actual parameters are copied to the stack, changing the values of the formal parameters in the body of the function will not change the values of the actual parameters (since this is a copy of the actual parameters).

8. What is the scope of the formal parameters of the function? Example

The scope of the formal parameters of the function is determined by the boundaries of the body of the function in which they are described. In the example below, a formal parameter n of an integer type has a scope within the curly braces { }.

Example. A function that calculates the factorial of an integer n.

// function, that calculates n!
unsigned long int MyFact(int n) // The beginning of the scope of the formal parameter n
{
    int i;
    unsigned long int f = 1; // result

    for (i=1; i<=n; i++)
        f = f*i;

    return f;  // The end of the scope of the formal value of n
}

Calling a function from another program code (another function)

// calling a function from another program code (another function)
int k;
unsigned long int fact;
k = 6;
fact = MyFact(k); // fact = 6! = 720

9. What is a function prototype? Example

A function prototype is a message to the compiler and other functions that such a function exists. In other words, this is a message to the compiler and other functions that there is a function with the specified signature in the program. A function prototype consists of an abbreviated description without a function body.

Function prototype contains:

  • function name;
  • function parameters or types of these parameters;
  • type of value returned by function.

The general form for declaring a function prototype is as follows:

return_type FuncName(parameters);

where

  • return_type – тип, возвращаемый функцией;
  • FuncName – function name;
  • parameters – function parameters.

When specifying a function prototype, parameter names are optional. For example, for function

double Average(int A[], int size);

you can specify the following prototype

double Average(int[], int);

In cases where the called function is declared before the calling function, you can do without using a prototype. In other cases, a prototype function is required.

If a function is declared in a class and called from methods of this class, then there will be no such errors. This is because in the class the function prototype is known to all class methods.

If the function is defined in the class and called from the methods of this class, then there will be no such errors. This is due to the fact that in the class the function prototype is known to all methods of the class.

10. An example demonstrating the need to use a function prototype

Let 2 functions with the names A() and B() are given. The order of declaring and the order of the call are important here. If we call function A() from function B(), the declaration and body of which are implemented after function B(), as shown below

// Function B () - knows nothing about the existence of function A ()
void B()
{
  // Calling function A()
  // error, function B() does not know anything about function A()
  A(); // error: 'Identifier 'A' not found'
}

// Function A()
void A()
{
  // Body of function A()
  // ...
}

void main()
{
  B();
}

then the compiler will generate an error message

'A': identifier not found

To correct the situation, you need to tell function B() that there is an implementation of function A() in the program (current module). In our case, the implementation of the function A() is placed after the implementation of the function B(). To do this, before the function B() you need to declare a prototype of the function A() as shown below

// The prototype of the function A()
void A();

// Function B() - now already knows about the existence of function A()
void B()
{
  // calling function A() from function B()
  A(); // the call is working correctly
}

void A()
{
  // body of function A()
  // ...
}

void main()
{
  B();
}

Related topics