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

Views: 8732


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

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

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

Взято и переработано с сайта
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;

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



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


  • Development board based on MCU PIC18F47Q84Development board based on MCU PIC18F47Q84
    Views: 1331 PIC18F47Q84 Microcontroller Family with CAN Flexible Data Status: In Production.
  • Интерактивные LedИнтерактивные Led
    Views: 464 Тема проекта   продолжение следует…. Это может быть интересно
  • Простой сенсорный регулятор светаПростой сенсорный регулятор света
    Views: 2313 Простой сенсорный регулятор. Проект – 2007 года. Регулятор выполнена на микроконтроллере PIC12F683 и имеет минимальное количество элементов. Выполняет стандартные функции, включение выключение света, изменение яркости, запоминание последнего установленного уровня …
  • MCC PIC24 – модуль OUTPUT COMPARE – в режиме генератора звуковых сигналовMCC PIC24 – модуль OUTPUT COMPARE – в режиме генератора звуковых сигналов
    Views: 610 При проектировании простых устройств автоматики, часто необходимо иметь механизм звукового оповещения. Самый верхний уровень, это формирование голосовых сообщений, но об этом, как то по позже… В самом примитивном …
  • MPLAB® Harmony – или как это просто! Часть 4.MPLAB® Harmony – или как это просто! Часть 4.
    Views: 2070 Часть четвертая – это может показаться немного сложно. Структура проекта. Для облегчения конфигурирования проекты MPLAB Harmony обычно структурированы таким образом, чтобы изолировать код, необходимый для настройки «системы», от …
  • Счетчики посетителейСчетчики посетителей
    Views: 1261 Вас сосчитали!? или счетчики посетителей.   Для чего нужны счетчики посетителей? Какие они бывают? ТОРГОВЛЯ. Подсчитайте, сколько ваш магазин посещает человек за день. Кок много человек приходит утром, какое …
  • My libraries for Altium DesignerMy libraries for Altium Designer
    Views: 4024 Attention, this version of the database is outdated today. See updates in articles https://catcatcat.d-lan.dp.ua/altium-designer-my-setup-system-and-project-structure  and https://catcatcat.d-lan.dp.ua/altium-designer-my-setup-system-and-project-structure-v23-2/    My libraries for Altium designer  (Updated V – 29/05/2022) (c) 2021 …
  • LCD драйвер – UC1601sLCD драйвер – UC1601s
    Views: 1599 http://svetomuzyka.narod.ru/project/UC1601s.html Читайте обновление на http://catcatcat.d-lan.dp.ua/?page_id=178 В данный момент можно приобрести в ООО “Гамма” несколько типов индикаторов на драйвере UC1601s. RDX0048-GC, RDX0077-GS, RDX0154-GC и RDX0120-GC выполнены по технологии COG.
  • MPLAB® Code Configurator and EncoderMPLAB® Code Configurator and Encoder
    Views: 1419 Еще раз про энкодер… Для некоторых приложений очень удобно и экономически выгодно, для настройки и управления использовать энкодер. Такие энкодеры имеют строенную тактовую кнопку которую можно применить для выбора …
  • Применение typedef, struct и unionПрименение typedef, struct и union
    Views: 8732 Полезные описания переменных Часто необходимо в памяти расположить последовательно разные виды данных, что бы потом можно было их использовать. Полезные ссылки Взято и переработано с сайта http://www.butovo.com/~zss/cpp/struct.htm http://cppstudio.com/post/9172/ …



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

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

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

НазадДалее