簡體   English   中英

如何取消引用指向int指針的n級void指針

[英]How to dereference a n-levels void pointer to an int pointer

我正在嘗試實現以下功能:

int foo(const void *p, unsigned int n);

其中p實際上是指向int值的n級指針,函數必須返回該值。 所以:

  • n = 0value = (int)(p);
  • n = 1value = *(int*)(p);
  • n = 2 :p是指向int值的指針

等等...

所以,我認為以下實現可能是正確的:

int foo(const void *p, unsigned int n) {

    if (!n) {

        return (int)p;
    }

    return foo((void*)*((int*)p), n - 1);
}

但是,在這段代碼中,我假設指針的大小總是等於int的大小,我知道它不是真的。 但是,由於p總是一個指向int( n次)指針的指針,我想也許我總是像在代碼中那樣將p轉換為指向int的指針。

我的想法是否正確? 我在互聯網上找不到類似的問題。

提前致謝!

遞歸的底部情況不正確,因為這假設void*int具有相同的寬度。

if (n == 1) return *(int*)p;

會更好。

我不確定你想要完成什么,但我懷疑有更好的方法。

無論如何,指向某事物的指針與指向某物的指針的指針大小相同,等等。

所以你可以將(void *)轉換為(void **)。

但是,將指針強制轉換為int可能會丟失信息,因為sizeof(void*)可能是> sizeof(int)

你應該寫:

int foo(const void *p, unsigned int n) {

    //if n is 0, then p is already an int, but has been casted to a void*
    //This should probably never happend, so you should assert that n > 0

    //if n is 1, then p is actually a pointer to an int
    if (n == 1) return *(int*)p; 

    //else dereference it (by casting it to a (void**) and *then* dereferencing it)
    return foo(*(void**)p, n-1);
}

假設你的int不大於void*

int foo(const void *p, unsigned int n) {
  if (!n) {
    return reinterpret_cast<int>(p);
  }

  return foo(*static_cast<void**>(p), n - 1);
}

除了n=0情況,我們可以避免這種假設:

int foo(const void *p, unsigned int n) {
  if (!n) {
    return reinterpret_cast<int>(p);
  }
  if (n==1) {
    return *static_cast<int*>(p);
  }

  return foo(*static_cast<void**>(p), n - 1);
}

C您可以使用(X)替換static_cast<X>reinterpret_cast<X>子句。

一般來說,如果可能的話,通常最好堅持使用迭代解決方案,而不是遞歸。

int foo(void *p, unsigned int n) {
    for (unsigned int i = 0; i < n; ++i) {
        p = *((void**)p);
    }
    return (int)p;
}

IDEONE: 演示

它可以讓你避免與大theoretiaclly可能的堆棧溢出問題n秒(我不知道為什么你會需要提領1000+層次深的指針,但我不知道為什么你需要擺在首位這一功能,所以讓我們保持函數安全)並避免不必要的函數調用開銷(是的,它可能會被編譯器優化,但為什么不首先以最佳方式編寫它?)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM