struct
に配列をラップすることでこれを行うことができます。このパラメーターを明示的に渡す必要がないように、配列のサイズのフィールドを含めることができます。このアプローチには、余分なメモリ割り当てを回避して後で解放する必要があります。
Cはすでに引数に値を渡していますが、配列識別子はほとんどの式や特に関数呼び出しではポインタに崩壊します。しかし、struct
はポインタには崩壊しません。また、値は関数に渡されます。つまり、元の構造体のコピーとそのすべての内容が関数のスコープ内に表示されます。 struct
に配列が含まれている場合、これもコピーされます。代わりにstruct
に、たとえば、動的配列のint
へのポインタが含まれている場合は、struct
が関数に渡されたときにポインタがコピーされますが、同じメモリがコピーと元のポインタの両方によって参照されます。このアプローチは実際の配列を含むstruct
に依存しています。
また、struct
には、不完全な型のメンバーを含めることはできないため、VLAを含めることはできません。ここでは、同じstruct
タイプの異なるサイズの配列を処理するためのスペースを提供するために、グローバル定数MAX_ARR
を100と定義しました。
また、関数からstruct
を返すこともできます。私は、関数に渡された struct
を変更し、呼び出し元関数の別のArray
struct
に割り当てられるように変更されたstruct
を返します。これにより、呼び出し元は元の配列と変換された配列の両方にアクセスできます。
#include <stdio.h>
#define MAX_ARR 100
struct Array {
size_t size;
int array[MAX_ARR];
};
void print_array(struct Array local_arr);
void func(struct Array local_arr);
struct Array triple(struct Array local_arr);
int main(void)
{
struct Array data = {
.size = 10,
.array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
};
struct Array transformed_data;
func(data);
transformed_data = triple(data);
printf("Original\n");
print_array(data);
printf("Transformed\n");
print_array(transformed_data);
return 0;
}
void print_array(struct Array local_arr)
{
for (size_t i = 0; i < local_arr.size; i++) {
printf("%5d", local_arr.array[i]);
}
putchar('\n');
}
void func(struct Array local_arr)
{
for (size_t i = 0; i < local_arr.size; i++) {
local_arr.array[i] *= 2;
}
printf("Modified\n");
print_array(local_arr);
}
struct Array triple(struct Array local_arr)
{
for (size_t i = 0; i < local_arr.size; i++) {
local_arr.array[i] *= 3;
}
return local_arr;
}
プログラムの出力:
Modified
2 4 6 8 10 12 14 16 18 20
Original
1 2 3 4 5 6 7 8 9 10
Transformed
3 6 9 12 15 18 21 24 27 30
あなたは構造体でそれをラップすることができますが、それはハックのビットです。代わりに 'Foo'の中で' memcpy'を使うのはなぜですか? – Ryan
"*' //引数として整数配列arrを取る '*"実際には 'int *'をとります。関数引数を定義するコンテキストでは、 'T t []'は 'T * t'と等価です。 – alk