C语言复习之:数组
- 数组变量是数组第一个元素的首地址:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a[10];
printf("%s\n",a==&a[0]?"yes":"no");
return 0;
}
输出结果:
yes
- 数组变量是一个常量:
正常版本:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a[]={1,2,3,4,5};
printf("a[0] is %d\n",*a);
printf("a[1] is %d\n",*(a+1));
return 0;
}
错误演示:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a[]={1,2,3,4,5};
# 地址不能自增
printf("a[1] is %d\n",*(a++));
return 0;
}
但是!看下面这个:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a[]={1,2,3,4,5};
int *p=a;
printf("a[1] is %d\n",*(++p));
return 0;
}
结合上面的1
,是不是很诡异,为啥这里就是正确的呢?我们在使用上,a
的作用跟指针一样,但是,它本质上是带了一个暗含的const
的,即我们在定义int a[]={1,2,3,4,5};
的时候,其实本质上是const int a[]={1,2,3,4,5};
,所以使用上你可以当a
是指针来用,只是这个指针不允许修改值。
注意,这里是说不能修改变量a
中存储的值,即数组的地址,不代表不能修改数组中的值,这里的const
只限定了a
,并没有限制数组的值变化。
下面我们结合上面的结论,考虑一下,如果我们加入函数会怎么样呢?
下面是一段简单的代码:
#include <stdio.h>
void showArray(int *a,int length){
for (int i = 0; i < length; ++i)
{
printf("index:%d,data:%d\n",i,*a);
a++;
}
}
void showArray2(int a[],int length){
for (int i = 0; i < length; ++i)
{
printf("index:%d,data:%d\n",i,*a);
a++;
}
}
int main(int argc, char const *argv[])
{
int a[]={1,2,3,4,5};
int *p=a;
showArray(a,5);
showArray2(a,5);
return 0;
}
试问,编译时会不会错误?showArray
部分出错,还是showArray2
部分出错?
答案是都不会出错。
结合函数调用之堆栈部分我们知道,函数的传递在参数少的时候是借用寄存器来传递的,那么当参数的种类是一个数组的时候,直接传递一个数组的首地址不想吗?所以虽然上面使用了两种写法,但是本质上就是在寄存器里存了数组的首地址,即变量a
的值,注意!!!这里存储的是a
的值,所以在函数内部showArray
和showArray2
中的a
和main
中的a
不是同一个值(你从作用域的角度去理解也可以)。
所以在main
中的const
限制不到其中的修改。