为什么我得到; 使用’const char *’类型的表达式初始化’char *’会丢弃限定符?

我无法弄清楚为什么我会自己发出警告:

 function_prototype_const_modifier.c:13:8: warning: initializing 'char *' with an expression of type 'const char *' discards qualifiers [-Wincompatible-pointer-types] char *ptr1 = source; ^ ~~~~~~ 1 warning generated. 

代码非常简单

 #include char *my_strcpy(char *destination, const char *source); int main(void) { char str1[] = "this is something"; char str2[] = "123456789123456789"; my_strcpy(str2, str1); puts(str2); return 0; } char *my_strcpy(char *destination, const char *source) { char *ptr1 = source; char *ptr2 = destination; while(*ptr1 != '\0') { *ptr2++ = *ptr1++; } *ptr2 = '\0'; return destination; } 

任何的想法?

source是一个const char * ,一个指向const字符的指针,因此不能通过解除引用指针来改变字符(即source[0] = 'A';是一个约束违规)。

但是,将其分配给char * 会丢弃此约束; 一个简单的char *表明ptr1指针指向的字符不是常量,你现在可以自由地写ptr1[0] = 'A'; 没有得到编译器错误(“诊断消息”)。

考虑传递字符串文字时这意味着什么。 由于字符串文字是“只读”(它是一个const char [] ),因此尝试修改其内容是未定义的行为。 所以,如果你打电话

 my_strcpy(destination, "Constant String"); 

但是在代码中出于某种原因你写了

 ptr1[0] = 'A'; 

你不会得到编译器诊断消息,因为ptr1是指向非const字符的指针,但是你的程序仍会调用未定义的行为(实际上,很可能崩溃,因为字符串文字放在只读内存区域)。

你只需要改变:

 char *ptr1 = source; 

至:

 const char *ptr1 = source; 

因为LHS的类型是char * ,RHS的类型是const char *

原因正如错误所说:

function_prototype_const_modifier.c:13:8:警告:使用’const char *’类型的表达式初始化’char *’会丢弃限定符

该语句允许您丢弃const限定符,它允许通过ptr1ptr2修改指向的字符串,因此编译器会抱怨。

你指向内存中的相同区域,但不是将它限定为const ,参数是。

然后,您允许函数体修改标记为const的内存部分。

您正在将指向字符常量的指针指定给指向char的指针。 通过这样做,您可能会冒险修改角色

在这种情况下,我们可以做什么。

感谢@ user529758的清晰信息。

只是加上一个答案。

改性:

 #include char *my_strcpy(char *destination, const char *source); int main(void) { char str1[] = "this is something"; char str2[] = "123456789123456789"; my_strcpy(str2, str1); puts(str2); return 0; } char *my_strcpy(char *destination, const char *source) { char *ptr1 = (char*)source; char *ptr2 = destination; while(*ptr1 != '\0') { *ptr2++ = *ptr1++; } *ptr2 = '\0'; return destination; }