Страница 163 из 386
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 13, 2013 12:36:14
YS
Ввести глобальный флаг.
Код: Выделить всё
play()
{
if (status & TIMER_NOT_READY)
{
.....
.......
сдесь я запускаю Т2 и выпригиваю с данной ф-ции
}
else
{
сюда я возвращаюсь когда Т2 отсчитает определенное время
.....
......
status|=TIMER_NOT_READY;
}
}
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 13, 2013 12:45:22
Desutorakuta
Совершенно верно, с ГоуТу не поможет, только SetJump. Но это ещё более дурной тон.
Хороший тон в этом случа был бы разбить функцию Play в стиле конечного автомата. Ну что то вроде:
Код: Выделить всё
PlayState state = InitPlay();
for(;;){
if(Play(state)==PLEASE_SET_TIMER)SetTimer();
if(TimerInterrupt())PlayInterrupt(state);
}
ReleasePlay(state);
Или в стиле передачи сообщений:
Код: Выделить всё
play(PLAY_INIT);
for(;;){
witch(play(PLAY_START)){
case PLAY_PLEASE_SET_TIMER: SetTimer();
}
if(TimerInterrupt()) play(PLAY_TIME_OUT);
}
play(PLAY_RELEASE);
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 13, 2013 13:06:38
Psych
С помощью флажков можно ваабще кучу функций кода объединить в одну. Делают же наоборот--разбивают на более мелкие части.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 13, 2013 13:20:24
ploop
так шо без GOTO никак ?
а ведь некоторые вопиют что это дурной тон
Я и говорю - как, да ещё как! Моя мысль была "... если хочется влепить goto, значит надо пересмотреть логику". В 99.999% случаев есть более элегантное решение.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 13, 2013 13:40:45
Аlex
Desutorakuta писал(а): Но это ещё более дурной тон.
Разрешите поинтересоваться, откуда такие сведения ?
Я на нём (setjmp) сделал вполне нормально-работающий планировщик (кстати, он как раз и нужен вопрошающему). Просветите, а то вдруг я пишу в стиле говнокода, сам не зная этого ...

Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 13, 2013 15:36:32
Desutorakuta
Ну - если нормально работающий, значит не говнокод. На чём бы человек не писал, какие функции не применял - если программа работает как положено, она написана правильно.
Пример - попробуйте ка в ассемблере обойтись без Jxx инструкций xD. (Аналог if(x)then goto y же!)
Хороший тон в программировании определяется, в общем то, единственным факторами - насколько его легко прочитать другому человеку. Отсюда требование избегать GOTO, как потенциального средства запутывания кода. Отсюда же требование избегать ещё более свободный и менее очевидный setJmp.
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср авг 14, 2013 21:42:42
FreshMan
пытаюсь вникнуть в суть темы......, обясните пожалуйста на простом крестьянском языке чем
GOTO отличается от
setjmp кроме того что последняя сохраняет состояние процесса ?
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср авг 14, 2013 21:49:20
Desutorakuta
Это кардинальное отличие!
Кроме того по GOTO нельзя перейти в соседнюю функцию.
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср авг 14, 2013 22:02:23
FreshMan
а с помощью longjmp и setjmp, если я правильно понимаю, можна выйти хоть из n-го вложения, блока ?
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср авг 14, 2013 22:07:29
Аlex
Выйти никуда с их помощью нельзя. Один (setjmp) устанавливает точку возврата, с сохранением состояние, а второй (longjmp) - восстанавливает сохранённое состояние, вместе со счётчиком команд, по этому и происходит "прыжок" в то-же место, где было сохранено состояние.
ЗЫ: Состояние сохраняется в буфер типа jmp_buf, передаваемое параметром в эти макросы. По этому, таких состояний можно делать множество. Это так, для информации...
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср авг 14, 2013 22:10:20
Desutorakuta
Если мне не отшибло склероз, то переход внутри вложенных блоков одной функции не лимитируется. - По гоуту тоже можно выйти из n-вложенного цикла (По крайней мере на практике обычно работает)
А вот переходы между функциями - этого GOTO не может, так как ломается стек. SetJump же обеспечивает верный переход сохранением стека.
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср авг 14, 2013 22:31:56
Аlex
Вот Вам кодик, для примера
Код: Выделить всё
//********************************************************
#include "SetJmp.h"
jmp_buf j_buf;
//********************************************************
void mfun(void){
while(1){
if(!setjmp(j_buf)){ // Сохраняем точку возврата
return; // и выходим из функции
}
//..................
Nop(); // сюда вернёмся после longjmp
//..................
if(!setjmp(j_buf)){ // Сохраняем точку возврата
return; // и выходим из функции
}
//..................
Nop(); // сюда вернёмся после longjmp
//..................
if(!setjmp(j_buf)){ // Сохраняем точку возврата
return; // и выходим из функции
}
//..................
Nop(); // сюда вернёмся после longjmp
//..................
}
}
//********************************************************
void main (void){
mfun(); // Первый вызов ф-ии, для первого
// сохранения точки прыжка
while(1){
longjmp(j_buf, 1); // Прыгаем в сохранённую точку
Nop(); // Сюда будем возвращаться по return
}
}
//********************************************************
ЗЫ: Кстати, почти готовый планировщик

Осталось добавить ещё функций и буферы
jmp_buf для каждой из них, и вперёд ...
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср авг 14, 2013 23:07:27
shads
Аlex писал(а):Один (setjmp) устанавливает точку возврата, с сохранением состояние, а второй (longjmp) - восстанавливает сохранённое состояние, вместе со счётчиком команд, по этому и происходит "прыжок" в то-же место, где было сохранено состояние.
ВАУ..... это все стандартный Си ?
Или это уже от лукавого.....
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср авг 14, 2013 23:09:14
Аlex
Это делает стандартная библиотека Си - SetJmp. Ссылки выше.
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср авг 14, 2013 23:27:17
Jack_A
Desutorakuta писал(а):
Пример - попробуйте ка в ассемблере обойтись без Jxx инструкций xD. (Аналог if(x)then goto y же!)
Я думаю, если дизассемблировать Си-шную прошивку от самого лютого ненавистниика GOTO, то там этих GOTO, то-бишь JMP, будет до френа.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 27, 2013 05:14:10
pokk
Здравствуйте, что такой макрос делает ? В моём понимании он из принятого буфера выделяет ip адреса по структуре тд но вот
uip_buf[UIP_LLH_LEN] это же всего 1 элемент.
Код: Выделить всё
#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
uip_tcpip_hdr это структура заголовка IP
Спойлер
Код: Выделить всё
/* The TCP and IP headers. */
typedef struct {
/* IP header. */
u8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
u16_t ipchksum;
u16_t srcipaddr[2],
destipaddr[2];
/* TCP header. */
u16_t srcport,
destport;
u8_t seqno[4],
ackno[4],
tcpoffset,
flags,
wnd[2];
u16_t tcpchksum;
u8_t urgp[2];
u8_t optdata[4];
} uip_tcpip_hdr;
uip_buf это приёмный буфер
Дальше это всё используется так (сравнивается принятый IP адрес со своим)
Код: Выделить всё
if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] &&
BUF->srcipaddr[1] == FBUF->srcipaddr[1] &&
BUF->destipaddr[0] == FBUF->destipaddr[0] &&
BUF->destipaddr[1] == FBUF->destipaddr[1] &&
BUF->ipid[0] == FBUF->ipid[0] &&
BUF->ipid[1] == FBUF->ipid[1]) {
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 27, 2013 05:47:05
Kavka
Код: Выделить всё
((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
33333333333333333211111111111111111111
1 - это элемент массива
2 - взятие адреса этого элемента, т.е. получается указатель
3 - приведение типа указателя к указателю на uip_tcpip_hdr
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 27, 2013 06:11:30
pokk
Благодарю за ответ.
3 т.е получается мы как бы массив до элемента UIP_LLH_LEN преобразовали в структуру uip_tcpip_hdr ?
походу это я описал про такое
но тут весь массив преобразовали в структуру.
а что бы частично преобразовать надо было указатель(адрес) взять/преобразовать &uip_buf[UIP_LLH_LEN]
Так?
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 27, 2013 07:08:25
Kavka
Во-первых, не "до", а начиная с элемента в ячейке с номером взятом из UIP_LLH_LEN.
Во-вторых не преобразовывается, а указывается компилятору как работать с конкретным указателем. Расклад в памяти остаётся таким как был.
Берётся адрес в памяти и говориться компилятору, что с данными по этому адресу работать как со структурой. Ничего в памяти не копируется.
При этом порядок полей в структуре просто "раскладывается" на указанную область памяти. За соответствием полей надо следить самому.
Код: Выделить всё
uip_tcpip_hdr
-------------------
| | | | | | | | | |
-------------------------------------------------------
uip_buf| | | | | | |*| | | | | | | | | | | | | | | | | | | | |
-------------------------------------------------------
^
UIP_LLH_LEN
Попадает ли весь массив под структуру? Если количество байт у структуры и у массива совпадают, то да. Но это не обязательно. Например как на схеме выше.
В качестве более простого примера можно взять адрес переменной типа long и попросить компилятор работать с этим адресом как с char[4]. Получите доступ к long-у как к массиву байтов без масок и сдвигов.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт авг 27, 2013 08:59:52
pokk
Код: Выделить всё
Во-первых, не "до", а начиная с элемента в ячейке с номером взятом из UIP_LLH_LEN.
Благодарю а то со своим понимание "ДО" сразу затупил на следующей строчке
Код: Выделить всё
#define FBUF ((uip_tcpip_hdr *)&uip_reassbuf[0])
Во-вторых ...
Я примерно это так и представлял только правильно написал. С чем-то похожим сталкивался когда с переменной float воевал/
В качестве более простого примера можно взять адрес переменной типа long и попросить компилятор работать с этим адресом как с char[4]. Получите доступ к long-у как к массиву байтов без масок и сдвигов.
Это будет так ?
Код: Выделить всё
typedef struct {
char b[3];
} U8long;
U8long *u8 = (U8long*)h;