欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

深入理解C++:数组、指针与字符串详解——带你玩转Pointer heaven ????

最编程 2024-02-16 14:13:00
...
  • C语言指针详解,30分钟玩转C语言指针
  • 【动画教程】C语言指针动画演示

????内存空间的访问方式

  • 通过变量名访问
  • 通过地址访问

????指针变量的声明

  • 概念
    在这里插入图片描述
    • 指针:内存地址,用于间接访问内存单元。
    • 指针变量:用于存放地址的变量。

????指针运算

  • *称为指针运算符,是一个一元操作符,表示指针所指向的对象的值
  • &称为取地址运算符,也是一个一元操作符,是用来得到一个对象的地址
  • 指针变量的运算
    • 指针变量的算术运算
      在这里插入图片描述

      • 这种运算的结果取决于指针指向的数据类型
        在这里插入图片描述
    • 指针变量的关系运算&赋值运算
      在这里插入图片描述

????指针的赋值

  • 指针变量的初始化
    在这里插入图片描述
    • 注意事项
      • 用变量地址作为初值时,该变量必须在指针初始化之前已声明过,且变量类型应与指针类型一致。
      • 可以用一个已赋初值的指针去初始化另一个指针变量。
      • 不要用一个内部 auto 变量去初始化 static 指针。@野指针详解
  • 指针变量的赋值运算
    • 指针名 = 地址
      • “地址”中存放的数据类型与指针类型必须相符。
      • 向指针变量赋的值必须是地址常量或变量,不能是普通整数。但可以赋值为整数0,表示空指针。
      • 指针的类型是它所指向变量的类型,而不是指针本身数据值的类型,任何一个指针本身的数据值都是unsigned long int型。
      • 允许声明指向 void 类型的指针。该指针可以被赋予任何类型对象的地址。例: void *general; ,不能声明void类型的变量。

????指向常量的指针

  • 不能通过指针来改变所指对象的值,但指针本身可以改变,可以指向另外的对象。
    在这里插入图片描述

????指针类型的常量

  • 若声明指针常量,则指针本身的值不能被改变。
    在这里插入图片描述

  • const int * p1 int * const p2区别是什么
    • const int * p1 声明了一个指向整型常量的指针p1,因此不能通过指针p1来改变它所指向的整型值;
    • int * const p2声明了一个指针型常量,用于存放整型变量的地址,这个指针一旦初始化后,就不能被重新赋值了。

  • 定义一个整型变量a,一个整型指针p,一个引用r,通过p把a的值改为10,通过r把a的值改为5
    void main()
    {
    	int a;
    	int *p = &a;
    	int &r = a;
    	*p = 10;
    	r = 5;
    }
    

????用指针处理数组元素

  • 声明与赋值
    • int a[10], *pa; pa=&a[0]; pa=a;
    • 经过上述声明及赋值后:
      • pa就是a[0](pa+1)就是a[1],… ,*(pa+i)就是a[i]
      • a[i], *(pa+i), *(a+i), pa[i]都是等效的。
      • 不能写 a++,因为a是数组首地址是常量。

????指针数组

  • 数组的元素是指针型
    在这里插入图片描述
  • 指针数组VS二维数组
    在这里插入图片描述
    在这里插入图片描述

????用指针作为函数参数

  • 以地址方式传递数据,可以用来返回函数处理结果。
  • 实参是数组名时形参可以是指针。
  • 指向常量的指针做形参(不通过指针改变指针所指向对象的内容)
    #include<iostream>using namespace std;const int N = 6;void print(const int *p, int n);int main() 
    {
            int array[N]; 
            for (int i = 0; i < N; i++)    cin>>array[i];  
            print(array, N);  
            return 0;}void print(const int *p, int n) {  
            cout << "{ " << *p;  
            for (int i = 1; i < n; i++)     cout << ", " << *(p+i);  
            cout << " }" << endl;}
    

????指针类型的函数

  • 函数的返回值是地址,该函数就是指针类型的函数。
  • 声明形式:存储类型 数据类型 *函数名()
  • 注意
    • 不要将非静态局部地址用作函数的返回值。
    • 返回的指针要确保在主调函数中是有效、合法的地址。
      • 例1:主函数中定义的数组,在子函数中对该数组元素进行某种操作后,返回其中一个元素的地址,这就是合法有效的地址
      • 例2:在子函数中定义局部变量后将其地址返回给主函数,就是非法地址
      • 例3:在子函数中通过动态内存分配new操作取得的内存地址返回给主函数是合法有效的,但是内存分配和释放不在同一级别,要注意不能忘记释放,避免内存泄漏

????指向函数的指针

  • 声明形式:存储类型 数据类型 (*函数指针名)();
  • 函数指针指向的是程序代码存储区。
  • 典型用途——实现函数回调通过函数指针调用函数。
    • 例如将函数的指针作为参数传递给一个函数,使得在处理相似事件的时候可以灵活的使用不同的方法。
    • 调用者不关心谁是被调用者。它只需知道存在一个具有特定原型和限制条件的被调用函数。与函数名具有相同的作用。

????对象指针

  • 声明形式:类名 *对象指针名;
  • 通过指针访问对象成员:对象指针名->成员名ptr->getx()相当于(*ptr).getx();
  • this指针
    • 隐含于每一个类的成员函数中的特殊指针。
    • 明确地指出了成员函数当前所操作的数据所属的对象。
      • 当通过一个对象调用成员函数时,系统先将该对象的地址赋给this指针,然后调用成员函数,成员函数对对象的数据成员进行操作时,就隐含使用了this指针。
  • C++类和对象的使用之对象指针