19

ここで構造体について同様の質問をしましたが、変数の割り当てなどをCがどのように処理するか、および機能的に同じである場合にそれらを互いに割り当てることができない理由を理解しようとしています。

2 つの配列があるとします。

int x[10];  
int y[10];  

x = y がコンパイルされないのはなぜですか? 両方が同じ「署名」である場合、それらを前後に割り当てることができるはずではありませんか?

これらを C で実行できるように宣言できますか? あなたができることは私には理にかなっていますが、おそらくこれを行う方法はありますか? 構造体の Typedef が解決策のように見えましたが、配列の宣言と割り当てでも同じでしょうか?

皆さんの助けに感謝します。私は Stackoverflow を初めて使用しますが、これまでのところ私にとって本当に良いリソースでした!

4

7 に答える 7

28

簡単に言えば、配列は代入できません。それらは「変更不可能な左辺値」です。もちろん、これは疑問を投げかけます:なぜですか?詳細については、この質問を参照してください。

C++ が構造体内の配列のメンバーごとの割り当てをサポートしているのに、一般的にはサポートしていないのはなぜですか?

配列はポインターではありません。 xhere配列を参照しますが、多くの場合、これは最初の要素へのポインターに "減衰" (暗黙的に変換) されます。同様に、yポインターではなく、配列の名前も同様です。

構造体内で配列の割り当てを行うことができます。

struct data {
    int arr[10];
};

struct data x = {/* blah */};
struct data y;
y = x;

ただし、配列で直接行うことはできません。を使用しmemcpyます。

于 2009-04-13T16:50:40.723 に答える
4
int x [sz];
int *y = x;

これはコンパイルyされ、 と同じになりますx

于 2012-08-23T17:23:28.897 に答える
2

いくつかのメッセージは、配列の名前がその最初の要素のアドレスを与えることを示しています。常に正しいとは限りません:

#include <stdio.h>

int
main(void)
{
  int array[10];

  /*
   * Print the size of the whole array then the size of a pointer to the
   * first element.
   */
  printf("%u %u\n", (unsigned int)sizeof array, (unsigned int)sizeof &array[0]);

  /*
   * You can take the address of array, which gives you a pointer to the whole
   * array. The difference between ``pointer to array'' and ``pointer to the
   * first element of the array'' matters when you're doing pointer arithmetic.
   */
  printf("%p %p\n", (void*)(&array + 1), (void*)(array + 1));

  return 0;
}

出力:

40 4
0xbfbf2ca4 0xbfbf2c80
于 2009-04-13T17:11:04.543 に答える
1

配列を割り当てるには、配列内に値を割り当てる必要があります。

すなわち。x=y は次と同等です

for(int i = 0; i < 10 < ++i)
{
x[i] = y[i];
}
于 2009-04-13T16:50:57.133 に答える
1

ブランクの答えを補完するために、次のプログラムを考案しました。

localhost:~ david$ cat test.c
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char * argv [])
{
  struct data {
    int c [2];
  } x, y;
  x.c[0] = x.c[1] = 0;
  y.c[0] = y.c[1] = 1;
  printf("x.c %p %i %i\n", x.c, x.c[0], x.c[1]);
  printf("y.c %p %i %i\n", y.c, y.c[0], y.c[1]);
  x = y;
  printf("x.c %p %i %i\n", x.c, x.c[0], x.c[1]);
  printf("y.c %p %i %i\n", y.c, y.c[0], y.c[1]);

  return 0;
}

実行すると、以下が出力されます。

x.c 0x7fff5fbff870 0 0
y.c 0x7fff5fbff860 1 1
x.c 0x7fff5fbff870 1 1
y.c 0x7fff5fbff860 1 1

ポイントは、構造体の値のコピーがどのように発生するかを説明することです。

于 2011-06-01T19:16:22.733 に答える
0

私はCコンパイラを使用しましたが、それは問題なくコンパイルされます...そして実行すると、コードはxがyの配列を指すようになります。

ご覧のとおり、Cでは、配列の名前は配列の先頭を指すポインターです。実際、配列とポインターは本質的に交換可能です。任意のポインタを取り、配列のようにインデックスを付けることができます。

70年代初頭にCが開発されていた頃は、抽象化においてアセンブリ言語をかろうじて上回っていた比較的小さなプログラムを対象としていました。その環境では、配列のインデックス作成とポインタの計算の間を簡単に行き来できるのはとても便利でした。一方、データの配列全体をコピーすることは非常に費用のかかる作業であり、ユーザーから遠ざけたり、奨励したりすることはほとんどありませんでした。

はい、これらの現代では、アレイの名前を「アレイの前面にあるポンター」ではなく、「アレイ全体」の省略形にする方が理にかなっています。しかし、Cはこれらの現代では設計されていませんでした。以前の言語が必要な場合は、Adaを試してください。x:=yあなたが期待することを正確に行います。ある配列の内容を別の配列にコピーします。

于 2009-04-13T18:14:16.450 に答える
0

「int x[10]」と言うときは、「10個の整数用のスペースを確保して、その場所へのポインターを渡してください」と言っています。したがって、コピーを意味のあるものにするには、「メモリの場所の名前」ではなく、が指すメモリを操作する必要があります。

したがって、ここにコピーするには、for ループまたは memcpy() を使用します。

于 2009-04-13T16:53:15.787 に答える