对数组名取地址赋值给数组指针与普通指针的区别

我不是女神ヾ 2022-05-04 11:00 289阅读 0赞

对数组名取地址赋值给数组指针与普通指针的区别:

以下红色字体的说法是错误的:
使用一级指针来接受&arr,只是表示一个普通的一级指针,
它并没有接收到&arr赋来的跨度,而只接收到了地址而已。所以,
p1的跨度只有4个字节。它保存的地址所表示的是arr这个数组的首元素地址
相当于在赋值过程中,&arr退化为了arr,失去了数组本来拥有的跨度。
此时p1[i],就是在对数组中的每一个数组元素做遍历了。

p保存的是数组的地址&arr
*p保存的是数组首元素的地址:*&arr —-> arr

同理,以下红色字体的说法同样不正确:
p2此时的地址已经为arr,*p2就是数组元素的值了。
而二级指针的特点就是在于它保存的是一级指针的地址,即它的内容就是一级指针的地址。
*p2就是这个一级指针的地址。
*(*p2)则为对元素的值取地址,因为数组元素的值是手动赋值的,
那么**p此时就是对野指针的非法操作了。

p为&arr首地址
*p为arr首元素地址
**p为数组元素内容

综上:一维数组名对应一级指针,二维数组名对应二级指针,n维数组名对应n级指针。

  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include<stdio.h>
  3. #include<stdlib.h>
  4. int main(int argc, char *argv[])
  5. {
  6. int arr[5] = {1, 2, 3, 4, 5};
  7. /*一下的说法是错误的:
  8. 数组指针才是将地址连同&arr这个地址的跨度一起赋给了指针变量;
  9. 而是用普通的一级指针来接受的&arr,只是表示一个普通的一级指针,
  10. 它并没有接收到&arr赋来的跨度,而只接收到了地址而已。所以,
  11. p1的跨度只有4个字节。它保存的地址所表示的是arr这个数组的首元素地址
  12. 相当于在赋值过程中,&arr退化为了arr,失去了数组本来拥有的跨度。
  13. 此时p1[i],就是在对数组中的每一个数组元素做遍历了。
  14. */
  15. //p保存的是数组的地址&arr
  16. //*p保存的是数组首元素的地址:*&arr ---> arr
  17. int *p1 = &arr; //其实此处不需要取地址,将二级指针赋值给一级指针会有警告。
  18. for (int i = 0; i < 5; i++)
  19. {
  20. printf("%d\n", p1[i]);
  21. }
  22. printf("------------------------------\n");
  23. //*的优先级为2级,[]、()的优先级为1级
  24. //p2的内容是&arr
  25. //*p2的内容是*&arr ---> arr,即数组的首元素地址
  26. //
  27. int (*p2)[5] = &arr;
  28. for (int i = 0; i < 5; i++)
  29. {
  30. printf("%d\n", (*p2)[i]);
  31. }
  32. printf("------------------------------\n");
  33. /*同理,以下的说法同样不正确:
  34. p2此时的地址已经为arr,*p2就是数组元素的值了。
  35. 而二级指针的特点就是在于它保存的是一级指针的地址,即它的内容就是一级指针的地址。
  36. *p2就是这个一级指针的地址。
  37. *(*p2)则为对元素的值取地址,因为数组元素的值是手动赋值的,
  38. 那么**p此时就是对野指针的非法操作了。
  39. */
  40. //p为&arr首地址
  41. //*p为arr首元素地址
  42. //**p为数组元素内容
  43. int **p = &arr;
  44. for (int i = 0; i < 5; i++)
  45. {
  46. printf("%d\n", p[i]);
  47. }
  48. system("pause");
  49. return 0;
  50. }

发表评论

表情:
评论列表 (有 0 条评论,289人围观)

还没有评论,来说两句吧...

相关阅读