• 65.【警告 阅读前请喝水,挺干的。让你认清指针数组和数组指针 (超详版)】


    (一)、指针数组

    在这里插入图片描述

    1. 什么是指针数组:

    在C语言和C++等语言中,数组元素全为指针变量的数组称为指针数组,指针数组中的元素都必须具有相同的存储类型、指向相同数据类型的指针变量。指针数组是数组元素为指针的数组(例如 int *p[3],定义了p[0],p[1],p[2]三个指针),其本质为数组。

    2.指针数组的格式:

                     数据类型 *首地址[];
    
    • 1

    3.指针数组的作用:

    指针数组比较适合用来指向若干个字符串,使字符串处理更加方便、灵活。

    4.指针数组与一维数组的关系:

    指针数组每个元素都是指针,一维数组的地址可以赋值给指针。然后进行操作.

    #include
    using namespace std;
    int main()
    {
    	int* p[3];    //定义一个指针数组
    	int a[] = { 3,6,1,9,10 };   //定义一个整型数组
    	p[0] = a;        //p[0]是一个类型为int* 指向int的指针,a是一个int*,指向int 
    	p[1] = a + 1;
    	p[2] = a + 3;
    	cout << (*p[0]) << "  " << (*p[1]) << "  " << (*p[2]) << endl;   //[]优先级比()高,所以()没起到作用
    	cout << a[0] << "  " << a[1] << "  " << a[3] << endl;
    	int* q;       //普通指针
    	q = a + 1;
    	cout << *q;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    补充:::::::::::::::::::

    如果是 二维数组a[0]+1;代表a[0][1]; 这时候a[0]是行数组名它代表这一行的首地址就是a[0][0],+1就等于加它类型的字节数1x字节数,(+2就是2x字数)结果就是a[0][1];如果是一维的话,更简单;+1就等于加它类型的字节数x1;结果是a[1];
    在这里插入图片描述

    5.指针数组与二维数组的关系

    #include
    using namespace std;
    int main()
    {
    	int* p[3];    //定义一个指针数组
    	int a[2][3] = {{3,6,1} ,{12,9,10}};   //定义一个二维整型数组
    	p[0] = a[0];    //a[0]=&a[0][0]
    	p[1] = a[1];   // a[1]=&a[1][0]
    	cout << a[0][1] << endl;       //输出a[0][1]
    	cout << *(a[0] + 1) << endl;    //输出a[0][1],(a[0]+1)这样代表地址
    	cout << *(p[0] + 1) << endl;  //输出a[0][1],指针+1代表移动一个数(列)
    	cout << *(p[0] + 2) << endl;	//输出a[0][2],指针+1代表移动一个数(列)
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    接下来让我们练习一道题:(二维数组全部元素求和)

    #include
    using namespace std;
    int main()
    {
    	int sum=0;
    	int* p[3];    //定义一个指针数组
    	int a[2][3] = {{3,6,1} ,{12,9,10}};   //定义一个二维整型数组
    	p[0] = a[0];    //a[0]=&a[0][0]
    	p[1] = a[1];   // a[1]=&a[1][0]
    	for (int i = 0; i < 2; i++)
    	{
    		for (int j = 0; j < 3; j++)
    		{
    			sum += *(p[i] + j);//或者 *(*(p+i)+j) 或者 p[i][j]
    		}
    	}
    	cout << "求和后得:" << sum << endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    6.指针数组申请动态二维数组

    指针数组申请动态二维数组格式:

    【方法1基本格式】
    int **p;    //指针类型是int** 型,指向int*型的指针变量
    p=new int*[]
    for(int i=0;i<列;i++)
    {
        p[i]new int []
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    6.实战项目:

    在这里插入图片描述

    代码展示:

    1.错误示范:

     【指针指向二维数组不能用*p=a[0]#include 
    #include 
    using namespace std;
    int main()
    {
     int a[2][2] = {1,2,3,4};
     int* p;
     *p = a[0];
     for (int i = 0; i < 4; i++)
     {
      cout << setw(2) << *(p+i) ;
     }
     return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.指针数组申请动态二维数组

    #include 
    using namespace std;
    int main()
    {
        int m, n;
        cout << "请输入行数为:" << endl;
        cin >> m;
        cout << "请输入列数:" << endl;
        cin >> n;
        int**p;                 // 
        p = new int*[n];
        for (int i = 0; i < n; i++)
        {
            p[i] = new int[n];    //左边行,右边列
        }
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                cin >> p[i][j];
            }
        }
        cout << "输出为:" << endl;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                cout<< p[i][j]<<" ";
            }
        }
        delete[]p;
        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

    效果展示:

    1.错误示范效果展示:
    在这里插入图片描述
    2.申请动态二维数组正确效果
    在这里插入图片描述

    7.小结

    7.1指针数组名加1,移动多少字节?

    *(p+1):走了一行; * (p+1)+1走了一列

    7.2指针数组名相当于什么样的指针?

    指针数组名就是元素地址相当于一级指针取地址就是二级指针,故指针数组名相当于二级指针“数据类型 * p” 本身就是一个指针,而它的数据类型是int * 也是一个指针,故称为二级指针。

    (二)、数组指针:

    在这里插入图片描述

    1.什么是数组指针

    数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。例:int (*p)[10]; p即为指向数组的指针,又称数组指针。

    2.数组指针的格式:

                         数据类型(*p)[];
    
    • 1

    3.数组指针的作用:

    数组指针是指向数组地址的指针,其本质为指针;

    4.数组指针与二维数组的关系:

    #include
    using namespace std;
    int main()
    {
    	int(* p)[3];    //定义一个数组指针
    	int a[2][3] = {{3,6,1} ,{12,9,10}};   //定义一个二维整型数组
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里a是个二维数组的数组名,相当于一个二级指针常量;//二维数组名与二级指针毫无关系(初学者常常混淆)。
    p是一个指针变量,它指向包含5个int元素的一维数组,此时p的增量以它所指向的一维数组长度为单位;

    补充:::::::::::::::::::

    p+i是一维数组a[i]的地址,即p+i==&a[i];对该式两边作取内容运算()得(p+i)a[i],由于二维数组中a[i]&a[i][0], 则 * (p+i)表示a[i][0]的地址,即 * (p+i)==&a[i][0](p+2)+3表示a[2][3]地址(第一行为0行,第一列为0列),(*(p+2)+3)表示a[2][3]的值。

    多数组有关概念

    在这里插入图片描述

    注意a[0],a[1],a[2]表示的都是对应那行的数组首地址,和数组名,而不是一个元素,(这里得到*号不是指针,而是取地址)!!!!!!!!!!!
    多维数组地址的表示方法

    设有整型二维数组a[3][4]如下:
    1000 1001 1002 1003
    1004 1005 1006 1007
    1008 1009 1010 1011
    
    • 1
    • 2
    • 3
    • 4

    设数组a的首地址为1000,各下标变量的首地址及其值。C语言允许把一个二维数组分解为多个一维数组来处理。因此数组a可分解为三个一维数组,即a[0],a[1],a[2]。 每一个一维数组又含有四个元素。例如a[0]数组,含有a[0][0],a[0][1],a[0][2],a[0][3]四个元素。数组及数组元素的地址表示如下: a是二维数组名,也是二维数组0行的首地址,等于1000。a[0]是第一个一维数组的数组名和首地址,因此也为1000。(a+0)或a是与a[0]等效的,它表示一维数组a[0]0号元素的首地址。也为1000。&a[0][0]是二维数组a的0行0列元素首地址,同样是1000。因此,a,a[0] ,*(a+0), * a,&a[0][0]是相等的。同理,a+1是二维数组1行的首地址,等于1004。a[1]是第二个一维数组的数组名和首地址,因此也为1004。&a[1][0]是二维数组a的1行0列元素地址,也是1004。因此a+1,a[1],* (a+1),&a[1][0]是等同的。由此可得出:a+i,a[i], * (a+i),&a[i][0]是等同的。此外,&a[i]和a[i]也是等同的。因为在二维数组中不能把&a[i]理解为元素a[i]的地址,不存在元素a[i]。
    C语言规定,它是一种地址计算方法,表示数组a第i行首地址。由此,我们得出:a[i],&a[i], * (a+i)和a+i也都是等同的。另外,a[0]也可以看成是a[0]+0是一维数组a[0]的0号元素的首地址,而a[0]+1则是a[0]的1号元素首地址,由此可得出a[i]+j则是一维数组a[i]的j号元素首地址,它等于&a[i][j]。

    由a[i]= * (a+i)得a[i]+j= * ( a+i)+j,由于 * (a+i)+j是二维数组a的i行j列元素的首地址,该元素的值等于 * ( * (a+i)+j)。
    
    • 1

    4.实战项目:

    在这里插入图片描述

    代码展示:

    1.数组指针和二维数组的联用

    #include
    using namespace std;
    int main()
    {
    	int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
    	int(*p)[4];    
    	p = (int(*)[4])a;     //目的是为了把a看作参数
    	for (int i = 0; i < 3; i++)
    	{
    		for (int j = 0; j < 4; j++) printf("%d ", p[i][j]); //或者 *(*(p+i)+j) 或者 *(p[i]+j)
    		printf("\n");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.数组指针创建动态二维数组

    #include 
    using namespace std;
    int main()
    {
     int m, n;
     cout << "请输入行数为:" << endl;
     cin >> m;
     int(*p)[3];              
     p = new int[m][3];    //列数是实参,否则报错哦
     for (int i = 0; i < m; i++)
     {
      for (int j = 0; j < 3; j++)
      {
       cout << "请输入p[" << i << "][" << j << "]的值" << endl;
       cin >> p[i][j];
      }
     }
     cout << "输出为:" << endl;
     for (int i = 0; i < 5; i++)
     {
      for (int j = 0; j < 3; j++)
      {
       cout<< p[i][j]<<" ";
      }
     }
     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

    效果展示:

    1.数组指针和二维数组联用
    在这里插入图片描述
    2.数组指针和动态二维数组
    在这里插入图片描述

    (三)、数组指针和指针数组

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    祝君更上一层楼!!!!!!

  • 相关阅读:
    module.exports和exports,应该用哪个
    Java入门基础笔记
    人工智能:定义未来,揭开历史神秘面纱,展望无限可能!
    如何制作HTML网页设计【体育运动主题网站——中国篮球NBA】
    1055 The World‘s Richest
    牛客网刷题-(7)
    微信小程序案例:2-2本地生活
    SAP 通过游标来分批从数据库表读取2G数据
    Elasticsearch:搜索架构
    如何将docker 镜像上传到docker hub仓库
  • 原文地址:https://blog.csdn.net/qq_69683957/article/details/126328296