【问题标题】:Can I safely cast a &char[] to char**?我可以安全地将 &char[] 转换为 char** 吗?
【发布时间】:2015-07-02 08:38:33
【问题描述】:

有以下代码:

char data[2048];

还有一个这样声明的函数:

int f(char** data);

我可以这样称呼它吗:

f((char**)&data);

如果我只使用 &data,编译器会发出以下警告:

warning C4047: 'function' : 'char **' differs in levels of indirection from 'char (*)[2048]'

【问题讨论】:

标签: c arrays pointers char


【解决方案1】:

不,你不能。

data 是一个数组。 &data 是一个指向数组的指针。它不是指向指针的指针。尽管data在多个上下文中衰减指向一个指针,但它本身并不是一个指针——获取地址会给你数组的地址。

如果你想要一个指向数组的指针,你可以试试这样的:

char *pdata = data; // data decays to a pointer here
                    // (a pointer to the first element of the array)
f(&pdata);          // Now &pdata is of type char ** (pointer to a pointer).

当然,您实际需要什么取决于您的用例。

【讨论】:

  • 这不是和做演员表一样吗 (char**)&data ?
  • data 是一个数组。 pdata 是一个指针。虽然data 衰减 指向多个上下文中的指针,但它本身并不是指针 - 获取地址即可获得数组的地址。
  • 但是 (char**)&data 除了声明一个变量之外有什么区别?
  • data 和 pdata 是不同的! data 是一个数组。获取其地址与获取pdata 的地址 不同。考虑一下:int x = 0; &x 与 &0 有何不同? (提示:“唯一”的区别是我声明了一个变量)。
  • 然而,此代码确实依赖于实现该函数的人对数组和指针的工作方式感到困惑。我不会这么认为。尽管可能很少见,但他们实际上可能知道指针指向指针、指向数组的指针和指向数组第一个元素的指针之间的区别。它们都不兼容。
【解决方案2】:

指针指针不是数组,也不是指向数组的指针,也不应该用来指向数组。除了可以用来指向指针数组的第一项的特殊情况,这里不是这种情况。

函数int f(char** data); 不能接受char data[2048]; 数组作为参数。要么改变数组类型,要么重写函数。

正确的替代函数是:

int f (char* data);
int f (char data[2048]); // completely equivalent to char* data
int f (char (*data)[2048]); // array pointer, would require to pass the address of the array

【讨论】:

    【解决方案3】:

    如this more detailed example中所述:

    虽然数组名可能衰减为指针,但数组的地址不会衰减为指向指针的指针。为什么要这样做?这样对待数组有什么意义?

    有时会传递指向指针的指针来修改指针(简单的指针参数在这里不起作用,因为 C 通过值传递,它只允许修改指向的内容,而不是指针本身)。这是一些虚构的代码(不会编译):

    void test(int** p)
    {
        *p = malloc ... /* retarget '*p' */
    }
    
    
    int main()
    {
        int arr[] = {30, 450, 14, 5};
        int* ptr;
    
        /* Fine!
        ** test will retarget ptr, and its new value
        ** will appear after this call.
        */
        test(&ptr);
    
        /* Makes no sense!
        ** You cannot retarget 'arr', since it's a
        ** constant label created by the compiler.
        */
        test(&arr);
    
        return 0;
    }
    

    【讨论】:

    • 这有什么关系? OP 在 main() 中有一个静态分配的数组。
    • 正如您在发布的代码中所看到的那样,将静态数组传递给该测试函数是没有意义的。
    【解决方案4】:

    你可以这样做。

    char data[2048];
    char *a=&data[0];
    char **b=&a;
    f(b);
    

    【讨论】:

      猜你喜欢
      • 2018-05-09
      • 1970-01-01
      • 1970-01-01
      • 2013-01-10
      • 2010-10-12
      • 2012-03-26
      • 2021-04-29
      • 2013-10-18
      • 2012-01-15
      相关资源
      最近更新 更多