調べてみましょう (以下については、C++ でも同じであることに注意char const
してください)。const char
文字列リテラルと char *
"hello"
は、6 つの const 文字の配列です: char const[6]
. すべての配列と同様に、最初の要素へのポインターに暗黙的に変換できchar const * s = "hello";
ます。C コードとの互換性のために、C++ では別の変換が許可されchar * s = "hello";
ています。これは、C っぽいコードをコンパイルできるようにするための例外ですがchar *
、文字列リテラルを指すことは非推奨です。それで、私たちは何のために持っていchar * s = "foo";
ますか?
"foo"
-> array-to-pointer
-> char const*
-> qualification-conversion
-> char *
. 文字列リテラルは読み取り専用で、スタックに割り当てられません。それらを指すポインターを自由に作成し、クラッシュすることなく関数からそのポインターを返すことができます:)。
文字列リテラルを使用した配列の初期化
さて、何char s[] = "hello";
ですか?それはまったく別のことです。これにより、文字の配列が作成され、 String で埋められ"hello"
ます。リテラルは指されていません。代わりに、文字配列にコピーされます。そして、スタック上に配列が作成されます。関数からポインタを有効に返すことはできません。
配列パラメーターの型。
関数に配列をパラメーターとして受け入れるようにするにはどうすればよいですか? パラメータを配列として宣言するだけです。
void accept_array(char foo[]);
ただし、サイズは省略します。実際には、無視されるだけなので、任意のサイズで実行できます。標準では、そのように宣言されたパラメーターは次のように変換されると述べています。
void accept_array(char * foo);
エクスカーション: 多次元配列
char
配列自体を含む任意の型で置き換えます。
void accept_array(char foo[][10]);
最後の次元のサイズが 10 の 2 次元配列を受け入れます。多次元配列の最初の要素は、次の次元の最初のサブ配列です。では、変形してみましょう。再び最初の要素へのポインタになります。したがって、実際には 10 文字の配列へのポインタを受け入れます: ( []
in ヘッドを削除してから、頭に表示される型へのポインタを作成します):
void accept_array(char (*foo)[10]);
配列は最初の要素へのポインターに暗黙的に変換されるため、2 次元配列 (最後の次元のサイズは 10) を渡すだけで機能します。実際、特殊な場合の;を含む、任意のn 次元配列に当てはまります。n = 1
結論
void upperCaseString(char *_str) {};
と
void upperCaseString(char _str[]) {};
最初のものは単なる char へのポインタであるため、これらは同じです。ただし、文字列リテラルをそれに渡したい場合 (引数を変更しないとします)、char const* _str
非推奨のことをしないようにパラメーターを に変更する必要があります。