数组的C数组:为什么我需要在这里强制转换为常量?
为什么我需要将此代码中的数组的C数组:为什么我需要在这里强制转换为常量?,c,arrays,constants,C,Arrays,Constants,为什么我需要将此代码中的print_args调用更改为print_args(argc,(const char**)argv),以使其可编译 #include <stdio.h> void print_args(int argc, const char *argv[]) { for (int i = 0; i < argc; ++ i) { puts(argv[i]); } } int main(int argc, char *argv[])
print_args
调用更改为print_args(argc,(const char**)argv)
,以使其可编译
#include <stdio.h>
void print_args(int argc, const char *argv[]) {
for (int i = 0; i < argc; ++ i) {
puts(argv[i]);
}
}
int main(int argc, char *argv[]) {
print_args(argc, argv);
return 0;
}
(请注意,这只是一个简单的示例代码来说明问题。)comp.lang.c常见问题解答,总结:
无法将char**
值分配给const char**
指针有点模糊。假设const
限定符存在于
总之,编译器希望帮助您信守您的承诺
修改const
值。这就是为什么可以将char*
分配给常量的原因
char*
,但不是相反:显然,“添加”是安全的
const
-指向一个简单指针,但使用它会很危险
在C中,如果必须分配或传递具有限定符的指针
除第一级间接寻址之外的不匹配,必须使用
显式强制转换
下面是它给出的示例,其中第3行应该给出警告:
const char c = 'x'; /* 1 */
char *p1; /* 2 */
const char **p2 = &p1; /* 3 */
*p2 = &c; /* 4 */
*p1 = 'X'; /* 5 */
第1行和第2行显然很好。在第4行,&c
具有类型指向常量字符的指针
,并且由于char**
是类型指向常量字符的指针
,那么*p2
也是类型指向常量字符的指针
,因此该语句没有问题。第5行也可以,因为p1
是指向char的类型指针,所以您可以修改它指向的内容
因此,如果第3行是正常的,那么您将完全按照您期望的const
来执行,修改指针指向const char
的char
,因此第3行是不允许的,并且您不能在没有强制转换的情况下将char**
分配给const char**
请注意,使用强制转换只会隐藏问题,而不会解决问题。如果您添加了强制转换,那么上面的第3行就可以工作了,并且您可以间接地修改一个明显的常量char
。虽然这并不总是正确的,但这是一个很好的例子,表明屈服于显然需要在C中强制转换通常只是一个错误
<>注意,在C++中,你可以声明你的函数参数<代码> const char * const *ARGV,它将不需要强制转换,并且防止间接修改。< /P>切线,对使用< <代码> -> Werror <代码>很有好处,但是你也应该考虑使用<代码> -Walth-Wu-PotoNoth< /COD>。它们可能会给你一些善意的错误,但即使是那些对你理解也有好处。-Wextra
是的<代码>-pedantic
否,因为我使用GNU扩展(由\ifdef\uu GNUC\uuu
保护)。您可以使用额外的-Wno foo
选项关闭个别类型的警告。对于gnu扩展,我不确定具体的选项是什么,但可能类似于-Wno gnu扩展
。您甚至可以使用右侧的#pragma
s忽略特定行或块的警告。谢谢我必须在早上重新阅读这篇文章(在我睡觉后,当我可以再次集中注意力时)。char*const*argv
在普通C语言中也能很好地工作。而且不需要演员阵容。这取决于你所说的“作品”是什么意思。它不需要强制转换,因为它不为char
提供const
属性<代码>常量字符c='c';常量字符*pc=&c;char*const*ppc=&pc不允许使用code>,将char**
传递给接受char*const*argv
的函数将允许您执行**argv='x'代码>和类似的。我很困惑。常量修饰符的关联性是什么?因为添加typedef char*str
然后使用void print_args(int argc,const str argv[])
工作。我想说的是,print_args
不会改变传递的argv
的任何内容argv
在print\u args
中应该是完全不可变的。即使将其声明为void print\u args(int argc,const str const*const argv)
也行得通,但我认为其中一个const
是多余的。如果没有typedef
,我就不能这样做吗?
const char c = 'x'; /* 1 */
char *p1; /* 2 */
const char **p2 = &p1; /* 3 */
*p2 = &c; /* 4 */
*p1 = 'X'; /* 5 */