-1

これが私のコードです。

int main()
{
struct emp
{
    char *n;
    int age;
};
struct emp e1 = {"Dravid", 23};
struct emp e2 = e1;
strupr(e2.n);
printf("%s\n", e1.n);
return 0;
}

質問1:ウェブサイトによる答えは大文字の「ドラヴィッド」です。どうして、e2とe1は同じですか?つまり、e2.age ++の場合、この変更はe1にも反映されますか?

質問2:struprをstrcpyに変更すると、セグメンテーション違反が発生しますか?なんで?つまり、に変更した場合strcpy(e2.n,"hoho");

4

6 に答える 6

3

2 つempの を作成すると、次のように記憶されます。

e1.age  = 23
e1.name = 0x12345678 (Which is a pointer in memory to "Dravid")
e2.age  = 23
e2.name = 0x12345678 (Which is a pointer in memory to "Dravid")

今、あなたがやろうとしていることについてメモしてください。

  1. strupr(e1.name)文字列リテラルを変更することは許可されていないため、呼び出しは未定義の動作です。
  2. strcpy では、渡された 2 つのポインターが異なるメモリ部分を参照する必要があるため、呼び出しstrcpy(e1.name, e2.name)も未定義の動作です。また、文字列リテラルを変更できないため、UB です。
  3. strcpy(e1.name, "hiho")文字列リテラルを変更できないため、呼び出しも未定義の動作です。
于 2012-10-24T18:24:00.940 に答える
1

Q1. char * n にはコピーされたアドレスが格納されるため、両方の値を変更すると反映されます。

Q2. strcpy() には 2 つのパラメーターが必要です。何をコーディングしたかを教えてください。

于 2012-10-24T18:25:36.230 に答える
1

1) 構造体を割り当てると、メンバーごとのコピーが行われます。はポインタであるためn、ポインタ アドレスがコピーされ、同じ文字列を指します。

2) strcpy2 つの引数が必要です。e2.nポインタであることを忘れないでください。を呼び出すときに、新しい文字列の内容を保持するために、そのポインターに十分なスペースを割り当てる必要がありますstrcpy。あなたはより良いですstrncpy()

int maxlen = 20;
e2.n = malloc(maxlen);
strncpy(e2.n, "Any length string here", maxlen - 1) /* only copies 19 bytes + terminating null */
于 2012-10-24T18:21:09.773 に答える
1

構造体を別の構造体にコピーすると、構造体のすべての値がコピーされます。年齢については、値をコピーするだけなので、変更することができ、それらは異なります。

n の場合、文字列のアドレスをコピーしているため、文字列の 1 つを変更すると、他の文字列も変更されます。

そして、H2CO3 が指摘したように、strcpy を使用するときにしようとする文字列リテラルを変更することはできません。

于 2012-10-24T18:21:49.787 に答える
0

C は、Java とは異なり、変数ごとに異なるメモリ領域を使用します。したがって、ある構造体を別の構造体に割り当てると、基本的にある領域から別の領域への浅いコピーが行われます。浅いコピーとは、ポインターをたどってそれらのクローンを作成しないため、ポインターが同じ場所を指すことを意味します。これは、あるメモリ領域を別のメモリ領域にコピーするだけです。

言うstruct emp e2 = e1;ことは言うことと同じことmemcpy (&e2, &e1, sizeof(struct emp));

これは、構造体を別の構造体変数に割り当ててから、別の構造体変数のデータを変更した場合、最初の構造体変数は変更されないことを意味します。

そのため、C では、各変数は異なるメモリ位置にあり、Java やその他の言語と同様に、変数参照を操作していて、変数名は変数参照のコンテナーにすぎません (int などの組み込みプリミティブを除く)。

定数文字列を使用しているという点で、コードに問題がある可能性があります。strupr() で行っているように定数文字列を変更するのはよくありません。メモリがどのように割り当てられているか、どこに割り当てられているかがわからないためです。したがって、 strupr() を実行すると、基本的に幸運になります。

ディープ コピーとシャロー コピーの違いについては、こちらを参照してください。

于 2012-10-24T18:25:46.580 に答える
-1

strupr の呼び出し後は同じであってはなりません (ただし、文字列リテラルを変更することは安全ではなく、適切でもありません)。いいえ、への変更e2は反映されませんe1。代入は値によってオブジェクトをコピーするからです。

strupr 呼び出しを strcpy に変更すると、strcpy は 2 つの引数を取るため、変更するだけでコンパイル エラーが発生します。2 番目の引数として追加すると、メモリを指すように初期化されていないe1.nため、クラッシュします。e2.n

于 2012-10-24T18:23:17.977 に答える