Вопросы по С/С++ (СИ)
- Сообщения: 574
- Зарегистрирован: Вт ноя 02, 2010 17:46:37
Добрый день, подскажите при модульном программировании в каких случаях подключение других модуль производить в .h файле а в каких в .c файле. Раньше об этом не задумывался и постоянно подключал все в .h но недавно начали вылазить ошибки типа циклическое включение заголовков, так как тогда не было времени сильно разбираться некоторые заголовки перемести в .с файл и все заработало. А вот теперь при формировании новых библиотек задумался где что подключать.
- Реклама
Чтобы не было циклического включения и повторного переопределения ставят в .h файлах "экран"
Код: Выделить всё
#ifndef _DRIVER_H_
#define _DRIVER_H_
....сам х-файл
#endif
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- Сообщения: 535
- Зарегистрирован: Вт авг 28, 2012 22:21:33
Включать нужно туда, где это используется. Нужны типы int32_t в foo.h, включи stdint.h в foo.h. Если они нужны в foo.c, то включи stdint.h в foo.c. Нужны в обоих файлах (обычно так и бывает) включи в оба файла, и не важно, что в foo.c они будут опосредовано включены через foo.h. Лучше явно указать зависимости, а не надеяться, что кто-то где-то уже включил. Если при этом возникают ошибки - это проблема архитектуры, пересмотри зависимости между модулями.
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
Сюшная классика - все переменные до́лжно определять в начале блока. Многие компиляторы не так строги - и дозволяют разбрасывать объявления где заблагорассудится. Впрочем обойти тоже можно - огородившись "фиктивным" блоком:uldemir писал(а):declaration may not appear after executable statement in block [....] т.е. совершенно это неприемлет. Хотя, помнится, в IARе такое делал.
Код: Выделить всё
int i = 0;
[...]
i = 9;
{ // <- огораживаемся, огораживаемся
int u = 5; // и никто больше не ругается на это объявление
send (u);
} // ну вот и всё - окончен блок, беру шинель иду домой ...
У препроцессора есть возможность т.н. stringify с помощью одинарного # префикса - превращать число в строку. Вот если задавать коды в восьмеричных константах - по идее должно сработать:uldemir писал(а):Способ интересный, но тогда снова придётся делать два комплекта дефайнов - для констант и для строк.
Код: Выделить всё
#define S(_code) "\0" _S(_code)
#define _S(_code) #_code
#define OGO 000 // decimal 0
#define AGA 050 // decimal 40
const char* ppd = S(OGO) S(AGA); // const char* ppd = "\0" "000" "\0" "050";
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Сообщения: 2089
- Зарегистрирован: Вс июн 19, 2016 09:32:03
Для ARM gcc генерит одинаковый код при чтении, но разный при записи. Например, дляApparatchik писал(а):ARV писал(а): Есче интересно знать, битовые поля применяются когда оперативной памяти мало или просто для удобства. На сколько это выгоднее конструкции типа var |= 1 << 4;
Код: Выделить всё
RCC_CFGR->HPRE = presc;
Код: Выделить всё
RCC->CFGR = RCC->CFGR & ~RCC_CFGR_HPRE | (presc << 4);
Увы, подобным образом описаны только несколько регистров в CMSIS...ARV писал(а): на сколько я в курсе, подобным образом вся периферия ARM описана в соответствующих хедерах, и вся работа с нею ведется подобным образом
- Реклама
- Сообщения: 232
- Зарегистрирован: Чт янв 01, 2015 13:44:12
Привет всем! Для чего нужен суффикс типа вещественной переменной? Читаю книгу - там объявление используется с суффиксом, в других статьях используется без него. Компилятор компилирует два варианта написания.
В чем разница между объявлениями переменной с суффиксом и без:
float a=7.56F;
и
float a=7,56;
В чем разница между объявлениями переменной с суффиксом и без:
float a=7.56F;
и
float a=7,56;
Все гениальное - просто
В первом случае константа 7.56F - типа float, во втором константа 7.56 - типа double. Переменные же в обоих случаях float, и к ним эти суффиксы никак не относятся.
Будь компилятор поглупее и с отключенной оптимизацией, можно было бы предположить, что во втором случае он бы сгенерировал более сложный машинный код с приведением типов.
Будь компилятор поглупее и с отключенной оптимизацией, можно было бы предположить, что во втором случае он бы сгенерировал более сложный машинный код с приведением типов.
- Сообщения: 353
- Зарегистрирован: Вс янв 19, 2014 22:41:55
Хм, по ошущениям львиная доля применений f-суффикса - затыкать предупреждения компилятора на "возможную потерю точности" при приведении double литерала к типу float. Т.е. компилятор в сомнениях - или мы явно хотим использовать double константу, но почему-то втискиваем её во float, или просто неряшливо пишем код [без f-суффиксов] и тоже заслуживаем "фе" с его стороны. Но, с другой стороны, если преобразование 7.5 <-> 7.5f происходит без потери точности - отчего-бы и не соптимизировать.WiseLord писал(а):во втором случае он бы сгенерировал более сложный машинный код с приведением типов.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Сообщения: 232
- Зарегистрирован: Чт янв 01, 2015 13:44:12
Возможно ли в switch case использовать не отдельные числа, а промежутки чисел?
Например:
switch(a)
{
case 1: код; break;
case 2: код; break;
case 3: код; break;
...............
}
Можно ли на место числа 1, 2 или 3 вставить промежутки 1-2, 3-5 и т.д. ?
Например:
switch(a)
{
case 1: код; break;
case 2: код; break;
case 3: код; break;
...............
}
Можно ли на место числа 1, 2 или 3 вставить промежутки 1-2, 3-5 и т.д. ?
Все гениальное - просто
Да, такое возможно (как минимум, GCC поддерживает):
Код: Выделить всё
switch(f){
case 0 ... 5 : break;
case 6 ... 155: break;
default:
break;
}если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 232
- Зарегистрирован: Чт янв 01, 2015 13:44:12
Спасибо ARV ! Компилятор AtmelStudio с восторгом принял Ваш вариант кода. Я когда то видел такой вариант записи, пробовал писать, но забыл про пробелы - а писал так, например 1...3 . По этому компилятор и ругался.
Все гениальное - просто
Котаны, прошу помощи.
Си начал колупать недавно, опыта мало.
Мне надо объявить поле битов, но так, чтобы оно было видно во всех файлах *.с
Просто с переменной проблем не возникло, в main.c декларировал переменную, в main.h указал, что она extern -- и все поехало. А вот со структурой не получается.
Предыдущий программисть для однобитных флажков использовал целые байты. Теперь это боком вылазит, хочу эти флажки в поле затолкать.
Посоветуйте, плз!
Си начал колупать недавно, опыта мало.
Мне надо объявить поле битов, но так, чтобы оно было видно во всех файлах *.с
Просто с переменной проблем не возникло, в main.c декларировал переменную, в main.h указал, что она extern -- и все поехало. А вот со структурой не получается.
Предыдущий программисть для однобитных флажков использовал целые байты. Теперь это боком вылазит, хочу эти флажки в поле затолкать.
Посоветуйте, плз!
- Сообщения: 535
- Зарегистрирован: Вт авг 28, 2012 22:21:33
Код: Выделить всё
// foo.h
typedef struct
{
uint32_t a:2;
uint32_t b:21;
uint32_t c:4;
} flags_t;
extern flags_t flags;
Код: Выделить всё
// foo.c
flags_t flags;
Код: Выделить всё
// main.c
#include "foo.h"
int main(void)
{
flags.a = 1;
flags.b = 3;
flags.c = 2;
}
- Сообщения: 47
- Зарегистрирован: Вт авг 31, 2010 18:26:35
Здравствуйте
подскажите пожалуйста чего оно ругается
1 #define _XTAL_FREQ 20000000UL
2 #define PERIOD 5000UL //us
3 #define PULS 1000UL //us
4 #define PULS_CCPR1_UP ((_XTAL_FREQ/4UL)/(1000000UL/PULS))-1UL
5 #define PULS_CCPR1_DAUN ((_XTAL_FREQ/4UL)/(1000000UL/(PERIOD - PULS))-1UL
..................
6 CCPR1+=PULS_CCPR1_DAUN;
я подозреваю что непонятно вот это :(PERIOD - PULS) в строке 5, но как исправить не пойму
если можно напишите как правильно
спасибо
подскажите пожалуйста чего оно ругается
1 #define _XTAL_FREQ 20000000UL
2 #define PERIOD 5000UL //us
3 #define PULS 1000UL //us
4 #define PULS_CCPR1_UP ((_XTAL_FREQ/4UL)/(1000000UL/PULS))-1UL
5 #define PULS_CCPR1_DAUN ((_XTAL_FREQ/4UL)/(1000000UL/(PERIOD - PULS))-1UL
..................
6 CCPR1+=PULS_CCPR1_DAUN;
я подозреваю что непонятно вот это :(PERIOD - PULS) в строке 5, но как исправить не пойму
если можно напишите как правильно
спасибо
- Сообщения: 145
- Зарегистрирован: Ср фев 01, 2012 10:55:53
Скобки не хватает:
#define PULS_CCPR1_DAUN ((_XTAL_FREQ/4UL)/(1000000UL/(PERIOD - PULS)))-1UL
#define PULS_CCPR1_DAUN ((_XTAL_FREQ/4UL)/(1000000UL/(PERIOD - PULS)))-1UL
- Сообщения: 47
- Зарегистрирован: Вт авг 31, 2010 18:26:35
прошу помощи
есть у меня ф-ция разложения 2 разрадного числа
как ее надо усовершенствовать чтобы она разлаживала 3-х и более разрядные числа ?
есть у меня ф-ция разложения 2 разрадного числа
Код: Выделить всё
void Scr (int8_t temp)
{
Screen[0] = temp / 10;
Screen[1] = temp % 10;
}Tell Me The Truth
http://arv.radioliga.com/content/view/106/49/FreshMan писал(а):как ее надо усовершенствовать чтобы она разлаживала 3-х и более разрядные числа ?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Не разлаживала, а раскладывала.ARV писал(а):разлаживала 3-х и более разрядные числа
Как-то так, например:
Код: Выделить всё
void Scr (int8_t temp, uint8_t N)
{
char i;
for (i = N; i >= 0; i++) {
Screen[i] = temp % 10;
temp /= 10;
}
}


