首页 > 解决方案 > 在第 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. */

标签: cpointers

解决方案


你看到的是基本的指针算法。这就是在 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


推荐阅读