一、概念
数组是一种复合数据类型,对于复合数据类型,我们已经有学习指针的经验,数组和指针一样,如同指针类型是由指针和指针所指向的数据类型复合而成的,数组是由数组本身和数组元素的数据类型复合而成的。
数组是C语言为程序员提供的实现顺序存储结构的机制,对于顺序存储结构,指针是用来实现链式存储结构的,另外,数组本身也是一种存储相同数据类型元素的线性结构,从数据结构的角度看,它叫顺序表。
二、声明、定义、初始化
先说清楚,下面这种写法在C语言里不行,Java可以:
int[10] a = {0, 1, 2, 3, 4, 5, 6. 7, 8, 9};
C语言的数组定义必须这么写:
int a[] = {0, 1, 2, 3, 4, 5, 6. 7, 8, 9};
注:若初始化,可以不写元素个数(数组长度);不初始化,必须写上数组长度!
三、数组元素的访问
和枚举类似,数组中的每个数组元素的下标自带从0开始的默认值,也就是说第一个数组元素是a[0],第十个数组元素是a[9]。
怎么理解这个事?数组本身是一个复合数据类型,a[0]表示具体的数据类型,以上述定义的数组为例,a[0]的数据类型是整型。
四、二维数组
1 维的概念:
一维即直线或者说线性空间,二维即平面,三维即立体,我们人类便是生活在三维空间里,三维以上理论上存在,但是目前人类并不能感知到。
在实际应用中,除了在SVM等人工智能的方法里常用到高维,我们几乎用不到三维及以上的数组,也就是说,所谓多维数组也就是二维。
但是,不管一种数据结构逻辑上是几维的,实际只能是一维,因为内存本身是一个一维的线性空间。——这句话怎么理解?一个二维数组实际的存储是一个一维数组,数组元素为一维数组。
2 声明、定义、初始化
int aa[][3] = {{0, 1, 2},{ 3, 4, 5},{ 6, 7, 8}};
注:若初始化,二维数组必须写上列数;不初始化,必须全都写上!
3 对二维数组的认识
五、数组与指针的关系
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
// 下面对a、&a、&a[0]的输出是一致的,这说明了什么?(问题1)
printf("%p\n", a);
printf("%p\n", &a); // 数组名可以取地址
printf("%p\n", &a[0]);
int i = 1;
printf("%p\n", &(&i)); // 这是错误的,编译时不许通过,这说明了地址不能再取地址
printf("------------------------------------------------------\n");
// 这是二维数组的情况,输出结果全部一致,说明的问题和上一个问题同。
int aa[][3] = {{0, 1, 2},{ 3, 4, 5},{ 6, 7, 8}};
printf("%p\n", aa);
printf("%p\n", &aa);
printf("%p\n", &aa[0][0]);
printf("%p\n", aa[0]);
printf("%p\n", &aa[0]);
printf("------------------------------------------------------\n");
// 对二维数组的二维数组名和一维数组名进行运算,发现这种情况,这说明了什么?(问题2)
// 前两行输出一致
printf("%p\n", *aa);
printf("%p\n", aa[0]);
printf("%d\n", **aa);
printf("------------------------------------------------------\n");
// 输出一致
printf("%p\n", aa[1]);
printf("%p\n", aa + 1);
printf("------------------------------------------------------\n");
// 输出一致
printf("%p\n", &aa[0][1]);
printf("%p\n", aa[0] + 1);
return 0;
}
问题1:
数组名是一个特殊的指针,而不是一个地址,它的特殊性在于,该指针指向了自己。
问题2:
二维数组名是一个二级指针,一维数组名是一个一级指针。
六、字符数组是数组吗?(***重要问题***)
字符数组不是数组!
是采用数组实现的字符串。
数组和字符串是两种不同的数据类型:
#include <stdio.h>
int main() {
int a[2] = {0, 1}; // 数组
char s[2] = {'s', '\0'}; // 字符数组
printf("%ld\n", sizeof(a));
printf("%ld\n", sizeof(s));
return 0;
}