Применение typedef, struct и union

Views: 8914


Полезные описания переменных

Часто необходимо в памяти расположить последовательно разные виды данных, что бы потом можно было их использовать.

Полезные ссылки

Взято и переработано с сайта
http://www.butovo.com/~zss/cpp/struct.htm
http://cppstudio.com/post/9172/

Синтаксис структур.

Структуры в языке С аналогичны массиву тесно связанных атрибутов. Однако, в отличие от массива, структура позволяет иметь смешанные атрибуты различных типов данных.
Структура создается при помощи ключевого слова struct, за которым следует имя_типа (имя структуры) и список элементов. Описание структуры заканчивается точкой с запятой, т.к. оно является оператором:

struct имя_типа
{
  тип_элемента1 имя_элемента1;
  тип_элемента2 имя_элемента2;
  тип_элемента3 имя_элемента3;
  …
};

Пример описания структуры:

struct stboat
{
  char type[16];   // тип
  char model[16];  // модель
  char title[20];  // имя
  int year;        // год выпуска
  double price;    // цена
};

Эта структура описывает новый тип данных stboat и содержит три текстовых поля, одно целое и одно действительное.
С описанной структурой не связывается никакая переменная. Для создания новой переменной используется оператор (слово struct является необязательным):

struct имя_структуры имя-переменной;

Для вышеприведенного примера можно создать переменную used_boat:

struct sboat used_boat;

Если со структурой связывается только одна переменная, то ее можно объявить непосредственно в описании структуры перед точкой с запятой. Имя_типа в этом случае можно опустить:

struct
{
  char type[16];  // тип
  char model[16]; // модель
  char title[20]; // имя
  int year;       // год выпуска
  double price;   // цена
} used_boat;

Доступ к элементам структуры.

Для обращения к отдельным элементам структуры используется операция обращения к члену структуры – “точка”. Она разделяет имя структурной переменной и имя поля, например

used_boat.year=1955;
printf(“%lf”,used_boat.price);

Элементы структуры обрабатываются также, как и любые другие переменные С, необходимо только использовать операцию “точка”.
Можно создавать массивы структур и указатели на структуру, для обращения к элементам структуры предусмотрен оператор “->” (стрелка, он состоит из знаков минус и больше).

sboat boat_array[10];           // описание массива состоящего из 10 структур sboat
boat_array[3].year=1980;        // 
sboat *pboat;                   // описание указателя
pboat=&used_boat;               // получение адреса структуры
pboat->price=12570.25;          // загрузка данных в элемент price структуры

Передача структур в функции.

В функцию информация о структуре может передаваться как по значению, так и по ссылке. В первом случае в функцию передается копия структуры, что может снизить эффективность программы.
При передаче по ссылке копирование не выполняется, однако функция получает доступ к элементам структуры и может их изменять.
Можно также использовать указатели на структуру.

Структуры и битовые поля.

В языке С имеется возможность доступа к отдельным разрядам в более крупном типе данных, например в байте. Это полезно, например для изменения масок, установки флагов и т.д. В этом случае описание структуры выглядит следующим образом:

struct имя_типа
{
  тип_элемента1
  имя_поля1:колич_бит1,
  имя_поля2:колич_бит2,
  имя_поля3:колич_бит3,
  …;
  тип_элемента2
  …
};

В таких структурах можно использовать только целочисленные типы:

struct keybits
{
  unsigned char
  shift :1,
  ctrl :1,
  scrool:1,
  lock :1;
};
struct
   {
        unsigned REIN	 :1;// выбор режима индикации.
        unsigned INPREG	 :1;// флаг активации входов управления регуляторами
        unsigned ALRM	 :1;// флаг аварии
        unsigned BVKLNAF :1;// флаг блокировки одновременного включения нагрузок.
        unsigned ENPA	 :1;// деактивация пароля 1 уровня.
        unsigned DISTO	 :1;// деактивация таймера технического обслуживания
        unsigned ERDT    :1;// неисправность датчика температуры
        unsigned ERDA    :1;// сбой данных
    } flag;

Объединения.

Объединения – еще один тип данных, которые можно использовать различным образом. К примеру, некоторые данные в одном случае могут рассматриваться как целые, а в другом – как числа с плавающей точкой. По виду объединения напоминают структуры. Объединение тоже содержит несколько типов данных, однако эти данные занимают одну и ту же область памяти.
В структурах описанные данные располагаются последовательно в памяти, а в объединениях они наложены друг на друга.
Например? структура:

struct
{
  char type[2];   // тип
  char title;     // имя
  int year;       // год выпуска
} used_boat;

Будет располагаться в памяти последовательно

номер байта название переменной тип
байт 0 tipe[0] char
байт 1 tipe[1] char
байт 2 title char
байт 3 year int
байт 4

В объединении, например:

union 
{
  char c;
  int ivalue;
  long fvalue;
} type1;

расположение переменных в памяти, типа наложение

номер байта переменная c invalue fvalue
байт 0
байт 1
байт 1
байт 2

Переменная с будет иметь значение младшего байта переменных invalue и fvalue…

Объединение создается при помощи ключевого слова union:

union имя_типа
{
  тип_элемента1 имя_элемента1;
  тип_элемента2 имя_элемента2;
  тип_элемента3 имя_элемента3;
  …
};

К членам объединения можно обращаться так же, как и к членам структур, либо через операцию “точка”, либо через операцию “->” – для указателей:

union many_types
{
  char c[4];
  int ivalue[2];
  float fvalue;
} type1;

type1.fvalue=1.5;

printf(“%i %i”,type1.ivalue[0],type1.ivalue[1]);

Вариант объединения структур

volatile union
{
struct // 
{
    unsigned char adhes_RM;     // 
    unsigned char command;      // 
    unsigned char adhes_PU;     // 
};
struct // 
{
    unsigned char adhes_RM;     // 
    unsigned char command;      // 
    unsigned char adhes_PU;     // 
    unsigned long nom_rul;      // 
    unsigned char prefiks;      // 
};
struct  // 
{
    unsigned char adhes_RM;     // 
    unsigned char command;      // 
    unsigned char adhes_PU;     // 
    unsigned int pol_uk;        // 
};
struct  // 
{
    unsigned char adhes_RM;     // 
    unsigned char command;      // 
    unsigned char adhes_PU;     // 
    unsigned char data[29];     // 
};
}cammand_transferMMK;

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

в этом варианте, компилятор XC16 v 1.26 разместил данные long с байта 4

struct // 
{
    unsigned char adhes_RM;     // 0 - байт / слово 1
    unsigned char command;      // 1        /
    unsigned char adhes_PU;     // 2        / слово 2
                                // 3 - ?    /
    unsigned long nom_rul;      // 4-5-6-7  / слово 3-4
    unsigned char prefiks;      // 8        / слово 5
};

Дополнительные средства (typedef и enum).

При помощи оператора typedef можно связать новые типы данных с существующими:

typedef double real;

После такого описания можно использовать real вместо double.
Использовать typedef необходимо с осторожностью. Слишком много новых типов могут ухудшить читаемость программы.
Перечисляемый тип данных enum позволяет определить список последовательных целых чисел, каждое из которых имеет собственное имя. Объявление перечисляемого типа выглядит следующим образом:

enum имя_типа {имя1=знач1, имя2=знач2, имя3=знач3, …}переменная;

Здесь имя1, имя2,… – это имена констант. Им можно присваивать целочисленные значения. Если значения отсутствуют, то предполагается, что они последовательно увеличиваются на единицу, начинаясь с нуля. Память под эти константы во время выполнения не выделяется, поэтому удобно использовать этот оператор для создания констант, если не указывать имя_типа и переменную:

enum (с28=28, с29,с30,c31);

Тип enum часто используется, когда информацию можно представить списком целых значений, подобно номерам дней недели или месяцев в году:

enum months
{Jan=1,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec}
current_month;
current_month=Dec; //используется константа 12
int diff=(int)current_month-2;
//тип enum автоматически не преобразуется в int

Поскольку имена эквивалентны последовательным целым значениям, то с ними можно выполнять арифметические операции. Фактически в данном примере переменной current_month присваивается целочисленное значение 12.

Создание внешних переменных которые должны быть доступны из подключаемых библиотек

Например есть библиотека spi.h, в ней необходимо описать объединение и сделать так чтобы она была доступна в основной программе

#ifndef XC_HEADER_TEMPLATE_H
#define	XC_HEADER_TEMPLATE_H

#include <xc.h>                     // include processor files - each processor file is guarded.  

// описываем объединение
union _Bufer
{
    unsigned char dataSPI[4];       // буфер SPI [3][2][1][0]
    signed long codacp;             // 32 бита
};
// объявляем объединение как обычную переменную (внешнюю), просто вначале дописываем слово union
extern union _Bufer Bufer;


#endif	/* XC_HEADER_TEMPLATE_H */

В самом файле где предстоит использовать надо описать

#include "spi.h"

//------------------------------------------------------------------------------
union _Bufer Bufer;

дополнение возможно…



Это может быть интересно


  • VU Meter Tower ART – part 2VU Meter Tower ART – part 2
    Views: 1200 Проект – VU Meter Tower ART получил продолжение в своем развитии. Теперь можно заказать набор деталей из акрила для самостоятельной сборки. В проект корпуса внесено целый ряд доработок, …
  • Самый простой диммер для светодиодного освещенияСамый простой диммер для светодиодного освещения
    Views: 3202 Светодиоды все больше входят в нашу жизнь как источники освещения и как само собой разумеющееся, это вопрос регулировки яркости. Существует множество схемных решений, но в нашем варианте мы …
  • Проект с использованием MCC часть 15Проект с использованием MCC часть 15
    Views: 1733 EUSART – Универсальный асинхронный приёмопередатчик (УАПП, англ. Universal Asynchronous Receiver-Transmitter, UART) — узел вычислительных устройств, предназначенный для организации связи с другими цифровыми устройствами. … читать на вики. Внесем изменения в нашу схему, …
  • Регулятор влажностиРегулятор влажности
    Views: 1366 Регулятор ILLISSI-CH-1000 предназначен для контроля и регулировки относительной влажности в диапазоне от 0 до 100%. Регулятор позволяет работать как в режиме осушения, так и увлажнения. Для измерения возможно …
  • ch-4000 – универсальная печатная платаch-4000 – универсальная печатная плата
    Views: 1138 На смену устаревшей плате ch-3000, пришла новая ch-4000. Плату уже можно приобрести в магазине Ворон. Схема. Плата позволяет создавать таймеры, часы реального времени, регуляторы температуры, регуляторы влажности, вольтметры, …
  • ESP32-первое знакомствоESP32-первое знакомство
    Views: 7219 Музыкальная тема к статье, слушаем: Настало время познакомиться c ESP32 и для меня, для этого я приобрел в ГАММЕ отладочную плату с модулем ESP-WROOM-32 (ESP32-DevKitC). Первая задача, как …
  • Светодиоды со встроенным драйвером WS2812BСветодиоды со встроенным драйвером WS2812B
    Views: 1046 Производитель http://www.world-semi.com Краткое описание продукции фирмы Каталог продукции” catcatcat_ws_19 catcatcat_ws_15 catcatcat_ws_11 catcatcat_ws_07 catcatcat_ws_03 catcatcat_ws_18 catcatcat_ws_14 catcatcat_ws_10 catcatcat_ws_06 catcatcat_ws_02 catcatcat_ws_05 catcatcat_ws_09 catcatcat_ws_13 catcatcat_ws_17 catcatcat_ws_16 catcatcat_ws_12 catcatcat_ws_08 catcatcat_ws_04 catcatcat_ws_01 This jQuery …
  • Проект с использованием MCC часть 08Проект с использованием MCC часть 08
    Views: 1272 И так создадим проект в котором при помощи двух кнопок мы сможем управлять яркостью светодиодов. При использовании МСС у нас лафа полная, добрые дяди с Microchipa подготовили функции, …
  • MTouch® Модуль Емкостной Библиотеки для MPLAB®X Code Configurator (MCC)MTouch® Модуль Емкостной Библиотеки для MPLAB®X Code Configurator (MCC)
    Views: 1413 Введение MTouch ® Модуль Емкостной Библиотеки для MPLAB ® X Code Configurator (MCC) позволяет быстро и легко генерировать решение кода на  Cи для емкостной сенсорной кнопки, датчика приближения и слайдера.
  • MAX7219/21 и 8х8 LED дисплеиMAX7219/21 и 8х8 LED дисплеи
    Views: 1070 MAX7219, MAX7221 предназначены для вывода информации на 8 разрядов семисегментного индикатора, но на нем легко организовать вывод на светодиодные индикаторы 8х8. продолжение следует…. Это может быть интересно



Поделись этим!

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

Продолжайте читать

НазадДалее