たとえば、それぞれサイズ 10 の型の 2 つの配列arr1
を宣言し、最初の配列を初期化し、 inのコピーを作成したい場合。なぜ私は指示を与えることができないのですか?arr2
int
arr1
arr2
arr2 = arr1
同じタイプの 2 つの構造を割り当てることができることを知っています。なぜ配列の場合はそうではないのですか?
sizeof
配列の問題は、すべての式(および単項演算子に渡される場合を除く&
)で、最初の要素へのポインターに変換されることです。
だから、あなたが持っていると仮定します:
int arr1[10];
int arr2[10];
...
次に、次のようなものを書く場合
arr1 = arr2;
あなたは実際にこれを行おうとしています:
arr1 = &arr2[0];
またはこれ:
&arr1[0] = &arr2[0];
どちらの場合も、コードのコンパイルを妨げる問題があります。前者の場合、2つの互換性のない型(配列とポインター)の間で割り当てようとしていますが、後者の場合、定数ポインター(&arr1[0]
)を変更しようとしています。
実際にはできますが、間接的な方法で:
#include <stdio.h>
int main(){
int arr1[3] = {0};
int arr2[3] = {1, 2, 3};
struct tmp{
int arr[3];
};
printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);
// casting array to address of struct
// before dereferencing & asigning to it
*(struct tmp*)arr1 = *(struct tmp*)arr2;
printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);
return 0;
}
もう少し一般的な方法で作成することもできます。
#include <stdio.h>
#define STRUCT_TO(type, size) struct temp##__LINE__{type arr[size];}; *(struct temp##__LINE__*)
#define STRUCT_FROM *(struct temp##__LINE__*)
int main(){
int arr1[3] = {0};
int arr2[3] = {1, 2, 3};
printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);
STRUCT_TO(int,3) arr1 = STRUCT_FROM arr2;
printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);
return 0;
}
または...移植性をいくらか犠牲にすることができれば、構文をもう少し対称的にすることができます:
#include <stdio.h>
#define ARRAY_LENGTH(arr) (sizeof(arr)/sizeof(arr[0]))
#define TEMP_STRUCT struct temp##__LINE__
#define AS_STRUCT_DESTINATION(arr) TEMP_STRUCT{typeof(arr[0]) arrTmp[ARRAY_LENGTH(arr)];}; *(TEMP_STRUCT*) arr
#define AS_STRUCT_SOURCE(arr) *(TEMP_STRUCT*) arr
int main(){
int arr1[3] = {0};
int arr2[3] = {1, 2, 3};
printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);
AS_STRUCT_DESTINATION(arr1) = AS_STRUCT_SOURCE(arr2);
printf("%d %d %d\n", arr1[0], arr1[1], arr1[2]);
return 0;
}
変数が配列へのポインターである場合のように、配列を別の配列に割り当てることはできません。この場合でも、コピーは作成せず、同じ配列への別のポインターのみを作成します。
配列をコピーするには、memcpy() を使用してコンテンツ全体をコピーする必要があります。
int a[3] = {1,2,3};
int b[3];
memcpy(b, a, sizeof(a));