• C++基础——指针


    1 概述

    指针的作用:可以通过指针间接访问内存
    内存编号从0开始,一般使用十六进制数字表示,指针可以保存地址

    2 指针变量定义和作用

    int main() {
    
    	//1、指针的定义
    	int a = 10; //定义整型变量a
    	
    	//指针定义语法: 数据类型 * 变量名 ;
    	int * p;
    
    	//指针变量赋值
    	p = &a; //指针指向变量a的地址
    	cout << &a << endl; //打印数据a的地址
    	cout << p << endl;  //打印指针变量p
    
    	//2、指针的使用
    	//通过*操作指针变量指向的内存
    	cout << "*p = " << *p << endl;
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    指针和普通变量的区别:
    普通变量存放的是数据,指针存放的是地址,指针变量可以通过“*”解除引用运算符获取指针变量指向的内存中存储的数据。
    &是取地址运算法,可以用于获取普通变量的地址赋值给指针变量。

    3 指针占用内存

    看了一使用sizeof运算符获取指针占用的内存大小

    int main() {
        int a = 10;
    
        int *p;
        p = &a;
    
        cout << p << endl;
        cout << *p << endl;
        cout << sizeof(p) << endl;
        cout << sizeof(char *) << endl;
        cout << sizeof(int *) << endl;
        cout << sizeof(double *) << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    输出

    0xc8945ffbe4
    10
    8
    8
    8
    8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    打印指针变量,存储的是地址,使用*解除引用运算符可以获取指针指向内存存储的值。使用sizeof函数可以获取指针的大小,可以看到不同类型的指针大小相同,通常在32位程序中是4字节,64位程序中是8字节。

    4 空指针和野指针

    空指针: 指向内存中编号为0的指针
    用途: 用于初始化指针变量

    int main() {
        int *p = NULL;
        //int *p = nullptr;
        cout << *p << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    有两种方式,一种是C格式,使用NULL表示空指针,另一种是C++格式,使用nullptr表示空指针。
    上面程序会出错,因为内存编号0~255为系统占用内存,不允许用户访问。
    使用空指针调用函数还会报空指针导致进程结束。
    上面调用会出错:

    Process finished with exit code -1073741819 (0xC0000005)
    
    • 1

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

    int main() {
        int *p = (int *) 0x432;
    
        cout << *p << endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    也会报错,访问了非法内存

    5 const修饰指针

    const修饰指针存在三种情况:

    1. const修饰指针 ——常量指针
    2. const修饰变量 ——指针常量
    3. const既修饰指针,又修饰常量
    int main() {
    
    	int a = 10;
    	int b = 10;
    
    	//const修饰的是指针,指针指向可以改,指针指向的值不可以更改
    	const int * p1 = &a; 
    	p1 = &b; //正确
    	//*p1 = 100;  报错
    	
    
    	//const修饰的是常量,指针指向不可以改,指针指向的值可以更改
    	int * const p2 = &a;
    	//p2 = &b; //错误
    	*p2 = 100; //正确
    
        //const既修饰指针又修饰常量
    	const int * const p3 = &a;
    	//p3 = &b; //错误
    	//*p3 = 100; //错误
    
    	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

    看const修饰的是哪个,修饰的指针就是常量指针,值不能修改。修饰的是常量就是指针常量,指针指向不能修改。

    6 指针和数组

    可以使用指针访问数组元素

    int main() {
    
    	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    
    	int * p = arr;  //指向数组的指针
    
    	cout << "第一个元素: " << arr[0] << endl;
    	cout << "指针访问第一个元素: " << *p << endl;
    
    	for (int i = 0; i < 10; i++)
    	{
    		//利用指针遍历数组
    		cout << *p << endl;
    		p++;
    	}
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    数组名表示的是数组的首地址,所以可以直接赋值给指针。可以利用指针访问数组,指针加1表示指向数组的下一个元素。根据指针类型的不同,指针加一跳过的内存大小不同,始终指向数组的下一个元素。

    7 指针作为参数

    函数调用的时候,直接传递参数采用的是值传递,会将实参复制一个副本,赋值给形参,形参的改变不会改变实参。

    void change (int num1, int num2) {
    	int temp = num1;
    	num1 = num2;
    	num2 = temp;
    }
    
    ->
    int a = 10;
    int b = 20;
    change(a, b);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    上面调用change之后,a和b的值不会交换。
    但是使用指针作为参数就可以交换a和b的值。

    void change(int *num1, int *num2) {
        int temp = *num1;
        *num1 = *num2;
        *num2 = temp;
    }
    
    ->
    int a = 10;
    int b = 20;
    change(&a, &b);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    由于直接操作的是内存,所以能够交换成功。
    使用指针传递参数的另一个优势是性能,当参数是结构体对象时,传递结构体对象,会导致复制整个结构体,如果使用指针则传入的只是一个固定的指针大小,能够大大地减小性能消耗。

  • 相关阅读:
    postgresSQL多种字符串分割及查询汇总
    Altium Designer2022相关操作
    解释一下分库分表的概念和优缺点。如何设计一个高性能的数据库架构?
    中国婴幼儿早教市场规模逐年攀升,未来发展潜力巨大
    OSPF下的MGRE实验
    ElementUI之首页导航+左侧菜单
    SPI机制是什么?
    python Django的个人博客
    【无标题】
    天龙八部TLBB系列 - 关于包裹掉落的物品
  • 原文地址:https://blog.csdn.net/weixin_49274713/article/details/133868741