【问题标题】:Index of element pointed to by pointer指针指向的元素的索引
【发布时间】:2016-10-29 21:50:59
【问题描述】:

我有一个二维字符数组声明为

char A[100][100]

我还有一个指向该数组的一个元素的指针

char *ptr;
ptr = A[5]

这个指针被传递给另一个函数,它需要能够知道那个指针的索引(在本例中为 5)

void func(void *ptr) {
int index = ???
}

我该怎么做?这甚至可能吗?

【问题讨论】:

  • 为什么不直接传递索引:void func(void *ptr, size_t i);

标签: c arrays pointers


【解决方案1】:

是的,如果你能在func 中看到A 是可能的(A 只是一个双索引一维数组,而不是数组上的指针,这就是它可能的原因)。

#include <stdio.h>

char A[100][100];

void func(void *ptr) {
  char *ptrc = (char*)ptr;
  printf("index %d\n",int((ptrc-A[0])/sizeof(A[0])));
}

int main()
{
  char *ptr = A[5];
  func(ptr);
}

结果:

index 5

当然,如果您将不相关的指针传递给func,您将得到未定义的结果。

注意:需要将传入的void * 指针转换为char *,否则编译器不会让我们区分不兼容类型的指针。

编辑:当我被 chqrlie 挑战计算两个索引时,我尝试了它并且它有效(还增加了安全性以防止使用不相关的指针调用函数):

#include <stdio.h>
#include <assert.h>

char A[100][100];

void func(void *ptr) 
{
  char *ptrc = (char*)ptr;
  ptrdiff_t diff = (ptrc-A[0]);
  assert(0 <= diff);
  assert(diff < sizeof(A));
  printf("index %d %d\n",(int)(diff/sizeof(A[0])),(int)(diff % sizeof(A[0])));
}

int main()
{
  char *ptr = &(A[5][34]);
  func(ptr);
}

结果:

index 5 34

【讨论】:

  • 只是好奇,你为什么要做 char ptrc = (char) ptr; 的初始转换?你不能只在那个打印语句中使用 ptr 吗?
  • 我需要指针是同一类型,否则编译器不会让我区分指针。
  • 指针可以指向 inside 二维数组,计算两个索引似乎很可口。
  • @chqrlie 确实可以使用另一个例程,请参阅我的编辑。
  • 使用C就不需要在这里投char *ptrc = (char*)ptr;
【解决方案2】:

您可以计算ptr 从数组开头的偏移量并得出坐标:

#include <stdio.h>
#include <stdlib.h>

char A[100][100];

void func(void *ptr) {
    if (ptr == NULL) {
        printf("ptr = NULL\n");
        return;
    }
    ptrdiff_t pos = (char *)ptr - A[0];
    if (pos < 0 || pos > (ptrdiff_t)sizeof(A)) {
        printf("ptr points outside A: ptr=%p, A=%p..%p\n",
               ptr, (void*)A, (void*)&A[100][100]);
    } else {
        printf("ptr = &A[%d][%d]\n",
               (int)((size_t)pos / sizeof(A[0])),  // row number
               (int)((size_t)pos % sizeof(A[0])))  // column number
    }
}

int main(void) {
    char *ptr = &A[5][3];
    func(ptr);
    return 0;
}

【讨论】:

  • 对于这个size_t pos,有ptrdiff_t
  • @alk: 没错,但如果ptrA 内部或其上边缘的有效指针,则pos 构造为正。在这种情况下,转换很好。如果ptrNULL 或指向A 之外,无论如何计算差异是没有意义的。
猜你喜欢
  • 1970-01-01
  • 2011-03-12
  • 1970-01-01
  • 2018-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多