Intereting Posts
что такое segmentation fault (kernel сбрасывается)? Условное выполнение на основе логической операции короткого замыкания C Указатель для структуры – segmentation fault C, программирование сокетов: подключение нескольких клиентов к серверу с помощью select () Управление памятью CFErrorRef, возвращаемое ABRecordSetValue в чем преимущество хранения виртуального адреса в указателе, а не в физическом адресе? Почему указатели на недопустимые типы, а не переменные неполных типов? Скопируйте строку в C, используя указатель Последовательное устройство: чтение 8N1 работает, но запись одного байта не выполняется C – Указатель разыменования неполного типа Поиск длины самой длинной восходящей подсерии в массиве с использованием рекурсии и без петель Предотrotation переполнения буфера с помощью gets Что означает% s и% d в printf на языке C? Доступ к элементу массива с использованием неопределенного поведения char? в чем разница между AM_LDFLAGS и LDFLAGS

Правильный способ доступа к элементам массива как к другому типу?

У меня большой массив uint16_t .

Большинство его членов – uint16_t , но некоторые из них – int16_t и некоторые uint8_t .

Как бы вы справились с этим?


Кстати, я пробовал:

  1. указатели:

    Используются 2 указателя, один int16_t* и другой uint8_t* , оба из которых инициализируются в начале массива, для доступа к члену массива, который является int16_t и uint8_t .

    (Это сработало изначально, но я столкнулся с проблемами, когда позже в программе что-то изменило значение указателей, поэтому я не верю в это).

  2. Определение типа с объединением.

    В файле file.h:

     typedef union { uint16_t u16[NO_OF_WORDS]; // As uint16_t int16_t s16[NO_OF_WORDS]; // As int16_t uint8_t u8[2 * NO_OF_WORDS]; // As uint8_t } ram_params_t; extern ram_params_t ram_params[]; 

    В файле file.c:

     ram_params_t ram_params[] = {0}; 

    (Это действительно бомбило.)

  3. Кастинг.

    (Я не очень далека от этого.)

Проблема с вашей попыткой № 2 заключалась в том, что вы создали массив массивов.

Либо сделайте это:

 typedef union { uint16_t u16; // As uint16_t int16_t s16; // As int16_t uint8_t u8[2]; // As uint8_t } ram_params_t; extern ram_params_t ram_params[NO_OF_WORDS]; ram_params_t ram_params[NO_OF_WORDS]; uval16 = ram_params[i].u16; sval16 = ram_params[i].s16; uval8_1 = ram_params[i].u8[0]; uval8_2 = ram_params[i].u8[1]; 

Или вы делаете это:

 typedef union { uint16_t u16[NO_OF_WORDS]; // As uint16_t int16_t s16[NO_OF_WORDS]; // As int16_t uint8_t u8[2 * NO_OF_WORDS]; // As uint8_t } ram_params_t; extern ram_params_t ram_params; ram_params_t ram_params; uval16 = ram_params.u16[i]; sval16 = ram_params.s16[i]; uval8_1 = ram_params.u8[2*i]; uval8_2 = ram_params.u8[2*i+1]; 

Я не вижу ничего плохого в вашей попытке №1. Я думаю, что я, скорее всего, буду делать это, а не использовать союз.

Элементы массива других типов должны быть того же размера, что и uint16_t чтобы просто их uint16_t . В случае 8-битных данных существует вероятность того, что верхние 8 бит не определены, поэтому я скрыл их.

 #include  #define uint16_t unsigned short #define int16_t short #define uint8_t unsigned char int main() { uint16_t n; // convert uint16_t to int16_t n = 0xFFFF; printf ("%d\n", (int16_t)n); // convert uint16_t to uint8_t n = 168; printf ("%c\n", (uint8_t)(n & 0xFF)); return 0; } 

Выход программы

 -1 ¿