5.1.3 Passing function parameters
We know that a function is a relatively independent piece of code used to accomplish a certain function. When the function completes this function, it often needs the support of external data. At this time, it needs to pass the required data to it when calling this function to complete the function and obtain the result. For example, when you call an addition function, you need to pass two numbers to it as the addend and the addend, and then you can calculate the two numbers inside it to obtain the addition result. When defining a function, if the function needs to exchange data with the outside, a formal parameter table needs to be added to the function definition to determine the number and specific type of data that the caller of the function passes to the function. For example, you can define an addition function that requires two int type addends:
// Declare and define the Add () function
// The formal parameter table determines that this function requires two parameters of type int
int Add (int a, int b)
{
return a + b;
}
From the declaration of the Add () function, you can know that this function has two int type numbers as parameters, so when calling, you need to call them with two int type numbers as actual parameters:
// call Add () function with 1 and 2 as actual parameters
// That is, pass 1 and 2 data to this function
int nRes = Add (1, 2);
The parameters given in the formal parameter table when defining a function are called formal parameters, such as a and b here; and the parameters given in parentheses after the function name when the function is called are called actual parameters, such as 1 here And 2. When performing a function call, the system uses the actual parameters given when calling the function to assign values to each of the formal parameters in the function declaration. For example, when executing the "Add (1,2)" function call, the two actual parameters 1 and 2 are assigned to the two formal parameters a and b of the Add () function, respectively. In other words, when the program is executed inside the Add () function, the values of the two variables a and b are 1 and 2 at the beginning, which means that through the formal parameters, we transfer the data 1 and 2 from the function call The user passed into the Add () function. 5-6.
Figure 5-6 Parameter passing during function call
When performing a function call, the system needs to copy the actual parameters to the formal parameters to achieve data transfer. However, if you want to pass some large data to the function, such as an array with multiple data elements, this copying process will be very time consuming and significantly reduce the efficiency of the program. In order to improve efficiency, we often pass pointers to this large volume of data instead of passing the data itself. Inside a function, you can use pointers to access the external data it points to, and you can also pass data to the function. For example, in the previous salary program, after all salary data was entered into the arrSalary array, these salary data need to be passed to the GetAverage () function to calculate the average salary. At this time, we can pass a pointer to this array to the function, that is, the array name, to achieve the purpose of passing the entire array to the function:
// define the function that calculates the average of the array
float GetAverage (int * pArr, int nCount)
{
// determine whether the data is legal
if (nCount <= 0 || nullptr == pArr)
{
return 0; // if the data is invalid, return the default value
}
// Calculate the average
int nTotal = 0;
// Use a for loop to traverse the array and count the total salary
for (int i = 0; i <nCount; ++ i)
{
// Access the array element by passing the pointer to the first address of the array
nTotal + = pArr [i];
}
// Returns the quotient of the total salary and the number of data, which is the average salary
return (float) nTotal / nCount;
}
int main ()
{
// Define the array holding salary data
const int NUM = 100000;
int arrSalary [NUM] = {0};
// Enter salary data into array ...
// Call the function with the array name (the first address of the array) and the number of data elements as the actual parameters
float fAver = GetAverage (arrSalary, NUM);
cout << "Average salary is:" << fAver << endl;
return 0;
}
When defining the GetAverage () function, we defined two formal parameters. The first pArr of type "int *" represents a pointer to the first address of the array. As long as we have this pointer, inside the function, we can use it as an array name to directly access each data element in the array through it. For example, you can use the form "pArr [i]" in a for loop to access each element in the array. Because the first parameter is only the first address of the array and does not contain information about the number of array elements, to access the entire array, you need to use the second int formal parameter nCount to indicate the number of data elements in the array. . In this way, we can use the first address of the array and the number of elements passed in the function, use the for loop to traverse the entire array to access the total salary, and then calculate the average salary. When calling the GetAverage () function, we call the array name arrSalary, which is a pointer to the first address of the array, and the number of array elements NUM as the actual parameters.
// Call the function with the array name and the number of data elements as the actual parameters
float fAver = GetAverage (arrSalary, NUM);
When this function call is executed, the actual parameters arrSalary and NUM are copied to the formal parameters pArr and nCount, respectively. In this way, inside the GetAverage () function, the arrSalary array can be accessed through pArr and nCount, that is, a large array is passed to the function through a small pointer. The entire process does not need to copy 100,000 int type data of arrSalary data, and replaces it with a 4-byte array first address pointer, thereby avoiding the copying of a large amount of data and improving the efficiency of function calls.
Know more: access the parameters of the main function, receive the data passed from the command line
To pass data to an ordinary function, we can do it in the form of function parameters when calling the function. But the main function is not called by us. If we want to pass data to the main function, we need to complete it with the command line parameters when executing the program. For example, if we want to pass two addends to an addition calculation program add.exe and let it calculate the result, we can execute this program as the following command, it will receive the two addends on the command line and calculate got the answer:
F: \ code> add.exe 3 4 (Enter)
3 + 4 = 7 (output result)
To do this, we need to add two arguments to the main () main function: argc of type int and argv of string pointer array type. When we execute the program on the command line, the operating system assigns values to these two parameters according to our command line instructions. Among them, the first parameter argc is the number of instructions in the command line, including the program name itself. Here, for the command line command "add.exe 3 4", the value of argc should be 3. The second parameter argv is actually an array of string pointers, where each string pointer points to each instruction string in the command line in turn. Of course, the program name is also included. In this way, argv [0] points to the string "add.exe", while argv [1] points to the string "3", and so on. After understanding these rules, we can access these two parameters in the main function to receive the data passed from the command line:
#include <iostream>
using namespace std;
int main (int argc, char * argv [])
{
// Determine whether the instruction is correct according to the number of instructions (argc)
// If it is incorrect, it prompts the correct usage
if (3! = argc) // get the number of instructions through argc
{
// Get the name of the program via argv [0]
cout << "Usage:" << argv [0] << "num1 num2" << endl;
return -1; // The command line command is invalid and an error value is returned
}
// If the instruction is correct, access the number passed on the command line through argv
// Via the atoi () function,
// Convert the strings "3" and "4" pointed to by argv [1] and argv [2] to the numbers 3 and 4 respectively
int a = atoi (argv [1]);
int b = atoi (argv [2]);
// Calculate results using converted data
int res = a + b;
// output result
// Here, the command line instructions are accessed as a string and directly output
cout << argv [1] << "+" << argv [2] << "=" << res <<
return 0;
}
In the main function, we first use argc to determine the number of command line instructions to determine whether the program is executed correctly. Then, each instruction of the program execution is obtained from the argv string pointer array. Because argv provides us with a string of command line instructions, if it is a numeric instruction, we also need to use conversion functions such as atoi () to convert the string into corresponding numerical data. After the command line instructions are converted from strings to numbers, we can use them to calculate and output the results. In the output, we use the string pointer in the argv array as a string to directly output the command line instructions.
The argc and argv parameters of the main function allow us to receive data from the command line instructions, thereby controlling the behavior of the program (providing options or data, etc.) when executing the program, which greatly increases the flexibility of program execution .
5.1.4 Function return value
So far, we know that a function is like a box with some function. The raw material data is put in through the function parameters. After a certain processing of the function box, we get the result data we want. For example, if you put two integers in the Add () function box, you can get the sum of the two integers after adding and processing. Through the function parameters, we can put the raw data into the function box, so how do we get the result data from the function box?
Remember when you declared a function, did you need to specify the return type of the function? As long as the return type of a function is not void, it has a return value, and we use the function's return value to get the result data from the function. Take the Add () function as an example:
int Add (int a, int b)
{
// calculation result data
int res = a + b;
// Use the return keyword to return the result data
return res;
}
// Call the function and get the calculation result
int nRes = Add (2,3);
Inside the function, we first add and calculate the raw material data 2 and 3 passed in as parameters to get the result data 5, then use the return keyword to end the execution of the function and return the result data (5), and call this function from From the outside, the result data is the value of the entire function call expression "Add (2,3)". Furthermore, we can assign this value to the nRes variable, and the value of the nRes variable becomes 5. That is to say, we get the result data 5 from the Add () function by the return value. In other words, the value of the function call expression is the result data taken from the function box, and the type of this data is the function's return value type.
Since the entire function call expression can be seen as the result data obtained from the function and has a specific data type, in addition to using it to assign values to variables, it can also be applied to any place where this type of value can be used directly Participate in calculations. For example, a function call expression can be used in a conditional statement to indicate whether a complex condition is true:
// The return value of the IsPassed () function is of type bool
// its calling expression can be seen as a bool type of data, which can be directly logically operated with true
if (true == IsFinished ())
{
// ...
}
In addition, a function call expression that returns a bool type can be regarded as a bool type of data, so the above code can also be rewritten into the following more concise form:
// directly determine whether the return value of the IsFinished () function is true,
// If we want to determine whether the return value of the IsFinished () function is false,
// you can use the form if (! IsFinished ())
if (IsFinished ())
{
// ...
}
In addition, the function call expression can also be applied in another function call expression, directly participating in another as a parameter Function call. E.g:
// The function call expressions Power (2) and Power (3) are integer values,
// directly used as an integer parameter of the Add () function to participate in its call
int nRes = Add (Power (2), Power (3));
When performing the calculation, the values of the two function call expressions, Power (2) and Power (3), are first calculated to obtain 4 and 9, and then the Add () function is called with these two data as parameters to obtain the final result. Results 13. The value here is a reminder that this method of treating a function call expression as some data directly participates in the calculation, although it can make the code more concise, but it reduces the readability of the code to a certain extent, so there should be Use it selectively to avoid overly complex expressions and to achieve a balance between code simplicity and readability.
It can be noticed from the above code that each function has only a unique return value. Using the function return value can only take one data out of the function. What if you want to get multiple data from the function?
Recall how we passed a large volume of data into a function? Yes, we use pointers. Using the pointer's referential characteristics, you can use pointers inside the function to access the external memory it points to and read the data in it, thereby indirectly implementing the data outside the function into the function. Similarly, when we access the external memory pointed to by a pointer, we can also write the data in the function to this memory location, thereby indirectly implementing the data in the function to the function. Don't understand? Never mind, let's look at a practical example. In our previous salary program, we need to use an InputSalary () function to input the salary data. At this time, we need to use the pointer to transfer the salary data input into the function to the function:
// Enter salary data for employees
int InputSalary (int * pArr, const int MAX_NUM)
{
// parameter validity check ...
= 0; // temporary variable, temporary data
int nIndex = 0; // input sequence number
do
{
cout << "Please enter the salary of employee" << nIndex << ":" << endl;
cin >> nTemp;
// If the input is negative or zero, it means that the input work is over, and the input loop is skipped.
if (nTemp <= 0)
{
break;
}
// Save the legal data in the array and start the next input
// Write data to the external array pointed to by the pointer to realize data transmission
pArr [nIndex] = nTemp;
++ nIndex;
} while (nIndex <MAX_NUM);
// return the total number of input data
return nIndex;
}
The first parameter pArr of the InputSalary () function points to an array outside the function that holds salary data. In this way, inside the function, we can use this pointer to save the salary data entered by the user to the external array to which it points, thereby indirectly implementing the transfer of multiple data within the function. In addition, in this function, the total number of input data is also obtained from the function by using the function return value. This also shows that both the function return value and the function pointer parameter can pass data from the function. They can be used alone or in combination. In general, function return values are mostly used to return a single small volume of data from a function, such as result data of a basic data type, and function pointer parameters are mostly used to return multiple or large volumes of data from a function, such as containing multiple data Arrays or large structures.
Now, we can use the InputSalary () function to enter salary data into the arrSalary array, and then use the previous GetAverage () function to calculate the average salary, and implement the statistical function of the salary program on the average salary:
int main ()
{
// Define the array holding salary data
t int NUM = 100000;
int arrSalary [NUM] = {0};
// Enter salary data into an array and use pointers to implement outgoing data
int nCount = InputSalary (arrSalary, NUM);
// Calculate the average salary and use the pointer to implement the incoming data
float fAver = GetAverage (arrSalary, nCount);
cout << "Average salary is:" << fAver << endl;
return 0;
}
Here, we use the array name arrSalary as the parameter of the InputSalary () function to pass data from the function, and the same arrSalary used as the parameter of the GetAverage () function to pass data into the function. This is because, through a pointer, you can either write to the memory it points to, and then transfer the data inside the function to the function. At the same time, you can also perform the read operation to transfer the data outside the function into the function. Pointer parameters can be passed in or out, and whether they are passed in or out depends on whether the function internally accesses the memory it points to, as shown in Figure 5-7.
Figure 5-7 Transferring data in and out of functions through pointers
It can also be seen from this example that after the "top-down, step-by-step refinement" function decomposition, we encapsulate the relatively independent input function and statistical function in the main function into the InputSalary () function and GetAverage () function, respectively. Realize the work of decomposing and boxing complex programs. After such decomposition and encapsulation, the main function that was relatively complicated and bloated before, now only needs to call these two sub-functions to complete all the functions. By boxing the program into functions, the entire program structure becomes clearer and easier to implement and maintain.
Original address: http://www.cnblogs.com/nihaoCPP/p/4178228.html
(Reprinted) Hello, how does C ++ (26) exchange data with functions? 5.1.3 Passing function parameters