Цитата(Igor_U @ Jun 22 2006, 11:38)
Код
struct
{
uint16_t result_heater; // значение измерения ацп температуры нагревателя
uint16_t result_compensation; // значение измерения ацп температуры компенсации
uint16_t temperature_pid; // температура нагревателя для ПИД
uint16_t temperature_dec; // температура нагревателя для вывода на индикатор
uint8_t count; // подсчет циклов измерения
}adc;
На объявление этой структуры WinAVR говорит:
Код
Variable.hpp:13: warning: non-local variable '<anonymous struct> adc' uses anonymous type
Че за анонимный тип?
/*Цитата из Кернигана Ритчи*/
// Рекомендую целиком книгу прочитать
6.7 Средство typedef
Язык Си предоставляет средство, называемое typedef, которое позволяет давать типам данных новые имена. Например, объявление
typedef int Length;
делает имя Length синонимом int. С этого момента тип Length можно применять в объявлениях, в операторе приведения и т. д. точно так же, как тип int:
Length len, maxlen;
Length *lengths[];
Аналогично объявление
typedef char *String;
делает String синонимом char *, т. e. указателем на char, и правомерным будет, например, следующее его использование:
String р, lineptr[MAXLINES], alloc(int);
int strcmp(String, String);
p = (String) malloc(100);
Заметим, что объявляемый в typedef тип стоит на месте имени переменной в обычном объявлении, а не сразу за словом typedef. С точки зрения синтаксиса слово typedef напоминает класс памяти - extern, static и т. д. Имена типов записаны с заглавных букв для того, чтобы они выделялись.
Для демонстрации более сложных примеров применения typedef воспользуемся этим средством при задании узлов деревьев, с которыми мы уже встречались в данной главе.
typedef struct tnode *Treeptr;
typedef struct tnode { /* узел дерева: */
char *word; /* указатель на текст */
int count; /* число вхождений */
Treeptr left; /* левый сын */
Treeptr right; /* правый сын */
} Treenode;
В результате создаются два новых названия типов: Treenode (структура) и Treeptr (указатель на структуру). Теперь программу talloc можно записать в следующем виде:
Treeptr talloc(void)
{
return (Treeptr) malloc(sizeof(Treenode));
}
Следует подчеркнуть, что объявление typedef не создает объявления нового типа, оно лишь сообщает новое имя уже существующему типу. Никакого нового смысла эти новые имена не несут, они объявляют переменные в точности с теми же свойствами, как если бы те были объявлены напрямую без переименования типа. Фактически typedef аналогичен #define с тем лишь отличием, что при интерпретации компилятором он может справиться с такой текстовой подстановкой, которая не может быть обработана препроцессором. Например
typedef int (*PFI)(char *, char *);
создает тип PFI - "указатель на функцию (двух аргументов типа char *), возвращающую int", который, например, в программе сортировки, описанной в главе 5, можно использовать в таком контексте:
PFI strcmp, numcmp;
Помимо просто эстетических соображений, для применения typedef существуют две важные причины. Первая - параметризация программы, связанная с проблемой переносимости. Если с помощью typedef объявить типы данных, которые, возможно, являются машинно-зависимыми, то при переносе программы на другую машину потребуется внести изменения только в определения typedef. Одна из распространенных ситуаций - использование typedef-имен для варьирования целыми величинами. Для каждой конкретной машины это предполагает соответствующие установки short, int или long, которые делаются аналогично установкам стандартных типов, например size_t и ptrdiff_t.
Вторая причина, побуждающая к применению typedef,- желание сделать более ясным текст программы. Тип, названный Тreeptr (от английских слов tree - дерево и pointer - указатель), более понятен, чем тот же тип, записанный как указатель на некоторую сложную структуру.