You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言指针疑问:为何p[5]=98能修改数组a[2]的值?

C语言指针访问数组元素的疑问解答

刚接触C语言时,你可能会遇到这个依赖栈布局的指针问题:

原代码与需求

原代码如下:

#include <stdio.h>

int main(void)
{
  int n;
  int a[5];
  int *p;

  a[2] = 1024;
  p = &n;
  /*
   * write your line of code here...
   * Remember:
   * - you are not allowed to use a
   * - you are not allowed to modify p
   * - only one statement
   * - you are not allowed to code anything else than this line of code
   */
  
  /* ...so that this prints 98\n */
  printf("a[2] = %d\n", a[2]);
  return (0);
}

原代码输出a[2] = 1024,要求添加一行代码,满足不能使用变量a、不能修改p、仅一行代码的约束,让输出变为a[2] = 98。

找到的解决方案是添加p[5] = 98;,修改后代码:

#include <stdio.h>

int main(void)
{
  int n;
  int a[5];
  int *p;

  a[2] = 1024;
  p = &n;
  /*
   * write your line of code here...
   * Remember:
   * - you are not allowed to use a
   * - you are not allowed to modify p
   * - only one statement
   * - you are not allowed to code anything else than this line of code
   */
  p[5] = 98;
  /* ...so that this prints 98\n */
  printf("a[2] = %d\n", a[2]);
  return (0);
}

为什么p[5] = 98;能修改a[2]?

这个写法完全依赖于局部变量在栈上的特定存储布局,属于C语言的未定义行为(换编译器、平台或编译选项就可能失效),但在题目假设的环境下,逻辑是这样的:

  • C语言中,p[k]等价于*(p + k):指针p会先加上k个int类型的字节偏移(k * sizeof(int)),再解引用访问对应地址的内容。
  • main函数的局部变量n、a[5]、p都存在栈上,题目环境的栈布局满足:&a[2] = &n + 5 * sizeof(int)(即a[2]的地址比n的地址高5个int的长度)。
  • 因为p = &n,所以p + 5正好指向a[2]的地址,p[5] = 98就等价于直接给a[2]赋值98。

⚠️ 注意:这种写法在实际开发中绝对不能使用,它完全依赖特定实现,没有可移植性,还属于栈内存越界访问,可能导致程序崩溃或其他不可预测的问题。

内容的提问来源于stack exchange,提问作者Sunkanmi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:45:57