C 只读指针到指针
在C语言中,C 只读指针到指针,c,pointers,C,Pointers,在C语言中,const char*p有时被称为“只读”指针:指向常量对象的指针(在本例中为char) 看来两者都是 const char**p const char*const*p 将是指向指针的只读指针的等效声明,具体取决于 但是,编译器(gcc、clang)会生成一个警告 我的问题:如何将指向指针(如char**p)的指针作为“只读”指针传递给函数,而不生成警告?如果需要显式强制转换,为什么在char**p而不是char*p的情况下 更多细节 这是一个具体的例子,说明我正在努力实现的目标 只
const char*p
有时被称为“只读”指针:指向常量对象的指针(在本例中为char
)
看来两者都是
const char**p
const char*const*p
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;
}
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)
但gcc(8.1.1)也给出了警告
旁白:当我试图添加限定符时,clang说传递char**
会丢弃限定符,这似乎很奇怪
问题
char**p
)作为“只读”指针传递给函数,而不生成警告char**p
而不是char*p
的情况下A我知道您想要声明指向指向const chat的指针的const指针与指向const char的指针类似。宣言是:
void foo( const char ** const pointer )
这有点“棘手”,因为星星从相反的方向计数
让我们考虑一个非常简单的例子
#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;
}
foo1
函数参数的类型为指针指向常量指针指向常量字符
您可以将代码简化为:
char const ** var = (char**)0;
第二个事实。这不是一个错误。以下是测试用例:
我们再举一个例子:
void foo( const char ** const pointer )
{
const char *ptr = *pointer;
while(**pointer)
{
printf("%c", **pointer);
(*pointer)++;
}
printf("\n");
*pointer = ptr;
}
char const***** c1 = (char*****)0; // fail
char *const**** c2 = (char*****)0; // fail
char **const*** c3 = (char*****)0; // fail
char ***const** c4 = (char*****)0; // fail
char ****const* c5 = (char*****)0; // ok
char *****const c6 = (char*****)0; // ok
好。我们看到了模式
我猜C/C++不能保证您可以修改深度大于2的任何内容,因为前面已经讨论过常量正确性的一些问题。在GCC中,您可以通过以下方式禁用代码中的警告:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers"
readonly(ptr);
#pragma GCC diagnostic pop
我想clang也有类似的东西。至于你的第二个问题,注释中似乎有它。指向指针的等效只读指针是
char*const*ptr
“……有时被称为“只读”指针:…”——不被懂该语言的人所知。指针是可读写的。你完全错了。看看cdecl,检查一下你的课本。@melpomene它不是。指向指针的常量指针是常量字符**常量指针
。指针星的计数方向相反-参见我的答案和example@PeterJ_01我不是说常数指针对指针。请看问题的第一句:我们正在讨论“指向常量对象的指针”,即指向指向char的const指针的指针。“常量对象”是指向char的指针。@melpomene但是您声明了指向常量指针的指针,而不是指向指针foo(指针)的常量指针代码>是一个类型错误。从char**
转换为const char**
是不安全的;炭**pp;常量字符**ppc;pp=&p;ppc=pp*ppc=“foo”*p='x'代码>这不仅仅是“另一个警告”;这是一个类型错误。C使它成为一个错误,因为它删除了const
,这是一件坏事。请不要建议人们忽略其程序中的类型错误。我的示例显示,从char**
转换为const char**
是不安全的,因为它允许您将const char*
转换为char*
,这会自动去除const
,这是不安全的。您回答了一个问题。您提供了示例代码,说“它将给您一个警告,但它将按预期工作”。如果你不建议人们这样做,为什么还要张贴呢?
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers"
readonly(ptr);
#pragma GCC diagnostic pop