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参照の無効な初期化」と表示されます...

私がするとき:

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

エラーなしでコンパイルされます。

前者が機能しない理由を知る必要があります、ありがとう。

4

3 に答える 3

2

const char *&は a への非const参照char const *です。のタイプ"bye bye"ですchar const[8](サイズには終端のヌル文字が含まれます)。への呼び出しmystrcpyは暗黙的に を に変換 (または減衰) しchar const [8]ますが、これにより右辺値ポインターが生成され、非参照パラメーターchar const *にバインドすることはできません。const

関数の署名を次のように変更した場合

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

コードがコンパイルされます。同様に、ポインターを値で取得すると、コードはコンパイルされます

void mystrcpy(char *, const char *)

これらすべてを修正すると、未定義の動作が発生するため、コードがコンパイルされ、実行時にクラッシュする可能性があります。

char *hello="hello";

C++11 では、文字列リテラルを に変換することは禁止char *されており、C++03 では非推奨の動作でした。それだけでなく、mystrcpy呼び出しは文字列リテラルを上書きしようとしますが、これも未定義の動作です。

コンパイラの警告レベルを上げて、警告に注意してください。g++ は、上記の行に対して次の警告を生成します-pedantic

警告: ISO C++ は、文字列定数を 'char*' に変換することを禁止しています [-Wpedantic]

 char *hello="hello";
             ^
于 2015-07-14T16:36:10.810 に答える
2

「さようなら」はポインタではなく、文字の配列です。ポインターに減衰することはできますが、ポインターへの参照として渡すことはできません。

関数のシグネチャを変更する場合があります。

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 に答える