0

我做了一个 mystrcpy 函数,

void mystrcpy(char *&stuff, const char *&otherstuff){
    for(int i=0; stuff[i]&&other[i]; i++){
        stuff[i]=other[i];
    }
}

和一个主要功能:

int main(){
    char *hello="hello";
    mystrcpy(hello, "bye bye"/*<--i have no clue what data type this really is!!*/);
    printf("%s\n", hello);
    return 0;
}

它不编译,并说“从'const char *'类型的右值对'const char *&'类型的非常量引用的初始化无效”......

当我这样做时:

const char *bye="bye bye";
mystrcpy(hello, bye);

它编译没有错误。

我需要知道为什么前一个不起作用,谢谢。

4

3 回答 3

2

"bye bye" 不是指针,而是一个字符数组。它可以衰减为指针,但不能将其作为对指针的引用传递。

您可能会更改函数签名:

void mystrcpy(char *stuff, const char *otherstuff)

如果你想在编译时检查一个类型,你可能会使用一个静态断言来生成编译器错误:

#include <type_traits>

template <typename T>
void inspect_type(T&)
{
    static_assert(std::is_same<T, void>::value, "inspect_type");
}

int main()
{
    inspect_type("bye bye");
}

g++ 给出:

在 'void inspect_type(const T&) [with T = const char [8]]' 的实例化中......

于 2015-07-14T16:22:11.807 回答
2

const char *&是对 a 的非const引用char const *"bye bye"is的类型char const[8](大小包括终止空字符)。您的调用mystrcpy将隐式转换(或衰减char const [8]a char const *,但这会产生一个右值指针,您不能将其绑定到非const引用参数。

如果您将函数签名更改为

void mystrcpy(char *&, const char * const&)
//                                  ^^^^^ const reference

您的代码将编译。同样,如果您按值获取指针,您的代码将编译

void mystrcpy(char *, const char *)

一旦你修复了所有这些,你的代码将在运行时编译并可能崩溃,因为你有未定义的行为。

char *hello="hello";

C++11 禁止您将字符串文字转换为 a char *,并且它在 C++03 中已被弃用。不仅如此,您的mystrcpy调用还会尝试覆盖字符串文字,这又是未定义的行为。

调高编译器的警告级别,并注意警告。g++ 为上面的行产生以下警告-pedantic

警告:ISO C++ 禁止将字符串常量转换为 'char*' [-Wpedantic]

 char *hello="hello";
             ^
于 2015-07-14T16:36:10.810 回答
1

您的函数引用了一个指针,这有点不寻常。值得注意的是,这意味着输入必须是一个具有自己存储空间的指针(以便您可以引用该指针)。

const char *bye="bye bye"; mystrcpy(hello, bye);之所以有效,是因为bye它是一个指针变量,因此您可以对其进行引用。

mystrcpy(hello, "bye bye")失败是因为不是"bye bye"指针- 它是一个字符数组 (a ),因此没有指针可以引用。const char [8]

&您不需要mystrcpy函数签名中的引用 - 这只会使函数更难使用,并且如果您不小心调整函数中的指针(例如,如果您开始这样做*stuff++ = *other++;),可能会引入有趣的错误。

于 2015-07-14T16:29:49.183 回答