真实面经题目 · 原创解析
给定数组指针,如何访问第 50 个元素?
这道题考察的是数组下标、指针运算和数组指针类型的边界理解。核心回答应先澄清“第50位”通常指第50个元素,因此数组从 0 开始计数时应访问 arr[49],若给的是首元素指针则写成 *(p + 49)。如果题目说的是下标 50,则对应 arr[50],也就是第 51 个元素。
真实面经题目 · 原创解析
这道题考察的是数组下标、指针运算和数组指针类型的边界理解。核心回答应先澄清“第50位”通常指第50个元素,因此数组从 0 开始计数时应访问 arr[49],若给的是首元素指针则写成 *(p + 49)。如果题目说的是下标 50,则对应 arr[50],也就是第 51 个元素。
可以先说明数组访问的前提:C/C++ 中数组下标从 0 开始。如果题目里的“第50位”按日常表达理解为第 50 个元素,那么应访问下标 49,即 arr[49]。如果给的是指向首元素的指针 int *p,那么等价写法是 *(p + 49),因为 p + 1 不是移动 1 个字节,而是移动一个元素的大小。还要区分“数组名退化为指向首元素的指针”和“数组指针”这两个概念:arr 在表达式中通常会退化为 int *,而 int (*p)[100] 是指向整个含 100 个 int 的数组的指针。若 p 是 int (*p)[100],访问第 50 个元素应写成 (*p)[49] 或 *(*p + 49)。如果面试官强调的是下标 50,则答案改为 arr[50]、*(p + 50) 或 (*p)[50],并说明那是第 51 个元素。
“第50位”有两种可能理解:一种是自然语言里的第 50 个元素,另一种是程序下标为 50 的位置。数组下标从 0 开始,所以第 50 个元素对应下标 49,写作 arr[49]。如果直接说下标 50,则访问 arr[50],它实际上是第 51 个元素。优秀回答要先说明这个歧义,再给出对应写法。
如果题目说给了数组和数组指针,但实际指的是指向首元素的指针 int *p,那么 p 等价于指向 arr[0]。访问第 50 个元素时应写 *(p + 49),也可以理解为 p[49]。这里的 p + 49 按 int 的元素宽度移动 49 个位置,不是简单移动 49 个字节。
数组名 arr 在大多数表达式里会退化为指向首元素的指针,也就是 int *,因此 arr[49] 与 *(arr + 49) 等价。这个等价关系来自下标运算的定义:a[i] 本质上可以理解为 *(a + i)。但 sizeof(arr) 和取地址 &arr 等场景不会按普通首元素指针处理。
真正的数组指针类型是 int (*p)[100],它指向的是整个长度为 100 的数组,而不是单个 int 元素。此时 p + 1 会跨过一个完整的 100 元素数组,移动的跨度是 100 * sizeof(int)。所以访问第 50 个元素不能写 *(p + 49),而应先解引用整个数组,再访问元素:(*p)[49]。
长度为 100 的数组合法下标范围是 0 到 99。如果访问第 50 个元素,arr[49] 一定在范围内;如果访问下标 50,arr[50] 也在范围内,但含义不同。回答时应避免只给一个表达式而不说明语义,因为这类题通常在考察自然序号和程序下标之间的差异。
可以组织成一句完整回答:若第50位指第 50 个元素,则数组写 arr[49],首元素指针写 *(p + 49);若 p 是 int (*p)[100] 这种数组指针,则写 (*p)[49];若题目明确说下标 50,则访问 arr[50] 或 *(p + 50)。这样既回答了操作,也覆盖了类型差异。
int value_at_50(const int *arr, int len) {
if (arr == NULL || len < 50) {
return 0;
}
return arr[49]; /* same as *(arr + 49) */
} 因为第 50 个元素是自然序号,从 1 开始数;数组下标从 0 开始,所以第 1 个元素是 *(p + 0),第 2 个是 *(p + 1),依次类推,第 50 个就是 *(p + 49)。*(p + 50) 对应的是第 51 个元素。
在普通元素访问表达式中可以认为等价,因为 arr 会退化为指向首元素的指针,arr + 49 指向第 50 个元素,再解引用得到值。但在 sizeof(arr)、&arr 等场景里,arr 不按普通 int * 处理。
int *p 指向单个 int 元素,p + 1 前进一个 int;int (*p)[100] 指向一个包含 100 个 int 的完整数组,p + 1 会跨过整个数组。前者访问第 50 个元素写 *(p + 49),后者写 (*p)[49]。
不能。长度为 100 的数组合法下标只有 0 到 99,arr[100] 已经越界。即使内存上看起来有地址,也属于未定义行为,测试或开发中都不能依赖这种访问结果。
先说需要确认“第50位”是第 50 个元素还是下标 50。默认按第 50 个元素回答为 arr[49] 或 *(p + 49);如果给的是数组指针 int (*p)[100],则是 (*p)[49]。最后补充下标 50 对应 arr[50]。