一、数组定义
  • 数组在定义时,数组的大小必须为一个常数(可以使用宏定义、const常量)
  • C99标准允许变长数组(VLA)。GCC编译器实现了变长数组,但是其与C9标准不完全一致
二、数组注意事项
  • int num[5]={1,2,3};   //未初始化的都是0

C:07---数组_二维

  • int  num[]={1,2,3};  //数组大小自动设置为3
  • int num[5];   //都是垃圾值
  • 使用常量定义数组

C:07---数组_二维数组_02

三、二维数组
  • 概念:在内存中没有二维(多维)数组的概念,因为一维数组的元素可以是任何类型,所以二维实质就是元素为数组的一维数组
  • 例如:int num[12][31] 就是数组元素为12个数组的一维数组,每个数组的元素个数为31个
  • int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};  等价于 int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
  • int  a[][4]={1,2,3,4,5,6,7,8,9,10,11,12};   //自动是被是int  a[3][4];
  • int a[3][]={1,2,3,4,5,6,7,8,9,10,11,12};  //程序报错
  • int a[3][4]={1,2,3};  //缺省处用0补齐
  • int a[3][4]={{1,2},{3,4,5,6},{7,8,9,10}};  //缺省处用0补齐
  • int a[3][4]={{,2},{3,4,5,6},{7,8,9,10}};   //错误,逗号前面不能缺省

二维数组缺省

  • 我没说过二维数组本质是元素为数组的一维数组,因此二维数组第一个[]指向的是数组的索引,第二个[]指向的索引处对应的数组的再次索引
  • 例如:
int arr[2][2]={{1,2},{3,4}};

arr[1]对应于{1,2}这个数组,因此arr[1]是{1,2}这个数组的首地址
arr[2]对应于{3,4}这个数组,因此arr[2]是{3,4}这个数组的首地址
四、数组与指针的关系

一维数组:

  • 数组名就是数组的首地址(数组名相当于指针)

C:07---数组_二维_03

C:07---数组_数组指针_04

二维数组:

  • 数组名相当于第一个元素的地址(数组名相当于指针)
  • 每一行的首地址就等于二维数组的一维下标

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

  • a==&a[0][0]==a[0]==&a[0]

C:07---数组_二维_05

  • a+1==&a[1][0]==a[1]==&a[1]   //a+1相当于加了一行的地址

C:07---数组_二维数组_06

  • &a[1][1]==*(a+1)+1
  • ,&a[1]==*(a+1)

C:07---数组_数组_07

  • 若二维下标超界,就会向下一行去取值
  • 若二维下标低于0,就会向前一行去取值

C:07---数组_数组_08

  • *a[1]==a[1][0]

C:07---数组_数组_09

  • *a[1]+1==*(a[1]+1)==a[1][1]

C:07---数组_二维_10

  • 遍历二维数组

C:07---数组_一维数组_11

五、数组的指针

一维数组的指针

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

int *p1 = arr;       //p1是一级指针,指向数组元素的第一个元素
int (*p3)[3] = &arr; //重点,p3是一个指针(二级指针),指向含有3个元素的数组,然后数组的开头又是一个指针,所以指向arr需要&。

二维数组的指针

  • 因为二维数组是数组的数组,所以不能使用普通指针格式指向于二维数组
int arr[2][2]={{1,2},{3,4}};

int *p=arr; //错误
int p[2][2]=arr; //错误,p是一个二维数组,而arr是一个指针
  • 二维数组作为参数时,用法如下:
//演示案例
void print(int (*arr)[3]); //正确。参数arr指向数组的首元素(首元素也是一个数组),该首元素数组由3个元素构成
void print2(int  arr[][3]); //正确。arr也是一个二维数组指针,忽略了第一维度
void print2(int  arr[2][3]); //正确。arr也是一个二维数组指针,显式给出二个维度

int main()
{
    int arr[][3] = { {1,2,3},{4,5,6} };
    print(arr); //正确
    print2(arr); //正确
    print3(arr); //正确
}
六、指针数组、数组指针
  • 指针数组:是一个数组,里面都是指针
  • 数组指针:是一个指针,指向于数组

数组指针

  • 一维数组的指针

C:07---数组_数组_12C:07---数组_二维数组_13

  • 二维数组的指针(列数必须与定义的数组列数相同)
  • int (*p)[3]=a;  //正确
  • int *p=&a[0][0]; //错误的

C:07---数组_数组_14

指针数组(数组明前要加*号,并且数组的大小)

  • 一个数组,里面存放的是指针

C:07---数组_二维_15

七、数组类型别名(typedef、using)
  • 注意:下面起的别名是类型,而不是指针
typedef int arrT1[3]; //arrT1是一个类型别名,它表示的类型是含有3个整数的数组

using arrT2 = int[3]; //arrT2的作用同上
  • 演示案例

typedef int arrT1[3];
using arrT2 = int[3];

int main()
{
	arrT1 a={ 1,2,3 }; //arrT1相当于int [3],此语句相当于int a[2]={1,2,3};
	arrT2 b={ 1,2,3 }; //arrT2相当于int [3],此语句相当于int b[2]={1,2,3};
	
	for (int i = 0; i < 3; ++i)
		cout << a[i]<< endl;
	return EXIT_SUCCESS;
}