[C++] Code examples about references

Foreword :

        References are an important feature in C++ that can make code more efficient, concise, and readable. This blog will explore the relevant knowledge of citations in depth, including the concept of citations, usage methods, advantages and precautions, etc. It is recommended to practice according to the given code cases and get familiar with it.

Table of contents

Foreword:

1. The concept of reference

2. How to use the reference

1. Basic definition and use of references

2. References are passed as function parameters

3. References as function return values

4. References and constants

5. References and multidimensional arrays

The advantages of citing

1. References can improve the efficiency of the program

2. References can improve program readability

3. References can simplify code

4. Citations can improve program design

5. References can solve the problem of multidimensional arrays

4. Precautions for reference

1. References must be initialized at definition time

2. References do not return references to local variables

3. References cannot be bound to constant literals

4. References cannot point to null values

5. References cannot be rebound

Summarize:


1. The concept of reference

        A reference is a data type in C++, which is equivalent to an alias for a variable. References can be used not only for basic data types, but also for compound data types, such as arrays, structures, and classes. In C++, references are similar to pointers, but they are quite different. The basic syntax for quoting is:

数据类型 &引用名 = 变量名;

        Among them, & means to take the address symbol, and here means to define a reference.

        The essence of a reference is a pointer constant . It is resolved to a pointer at compile time, but at runtime it behaves like a direct access to the referenced variable. The memory space occupied by the reference is the same as the referenced variable , but the reference is not an independent variable, it is just an alias of the referenced variable, so it does not have its own address. In the assembly code generated by the compiler, the use of references is converted into pointer operations such as taking addresses and indirect references.

        In C++, reference is a very convenient mechanism, which can make the code more concise and easy to read, and can also avoid some problems caused by pointers, such as out-of-bounds and null pointers.

2. How to use the reference

1. Basic definition and use of references

#include <iostream>
using namespace std;

int main() {
    int a = 10;
    int &ref = a;
    cout << "a = " << a << endl; // 输出 a 的值
    cout << "ref = " << ref << endl; // 输出引用 ref 的值
    return 0;
}

        The above code defines an integer variable a, and defines a reference ref, which points to the memory address of a. The following part outputs the values ​​of a and ref, and the result is the same.

2. References are passed as function parameters

#include <iostream>
using namespace std;

void swap(int &a, int &b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 10, y = 20;
    cout << "x = " << x << ", y = " << y << endl;
    swap(x, y);
    cout << "x = " << x << ", y = " << y << endl;
    return 0;
}

        The above code defines a swap function that uses a reference as a parameter to exchange the values ​​of two integers. The swap function is called in the main function to exchange the values ​​of x and y.

3. References as function return values

#include <iostream>
using namespace std;

int &max(int &a, int &b) {
    if (a > b) return a;
    else return b;
}

int main() {
    int x = 10, y = 20;
    max(x, y) = 30;
    cout << "x = " << x << ", y = " << y << endl;
    return 0;
}

        The code above defines a max function that returns the larger of two integers and uses a reference as the return value. Call the max function in the main function, modify its return value to 30, and output the values ​​​​of x and y.

4. References and constants

#include <iostream>
using namespace std;

int main() {
    int a = 10;
    const int &ref1 = a; // 引用指向常量
    int &const ref2 = a; // 常量引用,即引用不能被修改
    const int &const ref3 = a; // 常量引用指向常量,引用和变量都不能被修改
    cout << "ref1 = " << ref1 << endl;
    cout << "ref2 = " << ref2 << endl;
    cout << "ref3 = " << ref3 << endl;
    return 0;
}

        The above code defines three references, which are reference to constant, constant reference and constant reference to constant. On output, you can see that the second reference cannot modify the value of the variable it refers to.

5. References and multidimensional arrays

#include <iostream>
using namespace std;

void printArray(int (&a)[3][3]) {
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
}

int main() {
    int a[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
    printArray(a);
    return 0;
}

        The above code defines a two-dimensional array a, and then defines a function printArray, which uses a reference as a parameter to conveniently output the value of the two-dimensional array. Call the printArray function in the main function to output the value of a.

The advantages of citing

1. References can improve the efficiency of the program

        References can avoid unnecessary memory copies and improve program efficiency. For large data structures and objects, using references can reduce memory overhead and time consumption.

void swap(int &x, int &y) {
    int temp = x;
    x = y;
    y = temp;
}

int main() {
    int a = 1, b = 2;
    swap(a, b);
    return 0;
}

        In the function swap, we use the pointer reference int &xand int &y, so that the actual parameters of the calling function can be directly modified without copying their values ​​​​to the inside of the function. This not only avoids extra memory overhead, but also reduces the execution time of the function, thereby improving the efficiency of the program.

2. References can improve program readability

        References to aliases that are equivalent to variables can make the code more concise and easy to read, and reduce the possibility of errors. In function calls, using references can make the meaning of function parameters and return values ​​clearer and easier to understand and maintain.

#include<iostream>
using namespace std;

void square(int & x) {
    x *= x;
}

int main() {
    int a = 2;
    square(a);
    cout << "The square of 'a' is: " << a << endl;
    return 0;
}

        Inside the function square, we use a reference int & x, which clearly expresses xthe value we will modify, and its value will be passed back outside the function. Doing so makes the program look clearer and easier to understand.

3. References can simplify code

        References can avoid frequent pointer operations and make the code more concise. Using references can make the code more readable and understandable, reduce the possibility of errors, and make the code easier to maintain and debug.

#include<iostream>
using namespace std;

void print(int & x) {
    cout << "The value of 'x' is: " << x << endl;
}

int main() {
    int a = 5;
    print(a);
    return 0;
}

        In the function print, we use a reference int & x, which avoids creating a new variable in the function to hold xa copy of the parameter. Doing so simplifies the code and is much cleaner.

4. Citations can improve program design

        The use of references can make the program more flexible and facilitate the optimization of object references, data transfer, and memory management. Passing a reference as a function parameter allows the function to process without changing the original data, which enhances the scalability and reusability of the program.

#include<iostream>
#include<string>
using namespace std;

class Person {
    private:
        string name;
        int age;
    public:
        void setName(string & n) {
            name = n;
        }
        void setAge(int & a) {
            age = a;
        }
        void print() {
            cout << "Name: " << name << ", Age: " << age << endl;
        }
};

int main() {
    string name = "Jack";
    int age = 25;
    Person p1;
    p1.setName(name);
    p1.setAge(age);
    p1.print();
    return 0;
}

        In the class Person, we use references string & nand int & a, so that we can pass the values ​​of the actual parameters into the class member variables instead of copying their values ​​​​in the function. Doing so improves the reusability and modularity of the code, making the code more robust and maintainable.

5. References can solve the problem of multidimensional arrays

        In C++, when a multidimensional array is passed to a function, it will degenerate into a pointer to the first element of the array, which will cause the information of the array to be lost. The solution to this problem is to use references. References can directly refer to multi-dimensional arrays, avoiding the loss of array information, and conveniently operate on multi-dimensional arrays.

#include<iostream>
using namespace std;

const int ROW = 5;
const int COL = 5;

void print_array(int (* arr)[COL]) {
    for(int i=0; i<ROW; i++) {
        for(int j=0; j<COL; j++) {
            cout << arr[i][j] << " ";
        }
        cout << endl;
    }
}

int main() {
    int arr[ROW][COL] = {
   
   {1, 1, 1, 1, 1}, {2, 2, 2, 2, 2}, {3, 3, 3, 3, 3}, {4, 4, 4, 4, 4}, {5, 5, 5, 5, 5}};
print_array(arr);
return 0;
}

        In the function `print_array`, we use the pointer to the integer array to refer to `int (* arr)[COL]`, so that a two-dimensional integer array with any number of rows and columns can be passed. This makes the code more concise, makes the code easy to understand, and can handle various types of arrays, improving the flexibility and scalability of the program.

4. Precautions for reference

1. References must be initialized at definition time

        Once a reference is defined, the variable it refers to cannot be changed, so it must be initialized when the reference is defined. If you uninitialize a reference, or try to point a reference to a variable that doesn't exist, your program will crash.

Here is a sample C++ code that references uninitialized:

int main() {
    int &a; // 错误:引用必须在定义时初始化
    return 0;
}

        In this example, we define a reference of type int a, but this reference is not initialized, so the compiler will generate an error. Therefore, we must initialize the reference at definition time.

2. References do not return references to local variables

        Do not return pointers and references to local variables in functions, because local variables are destroyed after the function finishes executing, and returning a pointer or reference to it will result in undefined behavior.

The following is a C++ sample code that returns a local variable reference:

#include<iostream>
using namespace std;

int &get_int() {
    int a = 5;
    return a; // 错误:返回局部变量引用
}

int main() {
    int b = get_int();
    cout << "The value of 'b' is: " << b << endl; // 输出'The value of 'b' is: -858993460',出现了未定义行为
    return 0;
}

        In the function get_int, we define a local variable aand return its reference. This is bad practice because when the function get_intcall ends, the reference will be bound to a variable that no longer exists, leading to undefined behavior.

3. References cannot be bound to constant literals

        Constant literals, such as 3.14 and "hello", are not stored in memory, so references cannot be bound to them. Attempting to do so will cause the program to crash. The solution to this problem is to assign the constant literal to a variable and then bind the reference to the variable.

Here is a sample C++ code that binds a reference to a constant literal:

int main() {
    int &a = 5; // 错误:不能将引用绑定到常量字面量
    return 0;
}

        In this example, we are trying to bind an integer reference ato a constant literal 5, which is wrong because constant literals cannot be modified. Therefore, in this case, we should use constants instead of references.

4. References cannot point to null values

        A reference cannot point to a null value because a reference is a pointer constant and it needs to point to an existing variable. Trying to make a reference to a null value will cause the program to crash. The way to solve this problem is to use pointers, which can be initialized to NULL, which means pointing to a null value.

Here is a sample C++ code that references a null value:

int main() {
    int *ptr = NULL;
    int &ref = *ptr; // 错误:引用指向空值,会导致未定义行为。
    return 0;
}

        In this example, we define a null pointer ptrand try to dereference it and assign the result to an integer reference ref, which is wrong because a null pointer cannot be dereferenced. So, in this case, we need to make sure that the pointer points to a valid memory address, otherwise undefined behavior occurs.

5. References cannot be rebound

        Once a reference is bound to a variable, it cannot be rebound to another variable. Attempting to do so will cause the program to crash. Therefore, special care needs to be taken when using references to avoid this problem.

Here is a sample C++ code where references are rebound:

int main() {
    int a = 1, b = 2;
    int &ref = a;
    ref = b; // 引用a被改变,而不是b
    return 0;
}

        In this example, we define an integer reference refwhose initial binding object is a variable a, and then we try to rebind it to the variable b, but doing so does not change refthe binding object of the reference, but changes the binding object. Specifies the value of the variable corresponding to the object. So in this case we have to use a new reference to bind to the variable b.

Summarize:

        Reference is a very important feature in C++. It can improve the efficiency, readability and flexibility of the program, and facilitate programmers to perform operations such as object reference, data transfer, and memory management. When using references, you need to pay attention to some details, such as the definition and initialization of references, and do not return references to local variables. Proficiency in the use of references can make C++ programs more beautiful, efficient and easy to maintain.

Guess you like

Origin blog.csdn.net/crr411422/article/details/130932100