为什么我的strCopy实现工作?

时间:2016-10-18 10:26:12

标签: c++

这是strCopy的实现

void strcopy2(char *dst, char const *src){
    while ((*dst++ = *src++))
        ;
}

我们的教授要求我们在不使用指针的情况下重现这段代码,所以我想出了以下函数:

void strcopy(char dst[], char const src[]){
    size_t i = 0;
    while (dst[i] = src[i++])
        ;
}

它运行良好,但我意识到,在引擎盖下,函数必须仍然使用指针,因为我们无处可返回任何值。换句话说,我虽然最后一个函数会使用pass by value但显然并非如此。那么在水下发生了什么,这两种方法实际上有什么区别吗?

3 个答案:

答案 0 :(得分:14)

不仅仅是幕后...... dstsrc,尽管有外表,但实际上指针!参数列表中的[]语法是语法糖(或语法胡椒),但它对你说谎;对于实数,这些是char* dstchar const* src

8.3.5 / 5 [dcl.fct]功能:

  

确定每个参数的类型后,任何类型为“T of T”或函数类型T的参数都将被调整为“指向T的指针”。

答案 1 :(得分:3)

  

这两种方法实际上有什么不同吗?

是的,第二个是错的:

void strcopy(char dst[], char const src[]){
    size_t i = 0;
    while (dst[i] = src[i++]) // (*)
        ;
}

标记为(*)的行是大多数C ++历史记录中未定义的行为。关于增量,没有i的两个读取的指定顺序。它可能会在您的平台上的编译器上正确排序。 i的增量可能会在它作为dst的索引读取之前发生,并且您的复制功能将被关闭一个。在C ++ 17中,将首先评估右侧,因此复制功能肯定会关闭。

您需要将增量设为自己的表达式:

void strcopy(char dst[], char const src[]){
    size_t i = 0;
    while (dst[i] = src[i]) {
        ++i;
    }
}

答案 2 :(得分:-1)

这是腐朽的过程

对于编译器,数组的 name 成为第一个元素的指针。

注意数组和指针不一样。它是名称符号,它被视为指向数组第一个元素的指针。

因此,在您的示例中,char dest[]被编译器视为&dest[0],或者换句话说,char* dest

根据语言规则,如果p是指针,则p[x]被视为*(p+x),这就是为什么两个示例中生成的机器代码几乎相同的原因。