zoukankan      html  css  js  c++  java
  • c++之指针

    一、指针的基本概念

    指针的作用:可以通过指针间接访问内存。

    • 内存编号是从0开始记录的,一般用十六进制数字表示。
    • 可以利用指针变量保存地址。

    二、指针变量的定义和使用

    指针变量定义语法:数据类型 *变量名

        int a = 10;
        //声明指针变量
        int* p;
        //指针指向a的地址
        p = &a;
        //利用*解引用,找到指针指向内存中的数据
        cout << *p << endl;

    三、指针所占内存空间

    在32位操作系统下,无论指针数据类型是什么数据类型,都是占4个字节,而在64位操作系统中占8个字节。

    四、空指针和野指针

    1.空指针:指针变量指向内存中编号为0的空间。

    用途:初始化指针变量。

    注意:空指针指向的内存是不能够访问的。

    int* p = NULL;
    //*p;内存0-255之间的内存编号是系统占用的,不可以访问

    2.野指针:指针变量指向非法的内存空间

    //在程序中,避免出现野指针
    int* p = (int*)0x1100;

    五、const修饰指针

    const修饰的指针有三种情况:

    • const修饰指针--常量指针
    • const修饰常量--指针常量
    • const修饰指针,又修饰常量
        int a = 10;
        int b = 10;
        //常量指针,指针指向的值不可以改,指针的指向可以改
        //即*p=20是非法的,p=&b是合法的
        const int* p = &a;
        //指针常量,指针的指向不可以改,指向的值可以改
        //即*p2=20是合法的,p2=&b是不合法的
        int* const p2 = &a;
        //指针指向的值和指向的值都不可更改
        //即* p3 = 20是不合法的,p3 = &b是不合法的
        const int* const p3 = &a;

    六、指针配合数组使用

    1.通过指针可以访问到数组中的值

    int main() {
        int arr[] = { 1,2,3,4,5,6 };
        //数组名就是数组的首个元素的地址
        int* p = arr;
        //利用指针访问数组中的第一个元素
        //解引用取出4个字节中的数据
        cout << *p << endl;
        //因为p是一个整型指针,执行p++之后,指针指向的就是下一个元素
        p++;
        //利用指针访问数组中的第二个元素
        cout << *p << endl;
    }

    2.通过指针来遍历数组

        //利用指针遍历数组:
        int* p2 = arr;
        for (int i = 0; i < (sizeof(arr) / sizeof(arr[0])); i++) {
            cout << *p2 << endl;
            p2++;
        }

    七、指针和函数

    主要区别是值传递还是引用传递

    1.值传递:改变形参的值不影响传递进来的实参

    #include <iostream>
    using namespace std;
    
    void swap(int num1, int num2) {
        cout << "交换之前num1的值:" << num1 << endl;
        cout << "交换之前num2的值:" << num2 << endl;
        int tmp = num1;
        num1 = num2;
        num2 = tmp;
        cout << "交换之后num1的值:" << num1 << endl;
        cout << "交换之后num2的值:" << num2 << endl;
    }
    
    int main() 
    {
        int a = 1;
        int b = 2;
        cout << "实参未传入之前a的值:" << a << endl;
        cout << "实参未传入之前b的值:" << b << endl;
        swap(a, b);
        cout << "实参传入之后a的值:" << a << endl;
        cout << "实参传入之后b的值:" << b << endl;
        system("pause");
        return 0;
    }

    输出:

    2.引用传递:改变形参的值会影响到实参的值;

    #include <iostream>
    using namespace std;
    
    void swap(int* num1, int* num2) {
        cout << "交换之前num1的值:" << *num1 << endl;
        cout << "交换之前num2的值:" << *num2 << endl;
        int tmp = *num1;
        *num1 = *num2;
        *num2 = tmp;
        cout << "交换之后num1的值:" << *num1 << endl;
        cout << "交换之后num2的值:" << *num2 << endl;
    }
    
    
    int main() 
    {
        int a = 1;
        int b = 2;
        int* p1 = &a;
        int* p2 = &b;
        cout << "实参未传入之前a的值:" << a << endl;
        cout << "实参未传入之前b的值:" << b << endl;
        swap(p1, p2);
        cout << "实参传入之后a的值:" << a << endl;
        cout << "实参传入之后b的值:" << b << endl;
        system("pause");
        return 0;
    }

    输出:

     八、指针函数和数组

    封装一个函数,利用指针对数组进行冒泡排序。

    #include <iostream>
    using namespace std;
    
    void bubbleSort(int* p,int length) {
        //如果在这里计算数组的长度,输出为1,因为传入进来的是数组的首地址,里面只存放1个元素
        //int len = sizeof(arr) / sizeof(arr[0]);
        //cout << len << endl;
        //arr是一个指针,指向数组的第一个元素,在数组中用下标访问元素的值时,相当于是将指针指向该元素的内存空间
        //我的理解是c++会自己定位到那,并取得值
        for (int i = length - 1; i >= 0; i--) {
            for (int j = i - 1; j >= 0; j--) {
                if (p[i] < p[j]){
                    int tmp = p[i];
                    p[i] = p[j];
                    p[j] = tmp;
                }
            }
        }
    }
    void printArr(int* arr, int length) {
        for (int i = 0; i < length; i++) {
            cout << arr[i] << endl;
        }
    }
    
    int main() {
        int arr[] = { 1,4,2,7,6,3,5 };
        //注意要在函数外先计算数组的长度
        //如果在函数里面计算,由于数组传进去的是首元素的地址,则长度永远是1
        int length = sizeof(arr) / sizeof(arr[0]);
        bubbleSort(arr, length);
        printArr(arr, length);
    
        system("pause");
        return 0;
    }

    输出:

    传入数组是引用传递,因此在里面改变了值会影响到原来数组arr的值,所以最后可以直接对arr进行打印输出。 

  • 相关阅读:
    洛谷 P1706 全排列
    n皇后问题
    跳马
    [HDOJ4612]Warm up(双连通分量,缩点,树直径)
    [POJ3177]Redundant Paths(双连通图,割边,桥,重边)
    [POJ3352]Road Construction(缩点,割边,桥,环)
    [POJ3694]Network(LCA, 割边, 桥)
    [UVA796]Critical Links(割边, 桥)
    [UVA315]Network(tarjan, 求割点)
    [HDOJ2586]How far away?(最近公共祖先, 离线tarjan, 并查集)
  • 原文地址:https://www.cnblogs.com/xiximayou/p/12080180.html
Copyright © 2011-2022 走看看