这是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但显然并非如此。那么在水下发生了什么,这两种方法实际上有什么区别吗?
答案 0 :(得分:14)
不仅仅是幕后...... dst
和src
,尽管有外表,但实际上是指针!参数列表中的[]
语法是语法糖(或语法胡椒),但它对你说谎;对于实数,这些是char* dst
和char 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)
,这就是为什么两个示例中生成的机器代码几乎相同的原因。