对于很多 C 语言初学者来说,指针是一大难题!
但是指针也是 c 语言的灵魂,离开指针,可能 c 语言就只能处理小学数学题了。
最后,如果大家如果在自学遇到困难,想找一个 C ++ 的学习环境,可以加入我们的 C ++ 学习圈,点击我加入吧,会节约很多时间,减少很多在学习中遇到的难题。
但是指针虽然难,但并没有难到大多数人学不会的程度。C 语言面向的使用群体是普通人,而不是智商超群的大佬们。只要用心学习,肯定是可以掌握的。
1+1 不等于 2? 来看这道奇怪的 C 语言题目
今天小编又给大家带来一道关于指针的 c 语言面试题,话不多说上代码:
include<stdio.h>
int main()
{
int vector2 = {
{1,2,3,4,5,6,7,8,9,10},
{11,12,13,14,15,16,17,18,19,20}
};
int(*a)[10] = vector;
printf(“%d %d %d %d %d
“,
a, (a + 1), (a + 1), (a[0] + 1), (a[1]));
return 0;
}
程序首先定义了一个二维数组 vector,并使用初始化的方式赋予了 1 -20 的初值。
接着又定义了一个指针 a,并令其指向 vector。
接下来程序通过指针依次输出 5 个值。
那么,这个 c 语言程序的输出是什么呢?
初步分析
显然这题的关键点在于指针 a
首先我们要明确一点:在理解指针的时候,要像 int char short 一样,将它当做一种数据类型。
分析 a 的定义语句:int(*a)[10] = vector,可以发现 a 其实是一个 int[10] 类型的数组指针。
那么这个 c 语言的程序输出结果是什么呢,得到答案最简单粗暴的方式就是直接运行代码:
1+1 不等于 2? 来看这道奇怪的 C 语言题目
c 语言中的指针移动
不仅仅是 c 语言,语言中的数据类型其实就是告诉处理器应该如何访问它,这句话是什么意思呢?请看下图:
1+1 不等于 2? 来看这道奇怪的 C 语言题目
大家都知道数据在内存中的最小粒度是一个字节,上图假设截取内存中的 10 个字节,在我的电脑上,c 语言类型占用了 4 个字节,因此 int 类型指针是逐 4 个字节访问内存的。
同理,short 类型的指针是逐 2 个字节移动的。char 类型的指针是逐字节的移动的。
到这里相信大家都发现了,指针的加减法并不像数学概念中的加减一样严格遵循 1+1 =2。
对于 int 型指针来说,+1 居然移动了 4 个字节,对于 short 型指针来说 + 1 又只移动了两个字节。
其实分析指针加减法的时候不应该从只从数学角度考虑,比如 1 千克 + 1 克 也不等于 2 对吧!
这提醒了我们应该不仅仅考虑数字,还需要考虑单位。
指针的单位就是数据类型。int 型指针的单位就是 sizeof(int),short 型指针的单位就是 sizeof(short), 这样考虑是不是觉得合理多了。
程序输出分析
明确了指针的加减法处理方式,再来分析程序输出就简单多了。
a, (a + 1), (a + 1), (a[0] + 1), (a[1]))
1 11 2 2 11
我们首先查看一下指针的数据类型(下图截取自 vs2019)。
1+1 不等于 2? 来看这道奇怪的 C 语言题目
从上图中我们可以清楚地看到 a 的数据类型就是一个 int[10]的数组指针。
那么 a 的数据类型就是一个 int[10] 的数组,显然 a 就等价于(*a+0)
那不就是数组的第 0 个元素 1 了吗。
**(a+1)不就相当于指针指向位置的第 0 个元素吗,也就是 11。
再来看第三个, a 的数据类型就是一个 int[10]的数组,那么a+ 1 就相当于移动到这个数组的第 1 个元素(下标从 0 开始),也就是 2。
第四个数字分析和第三个是类似的,因为 * a 等价于 a[0], 所以此处输出也是 2。
第五个数字的分析和第四个是类似的,因为 *(a+1)和 a[1]是等价的,输出为 11。