double test[] = { 1.0, 2.0, 3.0 };
test 의 자료형은 double [3] 입니다. double 이 3 개 묶여 있는 배열을 뜻합니다.
그래서 너무도 당연하게 &test 는 double [3] 가 저장된 메모리의 주소가 됩니다.
즉, { 1.0, 2.0, 3.0 } 이 저장된 메모리의 주소가 되겠죠.
&test + 1 은 test 다음의 double 3 개가 저장된 메모리의 주소가 됩니다.
그런데, 배열은 대부분의 수식에서 첫번째 요소의 주소로 변환됩니다.
즉, test 는 수식에서 &test[0] 으로 변환됩니다. 1.0 이 저장된 메모리의 주소가 되죠.
결국, &test 나 test의 변환값이나 수치적으로는 같습니다.
{ 1.0, 2.0, 3.0 } 이 저장된 메모리의 주소나, 1.0 이 저장되어 있는 주소나 같죠.
write 함수는 첫번째 인자로 전달된 주소의 메모리에 어떤 형이 저장되어 있는 지 알 수 없습니다.
두번째, 세번째 인자를 가지고 상상하는 것이죠. 두번째 인자(크기)가 세번째 인자(개수) 만큼 읽어서
write 하는구나 하고 말이죠.
fwrite(&test, sizeof(test), 1, f); 은 test 의 크기(sizeof(double[3]))를 1번에 write 하는 것입니다.
그래서 &test 로 쓰는 것이 의미적으로 정확한 것이고,
fwrite(test, sizeof(test), 1, f); 라고 해도 &test나 test의 변환값이 수치적으로 같아서,
결과는 같게 나오지만, 의미적으로는 틀린 것입니다.
double 이 저장되어 있는 주소를 전달하면서 double [3] 을 읽어 저장하는 꼴이기 때문에...
첫번째 인자로 test 를 사용하고 싶으면,
fwrite(test, sizeof(test[0]), 3, f); 으로 하는 것이 맞겠죠.
참고로, 대부분의 연산에서 변수는 변수에 저장된 값으로 변환되고,
함수는 함수가 저장된 메모리의 주소로 변환된 후 연산이 됩니다.
배열의 변환도 이러한 과정 중의 하나입니다.
이러한 변환이 일어나지 않는 연산자로는 다음과 같은 것들이 있습니다.
&, sizeof, = 의 왼쪽