цункции друг друга видят, но не компилится. ссылается на .. да вот
$ gcc *.c -o ./mainRRR /tmp/cckzpR0R.o: In function `add': main.c:(.text+0x0): multiple definition of `add' /tmp/cchkwV7r.o:include.c:(.text+0x0): first defined here collect2: ld returned 1 exit status
функции не определяются в хидерах. они там только описываются. в хидерах не должно быть тел функций.
не на 7 низя. Я с помощью RUN_FLAG лишние биты с Flags обрезаю... я просто не правильно понимал конструкцию 1<<RUN_FLAG я думал что это значит установить конкретный бит, а не подвигать единичку RUN_FLAG раз. СПАСИБО!
разве что при использовании расширений стандарта (например, GCC вполне позволяет делать локальные массивы с вычисляемым по ходу пьесы размером).
VLA - Variable-Length Array - это не расширение GCC, а стандарт C99, долгих лет ему жизни. И в локальных переменных, и в параметрах
ну, явидимо я невнимательно прочел доку... действительно, сказано, что это фича C99, а расширением GCC является в режиме C89... спасибо, что поправили.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
всем МЯУ!!! хлопцы, я чего то не могу понять. как то забил раньше, а сейчас решил разобраться. Как же правильно инициализировать структуры? не понятно именно со строками.
просто инициализировать сразу все структуры в массиве можно.... но а вдруг захочу менять в программе содержимое строк? вот и лажа. хочется разобраться. спасибо да, и еще: CVAVR говорит что индексы массивов вне диапазона
2demonchik , так и не догнал вопроса. Как это именять константы "flash struct MY_TAB" по ходу программы?
Для структур рекомендую использовать typedef. Снимает кучу проблем.
Код:
//объявили тип переменной, не саму переменную, а только её тип MY_TAB typedef struct { unsigned char a[30]; unsigned char b[30]; unsigned int data; } MY_TAB;
Теперь можно объявить переменную MY_TAB типа где угодно и инициализировать её:
Пишу под LPC1768 но куски своих програм тестирую на виндовых компиляторах.... (для работы с SPI памятью) Память устроена как 64 сектора в каждом секторе 1024 стр, и в каждой странице 256 байт...
В контроллере я создаю массив на 256 байт, и по 16 байт я его заполняю, постепенно... когда заполнится я его буду писать на флеш, чистить и заного заполнять
проблема в том что вывод DATABUF %s",&FlashDataBuf[0]); меня не радует, выплевывается почему-то только 16байт а не все 256...пробовал по разному никак
баян вот такой
Код:
#include <stdio.h> #include <stdlib.h>
typedef unsigned long uint32_t; typedef unsigned char uint8_t;
typedef struct { uint32_t RTC_Sec; /* Second value - [0,59] */ uint32_t RTC_Min; /* Minute value - [0,59] */ uint32_t RTC_Hour; /* Hour value - [0,23] */ uint32_t RTC_Mday; /* Day of the month value - [1,31] */ uint32_t RTC_Mon; /* Month value - [1,12] */ uint32_t RTC_Year; /* Year value - [0,4095] */ uint32_t RTC_Wday; /* Day of week value - [0,6] */ uint32_t RTC_Yday; /* Day of year value - [1,365] */ } RTCTime;
проблема в том что вывод DATABUF %s",&FlashDataBuf[0]); меня не радует, выплевывается почему-то только 16байт а не все 256...пробовал по разному никак
еще бы оно вас радовало... вы не забывайте, что не смотря на то, что в Си СТРОКА - ЭТО МАССИВ БАЙТОВ, обратное утверждение неверно: МАССИВ БАЙТОВ - ЭТО НЕ СТРОКА!!!! поэтому выводить массив, пользуясь строковыми средствами - НЕВЕРНО! кстати, в вашей строке я красным выделил ЛИШНЕЕ.
вам поможет простейшее средство, что-то типа такого:
Неопределённого результата быть, правда, всё равно, сдаётся мне, не должно, но сам код с операцией инкремента довольно странный, поскольку (++gps_led) эквивалентно (gps_led+=1). Не стоит в правой части модифицировать то, что и так будет затёрто при присваивании.
(++gps_led) эквивалентно (gps_led+=1). Не стоит в правой части модифицировать то, что и так будет затёрто при присваивании.
Точно!!! Мне-ж нафиг не нужно gps_led+=1 в правой части, а интересует только остаток от деления числа на 1 больше текущего... Надо отучать себя от конструкций a++, b--, --a, --b и писать конкретно: a=a+1; тогда и таких ляпов гораздо меньше будет... Спасибо!
_________________ — Не говорите мне что делать и я не скажу куда Вам идти...
При КАКИХ условиях и КАК может быть неопределенный результат?
В языке С есть понятие "точка следования" (sequence point). Все записи должны быть завершены в этих точках, но порядок записей и прочих побочных эффектов не определён. Т.е. отдаётся на откуп оптимизатору - как ему вздумается, так и может делать. Точка с запятой - одна из "точек следования" Итого, например, такое:
Код:
k= ++n + 2;
компилятор может реализовать так, заводя временные регистровые переменные:
Код:
temp1 = n temp1 = temp1 + 1 n = temp1 temp1 = temp1 + 2 k = temp1
а может так:
Код:
temp1 = n temp1 = temp1 + 1 temp2 = temp1 + 2 k = temp2 n = temp1
Тут от порядка выполнения последних двух операций результат не зависит.
Берём
Код:
gps_led=(++gps_led) % 10;
Код:
temp1 = gps_led temp1 = temp1 + 1 temp2 = temp1 % 10 gps_led = temp2 gps_led = temp1 - он имеет право записать temp1 после temp2! между точками следования порядок не определён
Вот он тут и предупреждает, что в зависимости от настроения оптимизатора порядок записи может сгулять, не в этой версии компилятора, так в следующей. А от этого изменится результат. Но он не виноват. Классика жанра - вопрос "сколько будет"
p.s. А в данном случае (как уже намекнули) писать надо было вообще такой код
Код:
if( ++gps_led > 9) gps_led = 0;
(скобки вокруг под-IF-нутого выражения - тоже точка следования, тут всё честно)
_________________ Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Хо-хо, век живи -- век учись. Как-то термин sequence point прошёл мимо меня. http://en.wikipedia.org/wiki/Sequence_point Действительно, никто не гарантирует, что к моменту выполнения собственно присваивания все последствия вычисления выражения в левой и правой частях присваивания уже наступят.
Классический-то пример некорректности из Кернигана и Ричи (http://lib.ru/CTOTOR/kernigan.txt, 2.12. Старшинство и порядок вычисления) проще:
Код:
A[I] = I++;
Но в примере понятно, тут никто не запрещает вычислить левое I ни до, ни после того, как выполнится I++
В любом случае, так писать просто не надо, достаточно один раз это запомнить.
В любом случае, так писать просто не надо, достаточно один раз это запомнить.
да, правило простое: переменная с оператором ++ или -- должна находиться в единственном экзкмпляре или только левее знака равенства, или только правее, но никак не с обоих сторон одновременно. подобных правил немного, но их соблюдение автоматически позволяет делать меньше трудновылавливаемых ошибок
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения