一.数组名的理解
其实在数组中,&arr[0]与arr都表示着首元素的地址,这里的话我们直接用代码来给大家展示一下。
这里就是上述所说的给首元素取地址和直接用数组名是一样的,都是数组的首元素地址。
但是接下来可能就会有点不一样了,如果我用sizeof(arr),阁下应该如何应对呢?
这里大家的猜想就是数组名首元素地址,然后大小就是4/8个字节对吗,毕竟算的时地址的大小也就是算的是指针的大小哦,大家不要糊涂了。
我这里还是直接写一个代码来看看事实是如何的呢?
可是这里算出来是16个字节的大小,所以我们这里要特别申明一下。
用sizeof(数组名)的时候计算的是整个数组的大小,单位是字节。(sizeof的括号里面只是单独放着数组名哦,大家要擦亮双眼)。
还有一种情况就是&(数组名)拿的是整个数组的地址,虽然我们看到的只是首元素的地址,但是这个地址就是代表着整个数组的地址哦。(这里整个数组的地址和首元素地址是有区别的,即使 表示的都是一样的,但是还是有很大的差别的)
这里就来直接写代码来看一下区别
这里我们可以直接看到的就是&数组名+1就是跳过整个数组,代码运行的结果我们可以看到28->50
这里跳过了40个字节(这里是十六进制)。
数组名的特殊情况只有上述两种,其他情况都是数组名是首元素地址。
二.使用指针访问数组
int main()
{
int arr[10] = { 0 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
//输⼊
int* p = arr;
for (i = 0; i < sz; i++)
{
scanf("%d", p + i);
//scanf("%d", arr+i);//也可以这样写
}
//输出
for (i = 0; i < sz; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
这里的输入我们直接用的是指针来进行输入,其实arr[0]与*(p+0)是一样的道理的。
三.一维数组传参的本质
能否在函数内部求一个数组的大小呢?
void test(int arr[])
{
printf("%zd\n", sizeof(arr));
}
int main()
{
int arr[4] = { 1,2,3,4 };
printf("%zd\n", sizeof(arr));
test(arr);
return 0;
}
这里就让我们知道数组名就是数组首元素的地址,本质其实传入的参数就是地址,那么函数的接收参数本质也就是指针了。所以当我们在函数内部计算arr的时候计算的就是地址的大小而不是一个数组的大小了,大家要把关系搞清楚哦。
四.二级指针
我们知道指针变量也是变量那么,指针变量放在哪里呢,那么我们由此就可以知道了二级指针就是存放一级指针变量的地址。
int main()
{
int a = 10;
int* pa = &a;//一级指针
int** ppa = &pa;//二级指针
**ppa = 5;//通过两次解引用改变变量的值
printf("%d ", a);
return 0;
}
五.指针数组
指针数组是数组,只不过数组的元素类型是指针而已,一定要搞清楚,不然会与数组指针搞混淆的哦,这里我们也可以知道int arr就是int类型的数组就是整形数组里面存放的元素是int类型的,而指针数组里面存放的自然而然就是指针类型的。
int* arr[5];//这就是指针数组的写法,[]的优先级更高所以是arr是先和[]结合成为数组,
int*就是元素的类型啦
六.模拟二维数组
刚刚我们知道了指针数组,那么我们可以尝试使用指针数组来模拟二维数组的创造。
int main()
{
int arr1[3] = { 1,2,3 };
int arr2[3] = { 4,5,6 };
int arr3[3] = { 7,8,9 };
int* parr[3] = { arr1,arr2,arr3 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", parr[i][j]);
}
}
return 0;
}
这里就是将指针数组的元素放的都是一维数组然后通过数组指针在进行寻找每一个一维数组,再通过[]进行一维数组种元素的查找,看起来像二维数组其实并不是,因为他们的内存空间并不是连续的。本质并不是二维数组。
总结
以上就是深入指针1的简单了解,有问题的话还请告诉小编,谢谢大家的观看。