C ++ by value and pass by reference

By value parameters

First, you must understand one truth: When you initiate a non-reference type variable initial values ​​are copied to the variable, then changes to variables will not flock to the initial value

int n = 0;
int i = 1;  // i是n的副本
i = 42;     // i的值改变,n的值不改变

The mechanism of transfer values of the parameters exactly the same, since each function call will re-create its parameter, and use the incoming parameter arguments to initialize , so all operations function parameter do not affect the argument , if we want the function to change the way we passed argument itself could have used a pointer parameter access external object function

Pointer parameter

Look at the piece of code:

int n = 0;
int i = 1;
int *p1 = &n; //p1指向n
int *p2 = &i; //p2指向i
*p1 = 42;     //n的值改变,p1不变
p1 = p2       //现在p1指向了i,但是i和n的值都不变

When performing copying operation pointer, copy the value of a pointer (address), then the copy, two pointers are different pointer as pointer allows us to indirectly access the object points, it is possible to modify the value of the object through a pointer

Pointer parameter does not have poor

// 接受一个int类型的指针,然后将指针所指向的对象置0
void reset(int* ip)
{
    *ip = 0; // 改变指针ip所指向对象的值
    ip = 0;  // 只改变了ip的局部拷贝,实参未被改变
}

void reset(int i)
{
    i = 0; 
}

int main()
{
    int i = 42;
    reset(i);                   // 改变i的值而非i的地址
    cout << "i = " << i << endl;
    reset(&i);                  // 改变i的值而非i的地址
    cout << "i = " << i << endl;
}

After calling this reset function, the argument object pointed to is set to 0, but the argument itself does not change, the output is as follows

i = 42

i = 0

Programmers familiar with C-shaped pointer to the object may be often used functions access to external parameters, but it is recommended to use in place of a reference parameter of type pointer in C ++

Reference arguments

We know that the operation is actually cited the role on the object referenced in:

int n = 0;
int i = 1;
int &r = n; // r绑定了n
r = 42;     // 现在n=42
r = i;      // 现在n的值和i相同=1
i = r;      // i的值和n相同

Similar reference shape Participation by reference parameter, to allow the function to change the value of the argument

// 接受一个int对象的引用,然后将对象的值置为0
void reset(int& i)
{
    i = 0; //改变了i所引对象的值
}

When you call this version of the reset, the incoming object directly without having to pass the address of the object to be changed is the argument passed reset

void reset(int& j)
{
    j = 0; //改变了i所引对象的值
}

int main()
{
    int j = 42;
    reset(j);
    cout << "j = " << j << endl;
}

Output:

j = 0

Avoid copy

For example, we are ready to write the length of a function to compare two string objects, objects may be very long, so they should try to avoid direct copy, this time a reference parameter copy can be avoided

Because the object without changing the content, so the parameter is defined as a reference to the constant

bool isShoter(const string &s1, const string &s2)
{
    return s1.size() < s2.size();
}

const argument parameter and

Briefly review under the const

const int ci = 42;  //顶层const,不能改变ci
int i = ci;         //√ 拷贝时候忽略了ci的顶层
int* const p = &i;  //顶层const,不能给p赋值(改变p指向的对象)
*p = 0;             //√ 可以通过p改变对象内容,i = 0

Comments on the const: https://www.cnblogs.com/zhxmdefj/p/11524403.html

Like, when initialization parameter is ignored by the top-level const

void fucn(const int i) {
    //fucn能读i,但不能向i写值
}
//调用fucn时,既可以传入const int,也可以传入int

But it will also pay attention to a problem

void fucn(const int i) {
    //fucn能读i,但不能向i写值
}

void fucn(int i) {}

Because the top const is ignored, so the above two parameters can fucn exactly the same, so the second will complain fucn

Const pointers or references between Form

Parameter initialization mode and variable initialization method is the same, the first review under the initialization rules:

int i = 42;
const int* cp = &i; //√ cp不能改变i
const int& r = i;   //√ r能改变i
const int& r2 = 42; //√ 
int* p = cp;        //× p的类型和cp不匹配
int& r3 = r;        //× r3的类型和r不匹配
int& r4 = 42;       //× 不能用字面值初始化非常量引用

Specific analysis: https://www.cnblogs.com/zhxmdefj/p/11524403.html

The same rules apply to the transfer parameters:

void reset(int* ip)
{
    *ip = 0; // 改变指针ip所指向对象的值
    ip = 0;  // 只改变了ip的局部拷贝,实参未被改变
}

void reset(int& j)
{
    j = 0; //改变了i所引对象的值
}

int main()
{
    int i = 0;
    const int ci = i;
    string::size_type ctr = 0;
    reset(&i);      //√ 调用void reset(int* ip)
    reset(&ci);     //× 不能用指向const int对象的指针初始化int*
    reset(i);       //√ 调用void reset(int& j)
    reset(ci);      //× 不能把普通引用绑定到const对象ci上
    reset(42);      //× 不能把普通引用绑定到字面值上
    reset(ctr);     //× ctr是无符号类型,类型不匹配
}

Try to use const reference

The function will not change the parameter defined as common references, often give a misleading caller function: The function can modify the value of its argument

While the argument is also greatly limits acceptable function (such as the above reset unacceptable const)

Array parameter

Characteristics of the two arrays: 1 will not allow copies of the array using an array 2 which is converted to a pointer.

Therefore, we can not use an array passed by value and pass an array, actually passed is pointing to the first element pointer

//等价
void print(const int*);
void print(const int[]);
void print(const int[10]);

The above three functions are equivalent, the only parameters are the shape of each function type const int *

void print(const int*);

int main()
{
    int i = 0;
    int j[2] = { 0,1 };
    print(&i);      //√ &i的类型是int*
    print(j);       //√ j转换成int*指向j[0]
}

Management array argument

Specified in the tag array length

(C-style character string stored in the character array, the last character followed by a null character)

//输出C风格字符串
void print(const char* cp) {
    if (cp)                 //若cp不是一个空指针
        while (*cp)         //只要指针所指的字符不是空字符
            cout << *cp++;  //输出当前字符,并向后移动一个位置
}

This method is applicable to the case where a clear end mark

Use standard library specification

Passing a pointer to the first array element and the rear tail element

//输出beg到end之间(不含end)所有元素
void print(const int* beg, const int* end) {
    while (beg != end)
        cout << *beg++ << endl; //输出当前元素,并向后移动一个位置
}

Passing a display showing the size of the array argument

C programs and old C ++ programmers often use this technique

void print(const int* ia, size_t size) {
    for (size_t i = 0; i != size; ++i)
        cout << ia[i] << endl;
}

And PS on array parameter const: when the function does not need to perform a write operation of the array element, the array should be the parameter of a pointer const

Array reference parameter

C ++ allows the definition of variables as a reference of the array, the parameter may be a reference to an array

void print(int(&arr)[10]) {
    for (auto elem : arr)
        cout << elem << endl;
}

Note (& arr) at both ends of the brackets essential

f(int &arr[10])     //arr是有10个整形引用的数组
f(int (&arr)[10])   //arr是有10个整数的整形数组的引用

Pass multidimensional arrays

Multidimensional array is actually an array of arrays, the first element is an array itself, bursts is a pointer to an array

//martrix指向数组的首元素,该数组的元素是由10个整数构成的
void print(int(*martrix)[10], int rowSize) {
}

(* Martrix) both ends of the brackets essential

//等价定义
void print(int martrix[][10], int rowSize) {
}

Guess you like

Origin www.cnblogs.com/zhxmdefj/p/11541763.html