Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

Сообщение pokk »

Добрый день, подскажите при модульном программировании в каких случаях подключение других модуль производить в .h файле а в каких в .c файле. Раньше об этом не задумывался и постоянно подключал все в .h но недавно начали вылазить ошибки типа циклическое включение заголовков, так как тогда не было времени сильно разбираться некоторые заголовки перемести в .с файл и все заработало. А вот теперь при формировании новых библиотек задумался где что подключать.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7382
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Чтобы не было циклического включения и повторного переопределения ставят в .h файлах "экран"

Код: Выделить всё

#ifndef _DRIVER_H_
#define _DRIVER_H_
....сам х-файл
#endif
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

Включать нужно туда, где это используется. Нужны типы int32_t в foo.h, включи stdint.h в foo.h. Если они нужны в foo.c, то включи stdint.h в foo.c. Нужны в обоих файлах (обычно так и бывает) включи в оба файла, и не важно, что в foo.c они будут опосредовано включены через foo.h. Лучше явно указать зависимости, а не надеяться, что кто-то где-то уже включил. Если при этом возникают ошибки - это проблема архитектуры, пересмотри зависимости между модулями.
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

uldemir писал(а):declaration may not appear after executable statement in block [....] т.е. совершенно это неприемлет. Хотя, помнится, в IARе такое делал.
Сюшная классика - все переменные до́лжно определять в начале блока. Многие компиляторы не так строги - и дозволяют разбрасывать объявления где заблагорассудится. Впрочем обойти тоже можно - огородившись "фиктивным" блоком:

Код: Выделить всё

  int i = 0;
[...]
  i = 9;

  {  // <- огораживаемся, огораживаемся
     int u = 5; // и никто больше не ругается на это объявление
     send (u);
  }  // ну вот и всё - окончен блок, беру шинель иду домой ...

uldemir писал(а):Способ интересный, но тогда снова придётся делать два комплекта дефайнов - для констант и для строк.
У препроцессора есть возможность т.н. stringify с помощью одинарного # префикса - превращать число в строку. Вот если задавать коды в восьмеричных константах - по идее должно сработать:

Код: Выделить всё

#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

Сообщение Reflector »

Apparatchik писал(а):
ARV писал(а): Есче интересно знать, битовые поля применяются когда оперативной памяти мало или просто для удобства. На сколько это выгоднее конструкции типа var |= 1 << 4;
Для ARM gcc генерит одинаковый код при чтении, но разный при записи. Например, для

Код: Выделить всё

RCC_CFGR->HPRE = presc;
он сгенерит код с инструкцией BFI, которая предназначена именно для работы с битовыми полями. Но для

Код: Выделить всё

RCC->CFGR = RCC->CFGR & ~RCC_CFGR_HPRE | (presc << 4);
получим BIC + OR, а если сдвигая 8 битное значение нельзя получить нужную маску, то добавится еще LDR.
ARV писал(а): на сколько я в курсе, подобным образом вся периферия ARM описана в соответствующих хедерах, и вся работа с нею ведется подобным образом
Увы, подобным образом описаны только несколько регистров в CMSIS...
Реклама
CB1
Прорезались зубы
Сообщения: 232
Зарегистрирован: Чт янв 01, 2015 13:44:12

Сообщение CB1 »

Привет всем! Для чего нужен суффикс типа вещественной переменной? Читаю книгу - там объявление используется с суффиксом, в других статьях используется без него. Компилятор компилирует два варианта написания.
В чем разница между объявлениями переменной с суффиксом и без:
float a=7.56F;
и
float a=7,56;
Все гениальное - просто
Реклама
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

В первом случае константа 7.56F - типа float, во втором константа 7.56 - типа double. Переменные же в обоих случаях float, и к ним эти суффиксы никак не относятся.

Будь компилятор поглупее и с отключенной оптимизацией, можно было бы предположить, что во втором случае он бы сгенерировал более сложный машинный код с приведением типов.
Контактная информация:
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

Сообщение Siarzhuk »

WiseLord писал(а):во втором случае он бы сгенерировал более сложный машинный код с приведением типов.
Хм, по ошущениям львиная доля применений f-суффикса - затыкать предупреждения компилятора на "возможную потерю точности" при приведении double литерала к типу float. Т.е. компилятор в сомнениях - или мы явно хотим использовать double константу, но почему-то втискиваем её во float, или просто неряшливо пишем код [без f-суффиксов] и тоже заслуживаем "фе" с его стороны. Но, с другой стороны, если преобразование 7.5 <-> 7.5f происходит без потери точности - отчего-бы и не соптимизировать.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
CB1
Прорезались зубы
Сообщения: 232
Зарегистрирован: Чт янв 01, 2015 13:44:12

Сообщение CB1 »

Возможно ли в switch case использовать не отдельные числа, а промежутки чисел?
Например:
switch(a)
{
case 1: код; break;
case 2: код; break;
case 3: код; break;
...............
}
Можно ли на место числа 1, 2 или 3 вставить промежутки 1-2, 3-5 и т.д. ?
Все гениальное - просто
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Да, такое возможно (как минимум, GCC поддерживает):

Код: Выделить всё

switch(f){
case 0 ... 5 : break;
case 6 ... 155: break;
default:
   break;
}
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
CB1
Прорезались зубы
Сообщения: 232
Зарегистрирован: Чт янв 01, 2015 13:44:12

Сообщение CB1 »

Спасибо ARV ! Компилятор AtmelStudio с восторгом принял Ваш вариант кода. Я когда то видел такой вариант записи, пробовал писать, но забыл про пробелы - а писал так, например 1...3 . По этому компилятор и ругался.
Все гениальное - просто
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2142
Зарегистрирован: Чт дек 12, 2013 11:18:14
Откуда: Украина, Черновцы

Сообщение Hand-Maker »

Котаны, прошу помощи.
Си начал колупать недавно, опыта мало.
Мне надо объявить поле битов, но так, чтобы оно было видно во всех файлах *.с
Просто с переменной проблем не возникло, в main.c декларировал переменную, в main.h указал, что она extern -- и все поехало. А вот со структурой не получается.
Предыдущий программисть для однобитных флажков использовал целые байты. Теперь это боком вылазит, хочу эти флажки в поле затолкать.
Посоветуйте, плз!
Вымогатель припоя
Аватара пользователя
Сообщения: 535
Зарегистрирован: Вт авг 28, 2012 22:21:33

Сообщение menzoda »

Код: Выделить всё

// 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;
}
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2142
Зарегистрирован: Чт дек 12, 2013 11:18:14
Откуда: Украина, Черновцы

Сообщение Hand-Maker »

Получилось!!
Пасибки, ловите плюску :wink:
Открыл глаза
Сообщения: 47
Зарегистрирован: Вт авг 31, 2010 18:26:35

Сообщение ____Eugene____ »

Здравствуйте
подскажите пожалуйста чего оно ругается

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

Сообщение BorisSPB »

Скобки не хватает:
#define PULS_CCPR1_DAUN ((_XTAL_FREQ/4UL)/(1000000UL/(PERIOD - PULS)))-1UL
Открыл глаза
Сообщения: 47
Зарегистрирован: Вт авг 31, 2010 18:26:35

Сообщение ____Eugene____ »

спасибо
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

прошу помощи
есть у меня ф-ция разложения 2 разрадного числа

Код: Выделить всё

void Scr (int8_t temp)
{
		Screen[0] = temp / 10;
		Screen[1] = temp % 10;
	
}
как ее надо усовершенствовать чтобы она разлаживала 3-х и более разрядные числа ?
Tell Me The Truth
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18787
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

FreshMan писал(а):как ее надо усовершенствовать чтобы она разлаживала 3-х и более разрядные числа ?
http://arv.radioliga.com/content/view/106/49/
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

ARV писал(а):разлаживала 3-х и более разрядные числа
Не разлаживала, а раскладывала.

Как-то так, например:

Код: Выделить всё

void Scr (int8_t temp, uint8_t N)
{
    char i;

    for (i = N; i >= 0; i++) {
        Screen[i] = temp % 10;
        temp /= 10;
    }
}
Ну, или, если наращивать функционал (отрицательные числа, заполнение нулями/пробелами) - как-то так.
Контактная информация:
Ответить

Вернуться в «Разные вопросы по МК»