指针减去数组和变量中的指针

Posted

技术标签:

【中文标题】指针减去数组和变量中的指针【英文标题】:pointer minus pointer in array and variable 【发布时间】:2020-12-19 16:02:24 【问题描述】:

谁能帮我解决这个问题。 我认为指针是一个保存变量地址的对象。所以当我减去一个指向指针的指针时。它得到这个结果。

int a = 2;
int b = 7;
int* c = &a;
int* d = &b;
int e = c - d; // = 3


int array[] =  1, 2, 6, 4, 7, 8, 5, 3 ;
int* f = &array[0];
int* g = &array[8];
int h = g - f; // = 8 

【问题讨论】:

不清楚你在问什么。你做了一个观察,但你没有问一个问题。结果有什么让你吃惊的地方?您的预期是什么,这与您观察到的有何不同? 请注意,int e = c - d; 是不允许的。您只能减去指向同一数组中元素的指针。 我想知道这是怎么发生的。 @FrançoisAndrieux 我跑了,它奏效了。 这是未定义的行为。这意味着编译器不需要产生错误,任何事情都可能发生。当我尝试时,我得到e == -1;。任何结果都是可能的,包括崩溃或根本没有结果。对于h,结果始终为 8,因为这是减去 array 中元素索引的结果。 注意&array[8]是否允许是一个灰色区域,因为最后一个元素是array[7]但是你可以得到一个指向one-past-the-end的指针,只要它没有被评估。 【参考方案1】:

在您的第一个示例中,减去独立指针是没有意义的。考虑到你的例子:

int a = 2;
int b = 7;
int* c = &a;
int* d = &b;
int e = c - d; // Nonsense

如果您尝试使用指针执行“2 - 7”操作,那么您首先必须取消对指针的引用(评估指针指向的变量所保存的值):

int e = (*c) - (*d);

【讨论】:

【参考方案2】:

你是对的,指针保存内存中对象的地址。在 C 和 C++ 中,我们可以进行指针运算,这让我们可以相互减去指针等等。减去指针为我们提供了内存中两个地址之间的距离。距离的单位由指针类型决定。这意味着减去两个int*s 将为您提供多少ints 是您的地址分开。在您的情况下,变量e 将是a 存储在内存中的位置与b 存储在内存中的位置之间的距离。运行你的代码我得到了e=1。我期望这是因为ab 是在彼此之后定义的,因此预计它们将占据堆栈上的两个相邻空间,但我猜这是编译器决定的。 另一方面,根据定义,所有元素一个接一个地存储,因此任何数组的第一个和第八个元素之间的距离总是8。也看看下面的代码:

int a = 2;
int b = 7;
int* c = &a;
int* d = &b;
int e = d - c; // e=1
//the unit of measurement for pointer subtraction is the type of the pointer
//therefore although first byte of b is stored 4 bytes (sizeof(int)) after the
//first byte of a, we get '1' as the distance. but we cast the pointer to another type
//say char, we get distance based on that type
int f= (char*)d-(char*)c;//f=4 or e*4 since sizeof(int)=4*sizeof(char) (on this particular environment)

【讨论】:

问题标记为 C++,d - c 是该语言中的未定义行为。也许它在C中是允许的,我不确定。没有正确、不正确或预期的结果。 @FrançoisAndrieux — 也不允许 I C。 C 或 C++ 中没有任何内容要求 ab 彼此相邻,也不需要按照它们的声明顺序分配。这个答案描述了常见的行为,但这不是你可以指望的。使用我以前使用的另一个编译器,区别应该是-1

以上是关于指针减去数组和变量中的指针的主要内容,如果未能解决你的问题,请参考以下文章

为啥在分配没有后续函数调用的大数组时,GCC 会向堆栈指针减去错误的值?

C语言的数据类型——指针

C语言的数据类型——指针

指针和引用指针数组和数组指针

指针数组的概念和定义方式

指针数组的概念和定义方式