Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么strcpy将const char*作为src而不是char*?_C_Pointers - Fatal编程技术网

为什么strcpy将const char*作为src而不是char*?

为什么strcpy将const char*作为src而不是char*?,c,pointers,C,Pointers,我实现了自己的strcpy,以查找src as const char*和char*之间是否有任何差异,但没有发现以下两个之间有任何差异&两者的工作原理相同 char * my_strcpy(char*dest, char* src) { while ('\0' != *src) *dest++ = *src++; *dest++ = '\0'; return dest; } char * my_strcpy2(char*dest, const c

我实现了自己的strcpy,以查找src as const char*和char*之间是否有任何差异,但没有发现以下两个之间有任何差异&两者的工作原理相同

char * my_strcpy(char*dest, char* src)
{
    while ('\0' != *src)
        *dest++ = *src++;
    *dest++ = '\0';
        return dest;
}

char * my_strcpy2(char*dest, const char* src)
{
    while ('\0' != *src)
        *dest++ = *src++;
    *dest++ = '\0';
    return dest;
}
strcpy将源指针作为const char*而不是char*,这有什么原因吗

strcpy接受源指针为char*而不是const char*有什么原因吗

源指针应该是
const char*
。原因对于所有不打算在函数内部意外更改源的函数(不仅仅是strcpy)来说都是常见的

这种做法既适用于库函数,如
strcpy
,也适用于您自己的自定义函数。与库函数(如
strcpy
一样,源代码不可能意外更改。但是对于您自己(或其他人)的自定义函数,任何事情都可能发生。如果你不小心修改了它,那么你会得到一个编译错误告诉你。这就是
常数产生差异的时候。

“不要在以下两个之间找到任何差异”——在你最疯狂的梦中,差异可能是什么

const声明的唯一区别在于调用方。通过const参数声明,函数承诺不会更改通过指针访问的内存。它承诺只通读它,这与
strcpy()
的语义一致。(注意:函数是否真的不通过指针写入根本不能保证。但它承诺。)

因此,调用者可以使用指向常量数据的指针调用函数,并假设函数不会尝试写入

这在句法、逻辑和物质上都很重要:

  • 该语言允许调用者提供指向常量数据的指针作为参数(对于第一个非常量版本,它不允许这样做)
  • 调用者可以确保敏感数据不会在函数内部作为副作用被更改;想象一下,这里有一个指向内核数据结构的指针。(反例:
    strtok()
    写入原始字符串,因此未声明为常量!)
  • 数据在物理上可能是只读的(比如,它可能会被烧录到控制器的ROM中),因此尝试写入它会导致引用优秀的Max Barry:a

对于启动器函数
strcpy
返回指向目标字符串的指针。函数还应该返回指向目标字符串的指针。这是C标准中处理字符串的函数的常见约定

因此,函数可以按以下方式显示

char * my_strcpy( char *dest,  const char *src )
{
    char *p = dest;

    while ( *p++ = *src++ );

    return dest;
}
const char *hello = "Hello, World!";
char s[14];

puts( s, hello );
在这种情况下,例如,可以通过以下方式调用它

char * my_strcpy( char *dest,  const char *src )
{
    char *p = dest;

    while ( *p++ = *src++ );

    return dest;
}
const char *hello = "Hello, World!";
char s[14];

puts( s, hello );
将函数的第二个参数指定为指向常量字符串的指针意味着1)函数保证不会更改指向的字符串,2)允许传递给函数常量字符串

指向非常量对象的指针可以隐式转换为指向常量对象的指针。如果没有显式强制转换,则不允许反向操作


因此,如果将参数声明为指向常量字符串的指针,则可以将非常量字符串与常量字符串一起传递给与参数相同的函数。否则,无法使用常量字符串调用该函数,因为编译器将发出一个错误,说明它无法将
const char*
类型的对象转换为
char*
类型的对象<由于历史原因,代码>strcpy
采用
const char*src
.IMHO。在大多数情况下,strcpy()可以内联,因此差异无论如何都是无效的。实际上,从C99标准开始,它的源参数定义为
const char*restrict
。例如,有关
restrict
关键字的更多信息,请参见。谷歌“const corrective”。顺便说一句,函数的返回值很奇怪。实际上,不通过指针写入根本不保证。。。是的,但如果程序员不做坏事(强制转换以消除常量),编译器会抱怨。@Jean BaptisteYunès没错,实现将不得不使用强制转换或做一些更虚假的事情。@BLUEPIXY谢谢。这是由于复制和粘贴造成的打字错误。