数组名是什么?
这个问题是一个难点,有的人觉得很简单,其实没那么容易!!!
int main()
{
int a = 10; //a是栈区的一块变量
int* pa = &a; //&a 是把a的地址取出来放到变量pa里面
//...
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//arr一定是数组的变量名字,那么...
int(*pArr)[10] = &arr;
//把数组arr的地址通过&arr取出来,放到了数组指针pArr中
printf("%d\n", *arr); //1
//这个通过*arr竟然打印出来1(第一个元素)
//这儿arr可能是首元素的地址,通过*把内容拿出来了。
return 0;
}
这个数组名在不同的情况下有不同的含义,至于为什么一个数组的名字为什么有不同含义,是怎么实现的,我不会,感觉这样搞得东西让人有一点难受!!!
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%zd\n", sizeof(arr)); //40
printf("%zd\n", sizeof(int[10])); //40
return 0;
}
上面代码我的理解是:sizeof()这个操作符关注的是()里面的类型是什么,通过类型来确定这个元素的大小!sizeof(数组名)里面就是数组的名字,既然是数组的名字,那么就算的是整个数组的大小!!!
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("&arr[0] = %p\n", &arr[0]);
printf("&arr[0]+1 = %p\n", &arr[0] + 1);
printf("arr = %p\n", arr);
printf("arr+1 = %p\n", arr+1);
printf("&arr = %p\n", &arr);
printf("&arr+1 = %p\n", &arr+1);
return 0;
}
通过上面代码可以看出arr和arr+1的差是4个字节,证明了arr就是首元素的地址,并且把首元素的地址打印出来和arr大的一样,进一步证明了arr是首元素的地址。
&arr和&arr+1相差40个字节,证明了&arr是整个数组的地址。
sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节
• &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素的地址是有区别的)
除此之外,任何地⽅使⽤数组名,数组名都表⽰⾸元素的地址。
使用指针访问数组及其数组传参的本质
指针访问数组
这个很简单其实arr除了两种特殊情况,它就是首元素的地址,这儿说一下,数组在内存中是连续存储的。
int main()
{
char str[4] = { 'a','b','c','d' };
printf("&str[0] = %p\n", &str[0]);
printf("&str[1] = %p\n", &str[1]);
printf("&str[2] = %p\n", &str[2]);
printf("&str[3] = %p\n", &str[3]);
return 0;
}
既然这样,访问数组的方式多种多样.
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(int);
int* p = arr;
for (int i = 0; i < sz; i++) {
//根据在内存中连续访问
printf("%d ", *(p + i));
printf("%d ", *(arr + i));
//根据下标访问
printf("%d ", p[i]);
printf("%d ", arr[i]);
}
return 0;
}
只要搞清楚了它的本质是什么,随便你怎么访问!!!
一维数组传参的本质
一维数组传参的本质其实就是传首元素的地址!!!证明如下:
void Print(int arr[], int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
void Print(int* arr, int sz)
{
//...
}
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(int);
Print(arr, sz);
return 0;
}
虽然形参有时候写成了int arr[],它的本质是一个指针变量,用于接受首元素的地址。
二级指针
二级指针准确的来说是二级指针变量,是用来接受一级指针变量的地址的,没有什么神奇的!!!
int main()
{
//创建a
int a = 10;
//存a的地址
int *pa = &a;
//存pa的地址
int* *ppa = &pa; //二级指针变量
return 0;
}
这儿在解释一下int* *ppa = &pa;这个代码. *ppa说明ppa是指针变量,int * 说明ppa是指向int *的指针变量,也就是说是存int *类型地址的指针变量。
指针数组
指针数组还是数组,只不过里面存放的元素的是指针类型!!!
用指针数组模拟二维数组!
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 2,3,4,5,6 };
int arr3[] = { 3,4,5,6,7 };
//把3个数组的首元素地址存到指针数组里面
int* pArr[] = { arr1,arr2,arr3 };
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
//通过pArr[i]可以把每个数组的首地址拿出来,在索引找元素
printf("%d ", pArr[i][j]);
}
printf("\n");
}
printf("\n");
return 0;
}
完结!!!