c中的许多函数将指针指向常量字符串/字符作为参数,例如void foo(const char *ptr)
。但是我希望更改它所指向的字符串(ptr
)。如何在c
答案 0 :(得分:2)
你可以抛弃const
:
void evil_function(const char *ptr)
{
char *modifiable = (char *) ptr;
*modifiable = 'f';
}
请注意,这很危险,请考虑传递给函数的数据确实无法更改的情况。例如,evil_function("bar");
可能会崩溃,因为字符串文字通常放在只读内存中。
答案 1 :(得分:1)
不要这样做会导致代码无法预测。基本上const char *指向的字符串可能存储在程序数据的只读部分中,如果你尝试在那里写一些东西,就会发生坏事。请记住,foo可以被称为foo("Test")
,在这里你没有为自己的“Test”分配内存,你只需要一个指向包含字符串的内存的指针。该内存可能是只读的。
答案 2 :(得分:1)
您可以将其复制到另一块内存中,并在那里进行修改。
如果你把它转换为非const,然后修改,很可能你只是段错误。
答案 3 :(得分:1)
void foo(const char *x);
char data[4] = "Hi!";
int sum = 0;
for (int k=0; k<strlen(data); k++) {
foo(data); /* foo first */
sum += data[k];
}
printf("%d\n", sum);
由于foo()
不会更改其参数,因此编译器可以将此代码更改为
void foo(const char *x);
char data[4] = "Hi!";
int sum = 0;
for (int k=0; k<strlen(data); k++) {
sum += data[k]; /* sum first */
foo(data);
}
printf("%d\n", sum);
但是,如果foo()
更改data
数组中的值,则结果将根据编译器选择编码循环的顺序而有所不同!
简而言之:不要欺骗你的编译器
如何欺骗编译器
远离const
void foo(const char *readonly) {
char *writable = (char *)readonly;
/* now lie to the compiler all you like */
}
答案 4 :(得分:0)
用符号“const char * ptr”我们告诉编译器 ptr包含的内容不应该更改。
只是,我们无法改变它!
答案 5 :(得分:0)
const的全部原因是为了表示底层内容不被这个函数修改,所以不要改变它,因为这很可能会破坏一些依赖于const的代码。除此之外,您始终可以使用const_cast<char*>
或直接转换指针
答案 6 :(得分:-1)
如果你这样做:
void dont_do_this_at_home(const char *ptr)
{
char **steve-o_ptr = (char **) &ptr;
char *bam_margera = "viva la bam";
*steve-o_ptr = bam_margera;
}
然后,尽管是一个const指针,你发送到函数中的指针也会被改变,到目前为止,其他建议只允许你改变字符串的内容,而不是指向字符串的指针。
我同意其他人你不应该,永远,“un-const”你得到的任何参数,因为被调用者可能真的依赖于没有副作用这些参数的功能。
还有这种方法可以摆脱警告/错误
typedef struct {
union {
const void* the_const;
void* the_no_const;
} unconsting;
}unconst_t;
/* Here be dragons */
void* unconst_pointer(const void* ptr) {
unconst_t unconst.unconsting.the_const = ptr;
return unconst.unconsting.the_no_const;
}
如你所见,实际上很有可能也很受欢迎,但你必须知道自己在做什么,否则可能会出现神秘的错误。