普通的内置数组语法基础

数组即一组类型相同的元素组成的集合,存放在计算机内存的一片连续存储空间里,空间大小=元素个数x元素类型所占字节大小。C++提供一种内置的数组,后面将会用C++ 11新增更方便、安全的模板类array替代它,下面先介绍一下数组的语法。

首先说明一个概念:什么是普通指针?什么是数组指针?什么是指针数组?

普通指针:顾名思义就是基本数据类型的指针 如 int *类型,string *等,有自己的内存空间,其上存储的是所指向变量的地址值,对其解引用得到变量的引用,可直接对变量进行读写(如没有const限制);在数组中,普通指针就是指向一维数组元素的指针。

数组指针:又叫行指针,定义如 int ( *)[]这样,指向一整个数组的指针,存储的是整个数组的地址(虽然打印出来和首元素地址一样,但不是一个概念),对其解引用得到的是一个数组,而不是一个数组的元素,主要用在二维数组中,用于指向二维数组中的每个一维数组。

                在一维数组里,数组名arr表示首元素的地址,&arr表示整个数组的地址,前者是int *类型,后者是 int(*)[]类型;

                同样,在二维数组里 arr表示第一个数组的地址,&arr是整个二维数组地址,前者是int (*)[]类型,后者是 int(*)[][]类型;

一,一维数组

①数组的定义:

    T a[n];          T:元素的数据类型   a:数组名  n:数组的长度即元素个数,注意,定义数组时,长度必须是明确的,只能是常量或常量表达式。

 例:

    int a[10]; //定义数组a时,系统会分配一片连续的内存空间,空间大小为10*4=40字节,用于存储10个int型变量,默认变量值都为0,空间的名字为a.

 

②数组初始化方法

 最常用的列表初始化: 

            int a[5]={1,2,3} ; //缺项默认初始化为0

            int a[5]{1,2,3};

            int a[]{1,2,4}

注意,C++中数组不支持用一个数组来初始化另一个数组,或者用一个数组赋值给另一个数组,只能每个元素逐个copy,这就是数组不方便的地方之一。

 

③复杂数组的声明:
(1)指针数组定义:

      int * ptrl[10];                                            //定义有10个整型指针的数组

(2)数组元素类型不能是引用,必须是实际存在的东西:

      int & ptrl[10];   //错误

(3) int (*ptrl)[10]=&arr                                 //定义一个数组指针ptrl,指向一个有10个int型元素的数组,对指针解引用得到一个数组,元素引用使用(*ptrl)[i]。

概念引入:   数组指针:指向数组的指针,解引用得到整个数组,       指针数组:表示存放的元素类型为指针的数组

(4) int (& ptrl)[10]=arr;                             //声明一个引用ptrl, ptrl是一个有十个int型变量的数组的引用(别名),数组名为arr,

 

③数组与指针

概念1:通过数组名和元素下标对元素的访问,本质上是一种指针访问,数组名就是首元素的地址值。

  int arr[10];

  arr[i]---------等同于--------*(arr +i)      //arr为首元素地址 ,arr==&arr[0]

 例:

   

 注意:&arr打印出来也是首元素的地址值,但它和首元素地址值不是一个概念,它也不是普通的指针类型

 如:

   int arr[10];    //&arr是 int(*)[10]的类型,即数组指针或者叫行指针,而不是int *类型,主要用于二维数组。

进而得到概念2::可以使用一个指针来指向数组的某个元素,然后用这个指针通过类似数组名和下标的方式来引用数组的元素。

例:

另外,auto p3(arr);   //因为数组不允许用一个数组初始化另一个数组,所以这里的arr指的是&arr[0],p3是一个指针类型。

概念3:

  指向数组元素的指针就是数组的迭代器,支持迭代器的操作:

     int *p1=&arr[i];

     int *p2=&arr[j];

     p1++ :指向数组的下一个元素,可以指向尾后,但不能对尾后进行解引用,因为元素不存在

     p1-- : 指向上一个元素

     p1+k:指向向后移动k个元素位置后的元素。

     p2-p1:所指向的元素下标相减

     p2<p1:比较所指向的元素下标大小。

④begin(arr)和end(arr)方法

数组的指针就是它的迭代器,类似vector和array,数组同样提供了获取指向首元素和尾后元素指针的方法begin(arr)和end(arr):

⑤数组的不安全性

C++和C都不会检查数组下标是否合法,像下面这种情况:

int arr[3]{1,2,3};

arr[-1]=3;

这里将一个数组3存入数组存储空间以外一个元素位置后的空间,然后程序并不会报错,所以如果有类似写法将可能埋下隐患,不好排查。

 

 

二,多维数组

下面来学习多维数组的相关知识。

概念:一个二维数组可以看做是由一组一维数组构成的一维数组,数组的每个元素为一个一维数组;同理,可以将三维数组看做是由一组二维数组组成的一维数组,数组元素为二维数组。

按这样的思路,那么二维数组的数组名或者首元素地址即为第一个数组的地址(或者说第一行数组的地址),且对地址进行解引用得到的地址上的值为一整个一维数组;同理三维数组名或三维数组首元素地址即为第一个二维数组的地址;且地址的解引用得到的是地址上的二维数组。

理解了上面的概念,下面来举例多维数组的操作(以二维举例):

①二维数组初始化:

int arr[2][3]={{1,2},{3,4}};

int arr[2][3]={{1},{2}};

int arr[2][3]={1,2,3,4,5,6}

②二维数组的一维引用

对二维数组的每个数组进行引用:

    int arr[2][3];

    int (&ptrl)[3]=arr[0];   //这里声明ptrl是一个对长度为3的int型数组的引用,引用的对象是arr[0],即二维数组arr的第一个数组(第一行)

   ptrl[0],ptrl[1],ptrl[2];   //同arr[0][0],arr[0][1],arr[0][2]都是对arr第一个数组的元素的引用。

③二维数组的数组指针

    可以使用数组指针或叫行指针来指向二维数组的每个一维数组,解引用得到每个一维数组

   int arr[2][3];

   int(*p)[3]=&arr[0];

   cout<<(*p)[0];  //打印得到arr[0][0];

④使用引用遍历二维数组:

⑤指针遍历二维数组

posted @ 2022-06-05 10:52  newloser  阅读(147)  评论(0)    收藏  举报