当前位置:首页 > C > 正文

深入理解C语言指针与数组(小白也能看懂的C语言指针与数组关系详解)

在学习C语言指针C语言数组时,很多初学者常常感到困惑:它们之间到底有什么联系?为什么有时候可以用指针访问数组,又为什么数组名看起来像一个指针?本文将用通俗易懂的方式,带你彻底搞懂指针与数组关系,让你轻松掌握这一核心概念。

一、数组的本质是什么?

在C语言中,数组是一段连续的内存空间,用于存储相同类型的数据。例如:

int arr[5] = {10, 20, 30, 40, 50};  

这行代码在内存中分配了5个连续的int类型空间(每个int通常占4字节),总共20字节。数组名 arr 实际上代表的是这段内存的起始地址

二、指针是什么?

C语言指针是一个变量,它存储的是另一个变量的内存地址。例如:

int x = 100;int *p = &x;  // p 指向 x 的地址  

这里,p 是一个指针,它保存了变量 x 在内存中的地址。

三、数组名其实是个“常量指针”

关键来了!在C语言中,数组名在大多数情况下会被解释为指向数组第一个元素的指针。也就是说:

int arr[5] = {10, 20, 30, 40, 50};// 以下两种写法是等价的:printf("%d\n", arr[2]);      // 输出 30printf("%d\n", *(arr + 2));  // 同样输出 30  

这里,arr 被当作一个指向 arr[0] 的指针使用。arr + 2 表示从起始地址向后偏移2个int的位置,再用 * 解引用,就得到了 arr[2] 的值。

深入理解C语言指针与数组(小白也能看懂的C语言指针与数组关系详解) C语言指针 C语言数组 指针与数组关系 C语言编程教程 第1张

四、指针也可以像数组一样使用

既然数组名可以当指针用,那么反过来,指针也可以用下标访问,就像数组一样:

int arr[5] = {10, 20, 30, 40, 50};int *p = arr;  // p 指向 arr 的首地址// 以下全部等价:printf("%d\n", p[3]);       // 输出 40printf("%d\n", *(p + 3));   // 输出 40printf("%d\n", arr[3]);     // 输出 40  

这说明,在C语言中,a[i] 本质上就是 *(a + i) 的语法糖!这也是为什么指针与数组关系如此紧密。

五、重要区别:数组名 vs 指针变量

虽然数组名可以当指针用,但它不是一个真正的指针变量!关键区别在于:

  • 数组名是一个常量地址,不能被修改(例如不能写 arr = p;
  • 指针变量是一个可变的变量,可以重新赋值(例如 p = &x;
  • 对数组使用 sizeof 得到的是整个数组的大小,而对指针使用 sizeof 得到的是指针本身的大小(通常是8字节或4字节)
int arr[5];int *p = arr;printf("%zu\n", sizeof(arr));  // 输出 20(5 * sizeof(int))printf("%zu\n", sizeof(p));    // 输出 8(64位系统下指针大小)  

六、总结

通过本篇C语言编程教程,我们了解到:

  • 数组在内存中是连续存储的
  • 数组名在表达式中会“退化”为指向首元素的指针
  • 指针和数组在访问元素时语法可以互换(a[i] == *(a+i)
  • 但数组名是常量地址,指针是变量,二者本质不同

掌握这些知识,你就能更自信地编写和阅读涉及C语言指针C语言数组的代码了!希望这篇关于指针与数组关系的教程对你有帮助。