基本概念
// 数组与指针
- 使用数组时,编译器一般会把它转换为指针
- 很多使用到数组名的地方,编译器会自动将数组名替换为一个指向数组首元素的指针
// 数组的下标类型
- 通常定义的数组为size_t类型,被定义在stddef.h或cstddf中
- size_t是一种与机器无关的无符号类型,设计的足够大,以便表示内存中任意足够大的对象
- 数组、vector、string均可执行下标运算
- 标准库类型限定使用的下标必须是无符号类型,内置的下标运算无此要求
// 数组与链表的比较
- 数组内存空间连续,链表不连续
- 数组能更好地利用CPU的cache(预读、局部性原理)
- 数组只需要存储数据,链表还要存储指针域,数组的内存使用效率更高
定义不同类型的数组
int (*p)[10]; // 定义一个指向10个int元素的数组的指针
typedef int (*ptr)[10];
- // 定义一个数组指针类型
int (&ref)[10];
- // 定义数组的引用,数组元素为int
int* (&ref)[10];
- // 同上,数组元素为`int*
int* p[10]
- // 定义一个数组,数组元素是int*
- // p与[]结合是左结合,故p是数组名
- // 默认情况下,类型修饰符是从右向左绑定的,[]修饰符优先级高于*优先级
int (*p)[10]=&arr;
- // p与*结合,故p是指针,该指针指向一个数组,数组元素的类型是int,数量为10,
int (*p)(int);
- // p是一个指针,该指针指向一个函数,即p是函数指针,函数的返回值是int,参数类型是int
int (*p[5](int));
- // 这是一个存有5个函数指针的数组, p与[]结合,故p是数组名,该数组有5个元素
- // 每个元素是一个指针,该指针指向一个函数,函数的返回值是int,函数的参数是int
int (**p)(int);
- // p是一个指针,该指针指向一个函数指针
定义数组
// 开辟堆上夫维数组空间
#define M 3
#define N 4
void test()
{
int** p = (int**)malloc(sizeof(int*) * M);
assert(p != NULL);
for (int i = 0; i < N; ++i)
{
p[i] = (int*)malloc(sizeof(int) * N);
assert(p[i] != NULL);
}
}
数组作函数参数
- 二维数组作为参数传递给函数时,为什么不能省略列信息
arr[i][j]=base+i*col*sizeof(dataType)+j*sizeof(dataType);
// col为列信息,没有列信息,就无法求出某元素的地址