数组名的理解
数组名本来就是地址,⽽且是数组⾸元素的地址,即:
&arr[0]=arr
上面代码,打印出来的地址都是一样的,证明了:数组名就是数组⾸元素(第⼀个元素)的地址
但是有两个例外:
• sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", sizeof(arr));
return 0;
}
//输出的结果为40
• &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素的地址是有区别的)
除此之外,任何地⽅使⽤数组名,数组名都表⽰⾸元素的地址。
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("&arr[0] = %p\n", &arr[0]);
printf("arr = %p\n", arr);
printf("&arr = %p\n", &arr);
return 0;
}
上面代码输出的结果一样,为什么呢?&arr与arr又有什么区别呢?
因为这三个的地址都开始在同一地方,也就是都是从数字1那个地方开始读地址
&arr与arr又有什么区别呢?
&arr[0]和&arr[0]+1相差4个字节,arr和arr+1 相差4个字节,所以+1的时候,它们就会跳过一个元素(4字节)
而&arr 和 &arr+1相差40个字节,这就是因为&arr是数组的地址,+1 操作是跳过整个数组的
使⽤指针访问数组
*(p+i)=*(arr+i)===arr[i]
加法是可以交换律的
*(i+arr)=i[arr]
因此可以得出[]只是操作符
1.数组就是数组,是可以存放一个或者多个数组的
2.指针变量是一个变量,是可以存放地址的变量
数组和指针不是一回事
但是可以是一种指针来访问数组
为什么可以使用指针来访问数组呢
1.数组在内存中是连续存放的
2.指针的元素可以很方便来遍历数组,取出数组的内容
⼀维数组传参的本质
因为int* arr=int arr[],这实际上是指针变量,不是数组
数组传参的时候,形参可以写成数组,也可以写成指针
写成数组的形式,最简单,是为了方便理解,容易接受这种语法
但是即使写成数组的形式,本质上还是指针
eg:
#include<stdio.h>
void test(int arr[10] /*也可以写成int* arr*/,int sz)
{
printf("%d",sz);
}
int main()
{
int arr[5]={1,2,3,4,5};
int sz=sizeof(arr)/sizeof(arr[0]);
test(arr,sz)
return 0;
}
arr是数组名,数组名表示数组首元素的地址
数组传参的本质,传递的是数组首位元素的地址
所以,形参即使写成数组的形式,本质上也是一个指针
函数内部是没办法求的数组元素个数的原因:
函数形参的部分理论上应该使⽤指针变量来接收⾸元素的地址。那么在函数内部我们写
sizeof(arr) 计算的是⼀个地址的⼤⼩(单位字节)⽽不是数组的⼤⼩(单位字节)
⼆级指针:指针变量也是变量,是变量就有地址,那指针变量的地址存放的地方
#include<stdio.h>
int main()
{
int a=20;
int* pa=&a;
int* *ppa=&pa;
return 0;
}
二级指针变量是用来存放一级指针变量的地址
int* *解读:
分开理解,将分成int*和*两个部分
int*表示ppa指向的pa类型是int*
第二个*表示说明ppa是指针变量
注意:二维指针和二维数组没有必然的联系
对于⼆级指针的运算有:
1.*ppa 通过对ppa中的地址进⾏解引⽤,这样找到的是 pa , *ppa 其实访问的就是 pa
int b = 20;
*ppa = &b;//等价于 pa = &b
2.**ppa 先通过 *ppa 找到 pa ,然后对 pa 进⾏解引⽤操作: *pa ,那找到的是 a
**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;
指针数组
类比一下:
整形数组:是存放整型的数组,
字符数组:是存放字符的数组。
所以指数数组是存放指针的数组。
指针数组模拟⼆维数组
#include<stdio.h>
int main()
{
int arr1[5]={1,2,3,4,5};
int arr2[5]={2,3,4,5,6};
int arr3[5]={3,4,5,6,7};
int* pa[5]={arr1,arr2,arr3};
int i=0;
int j=0;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
printf("%d",pa[i][j]); //也可以写成*(*(pa+i)+j)
}
}
return 0;
}
parr[i]是访问parr数组的元素,parr[i]找到的数组元素指向了整型⼀维数组,parr[i][j]就是整型⼀维数组中的元素。
实际上并⾮完全是⼆维数组,因为每⼀⾏并⾮是连续的。