Вопросы по С/С++ (СИ)
Re: Вопросы по С/С++ (СИ)
вопрос относительно построения программы по модульному принципу
допустим в моем проэкте есть два модуля
main.c
module_1.c
по общепринятым правилам в main.c я должен прописать хидер #include "module_1.h" в котором я должен обозначить прототипы ф-ций
1)зачем в данном случае вообще нужен хидер ? ведь все файлы которые есть в проэкте с расширением с при компиляции все-равно сливаются воедино
2) почему бы тогда в хидере не писать сразу все ф-ции целиком ?
допустим в моем проэкте есть два модуля
main.c
module_1.c
по общепринятым правилам в main.c я должен прописать хидер #include "module_1.h" в котором я должен обозначить прототипы ф-ций
1)зачем в данном случае вообще нужен хидер ? ведь все файлы которые есть в проэкте с расширением с при компиляции все-равно сливаются воедино
2) почему бы тогда в хидере не писать сразу все ф-ции целиком ?
Tell Me The Truth
- Реклама
- coredumped
- Опытный кот
- Сообщения: 838
- Зарегистрирован: Вт апр 12, 2011 18:38:19
- Откуда: с Земли
Re: Вопросы по С/С++ (СИ)
#include "module_1.h" выполняется препроцессором и вызывает вставку всего содержимого файла "module_1.h" в компилируемый файл. Если Вы опишите в "module_1.h" функции полностью, а не только прототипы, то файлы скомпилятся, однако при линковке Вы получите сообщение об ошибке (что-то типа "функция с именем бла-бла объявлена несколько раз"). Это, если хидер включен в несколько модулей программы.FreshMan писал(а):
по общепринятым правилам в main.c я должен прописать хидер #include "module_1.h" в котором я должен обозначить прототипы ф-ций
1)зачем в данном случае вообще нужен хидер ? ведь все файлы которые есть в проэкте с расширением с при компиляции все-равно сливаются воедино
2) почему бы тогда в хидере не писать сразу все ф-ции целиком ?
Поэтому, делается так: пишем функции в отдельном модуле - файле xxx.c, затем создаем хидер (xxx.h), содержащий прототипы функций, которые мы хотим использовать в других модулях, а в самих модулях делаем включение #include "xxx.h".
Включение нужно для того, чтоб компилятор понял какие именно параметры будут в функции, которая позднее будет подлинкована из других модулей. Можно вместо хидера писать в каждом модуле описание прототипа функции, например extern int my_blackbox(int a);(extern можно не писать для большинства компиляторов).
Еще оди совет: в хидерах используйте условное объявление типа #ifndef _MODULE_H_ #define _MODULE_H_ ... содержимое хидера ... #endif
Пример:
Код: Выделить всё
#ifndef __FPGA_CONF_H
#define __FPGA_CONF_H
#include "stm32f4xx.h"
#define FPGA_INIT_CYCLE 50 /* extra DCLK cycles while initialization is in progress */
#define FPGA_RECONF_COUNT_MAX 5 /* #auto-reconfiguration when error found */
uint8_t fpga_load(void);
#endif /* __FPGA_CONF_H */
Все будет только лучше, в крайнем случае - хуже.
Re: Вопросы по С/С++ (СИ)
а если он включен только в один модуль ?coredumped писал(а):Это, если хидер включен в несколько модулей программы.
если мой проэкт имеет только один модуль, ну окромя главного(main), то тогда можна прямо в хидере описывать полностью ф-ции ?
Tell Me The Truth
Re: Вопросы по С/С++ (СИ)
Можно. Но не стоит так делать - кто знает, что Вы захотите с этими файлами сделать потом... Вообще обычно модули пишут в частности и для того, чтобы использовать код повторно.то тогда можна прямо в хидере описывать полностью ф-ции ?
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Re: Вопросы по С/С++ (СИ)
можно, только если потом включить этот хидер более чем в один с-файл, то получите ошибку о множественом определении функций.то тогда можна прямо в хидере описывать полностью ф-ции ?
- Реклама
- vitalik_1984
- Поставщик валерьянки для Кота
- Сообщения: 2482
- Зарегистрирован: Пт авг 27, 2010 05:57:06
- Откуда: Тюмень
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Это все правильно только чувак задал вопрос зачем они вообще нужны эти модули.coredumped писал(а):Еще оди совет: в хидерах используйте условное объявление типа #ifndef _MODULE_H_ #define _MODULE_H_ ... содержимое хидера ... #endif
Вот ответ
Так сказать для уменьшения времени разработки и тестирования программ. То есть если какая то полезная функция будет написана внутри основного файла будет очень трудно вынести данный код из общей массы. А так легко использовать модуль, который создан для выполнения одной конкретной задачи.YS писал(а):Вообще обычно модули пишут в частности и для того, чтобы использовать код повторно.
Так же создание отдельных файлов позволяет компилировать их отдельно, что так же позволяет сократить время разработки больших проектов. Не прибегая к полной компиляции.
Это было по первому вопросу вот еще в Вики статья
А по второму вопросу немного другая тема
Вот статья
Re: Вопросы по С/С++ (СИ)
Здравствуйте коты, разбираюсь с подключением AVR по юсб, нашел отличный проект, но теперь не могу разобраться с программой на стороне компа, в проекте есть Dll библиотека и пользовательская программа в качестве примера, но они на Delphi, а я пишу на с++ и дельфи вообще не знаю. В проекте упоминается, что данную Dll можно использовать и для с++, подскажите пожалуйста как это делается.
Вот ссылка проекта http://www.gaw.ru/html.cgi/txt/app/micr ... AVR309.htm, там же в конце все файлы.
Вот ссылка проекта http://www.gaw.ru/html.cgi/txt/app/micr ... AVR309.htm, там же в конце все файлы.
Re: Вопросы по С/С++ (СИ)
Если смотрите на программную реализацию USB на AVR-ках, то лучше используйте вот эту реализацию.
http://www.obdev.at/products/vusb/index.html
http://www.obdev.at/products/vusb/index.html
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Re: Вопросы по С/С++ (СИ)
Спасибо, но тот, про который я говорю считаю лучшим, потому что там реализована сразу куча функций, не переделывая прошивки я могу делать на одном микроконтроллере конечное устройство и, самый главный плюс, здесь есть примеры всех этапов программирования от железячки до конечного пользователя. Просто я сейчас делаю курсовую, мне нужно разработать драйвер, драйвер я худо-бедно разобрал полностью, а вот dllку к нему освоить не получается никак, повторюсь в дельфи я полный 0.
- urry
- Сверлит текстолит когтями
- Сообщения: 1262
- Зарегистрирован: Пн дек 08, 2008 10:58:48
- Откуда: Винница
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
http://forum.sources.ru/index.php?showtopic=248068
здесь находится h файл для загрузки этой длл.
Но на месте препода я бы это не принял - тема умерла лет так 10 назад. Ну скажем, утратила актуальность
Когда мега работает с юсб, она больше практически ни на что не отвлекается - да и делает это достаточно криво. Сейчас полно дешевых мк с аппаратным блоком юсб.
здесь находится h файл для загрузки этой длл.
Но на месте препода я бы это не принял - тема умерла лет так 10 назад. Ну скажем, утратила актуальность
Когда мега работает с юсб, она больше практически ни на что не отвлекается - да и делает это достаточно криво. Сейчас полно дешевых мк с аппаратным блоком юсб.
Re: Вопросы по С/С++ (СИ)
Большое спасибо! Я с вами не спорю, я все собираюсь начать осваивать stm32,там и юсб и сами они посовременнее, но постоянно что-то отвлекает. На счет принял бы или нет препод, то почему нет, ведь задача стоит научиться писать драйверы, а как работает все что выше или ниже его - без разницы, это уже просто моя личная любознательность. Просто Вы не представляете в каком отсталом месте я учусь и изначально мне давали задание написать драйвер консоли для дос на ассемблере, я подумал что если уж тратить время, то на что-то хоть немного полезное и интересное. Если Вас не затруднит, можно примерчик вызова любой функции из этой библиотеки, а то везде натыкаюсь на примеры с использованием lib? И еще вопрос: по ссылке что вы дали речь идет о старой и новой версии данной dll, файл .h там как я понял к старой, а dll у меня новая, нужно мне изменять файл .h или так работать тоже будет? Или я вообще что-то не так понял?
Re: Вопросы по С/С++ (СИ)
Здравствуйте, почему у меня не получается сделать обращение через точку к структуре
Через указатель работает всё
Делаю вот так вот
Rомпилятор(IAR) ругается
Error[Pe040]: expected an identifier C:\STM32\W5100 v12(trap list)\main.c 114
Error[Pe144]: a value of type "int" cannot be used to initialize an entity of type "List_IP_PORT" C:\STM32\W5100 v12(trap list)\main.c 114
Пытаюсь разобраться в чём отличия обращения к элементам структуры через точку или стрелочку. Пока только одна мысль что через стрелочку можно структуру наложить на массив а через точку нет.
Код: Выделить всё
typedef struct List_IP_PORT1 {
unsigned char n;
unsigned char IP[2][4];
unsigned int port[2];
} List_IP_PORT;
Код: Выделить всё
List=(List_IP_PORT *)srt_buf;
List->n=number;
List->IP[0][0]=ip1[0];
List->IP[0][1]=ip1[1];
List->IP[0][2]=ip1[2];
List->IP[0][3]=ip1[3];
List->IP[1][0]=ip2[0];
List->IP[1][1]=ip2[1];
List->IP[1][2]=ip2[2];
List->IP[1][3]=ip2[3];
List->port[0]=port1;
List->port[1]=port2;
Код: Выделить всё
List_IP_PORT.n=24;Error[Pe040]: expected an identifier C:\STM32\W5100 v12(trap list)\main.c 114
Error[Pe144]: a value of type "int" cannot be used to initialize an entity of type "List_IP_PORT" C:\STM32\W5100 v12(trap list)\main.c 114
Пытаюсь разобраться в чём отличия обращения к элементам структуры через точку или стрелочку. Пока только одна мысль что через стрелочку можно структуру наложить на массив а через точку нет.
Re: Вопросы по С/С++ (СИ)
List_IP_PORT - это тип. Объявите переменную вашего типа и обращайтесь через точку:
List_IP_PORT x;
x.n = 5;
Стрелочкой
работают с указателями.
List_IP_PORT x;
x.n = 5;
Стрелочкой
Re: Вопросы по С/С++ (СИ)
Код: Выделить всё
List=(List_IP_PORT *)srt_buf;Re: Вопросы по С/С++ (СИ)
В Вашем случае List_IP_PORT это тип, определенный через typedef. Соответственно, ему ничего нельзя присвоить.Делаю вот так вот
Как сказали выше, надо объявить переменную этого типа и использовать ее.
Код: Выделить всё
List_IP_PORT my_list;
...
my_list.n=24;
...
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Re: Вопросы по С/С++ (СИ)
Вечер добрый!
Помогите пожалуйста справиться с 74HC595. Написал код для проверки, но он не пашет. Подскажите пожалуйста, где ошибка?
Пардон 
Код рабочий, я просто не соединил в протеусе пин OE на землю. Щас наткнулся только на статью, где такое действие описано...
Помогите пожалуйста справиться с 74HC595. Написал код для проверки, но он не пашет. Подскажите пожалуйста, где ошибка?
Код: Выделить всё
if (b1 == 0) {
PORTB.2 = 0x00; //ST
PORTB.0 = 0x00; //SH
PORTB.3 = 0x00; //MR
delay_us(2);
PORTB.3 = 0x01; //MR
for ( x1=0;x1<8;x1++) {
PORTB.1 = AA1[x1]; // char AA1[8] = {0,0,0,1,0,0,0,0};
PORTB.0 = 0x01; //SH
delay_us(2);
PORTB.0 = 0x00; //SH
}
b1 = 1;
PORTB.2 = 0x01; //ST
delay_us(2);
PORTB.2 = 0x00; //ST
}
else {PORTB.3 = 0x00;} //MR
Код рабочий, я просто не соединил в протеусе пин OE на землю. Щас наткнулся только на статью, где такое действие описано...
Re: Вопросы по С/С++ (СИ)
Скажу честно - мне лень анализировать, где конкретно ошибка.
Давайте я покажу, как это работает у меня...

Спойлер
Код: Выделить всё
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#define HC_PORT PORTD
#define HC_DDR DDRD
#define HC_ST (1<<PD6)
#define HC_SH (1<<PD7)
#define HC_DS (1<<PD5)
void HC_InitLines(void)
{
HC_DDR|=HC_DS | HC_ST | HC_SH;
HC_PORT&=~(HC_DS | HC_ST | HC_SH);
}
void HC_ShiftByte(uint8_t b)
{
uint8_t msk;
HC_PORT&=~HC_ST;
for (msk=0x80; msk; msk=msk >> 1)
{
HC_PORT&=~HC_SH;
if (b & msk)
{
HC_PORT|=HC_DS;
}
else
{
HC_PORT&=~HC_DS;
}
HC_PORT|=HC_SH;
}
HC_PORT|=HC_ST;
}
void main(void)
{
HC_InitLines();
while (1)
{
HC_ShiftByte(0x55);
_delay_ms(500);
HC_ShiftByte(0xAA);
_delay_ms(500);
}
}
Вообще, начинать изучение любой микросхемы принято с официальной документации.Щас наткнулся только на статью, где такое действие описано...
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Re: Вопросы по С/С++ (СИ)
Был бы мой английский столь совершенен, чтоб разобрать без бутылки что там написано...
Re: Вопросы по С/С++ (СИ)
Благодарю за помощь теперь стало понятнее.
И ещё не большой вопросик появился если надо передать в функцию много параметров штук 10 как это сделать правильно ?
Причём из этих 10 штуки 2-3 это массивы. Если всё в лоб то она большая сильно становится.
По пробовал эти все параметры запихать в структуру и в функцию только структуру передавать. Но всё равно перед функцией
все эти данные объявить. Хотя мне так больше нравится.
А как быть с таким вот случаем
если содержимое массива community меньше 20 к примеру 10 занимается остальное нули. как сделать что бы вместо нулей была переменная n ? думал сделать вот такое но адрес community почему-то 0.
В данном примере это не сильно важно но вот в другой структуре это критично. Но пока всё работает стабильно если что отвалится буду знать куда копать.(Я так понял что отвалится она может при смене компилятора или если в настройках выравнивания структуры похимичить ?)BorisSPB писал(а):С приведением типов указателей надо быть осторожным
И ещё не большой вопросик появился если надо передать в функцию много параметров штук 10 как это сделать правильно ?
Причём из этих 10 штуки 2-3 это массивы. Если всё в лоб то она большая сильно становится.
По пробовал эти все параметры запихать в структуру и в функцию только структуру передавать. Но всё равно перед функцией
все эти данные объявить. Хотя мне так больше нравится.
А как быть с таким вот случаем
Код: Выделить всё
typedef struct Setting {
u8_t community[20];
u8_t n;
} Setting;Код: Выделить всё
typedef struct Setting {
u8_t *community;
u8_t n;
} Setting;- coredumped
- Опытный кот
- Сообщения: 838
- Зарегистрирован: Вт апр 12, 2011 18:38:19
- Откуда: с Земли
Re: Вопросы по С/С++ (СИ)
Если размер массива меняется, то логично использовать указатель, как Вы написали, однако указателю нужно присвоить значение - адрес массива. Те сначала нужно выделить память под массив, а потом присвоить адрес этой памяти массиву. Механизмы выделения-освобождения памяти отличаются от операционной системы, под которую пишется программа. Вот пример под Linux с Вашей структурой
Таким образом мы имеем дело с динамически выделяемой памятью или "динамической памятью" (еще используется термин "куча").
Для МК тоже есть реализации упрощенного управления динамической памятью, однако в отличии от "взрослых" ОС память может выделяться из заранее отведенной области и только непрерывным блоком. Обсуждение механизмов управления динамической памятью заслуживает целой книги.
Можете погуглить словам malloc, heap.
PS: если Вы имеете дело с маленьким МК и памяти хватает, проще выделить статический массив с запасом, чем возиться с перераспределением памяти. Тут делема: производительность - расход памяти. Я советую использовать танцы с динамическим распределением, если памяти не хватает (в случае МК, естественно). Есть много методов оптимизации использования памяти, но все они приводят к снижению скорости выполнения программы.
Код: Выделить всё
typedef struct Setting {
u8_t *community;
u8_t n;
} Setting;
Settings.community = malloc(100); // Выделяем 100 байт
// ...........
free(Settings.community); // Освобождаем ранее выделенную память
Таким образом мы имеем дело с динамически выделяемой памятью или "динамической памятью" (еще используется термин "куча").
Для МК тоже есть реализации упрощенного управления динамической памятью, однако в отличии от "взрослых" ОС память может выделяться из заранее отведенной области и только непрерывным блоком. Обсуждение механизмов управления динамической памятью заслуживает целой книги.
Можете погуглить словам malloc, heap.
PS: если Вы имеете дело с маленьким МК и памяти хватает, проще выделить статический массив с запасом, чем возиться с перераспределением памяти. Тут делема: производительность - расход памяти. Я советую использовать танцы с динамическим распределением, если памяти не хватает (в случае МК, естественно). Есть много методов оптимизации использования памяти, но все они приводят к снижению скорости выполнения программы.
Все будет только лучше, в крайнем случае - хуже.


