只读指针指针

Kri*_*ris 7 c pointers

在C中,const char *p有时称为"只读"指针:指向常量对象的指针(在本例中为a char).

看起来似乎也是如此

  1. const char **p
  2. const char *const *p

将是指向指针的只读指针的等效声明,具体取决于间接的多少级别是不可变的.

但是,编译器(gcc,clang)会生成警告.

我的问题:如何在char **p没有生成警告的情况下将指针(如)作为"只读"指针传递给函数?如果需要明确的演员表,为什么char **p不是char *p

更多细节

这是我想要实现的具体例子.

只读指针

此代码视为char *ptr只读指针.

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

void readonly(const char *ptr)
{
    // ... do something with ptr ...

    // but modifying the object it points to is forbidden
    // *ptr = 'j';  // error: read-only variable is not assignable
}

int main(void)
{
    char *ptr =  malloc(12*sizeof(char));
    strcpy(ptr, "hello world");

    printf("before: %s\n", ptr);
    readonly(ptr);
    printf("after: %s\n", ptr);

    free(ptr);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

预选赛const添加函数调用,没有任何怨言.

只读指针指针

我希望通过指向指针的指针可以进行​​类似的函数调用.

void readonly(const char *const *ptr)
{
    //  ... do something with ptr ...

    // but modifying the object it points to is forbidden
    // **ptr = 'j';
}

int main(void)
{
    char **ptr;

    ptr = (char **) malloc(2*sizeof(char *));

    ptr[0] = malloc(14*sizeof(char));
    strcpy(ptr[0], "hello world 0");

    ptr[1] = malloc(14*sizeof(char));
    strcpy(ptr[1], "hello world 1");

    printf("before: %s %s\n", ptr[0], ptr[1]);
    readonly(ptr);
    printf("after: %s %s\n", ptr[0], ptr[1]);

    free(ptr[1]);
    free(ptr[0]);
    free(ptr);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

clang编译器(版本6.0.0)提供了最易读的警告.

warning: passing 'char **' to parameter of type
    'const char *const *' discards qualifiers in nested pointer types
    [-Wincompatible-pointer-types-discards-qualifiers]
    readonly(ptr);
         ^~~
note: passing argument to parameter 'ptr' here
    void readonly(const char *const *ptr)
Run Code Online (Sandbox Code Playgroud)

但是gcc(8.1.1)也给出了警告.

旁白:当我试图添加限定符时,clang说传递char ** 丢弃限定符似乎很奇怪?

问题

  1. 如何在char **p没有生成警告的情况下将指针(如)作为"只读"指针传递给函数?

  2. 如果需要明确的演员表,为什么char **p不是char *p

P__*_*J__ -1

AI 了解您想要声明指向 const chat 的指针的 const 指针,类似于指向 const char 的指针。声明是:

void foo( const char ** const pointer )
Run Code Online (Sandbox Code Playgroud)

这有点“棘手”,因为星星是从相反的方向数的。

让我们考虑一个非常简单的例子

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

void foo( const char ** const pointer )
{
    while(**pointer)
    {
        printf("%c", **pointer);
        (*pointer)++;
    }
    printf("\n");
}

void foo1( const char *const * pointer)
{
    while(*pointer)
    {
        printf("%s\n", *pointer++);
    }
}


int main(void) 
{
    char **pointer = malloc(sizeof(char *));
    char **pointer1 = malloc(sizeof(char *) * 4);

    char strings_in_RAM_0[] = "one";
    char strings_in_RAM_1[] = "two";
    char strings_in_RAM_2[] = "three";

    pointer1[0] = strings_in_RAM_0;
    pointer1[1] = strings_in_RAM_1;
    pointer1[2] = strings_in_RAM_2;
    pointer1[3] = NULL;

    *pointer = malloc(50);

    strcpy(*pointer,"Const pointer to pointer");

    foo(pointer);
    foo1(pointer1);

    free(*pointer);
    free(pointer);
    free(pointer1);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它会给你一个警告,但它会按预期工作,直到免费为止。然后(因为指针改变了)释放失败。为了避免这种情况,您需要将原始指针保存到 char 例如:

void foo( const char ** const pointer )
{
    const char *ptr = *pointer;
    while(**pointer)
    {
        printf("%c", **pointer);
        (*pointer)++;
    }
    printf("\n");
    *pointer = ptr;
}
Run Code Online (Sandbox Code Playgroud)

函数foo1参数的类型为指向 const 的指针 指向 const char 的指针

https://ideone.com/JSewN4

  • 这不仅仅是“另一个警告”;而是“另一个警告”。这是一个类型错误。C 使它成为一个错误,因为它删除了 `const`,这是一件坏事。请不要建议人们忽略程序中的类型错误。 (2认同)