3

コード:

    #include <stdio.h>
    int main() {
        char *str;
        char i = 'a';
        str = &i;
        str = "Hello";
        printf("%s, %c, %x, %x", str, i, str, &i);
        return 0;
    }

私はこの出力を得る:

Hello, a, 403064, 28ff0b

次の2つの疑問があります。

  1. メモリを割り当てずに文字列を保存するにはどうすればよいですか。strは文字ポインタであり、 where char variable を指していますi。追加するとき、割り当てられていないその場所からのバイトstr = "Hello";を使用していませんか?54

  2. 以来、私はそれらを印刷するときに同じ値を持つstr = &i;べきではstrありませんか?記載を&i除いた場合も同様です。そして、とが同じである場合、上書きする必要があり、残りは後続のバイトに入ると言ったときに信じます。str = "Hello";str&istr&istr = "Hello"'a''H''ello\0'

    全体の問題はstr = "Hello"ステートメントにあると思います。思ったようにうまくいかないようです。

誰かがそれがどのように機能するか説明してください??

4

7 に答える 7

7

コンパイラが文字列リテラル (この場合"Hello") を検出すると、静的 (グローバル) メモリ領域にメモリが割り当てられます。この「割り当て」は、プログラムが実行される前に行われます。

プログラムが で実行を開始すると、 :とmainのローカル変数を格納するためにスタック フレームが割り当てられます。アドレスを格納するだけの単純な変数であることに注意してください。文字は格納されません。ポインタを格納するだけです。mainstristr

このステートメントは、 のアドレスstr = &i;を変数に書き込みます。stri

このステートメントは、変数に、コンパイラによって事前に割り当てられた文字列リテラルのアドレスをstr = "Hello"書き込みます。これは のアドレスとはまったく別のアドレスです。その代入は、「Hello」という単語の文字をどこにも移動しません。str"Hello"i

TL;DR C の「文字列」変数の値は単なるポインタです。文字列変数への代入は、番号、つまりアドレスを代入することです。

于 2013-11-01T04:42:07.583 に答える
1

str = "Hello" と言うと、その場所から 5 バイトを使用していませんか?そのうち 4 バイトは割り当てられていませんか?

いいえ。コンパイラは、メモリの別の部分(読み取り専用部分ですが、それは別の質問に対する回答です) に 6 バイト (null ターミネータを思い出してください) を確保します。課題:

str = "Hello";

これらstrの 6 バイトの最初の位置、H.

以来、私は str=&i; と言いました。str と &i を printf するときに同じ値を持つべきではありませんか?

はい、しかし、str何かを印刷する前に、次の行で別のものを指すように設定しました。

于 2013-11-01T04:40:42.093 に答える
0

リテラル文字列"Hello"は、おそらくプログラム空間のどこかで 6 バイトのメモリを使用しています。それにポインターを割り当てると、ポインターが文字列が既に存在する場所に設定されます。文字をまったくコピーしません。

文字をコピーしたい場合は を使用する必要がありますがstrcpy、ポインターを十分なサイズの書き込み可能なバッファーに設定していないため、設定すると未定義の動作が発生します。

于 2013-11-01T04:40:11.807 に答える
0
  1. strcharへのポインタです。str = &i;あなたがそれをintに向けていると言うとき。str = "Hello";文字シーケンス 'H'、'e'、'l'、'l'、'o'、0 が格納されている場所を指すように str を変更していると言う場合。

  2. でもあなたは言っstr = something elseた直後に言うstr = &i

まだポインタを完全に把握していないようです...

于 2013-11-01T04:40:24.347 に答える
0

簡単に言えば、すべての文字列は C のポインターです。

これで実行すると:

int main() {
    char *str;
    char i='a';
    str = &i;
    str = "Hello";
    printf("%s, %c, %x, %x", str, i, str, &i);
    return 0;
}

を設定するstr = &iと、 がstr ポイントになりiます。したがって、真実i == *str&i == str保持します。

を呼び出すとstr = "Hello";strサイズ 6 の静的に割り当てられた配列を指すようになりました (これは通常、プログラム コードに直接存在します)。はポインターであるためstr、新しい配列を指すようにリセットしても、 は変更されませんistrここで、 を に設定する代わりに"Hello"を行った場合*str = 'Z';iは 'Z' の値を持ちますが、 はstrまだ を指していiます。

于 2013-11-01T04:40:26.473 に答える
0

まず、メモリを割り当てずに文字列を保存するにはどうすればよいですか。str は文字ポインタであり、char i が格納されている場所を指しています。str = "Hello" と言うとき、その場所から 5 バイトを使用していませんか?そのうち 4 バイトは割り当てられていませんか?

文字列のメモリは、コンパイラによって割り当てられます。コンパイラがこれを行う方法を標準が正確に指定しているとは思いません。実行可能ファイルに対して「strings」を実行すると、どこかに「Hello」が見つかるはずです。

以来、私は str=&i; と言いました。str と &i を printf するときに同じ値を持つべきではありませんか? str = "Hello" ステートメントを削除すると、str と &i は同じです。そして、str と &i が同じである場合、str="Hello" と言うと、「a」を「H」で上書きし、残りの「ello\0」が後続のバイトに入るはずです。

ここで見逃しているのは、str = "Hello" が文字列を str が指す場所にコピーしないことだと思います。str が指すものを変更します。「こんにちは」はメモリ内にあり、そのメモリ位置をポインタに割り当てています。メモリをポインターにコピーする場合は、memcpy() などを使用する必要があります。

于 2013-11-01T04:41:54.557 に答える