c - 在第 5 行查找值“pp-p”的给定示例中,为什么在解释中这些值除以 2?
问题描述
#include<stdio.h>
void main ()
{
int a[10] = {100, 206, 300, 409, 509, 601}; //Line 1 array declared
int *p[] = {a, a+1, a+2, a+3, a+4, a+5}; //Line 2 pointer to the array
int **pp = p; //Line 3 double pointer initialized
pp++; // Line 4 double pointer incremented
printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 5
*pp++; // Line 6
printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 7
++*pp; // Line 8
printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 9
++**pp; // Line 10
printf("%d %d %d\n",pp-p,*pp - a,**pp); // Line 11
}
/* 第 5 行包含一个打印三个值的表达式,即 pp - p、*pp - a、**pp。让我们计算它们中的每一个。
pp = 302, p = 300 => pp-p = (302-300)/2 => pp-p = 1, i.e., 1 will be printed.
pp = 302, *pp = 202, a = 200 => *pp - a = 202 - 200 = 2/2 = 1, i.e., 1 will be printed.
pp = 302, *pp = 202, *(*pp) = 206, i.e., 206 will be printed. */
解决方案
你看到的是基本的指针算法。这就是在 C 中对指针进行加减运算的方式。
让我们从一个数组开始:
int a[10] = {100, 206, 300, 409, 509, 601};
您可以使用数组语法访问这些元素:
a[0] = xy;
a[2] = 1;
这与使用指针算术的以下语法相同:
*a = xy;
*(a+2) = 1;
您可以看到您可以添加一个索引n
来访问n
数组的第 th 个元素。出于显而易见的原因,这不仅仅是将索引添加到地址。每个元素都有一定的大小。因此,算术规则告诉我们地址是按n
字节调整的,但按n
数据对象调整。我们需要添加/减去多少字节来自每个对象的大小。因为a
它是sizeof(int)
,因为p
它是sizeof(int*)
。
把一个数加到一个指针上的结果又是一个指针。使用普通的数学规则,您可以减去 2 个指针(如果它们指向同一个数组)并得到一个数字,该数字(再次)是对象数,而不是字节数。
这意味着&a[2] - &a[1] == 1
。这适用于任何尺寸。
现在我们看看你的代码:
int **pp = p;
pp++;
pp = &p[1]
这与which is相同pp=p+1
。因此*pp==p[1]==a+1
现在打印它:
printf("%d %d %d\n",pp-p,*pp - a,**pp);
从上面应用规则:
pp-p == p+1 - p == 1
*pp-a == p[1] - a == a+1 - 1 == 1
**pp == *p[1] == *(a+1) == a[1] = 206
==>1 1 206
推荐阅读
- oracle - Docker 容器内的 Oracle 表单和报表服务器
- c# - 在 for 循环中从 ICollection 列表读取的 Asp.NET CSHTML 数据在页面加载时未设置
- node.js - 错误无法使用 express 和节点发布 /
- tensorflow - 在 Keras、Tensorflow 中加载训练数据
- java - 致命异常:java.lang.NoSuchMethodError:没有虚拟方法 callEngineReleaseConnection(Lcom/squareup/okhttp/Call;)
- android - Fragment 类无法访问 Kotlin 中布局文件内的组件
- python - 如何在训练/测试拆分中使用不同的数据帧
- vba - CATIAV5 汇编或反汇编一个 catvba 项目进行版本控制
- javascript - 如何在 y 轴上偏移 Material-UI Popper(popper.js 库)位置?
- netbeans-8 - JavaFX 持久层 - 删除检索()和持久()并添加带有数据文件的 CRUD 应用程序