一维数组
数组名
在 C中,几乎所有使用数组名的表达式中,数组名的值是一个指针常量(所以你不能给数组名重新赋一个新的地址),也就是数组第一个元素的地址;
但是数组和指针并不是等价的哟,数组具有一定数量的元素,而指针只是一个标量值;
只有两种场合,数组名并不用指针常量来表示,sizeof操作符时,返回的是整个数组的长度,而不是指向数组的指针的长度,取一个数组名的地址所产生的是一个指向数组的指针,而不是一个指向某个指针常量值的指针。
下标引用
在使用下标引用的地方,可以使用对等的指针算术再间接引用的表达式来代替。在使用指针表达式的地方,也可以使用下标表达式来代替。
提示:编译器不会检测数组下标越界等错误(发送错误后发现得了不,这得看运气),即使有的编译器支持,也可以选择关闭。
指针和下标的效率比较
下标绝不会比指针更有效率,但指针有时会比下标更有效率。
详情看C和指针145页。
指针的效率
数组和指针
声明数组参数
初始化
数组可以是静态变量,也可以是自动变量,但自动变量每次进入相应局部都要赋值会浪费时间。所以当数组非常庞大的时候,就要考虑一下是不是有必要声明为静态变量。
1、不完整的初始化
int vector[5]={1,2,3};后面少的两个会默认为0
2、自动计算数组长度
int vector[]={1,2,3,4,5,6,7};
3、字符串是一个以'\0'结尾的字符数组,其声明方式有两种
(1)char message[]={'H','e','l','l','o',0};
(2)char message[]="hello";/*也许会有很多人仍未这里是一个字符串常量,其实这里只是一种初始化列表的快快速记法。那到底怎么和字符串常量进行区分呢?这个就更具上下文环境,当用于初始化一个字符数组时,他就是一个初始化列表,其他任何地方都代表一个字符串常量*/
辩一辩
char message[]="hello";
char *message2="hello";
多维数组
int c[6][10];
c只是在b的基础上再增加一维,所以我们可以把c看作是一个包含6个元素的向量,只不过它的每个元素本身是一个包含1-个整形元素的向量。
数组名
int array[3][10];
一维数组名的值是一个指针常量,它的类型是“指向元素类型的指针”,它指向数组的第一个元素。多维数组也一样,只不过多维数组第一维实际上存的是另一个数组(也就是多维数组的第一维存储的是另一个数组的首地址),所以多维数组的数组名指的是存另一维数组首地址的数组首地址。
所以*array,array[1]代表的是另一个(另一维)数组的首地址。
tips:array[3,4];指的是array[4]哟2333333333333
指向数组的指针
这个概念也就是多维数组中最外面那维数组存储的值。
作为函数参数的多维数组
初始化
int matrix[2][3]={100,101,102,110,111,112};
int matrix[2][3]={
{100,101,102},
{110,111,112}
};
加不加花括号本身对初始化过程不会产生影响?但为什么还是要发明花括号这种声明呢?一是为了观察直接,二是加花括号
指针数组
int *api[10]:指针数组,每个数组元素存的是int *类型指针;
int (*p)[10]:数组指针,一个指针p指向的是一个数组的地址。
在矩阵中,每行必须与最长字符串的长度一样长,但它不需要任何指针。指针数组本身要占有空间,但每个指针所指向的字符串所占有的内存空间就是字符串本身的长度,没有必要要和最长的一样长。