как объявить переменную типа typedef struct на си для 8051
Пишу библиотеку для дисплея на 8051(keil). Хочу сделать отдельный заголовочный файл с описанием всех цветов, а потом использовать его в библиотеке и програме. Вот файл Colors.h:
#ifndef COLORS
#define COLORS
typedef struct {
int red,
green,
blue;
} color;
color RED = {0xFF, 0xFF, 0};
#endif
потом в основной программе делаю так:
#include "Colors.h"
color col;
...
col = RED; //*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
есть ли вообще какой-то красивый способ объявить константы для разных цветов и использовать их в аргументах функций прорисовки? (цвет содержит 3 байта RGB, т.е. в int не влезет)
Ответы (2 шт):
Когда Вы пишите объявление структуры, Вы просто объясняете компилятору, что у Вас есть такая структура. Когда же Вы объявляете (declare) переменную, тоже - Вы объясняете компилятору, что есть такая переменная. Хорошая особенность объявлений - их может быть много, главное, что бы они совпадали. Но обычно переменные определяют (definition) - тогда компилятор выделяет сразу выделяет место под эту переменную. Если в хедер поместить несколько определений и этот хедер подключить в несколько с файлов (единиц компиляции), то компилятор с линковщиком будут вынуждены выделить несколько раз место под одну и ту же переменную. А они так не могут. Что делать? Есть классический способ.
В хедере пишете вот так (это объявление, а их может быть много!)
extern col RED;
а в любом c файле пишете
color RED = {0xFF, 0xFF, 0};
теперь определение одно, компилятор с линковщиком знают, где разместить в памяти переменную и все ок.
Есть второй способ, писать в хедере вот так
static color RED = {0xFF, 0xFF, 0};
в этом случае эта переменная не покинет пределы единицы компиляции и то же все будет работать. Но у этого способа есть один маленький минус. Теперь константы могут хранится в каждом файле, куда Вы заинклюдили свой хедер. Компилятор с линковщиком могут оптимизировать, а могут и нет. И если Вам дорог каждый байт (в микрокотроллерах так бывает), то лучше проверить оба способа и сравнить размер бинарника.
Для такого рода констант обычно используют макросы.
Если компилятор поддерживает в каком-либо виде 32-х битный тип, то нормальным решением будет хранить цвет в нём:
typedef uint32_t color_t;
#define RED (color_t)0x00FFFF00ll
В противном случае, если компилятор поддерживает С99, то можно использовать макрос с составным литералом:
#define RED (color_t){0xFF, 0xFF, 0x00}
Для C89 нормального способа на вскидку не вспомню.