• C++ pointer from beginner to advanced


    Introduction to C++ pointers

    #include 
    
    using namespace std;
    
    int main() {
        int n = 5;
        cout << n << endl;
        cout << &n << endl;  // address of n
    
        int *ptr = &n;
        cout << ptr << endl;
        cout << *ptr << endl;
    
        *ptr = 10;
        cout << *ptr << endl;
        cout << n << endl;  // 10
    
    
        /* pointer should be initialized before deference
        int *ptr1;
        *ptr1 = 6;  // Variable 'ptr1' is uninitialized when used here
        */
    
        int v;
        int *ptr2 = &v;
        *ptr2 = 6;          // deference pointer
        cout << "v=" << v << endl;  // 6
    
        return 0;
    }
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30

    What is a void pointer?

    #include 
    
    using namespace std;
    
    void printNumber(int *numberPtr) {
        cout << *numberPtr << endl;
    }
    
    void printLetter(char *letterPtr) {
        cout << *letterPtr << endl;
    }
    
    // void pointer can point to any data type
    void print(void *ptr, char data_type) {
        switch (data_type) {
            case 'i':
                cout << *((int *) ptr) << endl;  // cast void pointer into an int pointer
                break;
            case 'c':
                cout << *((char *) ptr) << endl;
    // be careful when using void pointer, compiler don't know you are making an error or not in this particular situation:
    //            cout << *((float *) ptr) << endl;
                break;
            default:
                cout << *((double *) ptr) << endl;
        }
    }
    
    int main() {
        int number = 1;
        printNumber(&number);
        char letter = 'a';
        printLetter(&letter);
    
        print(&number, 'i');
        print(&letter, 'c');
    
        return 0;
    }
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    How to use pointers and arrays

    #include 
    
    using namespace std;
    
    void test1() {
        int luckyNumbers[5] = {1, 2, 3, 4, 5};
        cout << &luckyNumbers[0] << endl;  // 012FF704  // address of first element
        cout << &luckyNumbers[1] << endl;  // 0083FD08
        cout << &luckyNumbers[2] << endl;  // 0083FD0C
    
        cout << endl;
        cout << luckyNumbers << endl;      // 012FF704  // address of first element
        cout << luckyNumbers + 1 << endl;  // 012FF708
        cout << luckyNumbers + 2 << endl;  // 012FF70C
    
        cout << endl;
        cout << *(luckyNumbers + 1) << endl;  // 2
        cout << *(luckyNumbers + 2) << endl;  // 3
    }
    
    int main() {
    //    test1();
    
        int luckyNumbers[5];
        for (int i = 0; i < 5; ++i) {
            cout << "Number: ";
            cin >> luckyNumbers[i];
        }
    
        for (int i = 0; i < 5; ++i) {
            cout << *(luckyNumbers + i) << " ";
        }
    
        /* if change iteration to 6, we will get a junk number, so be careful when iterating through array or using pointer
        for (int i = 0; i < 6; ++i) {
            cout << *(luckyNumbers + i) << " ";
        }
        1 2 3 4 5 -858993460
        */
    }
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    Return multiple values from a function using pointers?

    #include 
    
    using namespace std;
    
    int getMin(const int numbers[], int size) {
        int min = numbers[0];
        for (int i = 1; i < size; ++i) {
            if (numbers[i] < min) {
                min = numbers[i];
            }
        }
        return min;
    }
    
    int getMax(const int numbers[], int size) {
        int max = numbers[0];
        for (int i = 1; i < size; ++i) {
            if (numbers[i] > max) {
                max = numbers[i];
            }
        }
        return max;
    }
    
    // using pointer to return multiple value from a function
    void getMinMax(const int numbers[], int size, int *min, int *max) {
        for (int i = 1; i < size; ++i) {
            if (numbers[i] > *max) {
                *max = numbers[i];
            }
            if (numbers[i] < *min) {
                *min = numbers[i];
            }
        }
    }
    
    int main() {
        int numbers[5] = {1, 3, -2, 10, 28};
        cout << "min is " << getMin(numbers, 5) << endl;
        cout << "max is " << getMax(numbers, 5) << endl;
    
        int min = numbers[0], max = numbers[0];
        getMinMax(numbers, 5, &min, &max);
        cout << "min is " << min << " " << "max is " << max << endl;
        return 0;
    }
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    Dynamic arrays - How to create/change arrays at runtime?

    // Dynamic arrays
    #include 
    
    using namespace std;
    
    /*
     * we want to achieve some situations such as below:
        int size;
        cin >> size;
        int myArray[size];
    
       however, the size of the array had to be constant, which means that
       the size of the array had to be known before we started our program.
    
       we can use dynamic array as a solution. For example:
       new keyword allocates memory: an array of specific size by user,
       and that address of the first element of array is stored in this myArray pointer.
     */
    
    int main() {
        int size;
        cout << "Size: ";
        cin >> size;
    
        int *myArray = new int[size];
    
        for (int i = 0; i < size; ++i) {
            cout << "myArray[" << i << "]: ";
            cin >> myArray[i];
        }
    
        for (int i = 0; i < size; ++i) {
    //        cout << myArray[i] << " ";
            cout << *(myArray + i) << " ";
        }
    
        delete[] myArray;  // deallocate memory
        myArray = nullptr;
    
        return 0;
    }
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    Two-dimensional dynamic array

    #include 
    
    using namespace std;
    
    int main() {
        int rows = 3, cols = 5;
    
        int **table = new int *[rows];  // pointer to pointer, create a new interger array of pointers
    
        for (int i = 0; i < rows; ++i) {  // for each element, create a separate dynamic array
            table[i] = new int[cols];
        }
    
        table[1][2] = 100;  // access to elements on a specific position
    
        for (int i = 0; i < rows; ++i) {
            delete[] table[i];
        }
        delete[] table;
        table = nullptr;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    Function pointer

    #include 
    #include 
    
    using namespace std;
    
    int getNumber() {
        return 5;
    }
    
    int add_two_num(int a, int b) {
        return a + b;
    }
    
    bool ascendingCompare(int a, int b) {
        return a < b;
    }
    
    bool decendingCompare(int a, int b) {
        return a > b;
    }
    
    
    void sortAscending(vector<int> &numbersVector) {
        for (int i = 0; i < numbersVector.size(); ++i) {
            int bestIndex = i;
            for (int curIndex = i + 1; curIndex < numbersVector.size(); ++curIndex) {
                if (ascendingCompare(numbersVector[curIndex], numbersVector[bestIndex])) {
                    bestIndex = curIndex;
                }
            }
            swap(numbersVector[i], numbersVector[bestIndex]);
        }
    }
    
    
    void sortDescending(vector<int> &numbersVector) {
        for (int i = 0; i < numbersVector.size(); ++i) {
            int bestIndex = i;
            for (int curIndex = i + 1; curIndex < numbersVector.size(); ++curIndex) {
                if (decendingCompare(numbersVector[curIndex], numbersVector[bestIndex])) {
                    bestIndex = curIndex;
                }
            }
            swap(numbersVector[i], numbersVector[bestIndex]);
        }
    }
    
    
    // use function pointer to optimize two functions above
    void customSort(vector<int> &numbersVector, bool (*compareFunc)(int, int)) {
        for (int i = 0; i < numbersVector.size(); ++i) {
            int bestIndex = i;
            for (int curIndex = i + 1; curIndex < numbersVector.size(); ++curIndex) {
                if (compareFunc(numbersVector[curIndex], numbersVector[bestIndex])) {
                    bestIndex = curIndex;
                }
            }
            swap(numbersVector[i], numbersVector[bestIndex]);
        }
    }
    
    
    void printNumber(const vector<int> &numbersVector) {
        for (int i: numbersVector) {
            cout << i << " ";
        }
        cout << endl;
    }
    
    int main() {
    
        /*
         * introduction
         */
        int (*funcPtr)() = getNumber;
        cout << funcPtr() << endl;
    
        int (*funcAdd)(int, int) = add_two_num;
        cout << funcAdd(3, 3) << endl;
    
        // compile error when lacking parameter
        // Cannot initialize a variable of type 'int (*)()' with an lvalue of type 'int (int, int)': different number of parameters (0 vs 2)
        // int (*funcAdd)() = add_two_num;
    
    
        /*
         * demo of using function pointer
         */
        vector<int> myNumbers = {2, 5, 1, 3, 6, 4};
        sortAscending(myNumbers);
        printNumber(myNumbers);
    
        vector<int> myNumbers2 = {2, 5, 1, 3, 6, 4};
        customSort(myNumbers2, ascendingCompare);
        printNumber(myNumbers2);  // 1 2 3 4 5 6
        customSort(myNumbers2, decendingCompare);
        printNumber(myNumbers2);  // 6 5 4 3 2 1
    
        return 0;
    }
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    Smart pointer

    #include 
    #include 
    
    using namespace std;
    
    /*
     * smart pointer: the memory is deallocated automatically which means don't worry about leaking memory
     */
    
    void test_demo() {
    // create a unique pointer to an integer and assign value of 25 to address that unPtr1 is pointing to
        unique_ptr<int> unPtr1 = make_unique<int>(25);
    
    //  cout << unPtr1 << endl;
        cout << *unPtr1 << endl;
    
    //  unique_ptr unPtr2 = unPtr1;  // error, can't assign a unique pointer to another unique pointer
    
        unique_ptr<int> unPtr2 = move(unPtr1);
        cout << *unPtr2 << endl;
    //  cout << *unPtr1 << endl;  now, the pointer unPtr1 is empty, it's not pointer
    }
    
    
    class MyClass {
    public:
        MyClass() {
            cout << "Constructor invoked" << endl;
        }
    
        ~MyClass() {
            cout << "Destructor invoked" << endl;
        }
    };
    
    
    void test_unique_pointer() {
        {
            unique_ptr<MyClass> unPtr1 = make_unique<MyClass>();  // Constructor invoked
        }  // Destructor invoked
    }
    
    
    void test_shared_pointer() {
        /*
         * the momory location will automatically be deallocated when there is no pointer pointing to that memory location
         */
        shared_ptr<MyClass> sharedPtr1 = make_shared<MyClass>();  // shared_ptr {...} [1 strong ref] [make_shared]
        cout << sharedPtr1.use_count() << endl;  // 1
        {
            shared_ptr<MyClass> sharedPtr2 = sharedPtr1;
            cout << sharedPtr1.use_count() << endl;  // 2
        }
        cout << sharedPtr1.use_count() << endl;  // 1
    }
    
    /*
     * main difference between a `weak pointer` and a `shared pointer`:
     * When assign a specific memory locaion to a `shared pointer`,
     *      that is going to increase the number of owners of that memory location,
     *      using shared pointer will keep object in memory alive.
     * But if assign that same memory location to a `weak pointer`,
     *      that will not increase the number of its owners,
     *      this means that we use weak pointer in order to observe objects in memory, to locate a specific object,
     *      but weak pointer will not keep that object alive if nothing else needs it.
     *
     */
    void test_weak_pointer() {
        weak_ptr<int> weakPtr1;
        {
            shared_ptr<int> sharedPtr1 = make_shared<int>(25);  // shared_ptr 25 [1 strong ref] [make_shared]
            weakPtr1 = sharedPtr1;
            // value of weakPtr1 changes:
            // empty  ->  weak_ptr 25 [1 strong ref, 1 weak ref] [make_shared]  ->  expired [1 weak ref] [make_shared]
        }
    }
    
    
    int main() {
    //    test_demo();
    //    test_unique_pointer();
    //    test_shared_pointer();
        test_weak_pointer();
        return 0;
    }
    
    • 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
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    Video Tutorial Link:https://www.youtube.com/watch?v=kiUGf_Z08RQ&t=1746s

  • 相关阅读:
    asp.net+sqlserver+c#学生作品展示及评分系统
    [工具] 站长好帮手V1.0,站长人手一份的好工具;集成多域名SEO自动推送,密码资料管理,流水账管理,网盘分享链接管理,备忘录管理,永久免费使用
    数据库设计详细教程上篇(数据库设计流程)
    html设计(两种常见的充电效果)
    Django--重定向redirect
    mysql—查询加强练习
    react 及 umi 分别如何使用阿里的字体图标
    基于PHP+MySQL动漫周边商城销售网站的开发与设计
    【Python简明教程二十八】PIP
    stack栈、queue队列、list链表容器
  • 原文地址:https://blog.csdn.net/qq_31362767/article/details/126032001