Работа с последовательностью данных переменного формата
Если посмотреть на массив и на структуру с точки зрения последовательности хранимых в них данных, то массив хранит последовательность переменных одного типа, а структура - фиксированную последовательность переменных различных типов. Но существуют данные иного рода - в которых заранее неизвестны ни типы переменных, ни их количество, а заданы только общие правила их следования (формат). В таком формате значение предыдущей переменной может определять тип и количество расположенных за ней переменных.
Последовательности данных переменного формата широко используются при упаковке больших массивов данных, представлении объектов с переменной размерностью и произвольными свойствами и т.д.. При работе с ними требуется последовательно просматривать область памяти, извлекая из нее переменные разных типов и на основе анализа их значений делая вывод о типах последующих переменных. Такая задача может быть решена с использованием нескольких указателей различного типа, которые сохраняют одинаковое значение (адрес) путем взаимного присваивания. Более просто это сделать с использованием операции явного преобразования типа указателя. Заметим, что операция *p++ применительно к любому указателю интерпретируется как " взять указуемую переменную и перейти к следующей" , следовательно, значением указателя после выполнения операции будет адрес переменной, следующей за выбранной:
char *p, A[100], c;
int i;
long r;
p=A;
// взять int по указателю и переместить указатель
// к следующей переменной
i = * (( int*)p )++;
// взять long по указателю и переместить указатель
// к следующей переменной
r = *((long*)p)++;
c = *p++; // взять байт по указателю
Другой вариант заключается в использовании объединения (union), которое, как известно, позволяет использовать общую память для размещения своих элементов. Если элементами union являются указатели, то операции присваивания можно исключить.
union ptr
{ char *p;
int *q;
long *l;
} PTR;
i = *(PTR.q)++; r = *(PTR.l)++; c = *(PTR.p)++;