функции не определяются в хидерах. они там только описываются. в хидерах не должно быть тел функций.Кислый писал(а):
цункции друг друга видят, но не компилится. ссылается на .. да вот
$ 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
Вопросы по С/С++ (СИ)
- Реклама
- Сообщения: 87
- Зарегистрирован: Пт ноя 02, 2007 18:18:26
не на 7 низя. Я с помощью RUN_FLAG лишние биты с Flags обрезаю..._AHTOXA_ писал(а):Поправочка: на 6.Кислый писал(а):задефайнь RUN_FLAG просто на 7.
Ибо 0b01000000 == 1<<6.
я просто не правильно понимал конструкцию 1<<RUN_FLAG я думал что это значит установить конкретный бит, а не подвигать единичку RUN_FLAG раз.
СПАСИБО!
ну, явидимо я невнимательно прочел доку... действительно, сказано, что это фича C99, а расширением GCC является в режиме C89...avreal писал(а):VLA - Variable-Length Array - это не расширение GCC, а стандарт C99, долгих лет ему жизни.ARV писал(а):разве что при использовании расширений стандарта (например, GCC вполне позволяет делать локальные массивы с вычисляемым по ходу пьесы размером).
И в локальных переменных, и в параметрах
спасибо, что поправили.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Всем спасибо все молодцы !!
Видимо мне надо ложиться раньше, и постить только на свежую голову
хех..
Видимо мне надо ложиться раньше, и постить только на свежую голову
хех..
Код: Выделить всё
error: variable-sized object may not be initializedRETI ;рети-рети интеррапт, через шины данных тракт, через память, через порт, возвращайся в главный код
@hobbyelectronics
@hobbyelectronics
- Реклама
всем МЯУ!!! хлопцы, я чего то не могу понять. как то забил раньше, а сейчас решил разобраться. Как же правильно инициализировать структуры? не понятно именно со строками.
вот именно не канает.
а второй раз писать - не выход из ситуации и не катит че-то.
помогите пожалуйста.
Код: Выделить всё
flash struct MY_TAB
{
unsigned char a[30];
unsigned char b[30];
unsigned int data;
};
void main(void)
{
struct MY_TAB table[1]={"sinhrofazotron","100",12};
int a = table[1].data; // это
table[2].data=12; // я
table[3].data=35; // учуся так
table[5].a="kosyak"; // а эта фигня не канает, но надо
while (1)
{
};
}
Код: Выделить всё
table[5].a="kosyak"; а второй раз писать
Код: Выделить всё
struct MY_TAB table[1]={"sinhrofazotron","100",12};помогите пожалуйста.
радиоэлектроника - жизнь моя...
просто инициализировать сразу все структуры в массиве можно.... но а вдруг захочу менять в программе содержимое строк? вот и лажа. хочется разобраться. спасибо
да, и еще: CVAVR говорит что индексы массивов вне диапазона
и этого не пойму
да, и еще: CVAVR говорит что индексы массивов вне диапазона
Код: Выделить всё
table[2].data=12; // я
table[3].data=35; // учуся такрадиоэлектроника - жизнь моя...
в Си нельзя оператором присваивания копировать содержимое строк, для этого есть функции memcpy, strcpy и ряд других.
Код: Выделить всё
strcpy(table[5].a,"kosyak"); // вот так можно задать новое значение строкиесли рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 703
- Зарегистрирован: Вс янв 18, 2009 21:12:49
2demonchik , так и не догнал вопроса. Как это именять константы "flash struct MY_TAB" по ходу программы?
Для структур рекомендую использовать typedef. Снимает кучу проблем.
Теперь можно объявить переменную MY_TAB типа где угодно и инициализировать её:
Для структур рекомендую использовать typedef. Снимает кучу проблем.
Код: Выделить всё
//объявили тип переменной, не саму переменную, а только её тип MY_TAB
typedef struct
{
unsigned char a[30];
unsigned char b[30];
unsigned int data;
} MY_TAB;
Код: Выделить всё
//FLASH:
flash MY_TAB MY_TAB_flash = {
"12345678901234567890123456789",
"12345678901234567890123456789",
0xFFFF,
};
//RAM:
MY_TAB MY_TAB_ram = { "...", "...", ... };
//EEPROM: (если компилятор поддерживает генерацию eeprom файла)
eeprom MY_TAB MY_TAB_eeprom = { "...", "...", ... };
//массив во FLASH
flash MY_TAB MY_TAB_flash_array[] = {
{"...", "...", ...},
{"...", "...", ...},
...
};
ого... вы открыли мне глаза! спасибо большое! 
радиоэлектроника - жизнь моя...
Дорогие коты подскажите вчем проблема...фигня какаято получается...
Пишу под LPC1768 но куски своих програм тестирую на виндовых компиляторах.... (для работы с SPI памятью)
Память устроена как 64 сектора в каждом секторе 1024 стр, и в каждой странице 256 байт...
В контроллере я создаю массив на 256 байт, и по 16 байт я его заполняю, постепенно... когда заполнится я его буду писать на флеш, чистить и заного заполнять
проблема в том что вывод DATABUF %s",&FlashDataBuf[0]); меня не радует, выплевывается почему-то только 16байт а не все 256...пробовал по разному никак
баян вот такой
Пишу под 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;
unsigned char FlashDataBuf[256];
unsigned char FlashPrepBuf[16];
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;
RTCTime local_time;
uint32_t GetFFlashADR(void)
{
uint32_t BAddr=0;
uint32_t TimeInSec=0;
TimeInSec=((uint32_t)((local_time.RTC_Mday-1)* 86400 + local_time.RTC_Hour * 3600 + local_time.RTC_Min * 60 + local_time.RTC_Sec)/5+16);
BAddr=TimeInSec*16;
return BAddr;
}
void FBTransfer(uint32_t FAddr,uint8_t* buff)
{
uint8_t num;
uint8_t i;
num=FAddr & 0xFF;
for (i=0; i<16;i++)
{
printf("i=%d num=%d\r\n",i, num);
FlashDataBuf[i+num] = *buff;
buff++;
if ((i+num)==255) { printf("DATABUF %s",&FlashDataBuf[0]); break; }
}
}
int main(void)
{
int i,Z;
local_time.RTC_Sec=0;
local_time.RTC_Min=0;
local_time.RTC_Mday=1;
for(Z=0; Z<15; Z++)
{
FlashPrepBuf[Z]=Z+45;
}
for (i=0; i<61; i=i+5)
{
local_time.RTC_Sec=i;
FBTransfer(GetFFlashADR(),&FlashPrepBuf[0]);
if (i==60) {local_time.RTC_Sec=0; local_time.RTC_Min++; i=0;}
if(local_time.RTC_Min==2){break;}
printf("0x%X %d \r\n",GetFFlashADR(),i);
}
FBTransfer(GetFFlashADR(),&FlashPrepBuf[0]);
return 0;
}
Код: Выделить всё
0x1E0 10
i=0 num=240
i=1 num=240
i=2 num=240
i=3 num=240
i=4 num=240
i=5 num=240
i=6 num=240
i=7 num=240
i=8 num=240
i=9 num=240
i=10 num=240
i=11 num=240
i=12 num=240
i=13 num=240
i=14 num=240
i=15 num=240
DATABUF -./0123456789:;0x1F0 15 еще бы оно вас радовало... вы не забывайте, что не смотря на то, что в Си СТРОКА - ЭТО МАССИВ БАЙТОВ, обратное утверждение неверно: МАССИВ БАЙТОВ - ЭТО НЕ СТРОКА!!!! поэтому выводить массив, пользуясь строковыми средствами - НЕВЕРНО! кстати, в вашей строке я красным выделил ЛИШНЕЕ.truebest писал(а):проблема в том что вывод DATABUF %s",&FlashDataBuf[0]); меня не радует, выплевывается почему-то только 16байт а не все 256...пробовал по разному никак
вам поможет простейшее средство, что-то типа такого:
Код: Выделить всё
char *ptr = FlashDataBuf;
for(int i=0; i<=255; i++) printf("%c",*ptr++);если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Добрый день.
Вот на такой кусочек:
GCC говоритНо, что-то мне не приходит в голову: При КАКИХ условиях и КАК может быть неопределенный результат?
Вот на такой кусочек:
Код: Выделить всё
void timer_process() {
static char gps_led=0;
gps_led=(++gps_led) % 10;
if (gps_led<3) {GPS_NONE;} else {GPS_LED_FIX;}
......
}
Код: Выделить всё
../main.c:55: предупреждение: операция над ‘gps_led’ может дать неопределенный результат— Не говорите мне что делать и я не скажу куда Вам идти...
- Сообщения: 100
- Зарегистрирован: Сб янв 22, 2011 16:57:45
Я бы написал по-простому:md5sum писал(а):Код: Выделить всё
gps_led=(++gps_led) % 10;
Код: Выделить всё
gps_led=(gps_led+1) % 10;Код: Выделить всё
gps_led++; gps_led %= 10;Клоподавер упрыгхт
Точно!!! Мне-ж нафиг не нужно gps_led+=1 в правой части, а интересует только остаток от деления числа на 1 больше текущего...ellioh писал(а): (++gps_led) эквивалентно (gps_led+=1). Не стоит в правой части модифицировать то, что и так будет затёрто при присваивании.
Надо отучать себя от конструкций a++, b--, --a, --b и писать конкретно: a=a+1; тогда и таких ляпов гораздо меньше будет...
Спасибо!
— Не говорите мне что делать и я не скажу куда Вам идти...
- Сообщения: 100
- Зарегистрирован: Сб янв 22, 2011 16:57:45
Да ну, не надо. Половина прелести C уйдёт. Без конструкций вида a[i++] и *++p жизнь тосклива.md5sum писал(а):Надо отучать себя от конструкций a++, b--, --a, --b и писать конкретно: a=a+1
Просто один раз запомнить: "++" != "+1"
Клоподавер упрыгхт
Скорее всего, это связано с особенностями внутренней реализации указанных операций компилятором...md5sum писал(а): ... При КАКИХ условиях и КАК может быть неопределенный результат?
Попробуйте так:
Код: Выделить всё
...
static char gps_led=0;
++gps_led;
gps_led%=10;
if (gps_led<3)....
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
В языке С есть понятие "точка следования" (sequence point).md5sum писал(а):При КАКИХ условиях и КАК может быть неопределенный результат?Код: Выделить всё
gps_led=(++gps_led) % 10;
Все записи должны быть завершены в этих точках, но порядок записей и прочих побочных эффектов не определён. Т.е. отдаётся на откуп оптимизатору - как ему вздумается, так и может делать.
Точка с запятой - одна из "точек следования"
Итого, например, такое:
Код: Выделить всё
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! между точками следования порядок не определёнКлассика жанра - вопрос "сколько будет"
Код: Выделить всё
i = 5;
i = ++i + ++i;p.s. А в данном случае (как уже намекнули) писать надо было вообще такой код
Код: Выделить всё
if( ++gps_led > 9) gps_led = 0;Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
- Сообщения: 100
- Зарегистрирован: Сб янв 22, 2011 16:57:45
Хо-хо, век живи -- век учись. Как-то термин sequence point прошёл мимо меня. http://en.wikipedia.org/wiki/Sequence_point
Действительно, никто не гарантирует, что к моменту выполнения собственно присваивания все последствия вычисления выражения в левой и правой частях присваивания уже наступят.
Классический-то пример некорректности из Кернигана и Ричи (http://lib.ru/CTOTOR/kernigan.txt, 2.12. Старшинство и порядок вычисления) проще:
Но в примере понятно, тут никто не запрещает вычислить левое I ни до, ни после того, как выполнится I++
В любом случае, так писать просто не надо, достаточно один раз это запомнить.
Действительно, никто не гарантирует, что к моменту выполнения собственно присваивания все последствия вычисления выражения в левой и правой частях присваивания уже наступят.
Классический-то пример некорректности из Кернигана и Ричи (http://lib.ru/CTOTOR/kernigan.txt, 2.12. Старшинство и порядок вычисления) проще:
Код: Выделить всё
A[I] = I++;В любом случае, так писать просто не надо, достаточно один раз это запомнить.
Клоподавер упрыгхт
да, правило простое: переменная с оператором ++ или -- должна находиться в единственном экзкмпляре или только левее знака равенства, или только правее, но никак не с обоих сторон одновременно. подобных правил немного, но их соблюдение автоматически позволяет делать меньше трудновылавливаемых ошибокellioh писал(а):В любом случае, так писать просто не надо, достаточно один раз это запомнить.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!


