Вопросы по С/С++ (СИ)
-
BerZerK-ku
- Мучитель микросхем
- Сообщения: 492
- Зарегистрирован: Вт июл 22, 2008 08:10:54
Re: Вопросы по С/С++ (СИ)
';' лишнее в дефайне
Re: Вопросы по С/С++ (СИ)
Следующая заморочка... похоже, что #define нельзя экранировать условной компиляцией? Я вот из ассемблерного исходника хочу перейти на С:
Получается, что дефайнами я такое выразить не могу? как быть?
Код: Выделить всё
let_7 SET invertmask(seg_a+seg_b+seg_c)
IFNDEF TAILLESS
let_7 SET invertmask((invertmask(let_7))+seg_f)
ENDIF
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- BCluster
- Собутыльник Кота
- Сообщения: 2512
- Зарегистрирован: Пн апр 06, 2009 19:33:29
- Откуда: Молдова, Кишинев
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Почему нельзя?
Код: Выделить всё
#if defined DEBUG
#define SOME_DEBUG_DEF 0x04
#else
#define SOME_RELEASE_DEF 0x07
#endif
Re: Вопросы по С/С++ (СИ)
В книжке нет таких директив. есть #ifdef, #ifundef. компилятор тоже ругается.
ладно. кое-как заборол. Спасибо всем за помощь
ладно. кое-как заборол. Спасибо всем за помощь
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- BCluster
- Собутыльник Кота
- Сообщения: 2512
- Зарегистрирован: Пн апр 06, 2009 19:33:29
- Откуда: Молдова, Кишинев
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
uldemir писал(а):В книжке нет таких директив. есть #ifdef, #ifundef. компилятор тоже ругается.
ладно. кое-как заборол. Спасибо всем за помощь
я ж не знаю что у вас за компилятор ) в том на котором я сейчас работаю такие фишки проходят - в вашем случае тоже самое, только используйте #ifdef вместо #if defined
Re: Вопросы по С/С++ (СИ)
Сейчас пользуюсь IARом. А справочник Болски "Язык программирования Си" М.:1988. Немного путаюсь, раньше писал на Small C (я думаю, многие по ней в своё время делали кросс компилятор. Мы - тоже), поэтому привычен к игнорированию некоторых вещей. И кстати, там нельзя было делать вложение директив препроцессора - поэтому я испугался, когда повалили в этом месте ошибки. А ошибка была в том, что в макроассемлерном варианте я один символ определял через другой. Т.е. let_7 с хвостиком, это ранее определенный let_7 без хвостика плюс сегмент_f. Компилятор на это руганулся, ну я и влепил #undef, чем полностью себя запутал. Ну ничего, вроде разобрался.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
первая ссылка в гугле на запрос "IAR preprocessor directives" выдал нужную инфу
Ставим плюсы: )
Re: Вопросы по С/С++ (СИ)
Tell Me The Truth
- ibiza11
- Поставщик валерьянки для Кота
- Сообщения: 1900
- Зарегистрирован: Сб фев 21, 2009 13:11:40
- Откуда: Москва
Re: Вопросы по С/С++ (СИ)
основные типы определены, но порой требуется создать свой тип данных.
например при объявлении структур одинакового состава.
создадим типизированную структуру type_student, которой будем описывать студентов группы.
у каждого студента есть имя, возраст и адрес проживания.
после создания структуры легко определить массив структур, в котором будет храниться информация о всех студентах.
например при объявлении структур одинакового состава.
создадим типизированную структуру type_student, которой будем описывать студентов группы.
Код: Выделить всё
typedef struct {
unsigned char name[10];
unsigned char age;
unsigned char address[20];
}type_student;после создания структуры легко определить массив структур, в котором будет храниться информация о всех студентах.
Код: Выделить всё
type_student group[25];Ставим плюсы: )
- BCluster
- Собутыльник Кота
- Сообщения: 2512
- Зарегистрирован: Пн апр 06, 2009 19:33:29
- Откуда: Молдова, Кишинев
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
А еще я всегда делаю себе определения, которые принято использовать в виндах. Ибо привык )
Типа
typedef long DWORD;
typedef unsigned char BYTE; и т.д. просто удобнее
Но самое главное, конечно, структуры )
Типа
typedef long DWORD;
typedef unsigned char BYTE; и т.д. просто удобнее
Но самое главное, конечно, структуры )
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
самое главное - это то, что не смотря на толерантность Си к несовпадению типов операндов, компилятор все-таки варнингует на эти моменты, что позволяет отловить многие ошибки и "слабые" места в программе еще в момент компиляции. например, вы делаете функцию, которая принимает в качестве параметра номер нажатой кнопки и что-то делает в зависимости от этого номера. при этом в вашем устройстве всего 5 конопок. обычно делают примерно так:казалось бы - чего тут неправильного, опасного или ошибочного? а оно-таки есть!
прежде всего, внутри switch нет обработчика по умолчанию - метки default. может, это и не плохо, а может и плохо. но, самое главное, что эта функция никак не отреагирует на передачу ей переменной, содержащей число дней недели, количество топлива в баке и т.п. - если эти переменные имеют тип unsigned char - компилятор проглотит и не икнет! это означает то, что если вы по ошибке/запарке обратитесь к этой функции неправильно - узнать об этом вы сможете только после запуска изделия в работу по его странному поведению (либо в отладчике/симуляторе, что тоже не очень радостно).
и вы скажете: как же типы помогут в этом случае? да очень просто! если вы определите свой "доморощенный" тип для кода кнопки, для топлива в баке, для дня недели и т.п., то при попытке засунуть переменную НЕ ТОГО ТИПА в параметр функции, вы получите WARNING от компилятора!
конечно, я привел весьма тупой пример, но все-таки показательный. на самом деле для переменной, которая может содержать только ОГРАНИЧЕННЫЙ набор значений следует использовать тип-ПЕРЕЧИСЛЕНИЕ, однако это уже не совсем Си, а С++, хотя с некоторым кривобоким переподвыподвертом можно и для си применить enum - и, если можно, обязательно следует его применять!!!
P.S. вообще говоря, это все не всегда так здорово работает, как я расписал, ибо далеко не всеми версиями компилятора поддерживается, или для этого нужно какие-то опции активировать в компиляторе, но стремиться "писать правильно" нужно независимо от компилятора.
Код: Выделить всё
void func(unsigned char keynum){
switch(keynum){
case 1:
// обработка кнопки
break;
case 2:
// обработка кнопки
break;
case 3:
// обработка кнопки
break;
case 4:
// обработка кнопки
break;
case 5:
// обработка кнопки
break;
}
}прежде всего, внутри switch нет обработчика по умолчанию - метки default. может, это и не плохо, а может и плохо. но, самое главное, что эта функция никак не отреагирует на передачу ей переменной, содержащей число дней недели, количество топлива в баке и т.п. - если эти переменные имеют тип unsigned char - компилятор проглотит и не икнет! это означает то, что если вы по ошибке/запарке обратитесь к этой функции неправильно - узнать об этом вы сможете только после запуска изделия в работу по его странному поведению (либо в отладчике/симуляторе, что тоже не очень радостно).
и вы скажете: как же типы помогут в этом случае? да очень просто! если вы определите свой "доморощенный" тип для кода кнопки, для топлива в баке, для дня недели и т.п., то при попытке засунуть переменную НЕ ТОГО ТИПА в параметр функции, вы получите WARNING от компилятора!
Код: Выделить всё
typedef unsigned char type_for_keynum;
void func(type_for_keynum keynum){
...
}
type_for_keynum var1;
unsigned char var2;
func(var1); // нет варнинга
func(var2); // ЕСТЬ ВАРНИНГконечно, я привел весьма тупой пример, но все-таки показательный. на самом деле для переменной, которая может содержать только ОГРАНИЧЕННЫЙ набор значений следует использовать тип-ПЕРЕЧИСЛЕНИЕ, однако это уже не совсем Си, а С++, хотя с некоторым кривобоким переподвыподвертом можно и для си применить enum - и, если можно, обязательно следует его применять!!!
P.S. вообще говоря, это все не всегда так здорово работает, как я расписал, ибо далеко не всеми версиями компилятора поддерживается, или для этого нужно какие-то опции активировать в компиляторе, но стремиться "писать правильно" нужно независимо от компилятора.
битва с дураками проиграна, победители торжествуют. слава победителям!
- BCluster
- Собутыльник Кота
- Сообщения: 2512
- Зарегистрирован: Пн апр 06, 2009 19:33:29
- Откуда: Молдова, Кишинев
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Почему в Си нельзя использовать енум?))) Можно, чем мы вовсю и пользуемся. Мы бы без них погибли 
Насчет остального - может в этом что-то и есть, но я лично не вижу особого смысла применять такие вещи для простых типов данных. Скорее всего дело вкуса, но меня выводит огномное количество типов.
Насчет остального - может в этом что-то и есть, но я лично не вижу особого смысла применять такие вещи для простых типов данных. Скорее всего дело вкуса, но меня выводит огномное количество типов.
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
спорить бесполезно, холивары ни к чему. рекомендации по написанию качественного кода давно известны, тому посвящено множество книг именитых авторов... но каждый выбирает для себя 
а enum в Си можно использовать - я не утверждал обратного! просто далеко не всегда это УДОБНО и не всегда возможно. например, сделать тип перечисление для чисел от -12 до 130 хотя и можно при помощи enum-а, но, согласитесь, очень трудоемко
и еще один неприятный момент enum-а в приложении к WinAVR во всяком случае: по умолчанию для типа enum выделяется размер типа int, т.е. 2 байта. поэтому использование структур с полями типа enum черевато лишним расходом памяти, если не предпринимать особых мер.
а enum в Си можно использовать - я не утверждал обратного! просто далеко не всегда это УДОБНО и не всегда возможно. например, сделать тип перечисление для чисел от -12 до 130 хотя и можно при помощи enum-а, но, согласитесь, очень трудоемко
битва с дураками проиграна, победители торжествуют. слава победителям!
- Леонид Иванович
- Друг Кота
- Сообщения: 4779
- Зарегистрирован: Сб апр 02, 2011 12:40:46
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Мастер Ломастер писал(а):как же типы помогут в этом случае? да очень просто! если вы определите свой "доморощенный" тип для кода кнопки, для топлива в баке, для дня недели и т.п. ...
Боязнь ошибок, доведённая до маразма.
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Леонид Иванович писал(а):Боязнь ошибок, доведённая до маразма.
Мастер Ломастер писал(а):спорить бесполезно, холивары ни к чему. рекомендации по написанию качественного кода давно известны, тому посвящено множество книг именитых авторов... но каждый выбирает для себя
битва с дураками проиграна, победители торжествуют. слава победителям!
Re: Вопросы по С/С++ (СИ)
Мастер Ломастер писал(а):и еще один неприятный момент enum-а в приложении к WinAVR во всяком случае: по умолчанию для типа enum выделяется размер типа int, т.е. 2 байта. поэтому использование структур с полями типа enum черевато лишним расходом памяти, если не предпринимать особых мер.
уточните, пож-ста как сказать компилеру использовать 8-битный int для enum. %)
-
Мастер Ломастер
- Поставщик валерьянки для Кота
- Сообщения: 1995
- Зарегистрирован: Ср май 11, 2011 21:37:45
- Откуда: Цветочный город
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
для того, чтобы компилятор всегда выделял под enum минимальное количество байтов, надо применять параметр -fshort-enums. для переменных, структур и их полей можно использовать атрибут packed. однако, все равно компилятор WinAVR может иногда поступать странно, особенно при структурах, в которых есть поля типа enum - я не стал долго мудрствовать и для таких полей принудительно указываю число бит, как для битового поля.
битва с дураками проиграна, победители торжествуют. слава победителям!
Re: Вопросы по С/С++ (СИ)
Мастер Ломастер писал(а): рекомендации по написанию качественного кода давно известны, тому посвящено множество книг именитых авторов...
какие именно книги ?

Tell Me The Truth

