Страница 14 из 386
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн фев 07, 2011 07:21:43
lix
Кислый писал(а):
цункции друг друга видят, но не компилится. ссылается на .. да вот
$ 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
функции не определяются в хидерах. они там только описываются. в хидерах не должно быть тел функций.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн фев 07, 2011 07:42:13
Qwq
_AHTOXA_ писал(а):Кислый писал(а):задефайнь RUN_FLAG просто на 7.
Поправочка: на 6.
Ибо 0b01000000 == 1<<6.
не на 7 низя. Я с помощью RUN_FLAG лишние биты с Flags обрезаю...
я просто не правильно понимал конструкцию 1<<RUN_FLAG я думал что это значит установить конкретный бит, а не подвигать единичку RUN_FLAG раз.
СПАСИБО!
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн фев 07, 2011 08:03:17
ARV
avreal писал(а):ARV писал(а):разве что при использовании расширений стандарта (например, GCC вполне позволяет делать локальные массивы с вычисляемым по ходу пьесы размером).
VLA - Variable-Length Array - это не расширение GCC, а стандарт
C99, долгих лет ему жизни.
И в локальных переменных, и в параметрах
ну, явидимо я невнимательно прочел доку... действительно, сказано, что это фича C99, а расширением GCC является в режиме C89...
спасибо, что поправили.
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн фев 07, 2011 08:34:07
Кислый
Всем спасибо все молодцы !!
Видимо мне надо ложиться раньше, и постить только на свежую голову
хех..
Код: Выделить всё
error: variable-sized object may not be initialized
Re: Вопросы по С/С++ (СИ)
Добавлено: Пн фев 07, 2011 20:33:11
levaclaus
а мне кто поможет?

Re: Вопросы по С/С++ (СИ)
Добавлено: Вт фев 08, 2011 00:07:46
demonchik
всем МЯУ!!! хлопцы, я чего то не могу понять. как то забил раньше, а сейчас решил разобраться. Как же правильно инициализировать структуры? не понятно именно со строками.
Код: Выделить всё
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)
{
};
}
вот именно
не канает.
а второй раз писать
Код: Выделить всё
struct MY_TAB table[1]={"sinhrofazotron","100",12};
- не выход из ситуации и не катит че-то.
помогите пожалуйста.
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт фев 08, 2011 00:12:45
demonchik
просто инициализировать сразу все структуры в массиве можно.... но а вдруг захочу менять в программе содержимое строк? вот и лажа. хочется разобраться. спасибо
да, и еще: CVAVR говорит что индексы массивов вне диапазона
Код: Выделить всё
table[2].data=12; // я
table[3].data=35; // учуся так
и этого не пойму
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт фев 08, 2011 12:51:59
ARV
в Си нельзя оператором присваивания копировать содержимое строк, для этого есть функции
memcpy,
strcpy и ряд других.
Код: Выделить всё
strcpy(table[5].a,"kosyak"); // вот так можно задать новое значение строки
Re: Вопросы по С/С++ (СИ)
Добавлено: Вт фев 08, 2011 23:59:00
asteroid7
2
demonchik , так и не догнал вопроса. Как это именять константы "
flash struct MY_TAB" по ходу программы?
Для структур рекомендую использовать typedef. Снимает кучу проблем.
Код: Выделить всё
//объявили тип переменной, не саму переменную, а только её тип MY_TAB
typedef struct
{
unsigned char a[30];
unsigned char b[30];
unsigned int data;
} MY_TAB;
Теперь можно объявить переменную 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[] = {
{"...", "...", ...},
{"...", "...", ...},
...
};
Re: Вопросы по С/С++ (СИ)
Добавлено: Ср фев 09, 2011 09:57:09
demonchik
ого... вы открыли мне глаза! спасибо большое!

Re: Вопросы по С/С++ (СИ)
Добавлено: Чт фев 10, 2011 22:25:19
truebest
Дорогие коты подскажите вчем проблема...фигня какаято получается...
Пишу под 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
Re: Вопросы по С/С++ (СИ)
Добавлено: Пт фев 11, 2011 08:38:38
ARV
truebest писал(а):проблема в том что вывод DATABUF %s",&FlashDataBuf[0]); меня не радует, выплевывается почему-то только 16байт а не все 256...пробовал по разному никак
еще бы оно вас радовало... вы не забывайте, что не смотря на то, что в Си СТРОКА - ЭТО МАССИВ БАЙТОВ, обратное утверждение неверно: МАССИВ БАЙТОВ - ЭТО
НЕ СТРОКА!!!! поэтому выводить массив, пользуясь строковыми средствами - НЕВЕРНО! кстати, в вашей строке я красным выделил ЛИШНЕЕ.
вам поможет простейшее средство, что-то типа такого:
Код: Выделить всё
char *ptr = FlashDataBuf;
for(int i=0; i<=255; i++) printf("%c",*ptr++);
неопределенный результат
Добавлено: Пт фев 11, 2011 19:51:32
md5sum
Добрый день.
Вот на такой кусочек:
Код: Выделить всё
void timer_process() {
static char gps_led=0;
gps_led=(++gps_led) % 10;
if (gps_led<3) {GPS_NONE;} else {GPS_LED_FIX;}
......
}
GCC говорит
Код: Выделить всё
../main.c:55: предупреждение: операция над ‘gps_led’ может дать неопределенный результат
Но, что-то мне не приходит в голову: При КАКИХ условиях и КАК может быть неопределенный результат?
Re: неопределенный результат
Добавлено: Пт фев 11, 2011 21:39:41
ellioh
Я бы написал по-простому:
или уже
Неопределённого результата быть, правда, всё равно, сдаётся мне, не должно, но сам код с операцией инкремента довольно странный, поскольку (++gps_led) эквивалентно (gps_led+=1). Не стоит в правой части модифицировать то, что и так будет затёрто при присваивании.
Re: неопределенный результат
Добавлено: Пт фев 11, 2011 21:55:45
md5sum
ellioh писал(а): (++gps_led) эквивалентно (gps_led+=1). Не стоит в правой части модифицировать то, что и так будет затёрто при присваивании.
Точно!!! Мне-ж нафиг не нужно gps_led+=1 в правой части, а интересует только остаток от деления числа на 1 больше текущего...
Надо отучать себя от конструкций a++, b--, --a, --b и писать конкретно: a=a+1; тогда и таких ляпов гораздо меньше будет...
Спасибо!
Re: неопределенный результат
Добавлено: Пт фев 11, 2011 22:08:03
ellioh
md5sum писал(а):Надо отучать себя от конструкций a++, b--, --a, --b и писать конкретно: a=a+1
Да ну, не надо. Половина прелести C уйдёт. Без конструкций вида a[i++] и *++p жизнь тосклива.

Просто один раз запомнить: "++" != "+1"

Re: неопределенный результат
Добавлено: Пт фев 11, 2011 22:09:39
Goodefine
md5sum писал(а):
... При КАКИХ условиях и КАК может быть неопределенный результат?
Скорее всего, это связано с особенностями внутренней реализации указанных операций компилятором...
Попробуйте так:
Код: Выделить всё
...
static char gps_led=0;
++gps_led;
gps_led%=10;
if (gps_led<3)....
А, вообще, можно было счетчик до 9 и попроще реализовать... Без взятия остатка...
Re: неопределенный результат
Добавлено: Сб фев 12, 2011 00:21:09
avreal
md5sum писал(а):
При КАКИХ условиях и КАК может быть неопределенный результат?
В языке С есть понятие "точка следования" (sequence point).
Все записи должны быть завершены в этих точках, но порядок записей и прочих побочных эффектов не определён. Т.е. отдаётся на откуп оптимизатору - как ему вздумается, так и может делать.
Точка с запятой - одна из "точек следования"
Итого, например, такое:
компилятор может реализовать так, заводя временные регистровые переменные:
Код: Выделить всё
temp1 = n
temp1 = temp1 + 1
n = temp1
temp1 = temp1 + 2
k = temp1
а может так:
Код: Выделить всё
temp1 = n
temp1 = temp1 + 1
temp2 = temp1 + 2
k = temp2
n = temp1
Тут от порядка выполнения последних двух операций результат не зависит.
Берём
Код: Выделить всё
temp1 = gps_led
temp1 = temp1 + 1
temp2 = temp1 % 10
gps_led = temp2
gps_led = temp1 - он имеет право записать temp1 после temp2! между точками следования порядок не определён
Вот он тут и предупреждает, что в зависимости от настроения оптимизатора порядок записи может сгулять, не в этой версии компилятора, так в следующей. А от этого изменится результат. Но он не виноват.
Классика жанра - вопрос "сколько будет"
http://lurkmore.ru/%2B%2Bi_%2B_%2B%2Bi
p.s. А в данном случае (как уже намекнули) писать надо было вообще такой код
(скобки вокруг под-IF-нутого выражения - тоже точка следования, тут всё честно)
Re: Вопросы по С/С++ (СИ)
Добавлено: Сб фев 12, 2011 01:50:50
ellioh
Хо-хо, век живи -- век учись. Как-то термин sequence point прошёл мимо меня.
http://en.wikipedia.org/wiki/Sequence_point
Действительно, никто не гарантирует, что к моменту выполнения собственно присваивания все последствия вычисления выражения в левой и правой частях присваивания уже наступят.
Классический-то пример некорректности из Кернигана и Ричи (
http://lib.ru/CTOTOR/kernigan.txt, 2.12. Старшинство и порядок вычисления) проще:
Но в примере понятно, тут никто не запрещает вычислить левое I ни до, ни после того, как выполнится I++
В любом случае, так писать просто не надо, достаточно один раз это запомнить.

Re: Вопросы по С/С++ (СИ)
Добавлено: Сб фев 12, 2011 11:31:04
ARV
ellioh писал(а):В любом случае, так писать просто не надо, достаточно один раз это запомнить.

да, правило простое: переменная с оператором ++ или -- должна находиться в
единственном экзкмпляре или только левее знака равенства, или только правее, но никак не с обоих сторон одновременно. подобных правил немного, но их соблюдение автоматически позволяет делать меньше трудновылавливаемых ошибок
