指针和数组的关系
数组的存储如下图,从下往上
我们先来创建一个数组
int main(){
//定义一个数组
int A[] = {2,4,5,8,1};
//定义变量i,做数组循环
int i;
//定义指针P,指向数组A
int *p = A;
//同样指针p指向了数组A,就只能通过指针对数组进行操作了
p++;
/*通过i获得数组下标来遍历数组*/
for(int i = 0; i<5; i++){
//打印数组中某个元素的地址
printf("Address = %d\n" , &A[i]);
//打印的结果和上一行一样,获得数组中元素的地址方法不一样
printf("Address = %d\n", A+i);
//打印出数组中的某一元素
printf("value = %d\n", A[i]);
//打印结果和上一行一样,另一种取方式
printf("value = %d\n", *(A+i));
}
}
我们在来看看地二篇文章中的指针运算,通过p+1进行解引用运算可以获得a的相邻的地址,而数组的特点是我们指导相邻的地址里有什么内容,就可以直接通过数组下标 A[i] 取到对应的数字。
数组的特点
数组还有另外一个特点,使用数组A时会得到一个指向数组首元素的指针,所以可以直接写成
int *p = A,不需像下面的使用 &符号
//指针运算
int a = 1025;
int *p;
p = &a;
printf("%d\n", p); //打印a变量的地址
printf("%d\n", p+1); //打印下一个整数型地址(例如: a地址2000,那么该行打印2004)
printf("size of integer is %d bytes\n", sizeof(int)); //因为整数类型占4个字符
printf("%d\n",*(p+1)); //打印一个随机值(垃圾值),由于没有为这个特定的内存地址分配一个变量,有时这种操作会引起不期望行为
下面我们来实战一下,将数组作为函数参数传递,来计算一个数组里所以元素的和
int SumOfElements(int A[], int size){
//初始化i做数组下标,用于循环数组,sum存储数组总和
int i, sum = 0;
for(i = 0; i<size; i++){
//每循环一次获取数组中一个元素相加
sum+= A[i];
}
return sum;
}
int main(){
//初始化一个数组
int A[] = {1,2,3,4,5};
//首先我们要计算数组中有多少个元素,也就是数组长度
//sizeof方法能够统计数组A总共字节数
//int类型占4个字节,我们通过A[0]获取一个数组元素的长度
//总字节数/一个元素所占字节数 = 数组长度了
int size = sizeof(A)/sizeof(A[0]);
//调用计算数组元素总和的方法,传入数组和数组长度的值
int total = SumOfElements(A, size);
//打印出数组元素总和
printf("Sum of elements = %d\n",total);
}
输出的结果
但是我们要注意是,把数组作为参数传递需要将数组的大小一起传递
为什么我们来看下面的代码
//这里的int A[]会转换为int* A,一个整数型指针是4个字节,指针默认指向数组的首元素
int SumOfElements(int A[]){
printf("SumOfElements of size = %d\n",sizeof(A));
//初始化i做数组下标,用于循环数组,sum存储数组总和
int i, sum = 0;
int size = sizeof(A)/sizeof(A[0]);
for(i = 0; i<size; i++){
printf("A of element = %d\n ", A[i]);
//每循环一次获取数组中一个元素相加
sum+= A[i];
}
return sum;
}
int main(){
//初始化一个数组
int A[] = {1,2,3,4,5};
//调用计算数组元素总和的方法,传入数组和数组长度的值
int total = SumOfElements(A);
printf("main of A = %d\n",sizeof(A));
//打印出数组元素总和
printf("Sum of elements = %d\n",total);
int b = 0;
int* p1 = &b;
printf("point size is = %d\n", sizeof(p1));
}
打印结果
因为系统是64位的原因,所以指针的大小是8