Использование указателей для доступа к данным
Управление данными посредством прямого доступа
Схема обмена данными методом побайтного обмена значениями.
#include <
stdio.h>
/**
* Функция выполняет побайтный обмен значениями.
* - frst - указатель на первый массив данных,
* - scnd - указатель на второй массив данных,
* - size - размер области памяти.
* Возвращаемое значение:
* нет.
*/
void swap(void *frst, void *scnd, unsigned int size);
struct MyStruct
{
int first;
double second;
char str[10];
};
/* Основная функция */
int main()
{
// вызов функции для значений целочисленного типа
int ifirst = 123, isecond = 321;
printf("%d - %d\n", ifirst, isecond);
swap(&ifirst, &isecond, sizeof(int));
printf("%d - %d\n", ifirst, isecond);
// вызов функции для значений с плавающей точкой
double dfirst = 123.4, dsecond = 432.1;
printf("%3.1f - %3.1f\n", dfirst, dsecond);
swap(&dfirst, &dsecond, sizeof(double));
printf("%3.1f - %3.1f\n", dfirst, dsecond);
// вызов функции для строк
char cfirst[] = { 'H','e','l','l','o',' ','w','o','r','l','d', '\0' };
char csecond[] = { 'd','l','r','o','w',' ','o','l','l','e','H', '\0' };
printf("%s - %s\n", cfirst, csecond);
swap(cfirst, csecond, sizeof(cfirst));
printf("%s - %s\n", cfirst, csecond);
// вызов функции для значений типа структуры
struct MyStruct sfirst = { 1, 2.3, "four" };
struct MyStruct ssecond = { 4, 3.2, "first" };
printf("%2d %1.1f %-10s - %2d %1.1f %-10s\n", sfirst.first, sfirst.second, sfirst.str, ssecond.first, ssecond.second, sfirst.str);
swap(&sfirst, &ssecond, sizeof(struct MyStruct));
printf("%2d %1.1f %-10s - %2d %1.1f %-10s\n", sfirst.first, sfirst.second, sfirst.str, ssecond.first, ssecond.second, sfirst.str);
return 0;
}
/*
В момент вызова функции выполняется неявное преобразование указателя
к неопределённому типу.
*/
void swap(void *frst, void *scnd, unsigned int size) {
unsigned char tmp;
/*
Поскольку после преобразования типа, указаетель ссылается просто
на участок памяти, можно выполнить побайтный обмен значений, не
обращая внимания на структуру данных.
*/
for (unsigned int i = 0; i <
size; i++) {
/*
Выполняем явное приведение к типу unsigned char для вычисления
побайтного смещения. Прибавляя значение индекса вычисляем смещение
указателя на очередной байт данных. Получаем значение по указателю.
*/
tmp = *((unsigned char*)scnd + i);
*((unsigned char*)scnd + i) = *((unsigned char*)frst + i);
*((unsigned char*)frst + i) = tmp;
}
}