为什么strcpy不使用const指针作为dest?

时间:2017-01-23 16:19:32

标签: c pointers const strcpy

strcpy的签名是否有原因:

char *strcpy(char *dest, const char *src);

而不是这个?

char *strcpy(char *const dest, const char *src);

据我所知,该函数永远不会改变指针。

我是否误解了应该使用的const指针?在我看来,当我写的函数接受一个不会被改变的指针(通过realloc等)时,我将它标记为一个const指针,这样可以确保调用者不会在它们上移动它们的指针。 (如果它们有其他结构/等等,引用那个过时的指针位置)

这是一种不错的做法,还是会产生意想不到的后果?

5 个答案:

答案 0 :(得分:11)

strcpy的源代码非常粗略:

char *strcpy(char *dest, const char *src)
{
  while (*dest++ = *src++);
}

这里我们实际上修改了dest但这对调用者没有任何影响,因为在strcpy函数内,dest是一个局部变量。

但是下面的代码将无法编译,因为dest是const:

char *strcpy(char * const dest, const char *src)
{
  while (*dest++ = *src++);
}

我们需要写这个:

char *strcpy(char * const dest, const char *src)
{
  char *temp = dest;
  while (*temp++ = *src++);
}

引入了一个非必要的temp变量。

答案 1 :(得分:3)

声明(原型)中函数参数的限定符完全忽略。这是C语言所要求的,这是有道理的,因为这种限定可能对函数的调用者没有任何可能的意义。

const char *src的情况下,参数src不符合条件;它指向的类型是合格的。在dest的假设声明中,限定符适用于dest,因此毫无意义。

答案 2 :(得分:2)

{ "myObject ":{ "myChildObject":"FooBar" } } 表示指针char *foo(char *const dest, const char *src) { ... }在函数体中不会改变。

这并不意味着dest指向的数据会发生变化,也不会发生变化。

dest确保const char *src指向的数据的调用代码不会更改。

在调用srcstrcpy(d,s)之类的函数时,调用代码并不关心函数是否更改指针的副本。所有调用代码都关心的是foo(d,s)s指向的数据是否已更改,并且是由d左侧的const控制的

*

答案 3 :(得分:1)

按照你的建议将它标记为const是没有意义的。在C中,函数参数作为副本传递。这意味着dest内的变量strcpy()实际上是一个新变量(在堆栈上推送),它保存相同的内容(这里是地址)。

看看这个函数原型:

void foo(int const a);

这没有语义价值,因为我们知道传递给foo()的原始变量a不能更改,因为它是副本。只有副本可能会更改。当foo返回时,我们保证原始变量a不变。

在函数参数中,如果函数实际上可以持久地更改变量的状态,则只想使用关键字const。例如:

size_t strlen(const char *s);

这将变量s的内容(即,存储在地址s处的值)标记为const。因此,当strlen返回时,保证您的字符串不会改变。

答案 4 :(得分:-1)

  

据我所知,该函数永远不会改变指针。

是的,但你可以。您可以自由更改指针。无需使用dest指针const

例如:

int main(void)
{
    char *s = "Hello";
    char *d = malloc(6);

    strcpy(d, s);
    puts(d);
    strcpy(d, "World");
    puts(d);
}