C + + value passing and reference passing

Source: Internet
Author: User

Today look at the data structure, because it is a C language version, just beginning to learn the hands on the hand of the burn, today, the discovery of the parameters when the,& symbol is also inexplicably, searched a good article, reproduced down.

First, Basic theory of function parameter transfer mechanism

The problem of function parameter passing mechanism is essentially the method that calls the function (procedure) and the called function (procedure) to communicate when the call occurs. There are two basic parameter passing mechanisms: value passing and reference passing. The following discussion calls functions that call other functions as the main function, and the function being called is the function being tuned.

In the process of value passing (passl-by-value), the formal parameters of the called function are treated as local variables of the called function, that is, the memory space is opened up in the stack to hold the value of the arguments put in by the key function, thus becoming a copy of the argument. the characteristic of value passing is that any operation of the function on the formal parameter is done as a local variable, without affecting the value of the argument variable of the main key function.

In the process of reference passing (pass-by-reference), the formal parameters of the called function, while also opening up memory space in the stack as local variables, are stored in the address of the argument variable that is put in by the main key function. any operation of the modulated function on the formal parameter is handled as an indirection, that is, the argument variable in the keynote function is accessed through the address stored in the stack. Because of this, any action taken by the modulated function on the parameter affects the argument variables in the keynote function.

Second, C the mechanism of function parameter passing in language

In the C language, value passing is the only available parameter passing mechanism. However, as far as I know, because of the effect of pointer variables as function parameters, many friends also think this situation is a reference pass. This is wrong. Take a look at the following code:

int swap (int *x, int *y)

{

int temp;

temp = *x; *x = *y; *y = temp;

return temp;

}

void Main ()

{

int a = 1, b = 2;

int *P1 = &a;

int *P2 = &b;

Swap (P1, p2)

}

The function swap takes two pointer variables as arguments, and when main () calls swap, the pointer variable p1, the value ofP2 (that is, the address of the variable A,b) is placed in the way of the value passed in the Swap is in the memory unit of the form parameter x, Y, which is opened in the stack.

Here we can get the following points:

  1. the stack store of a process is the primary area in which the master function and the modulated function communicate.

  2. The parameters in the C language are stacked from right to left.

  3. the stack area structure used by the tuned function is:

Local variables (such as temp)

return address

function parameters

Low Address

High Address

  4. The stack is cleaned up by the keynote function after the call.

  5. The return value of a function is typically placed in a register.

  Here are some additional points to note: First, the way the parameters are stacked. for internal types, the push instruction is used directly because the compiler knows the size of the memory used for each type of variable , and for a custom type (such as structure), a byte transfer from the source address to the destination (stack area) address is used to stack. The second is why the function return value is generally placed in the register , which is mainly to support interrupts, if placed on the stack may be overwritten because of the interruption. third, if the return value of the function is large , the byte is transferred from the stack to the address unit that holds the return value (which is provided by the main function before the call to the tuned function) for the purpose of the return. For the second and 3rd, "thinking in C + +" a book in Chapter 10 has a better elaboration. Four is an obvious conclusion that it is meaningless to return the address of the local variable in the function of the call, because the local variable is stored in the stack, and the stack is cleaned up after the invocation, and the addresses become invalid.

Third, C + + the mechanism of function parameter passing in language

As we all know, there are three ways to pass parameters when calling a function in C + +:

(1) transfer value call;

(2) call (pass pointer);

(3) citation transfer;

In fact, there is also a way to pass the parameter, that is, the global variable delivery mode. The "global" variable here is not necessarily the real global, all the code can be directly accessed, as long as the scope of the variable is sufficient to access the two functions, such as a class of two member functions can use a member variable to implement parameter passing, or use the static keyword definition, or use namespace for limitations, and the member variables here can be called "global" variables in this sense (there is no other word that is better than "global" for the moment). Of course, you can use real global variables outside of a class to implement parameter passing, but sometimes it's not necessary, and engineering, the smaller the scope the better. What are the advantages of this approach?

High Efficiency!

Indeed, this efficiency is the most efficient of all parameter passing methods, higher than the previous three methods, regardless of the circumstances. However, there is a fatal weakness in this way, that is, the support of multithreading is not good, if two processes call the same function at the same time, and through the global variables to pass parameters, the function can not always get the desired results.

The above three function passes are discussed separately.

1. From the function. Pass by value at the time of delivery, the argument is copied a copy, and then used in the function body, the function body modifies The parameter variable is a copy of the argument, and the argument itself is not changed, so if you want to modify the value of the argument in the called function, using the value of the pass is not achieved, You can only use reference or pointer delivery at this time. For example, to implement two numeric exchanges.

void swap (int a int b)

void Main () {

int A=1 b=2

Swap (a B)

}

Thus, the a-B value in the main () function is not actually exchanged, and if you want the interchange to be passed only with pointers or references, such as:

void swap (int pa int pb)

Or

void swap (int& ra int& RB)

2.from the transfer efficiency. The transfer efficiency here is that the code that invokes the called function passes the arguments to the body of the modulated function., as in the code above, this process is the functionIn Main ()A b passed to the functionThe procedure in swap (). This efficiency cannot be generalize. For built-inint char short long float etc.In the case of data types of 4 bytes or less, it is only necessary to pass1- 4 bytes, while using pointers when passing in 32 bit Span style= "font-family: ' Times New Roman ';" >cpu in the 32-bit pointers, double  long long et Span style= "font-family: ' Times New Roman ';" > 8 bytes of data, in 32-bit cpu, It is more efficient than passing pointers because 8 bytes Required 2 takes out. And in 64-bit cpu, The efficiency of the transfer and the transmission is the same. The reference pass, this depends on the compiler implementation, the most obvious way to implement the reference is to use pointers, in this case, the efficiency of the pointer is the same, and in some cases the compiler can be optimized, the use of direct addressing, in this case, efficiency than the value of the call and the invocation of the call is faster, It is quite efficient to pass the global variable in the above-mentioned way.

Besides the custom data type, theclass struct defines the data type. These data types generate a temporary object when a call is made to execute the constructor, and when the temporary object is destroyed, the destructor is executed, and if the constructors and destructors perform more tasks, or if the object size is larger, then the consumption of the call to the value is larger. In this case, the efficiency of the invocation of the call and the invocation of the reference is quite similar, as mentioned above, in some cases the reference pass may be optimized, and the overall efficiency is slightly higher than the address call.

3. from the efficiency of implementation. The efficiency of execution, as described here, refers to the efficiency of execution in the called function body. because the values are passed to the function body when the value is called, when the temporary object is generated, all the execution tasks are performed by direct addressing, and the pointers and most of the references are executed in an indirect manner, so the actual execution efficiency is lower than the value call. If the function in the body of the arguments passed over the variable to operate more frequently, the total number of executions of the case, the transmission of the call and the majority of cases of reference parameter delivery will result in a more obvious execution efficiency loss.

Combined with 2,32 cases, the specific implementation efficiency to the actual situation, by comparing the transfer process of resource consumption and execution function body consumption of the sum to choose which situation is more appropriate. as far as the efficiency of reference passing and pointer passing is, the efficiency of reference passing is always not lower than that of pointer passing, so in this sense, C The use of reference passing instead of pointers is preferred when parameters are passed in + +.

4. From a type safety perspective. Value passing and reference passing perform strongly typed checks during parameter passing, and the type check passed by the pointer is weaker, especially if the argument is declared void, it basically has no type checking, and as long as it is a pointer, the compiler considers it to be legal, so this gives the bug a chance to create The robustness of the program is slightly worse, if not necessary, the use of value passing and reference passing, it is best not to pass the pointer, better use of compiler type checking, so that we have fewer error opportunities to increase the robustness of the code.

Here is a special case, that is, for polymorphic situations, if the formal parameter is a parent class, and the argument is a subclass, when the value is passed, the temporary object constructs only the part of the parent class, is a purely parent class object, and does not construct any particular part of the subclass, because Virtual destructors, and no virtual constructors, this is a point to note. This is not possible if you want to get some subclass-specific behavior in the called function by calling virtual functions.

5. From the parameter check. A robust function that always checks the parameters passed in to ensure the legitimacy of the input data to prevent damage to the data and to better control the program in the desired direction, in which case it is much safer to use value passing than to pass the pointer, because you cannot pass a nonexistent value to a value parameter or a reference parameter. The use of pointers is likely to be an illegal address (no initialization, pointers to objects that have been deleted). So using value passing and reference passing can make your code more robust, whether it's using references or using it, the simplest principle is to see if the data type passed is not built-in, the built-in data type takes precedence over the value, and for the custom data type, especially the larger object, Then, use reference delivery.

6. From the flexibility. There is no doubt that pointers are the most flexible, because pointers can pass a null pointer, without passing any object, in addition to passing a specific type of object, such as value passing and reference passing. This advantage of pointers makes it useful, such as the time () function in the standard library, where you can pass a pointer to it, fill the value to the specified address, and you can pass a null pointer as long as the value is returned.

The advantages and disadvantages of four kinds of parameter transfer methods are discussed, and some common useful techniques are discussed in the process of parameter transfer.

1. Const keyword. when your parameters are input parameters, you do not want your input parameters to be modified, otherwise it is possible to generate a logic error, you can declare the function in front of the parameter with the const keyword, to prevent accidental modification of the function input when implemented. Programmers who use your code can also tell them that this parameter is input, and that the parameter without the CONST keyword may also be the output. such as strlen, you can declare

int strlen (char str)

There is certainly no problem with the function, but you want to tell the person using the function, the parameter str is an input parameter, it points to the data can not be modified, this is what they expect, there will be no one would like to ask people to give him a few dollars, there is a 100 into 10 pieces of the, Or the real money becomes counterfeit, they want a guarantee that the function will not break any of your data, and that the declaration will be reassuring to them as follows:

int strlen (const char str)

Can you add a limit to str itself, if the address is changed to a number of results is wrong? You have to give people a bit of freedom, as long as it helps you count the money on the line, why do you mind how he counted it? As long as you do not break your money is OK, if you give str a limit, there will be problems, according to the above statement, can be implemented as follows:

int strlen (const char str)

{int cnt

if (!STR) return 0

CNT = 0

while ((str++)) {

++cnt

}

Return CNT

}

But if you want to change the statement

int strlen (const char const STR)

The above function must not be able to run, can only use other implementations, but this is not too necessary. As long as we protect our money on the line, if it is wrong, next time I don't let it count, then another person is.

for member functions, if we are going to show the client code that a member function does not modify the value of the object, it will read only some content, or it can add a Const.

Class Person

{......

Public

unsigned char age (void) const//See Const is relieved that this function will definitely not modify m_age

Private

unsigned char m_age//I think this type is long enough, if you don't think it can be changed to unsigned long

}

2. default value. I think it's a handy feature to add a default value to a parameter, so you can define a function with several parameters, and then give some default values to the less commonly used parameters, and if the customer code thinks those default values are exactly what they want, It is convenient to simply fill in the necessary arguments when calling the function, which eliminates the hassle of overloading several functions. But I don't understand why C # has removed this feature, possibly for security, requiring that the function be given an argument every time it is called. So pay attention, this is a double-edged sword, if you want to use the knife to dewford with opponents, it is likely to hurt themselves.

3. parameter order. when the same function name has different parameters, if you have the same parameters as far as possible to put the parameters in the same position, to facilitate the client code.

C + + are frequently used in constant references, such as the SWAP2 instead:

    SWAP2 (const int& x; const int& y)

You will not be able to modify the contents of the reference address in the function, specifically,x and y will not appear to the left of "=".

Address: http://blog.chinaunix.net/uid-21411227-id-1826834.html

C + + value passing and reference passing

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.