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

Просмотров: 8620


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

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

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

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

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



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


  • Бегущие огни (ch-bo-36)Бегущие огни (ch-bo-36)
    Просмотров: 2376 Проект на PIC-микроконтроллере PIC16F648A. Количество каналов 36. Для индикации используется подключение по матрице 6х6. Расположение светодиодов в одну линию. Все эффекты написаны для возможности увеличения количества светодиодов. Рекомендуется …
  • Проект с использованием MCC часть 03Проект с использованием MCC часть 03
    Просмотров: 1502 Первым делом перенастроим регистры конфигурации, следующим образом: Отключим выход генератора (CLKOUT function is disabled. I/O function on the CLKOUT pin) Включим сторожевой таймер (WDT enabled) После этой настройки …
  • Стабилизатор тока для светодиодов SN3350Стабилизатор тока для светодиодов SN3350
    Просмотров: 2550 SN3350 ближайший аналог ZXLD1350 Как собрать готовый вариант, читайте во второй части – http://catcatcat.d-lan.dp.ua/stabilizator-toka-na-sn3350-chast-2/ 40V  драйвер светодиодов с внутренним ключом  SN3350 – импульсный понижающий преобразователь, разработанный для того, чтобы эффективно управлять одним или …
  • Проект с использованием MCC часть 13Проект с использованием MCC часть 13
    Просмотров: 977 Так как используя MCC мы можем его использовать со своими библиотеками, поэтому настало время и свое создать. Для начала откроем наш заголовочный файл в нем очень много букв: По …
  • Altium Designer my setup system and project structure V23.3Altium Designer my setup system and project structure V23.3
    Просмотров: 103 Оновлення бази даних та шаблонів від березня 2023 року. Updating the database and templates from March 2023. Altium Designer my Libraries, Project templates, System settings by Catcatcat. Дивись …
  • VU Meter Tower ART – part 2VU Meter Tower ART – part 2
    Просмотров: 928 Проект – VU Meter Tower ART получил продолжение в своем развитии. Теперь можно заказать набор деталей из акрила для самостоятельной сборки. В проект корпуса внесено целый ряд доработок, …
  • Сенсорный выключатель светаСенсорный выключатель света
    Просмотров: 8828 Хотя в настоящий момент актуальны системы управления освещением с передачей данных по электросети, но я думаю, что проекты такого рода тоже имеют право на жизнь. Анонс Три вида …
  • Temperature measurement with NTC thermistor.Temperature measurement with NTC thermistor.
    Просмотров: 150 Проекты в которых присутствовало измерение температуры начинал с цифровых датчиков, т.к. в них все просто и не надо ничего преобразовывать и вычислять. При использовании цифровых датчиков ты получаешь …
  • MCC – K42 – настройка модуля DMAMCC – K42 – настройка модуля DMA
    Просмотров: 699 MCC – в версии v.3.95.0 и начиная ядра 4.85.0 конфигуратор предоставляет графический интерфейс для настройки модуля DMA. Для начала: Посмотреть какая версия МСС можно в закладке версии, если …
  • DIXELL XWEB500D-EVO + RUT900 или как пробить NAT-серверDIXELL XWEB500D-EVO + RUT900 или как пробить NAT-сервер
    Просмотров: 958 Когда необходимо под какой нибудь контроллер имеющий вэб сервер в инет, то нужен статический IP, что оказалось проблемой при работе с операторами сотовых сетей, конкретно с оператором сети …



В записи нет меток.

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

Catcatcat

catcatcat

Development of embedded systems based on Microchip microcontrollers.

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

НазадДалее