Functions

rand function

Function prototype: int rand(void); Required header file: <cstdlib> Function and return value: Generates and returns a pseudo-random number


srand function

Function prototype: void srand(unsigned int seed); Parameter: seed for generating random numbers Required header file: <cstdlib> Function: Sets the starting point for rand() to generate a series of pseudo-random integers. Using 1 as the seed parameter can reinitialize rand().


It should be noted that if no seed is used, the random numbers generated each time the program runs will be fixed and unchanged. Therefore, the rand function returns pseudo-random numbers.

Concept of References

  • A reference (&) is an alias for an identifier;
  • When defining a reference, it must be initialized at the same time to point to an existing object. For example:
1
2
3
4
int i, j;
int &ri = i; // Define int reference ri and initialize it as a reference to variable i
j = 10;
ri = j; // Equivalent to i = j;
  • Once a reference is initialized, it cannot be changed to point to other objects. References can be used as formal parameters.

References can achieve bidirectional passing between function formal parameters and actual parameters

For example, the following program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<iostream>
using namespace std;

void swap(int& a, int& b) // Define reference type formal parameters
{
int t = a;
a = b;
b = 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;
}

Functions with Variable Arguments

C++ standard mainly provides two methods

  • If all actual parameter types are the same, you can pass a standard library type called initializer_list;
  • If the actual parameter types are different, we can write variable parameter templates (Chapter 9).

    initializer_list

initializer_list is a standard library type used to represent an array of values of a specific type, defined in the header file of the same name.


Usage of initializer_list

  • initializer_list is a class template (templates are introduced in detail in Chapter 9)
  • When using templates, we need to follow the template name with a pair of angle brackets, with type parameters inside the brackets. For example:
1
2
initializer_list<string>  ls;  // The element type of initializer_list is string
initializer_list<int> li; // The element type of initializer_list is int
  • A special point about initializer_list is that the elements in its objects are always constant values, and we cannot change the values of elements in initializer_list objects.
  • Functions with initializer_list formal parameters can also have other formal parameters at the same time

    Example of using initializer_list

  • When writing code to output error messages generated by the program, it’s best to use a unified function to implement this functionality, so that error handling for all errors can be uniform. However, the types of error messages are different, and the parameters passed when calling the error message output function will also vary.
  • Use initializer_list to write an error message output function that can work with a variable number of formal parameters.

    Inline Functions

  • Use the keyword inline when declaring.
  • At compile time, replace the call site with the function body, saving overhead from parameter passing, control transfer, etc.
  • Note:
    • Inline function bodies cannot have loop statements and switch statements;
    • The definition of an inline function must appear before the inline function is first called;
    • Exception interface declarations cannot be made for inline functions.

      Application Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

using namespace std;

const double PI = 3.14159265358979;

inline double calArea(double radius) // inline keyword
{

return PI * radius * radius;

}

int main()
{

double r = 3.0;

double area = calArea(r);

cout << area << endl;

return 0;

}

In essence, it omits function calls and returns, similar to directly pasting the function body to the call site.

### constexpr Functions (not very clear about usage)
#### constexpr Function Example
- constexpr int get_size() { return 20; } - constexpr int foo = get_size(); // Correct: foo is a constant expression

Functions with Default Parameter Values

Order of Default Parameter Value Declarations

  • Formal parameters with default values must be listed at the rightmost of the parameter list, that is, there cannot be parameters without default values to the right of default parameter values;
  • The binding order of actual parameters and formal parameters when calling is from left to right.
  • Example:

1
2
3
int add(int x, int y = 5, int z = 6);// Correct
int add(int x = 1, int y = 5, int z);// Error
int add(int x = 1, int y, int z = 6);// Error

Default Parameter Values and Function Call Location

If a function has a prototype declaration and the prototype declaration is before the definition, the default parameter values should be given in the function prototype declaration; if there is only the function definition, or the function definition is first, the default parameter values can be given in the function definition. For example:

1
2
3
4
5
6
7
8
9
int add(int x = 5 ,int y = 6)// Prototype declaration first
int main()
{
add();
}
int add(int x,int y)
{
return x+y;// Default values cannot be specified here again
}

1
2
3
4
5
6
7
8
int add(int x = 5 ,int y = 6)// Only definition, no prototype declaration
{
return x+y;
}
int main()
{
add();
}

Function Overloading

C++ allows functions with similar functionality to be declared with the same function name in the same scope, thus forming overloading. This is convenient to use and easy to remember.

Notes:

  • Overloaded functions must have different formal parameters: different number or different type.
  • The compiler will choose which function to call based on the best match of the type and number of actual parameters and formal parameters. (The compiler does not distinguish by formal parameter names and function return values)
  • Do not declare functions with different functionality as overloaded functions to avoid misunderstanding and confusion in call results.

Function Overloading Application Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;
int sumOfSquare(int a, int b) {
return a * a + b * b;
}
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 x, y;
cout << "Enter two real number: ";
cin >> x >> y;
cout<<"Their sum of square: "<<sumOfSquare(x, y)<<endl;
return 0;
}

Running result: Enter two integer: 3 5 Their sum of square: 34 Enter two real number: 2.3 5.8 Their sum of square: 38.93