Предположим, у вас есть массив как:
T a[N]; //T is the type of each element
//and N is the number of elements in the array
//fill the array here
Теперь вы хотите записать этот массив, используя fwrite
, поэтому вы передаете a
в качестве первого аргумента как:
fwrite(a, ..... );
Теперь, как fwrite
узнает, сколько байтов нужно записать? Он не может знать это из своего первого аргумента, потому что a
преобразуется в const void*
, что приводит к потере большого количества полезной информации, такой как тип каждого элемента в массиве 1 , тем самым мог бы рассчитать размер каждого элемента, но эта информация теряется в тот момент, когда вы передаете a
в качестве первого аргумента. Таким образом, вам нужно передать размер каждого элемента как:
fwrite(a, sizeof(T), ....);
Теперь fwrite
знает адрес (или указатель), с которого он будет читать элементы, а также знает размер каждого элемента. Но он все еще не знает , сколько элементов . Таким образом, вы передаете количество элементов в массиве, как:
fwrite(a, sizeof(T), N, ...);
И теперь он знает все о данных. Теперь все, что нужно знать, это указатель файла. Итак, здесь вы пишете это как:
FILE *fp = /*.....*/ ;
fwrite(a, sizeof(T), N, fp);
Надеюсь, это поможет.
1. Когда a
преобразуется в const void*
, он также теряет другую полезную информацию, которая является числом элементов. Но в C вы не можете передать массив в качестве аргумента. Когда вы это сделаете, он превратится в указатель, потеряв информацию о размере массива. fwrite
- это функция из библиотеки C. Однако, если вы используете fwrite
в C ++, вы можете заключить его в шаблон функции следующим образом:
template<typename T, size_t N>
size_t fwrite(T (&a)[N], FILE *fp)
{
return fwrite(a, sizeof(T), N, fp); //call the C function here
}
Тогда вы можете просто назвать это как:
int a={1,2,3,4,5,6,7};
double b={10,20,30,40,50,60,70};
fwrite(a,fp);
fwrite(b,fp);
Хорошо выглядит? Но вы не можете передать указатель на это:
float *c = new float[100];
fwrite(c,fp); //compilation error
Это потому, что наш шаблон функции fwrite
будет принимать только массив, а не указатель.