1.一维数组的地址
一维数组在内存中是连续的空间.
int arr[3] = {10,20,30};
在内存中高地址向低地址分配连续的12个字节的空间.
一维数组的地址.
是数组的低字节的地址
数组名就代表数组的地址.
数组第0个元素的地址.
数组的地址 ==数组名 ==数组的第0个元素的地址 ==数组的低字节地址.
一维数组的元素的本质是1个普通变量
int arr[3] = {10,20,30};
这数组有3个元素.每1个元素其实就是1个普通的int变量.
能否定义1个指针指向数组中的元素呢?
指向数组的元素的指针.
我们可以声明1个指针变量指向数组的元素.通过指针间接的操作数组的元素.
int arr[] = {10,20,30,40,50,60,70};
int *p1 = &arr[0];表示p1指针指向了数组中的第0个元素.
数组的第0个元素的地址就是数组的地址.数组名就代表数组的地址.
int* p2 = arr;这么做完全也是没有问题
因为arr代表数组的地址.也就是数组的第0个元素的地址.
我们可以这么认为. p2指针指向了数组的第0个元素.
2.使用指针遍历数组
1).使用指针遍历数组的第一种方式.
int arr[7] = {10,20,30,40,50,60,70};
int* p1 = arr;//p1指针指向了数组的第0个元素.
for(int i = 0; i < 7; i++)
{
printf("%d\n",*(p1+i));
}
2).使用指针遍历数组的第二种方式.
int arr[7] = {10,20,30,40,50,60,70};
for(int i = 0; i < 7; i++)
{
printf("%d\n",*(arr+i));
}
3).使用指针遍历数组的第三种方式.
int arr[7] = {10,20,30,40,50,60,70};
int* p1 = arr;
for(int i = 0; i < 7; i++)
{
printf("%d\n",*(p1++));
}
注意的地方,每次循环.p1的值都会变化.
最后1次执行完毕之后. p1指针指向外面去了.
p1就不再执行数组中的任何元素了.
注意:数组名代表数组的地址.而数组一旦创建.数组的地址就确定了.不能改变
所以.我们不能为数组名赋值.不能修改数组名的值.但是可以使用数组名的值.
结论:无法修改数组名的值.不能为数组名赋值.任何值都不可以.
为什么?因为数组名代表数组的地址.而数组一旦创建数组的地址是无法改变的.所以你不能给他赋值.
数组名是1个常量.1个地址常量
3数组作为函数参数
在声明这个参数数组的时候.它并不是去创建1个数组而是去创建1个用来存储地址的指针变量.
如果我们为函数写了1个数组作为参数.
其实啊,编译器在编译的时候,已经把这个数组换成了指针.
所以.在声明参数的时候不是创建数组,而是创建1个存储数组地址的指针变量.
这也就是为什么我们通过sizeof计算参数数组得到的永远都是8.
所以.以后,我们的函数如果带了1个参数这个参数是1个数组.
建议,不要写数组了,直接写1个指向数组的第0个元素的指针,=再传入长度
4索引的本质
1).指针变量后面可以使用中括弧,在中括弧中写上下标来访问数据.
2). p1[n];前提是p1是1个指针变量.
完全等价于 *(p1+n);
3).只要是指针都可以使用中括弧下标.就相当于是去访问指针指向的变量.
操作数组我们虽然使用的中括弧下标来操作,实际上内部仍然使用的指针来操作.