Basic part of C + + (Chapter 3 functions)

Chapter 3 functions

In the process oriented structured program, function is the basic unit of module division, and it is an abstraction of problem-solving process. In object-oriented programming, functions also play an important role
Function is the abstraction of function in object-oriented programming. A C + + program can be composed of a main function and several subfunctions. The main function is the entry of the program. The main function can call subfunctions, and the subfunctions can call other subfunctions.

3.1 definition and use of functions

Definition of function

Type specifier function name (list of formal parameters with type description){
    Statement sequence
    return expression (variable or constant belonging to function type specifier)
}

Formal parameter: it is used to realize the connection between the main function and the called function. In general, parameters are data processed by functions, factors affecting function functions, or results of function processing. When the function is not called, the parameter only marks what type of data should be in the position where the parameter appears. Only when the function is called, the main function will assign the actual parameter to the parameter.
Function return value: the return value of the function is to return the processing result to the calling function. The function type specifier determines the return value type. Return not only returns the processing results, but also ends the execution of the current function.

Function call

1. Direct call
Before calling a function, we need to declare the function, and the definition of function belongs to the declaration of function. Generally speaking, we can call this function directly after the definition of function, but if we want to call it before defining this function, we need to write the declaration of this function before calling the function.

//To call this function before defining a function, you need to declare the function first.
#include <iostream>
using namespace std;

double power(double,int);

int main()
{
    int value = 0;
    cout << "Enter an 8 bit binary number:" ;
    for(int i =7;i>=0;i--){
        char ch;
        cin>>ch;
        if(ch=='1'){
            value+=static_cast<int>(power(2,i));
        }
    }
    cout<< "Decimal value is :"<<value<<endl;
    return 0;
}

double power(double x,int n){
    double val = 1.0;
    while(n--){
        val*=x;
    }
    return val;
}

As shown in the above code, if we do not add the declaration of the power function, the main function cannot identify the power function that needs to be called. If the function power is defined before the main function, it will not be necessary to declare power for a long time.

#include <iostream>

using namespace std;


//To judge whether it is palindrome, you can use the method of taking the remainder by dividing 10, take out each digit of the number in turn from the lowest order, then the lowest order acts as the highest order, reorganize in reverse order, and compare with the original number
//Judge whether n is palindrome
bool symm(unsigned n){
    unsigned i = n;
    unsigned m = 0;
    while(i>0){
        m = m*10+i%10;  //Reverse output
        i = i/10;
    }
    return m==n;

}
int main()
{
    for(unsigned m =11;m<1000;m++){
        if(symm(m)&&symm(m*m)&&symm(m*m*m)){
            cout<<"m= "<<m;
            cout<<"  m*m= "<<(m*m);
            cout<<"  m*m*m="<<(m*m*m)<<endl;
        }

    }
    return 0;
}

2. Nested call
Nested call means that if function 1 calls function 2, function 2 calls function 3 again, thus forming a nested call.

#include <iostream>
using namespace std;

int fun2(int m ){
    return m*m;
}

int fun3(int i,int j){
    return fun2(i)+fun2(j);
}
int main()
{
    int a,b;
    cout<<"please enter a and b: ";
    cin>>a>>b;
    cout << "the sum of square of a and b is : " <<fun3(a,b)<<endl;
    return 0;
}

3. Recursive call
Function can call itself directly or indirectly, which is called recursive call. The essence of recursive algorithm is to decompose the original problem into a new problem, and then the new problem needs the solution of the original problem. Each new problem is a simplified subset of the original problem, and the original problem is finally decomposed into a subset of known solutions.

  • Recursion: decompose the original problem into new subproblems, gradually push from unknown to known problem, and the recursion ends after getting known problem.
  • Regression: starting from the known conditions, according to the inverse process of recurrence, evaluate the regression one by one until the beginning of recurrence.
    Tweet: 5! =5x4! -> 4!=4x3! -> 3!=3x2! -> 2!=2x1! -> 1!=1x0! ->0!=1
    Return: 0! =1 -> 0!x1=1!=1 ->1!x2=2!=2 ->… -> 4!x5 = 5!=120
#include <iostream>
using namespace std;

unsigned fun2(unsigned m ){
    if(m==0){
        return 1;
    }else{
        return fun2(m-1)*m;
    }
}


int main()
{
    unsigned n;
    cout<<"please enter n: ";
    cin>>n;
    cout <<n<< "!= " <<fun2(n)<<endl;
    return 0;
}

Example: using recursive algorithm to select kkk individuals from nnn individuals.
Among n n n individuals, choose k k k individuals = n − 1n-1n − 1, choose kkk individuals + n − 1n-1n − 1, choose k − 1k-1k − 1, so we can use recursive formula to find. When the exit of recursion is n=kn=kn=k or k=0k=0k=0, the combination number is 1, and then recursion begins.

#include <iostream>
using namespace std;

int comm(int n,int k){
    if(n<k){
        return 0;
    }else if(n==k||k==0){
        return 1;
    }else{
        return comm(n-1,k)+comm(n-1,k-1);
    }

}

int main()
{
    int n,k;
    cout << "Enter two integer n and k:";
    cin>>n>>k;
    cout<<"comm(n,k)= "<<comm(n,k)<<endl;
    return 0;
}

//The operation results are as follows
Enter two integer n and k:18 5
comm(n,k)= 8568

Example 2: recursive implementation of Hanoi Tower
Moving n plates from A to C can be divided into the following three steps:

  1. Move n − 1n-1n − 1 plate on A to B (via C)
  2. Move the remaining plate on A to C
  3. Move n − 1n-1n − 1 plate on B to C (via A)
#include <iostream>
using namespace std;

void move(char A, char C){
    cout<<A<<"--->"<<C<<endl;
}

void hanoi(int n,char A,char B,char C){
    if(n==1){
        move(A,C);
    }else{
        hanoi(n-1,A,C,B);
        move(A,C);
        hanoi(n-1,B,A,C);
    }
}
int main()
{
    int m;
    cout << "Enter the number of diskes: ";
    cin>>m;
    cout<<"the step to moving"<<m<<"diskes: "<<endl;
    hanoi(m,'A','B','C');
    return 0;
}

//The operation result is:
Enter the number of diskes: 3
the step to moving3diskes:
A--->C
A--->B
C--->B
A--->C
B--->A
B--->C
A--->C

Function parameter transfer

When the function is not called, the parameter of the function does not occupy the actual memory space. When the function is called, the parameter is given to the parameter and memory is allocated to the parameter. Parameter passing in function refers to the combination of formal parameter and actual parameter. There are two main types: Value Passing and reference passing.
1. value transmission
Value passing refers to allocating memory space to parameter and initializing parameter with parameter when function call occurs, that is, assignment operation. Value passing is just a one-way process of parameter value passing, which means that once a parameter gets a value, it will break away from the real parameter. No matter what happens to the parameter, it will not affect the real parameter. This is because after the parameter is assigned a value, the parameter has a specific position in memory, so the position of the parameter and the actual parameter is different in memory, so changing the value of the parameter will not affect the value of the parameter.

#include <iostream>
using namespace std;

void swap(int x,int y){
    int t = x;
    x = y;
    y = t;
    cout<<"The reslut in the function ====> ";
    cout<<"x= "<<x<<"y= "<<y<<endl;
}
int main()
{
    int x = 5,y = 10;
    cout<<"x= "<<x<<"y= "<<y<<endl;
    swap(x,y);
    cout<<"x= "<<x<<"y= "<<y<<endl;
    return 0;
}
//The operation result is:
x= 5 y= 10
The reslut in the function ====> x= 10 y= 5
x= 5y= 10

2. value transmission
A reference is a special type of variable that can be considered an alias for another variable. When a reference is used as a parameter, memory space is allocated for the parameter only when the calling expression in the calling function is executed, and the parameter is initialized with an argument. The shape of the reference type participates in the combination of the actual parameters and becomes an alias of the actual parameter. When there is any operation on the parameter, it will directly affect the actual parameter.

  • When a reference is declared, it must also be initialized so that it points to an existing object.
  • Once a reference is initialized, it cannot be changed to point to other objects.
#include <iostream>
using namespace std;

void swap(int &x,int &y){
    int t = x;
    x = y;
    y = t;
}
int main()
{
    int x = 5,y = 10;
    cout<<"x= "<<x<<" y= "<<y<<endl;
    swap(x,y);
    cout<<"x= "<<x<<" y= "<<y<<endl;
    return 0;
}

//The operation result is:
x= 5 y= 10
x= 10 y= 5
From the code and running results, it can be seen that the method of reference passing can successfully realize the exchange, and the writing method of reference passing and value passing is only different from that of parameter.
//The difference between value passing and reference passing
#include <iostream>
#include <iomanip>
using namespace std;

void findll(int &x,int y){
   x = x+100;
   y = y+100;
   cout<<"the values are:";
   cout<<setw(5)<<x;
   cout<<setw(5)<<y<<endl;
}
int main()
{
    int x = 5,y = 10;
    cout<<"the values are:";
    cout<<setw(5)<<x;    //setw(5) indicates the output interval, indicating that there are four spaces in the middle.
    cout<<setw(5)<<y<<endl;
    findll(x,y);
    cout<<"the values are:";
    cout<<setw(5)<<x;
    cout<<setw(5)<<y<<endl;
    return 0;
}
//The operation result is:
the values are:    5   10
the values are:  105  110
the values are:  105   10

3.2 inline functions

We use functions to realize code reuse, improve development efficiency, enhance program reliability, facilitate division of labor and cooperation, and facilitate modification and maintenance. However, the use of functions will also reduce the efficiency of the program, while increasing the time and space overhead. So, for some functions with single function, we design them as inline functions. An inline function does not transfer control at call time, but embeds the body of the function into every call at compile time.

//Inline functions can also be done without inline decoration.
#include <iostream>
using namespace std;

const double PI = 3.14159265358987;

inline double calArea(double r){
    return PI*r*r;
}

int main()
{
    double r = 3.0;
    double area = calArea(r);
    cout<<area<<endl;
    return 0;
}

3.3 functions with default parameter values

The function can also declare the default parameter value in advance when defining. If the parameter value is given when calling, the parameter will be initialized. If there is no parameter for initialization, the default parameter value will be used.
Parameter with default value must be at the end of parameter list, that is to say, parameter without default value cannot appear after parameter with default value. It is not allowed to define the same parameter repeatedly in multiple declarations of the same function in the same scope, even if the values defined before and after are the same.

#include <iostream>
using namespace std;

/**
int add(int x,int y = 5,int z = 6);   Correct expression
int add(int x = 5,int y = 6,int z);   Wrong expression
int add(int x = 5,int y,int z = 7);   Wrong expression
**/
int add(int x = 5,int y = 6);

int main()
{
    int result;
    reslut = add();
    cout<<result<<endl;
    return 0;
}

int add(int x/*=5*/,int y/*=6*/){ //If the default value is defined here, it does not meet the requirements, because the default value of function parameter has been given in the previous declaration.
    return x+y;
}

function overloading

The meaning of function overload is similar to the polysemy of the word, for example: shoe polishing, table cleaning, car cleaning, etc. They all use wipes, but they have different functions and different methods. When it comes to programming, we use function overloading to realize different functions of the same function.
More than two functions have the same function name, but the number or type of parameters are different. The compiler automatically determines which function to call according to the number or type of parameters, which is the function overload. (whether the function is overloaded is not judged by the parameter name and the return value of the function. At the same time, pay attention to the function of the default parameter, because it is easy to have ambiguity.)

#include <iostream>
using namespace std;

int sumOfSquare(int x,int y){
    return x*x+y*y;
}

double sumOfSquare(double a,double b){
    return a*a+b*b;
}
int main()
{
    int m,n;
    cout<<"Enter two Integer:";
    cin>>m>>n;
    cout<<"their sum of square: "<<sumOfSquare(m,n)<<endl;
    double a,b;
    cout<<"Enter two real number:";
    cin>>a>>b;
    cout<<"their sum of square: "<<sumOfSquare(a,b)<<endl;
    return 0;
}
//The operation result is:
Enter two Integer:3 5
their sum of square: 34
Enter two real number:2.3 5.8
their sum of square: 38.93

3.6 function operation stack

Global variable: the definition of variable is all written outside the function, and memory address will be allocated to it at the beginning of program running.
Local variable: the definition of variable is all within a function. Once the function returns, the local variable will fail, so its life cycle is far less than the running cycle of the whole program. At the same time, if there is a recursive call, the same local variable will have different values, so it is not feasible to assign a unique address to the local variable like the global variable. Local variables are stored in a data structure such as stack.
The running stack is actually the memory space of a section of area, which is the same as the space for storing global variables, but the addressing method is different. The data in the running stack is divided into stack frames. Each stack frame corresponds to a function call. The stack frame contains the parameter value, some control information, local variable value and some temporary data of the function call.

3.7 summary

This chapter mainly introduces the function function in the programming, and the writing method of the function. After the function is written, it can be reused. When it is used, it only cares about the function and use method of the function, not the specific implementation of the function. This is conducive to code reuse and improve development efficiency.

Published 3 original articles, won praise 0, visited 50
Private letter follow

Tags: Programming less

Posted on Wed, 04 Mar 2020 01:37:04 -0800 by nrsh_ram