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

Views: 8707


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

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

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

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

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



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


  • Проект с использованием MCC часть 01Проект с использованием MCC часть 01
    Views: 2493 Для изучения MCC я выбрал простой контроллер PIC16F1509. Выбор его был обусловлен богатой новой периферией которую можно изучить. Для начала была собрана схема на макетной плате Внешний вид …
  • Гаджеты для домашней автоматики – Датчик движенияГаджеты для домашней автоматики – Датчик движения
    Views: 1435 Управление светодиодным освещением – Датчик движения. Данный гаджет предназначен для управления освещением рабочих столов (кухонных столов), освещение прихожих, освещение зеркал в прихожих, автоматическое включение света в коридорах. Датчик позволяет …
  • LCD драйвер – UC1601sLCD драйвер – UC1601s
    Views: 1567 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: 1401 Еще раз про энкодер… Для некоторых приложений очень удобно и экономически выгодно, для настройки и управления использовать энкодер. Такие энкодеры имеют строенную тактовую кнопку которую можно применить для выбора …
  • Светодиоды со встроенным драйвером WS2812BСветодиоды со встроенным драйвером WS2812B
    Views: 916 Производитель 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 часть 14Проект с использованием MCC часть 14
    Views: 804 С выводом данных на дисплей мы справились (но могу сразу сказать библиотеку графики к этой статьи пришлось доработать, поэтому в этом проекте она обновлена). У нас на текущем …
  • TDA7294 part 1TDA7294 part 1
    Views: 219 TDA7294 має унікальні дані для створення підсилювачів звукової частоти HI-FI класу. Варіант застосування є конфігурація BRIDGE (мостова схема включення), де використовуються два TDA7294, як показано на схематичній діаграмі …
  • Модуль CAN в микроконтроллерах PIC18Модуль CAN в микроконтроллерах PIC18
    Views: 5694 Введение   CAN последовательный интерфейс связи, который эффективно поддерживает распределенное управление в реальном масштабе времени с высокой помехозащищенностью. Протокол связи полностью определен Robert Bosch GmbH, в спецификации требований …
  • WiFi ESP8266 – AT команды связанные с функцией TCP/IP (v.1.6.1)WiFi ESP8266 – AT команды связанные с функцией TCP/IP (v.1.6.1)
    Views: 5009 AT команды связанные с функцией TCP/IP В этом разделе описаны команды которые позволяют устанавливать соединения между серверами и клиентами в сети. Приведено описание команд и примеры их выполнения. …
  • Development of temperature control and management systemsDevelopment of temperature control and management systems
    Views: 63 Catcatcat Electronics Пошта для контакту e-mail: catcatcat.electronics@gmail.com



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

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

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

НазадДалее