Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
lix
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 17, 2010 15:32:19
Откуда: Курган

Re: Вопросы по С/С++ (СИ)

Сообщение 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


функции не определяются в хидерах. они там только описываются. в хидерах не должно быть тел функций.
Qwq
Встал на лапы
Сообщения: 87
Зарегистрирован: Пт ноя 02, 2007 18:18:26
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Qwq »

_AHTOXA_ писал(а):
Кислый писал(а):задефайнь RUN_FLAG просто на 7.

Поправочка: на 6.
Ибо 0b01000000 == 1<<6.

не на 7 низя. Я с помощью RUN_FLAG лишние биты с Flags обрезаю...
я просто не правильно понимал конструкцию 1<<RUN_FLAG я думал что это значит установить конкретный бит, а не подвигать единичку RUN_FLAG раз.
СПАСИБО!
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

avreal писал(а):
ARV писал(а):разве что при использовании расширений стандарта (например, GCC вполне позволяет делать локальные массивы с вычисляемым по ходу пьесы размером).
VLA - Variable-Length Array - это не расширение GCC, а стандарт C99, долгих лет ему жизни.
И в локальных переменных, и в параметрах
ну, явидимо я невнимательно прочел доку... действительно, сказано, что это фича C99, а расширением GCC является в режиме C89...
спасибо, что поправили.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Кислый
Поставщик валерьянки для Кота
Сообщения: 2095
Зарегистрирован: Чт апр 08, 2010 18:50:01
Откуда: Краснодар
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Кислый »

Всем спасибо все молодцы !!
Видимо мне надо ложиться раньше, и постить только на свежую голову :roll:

хех..

Код: Выделить всё

error: variable-sized object may not be initialized
RETI ;рети-рети интеррапт, через шины данных тракт, через память, через порт, возвращайся в главный код
@hobbyelectronics
Аватара пользователя
levaclaus
Потрогал лапой паяльник
Сообщения: 302
Зарегистрирован: Пн янв 07, 2008 16:56:28
Откуда: Минск

Re: Вопросы по С/С++ (СИ)

Сообщение levaclaus »

а мне кто поможет? :shock:
Аватара пользователя
demonchik
Встал на лапы
Сообщения: 94
Зарегистрирован: Вт апр 07, 2009 13:39:13
Откуда: одесса
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение 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)
      {


      };
}

вот именно

Код: Выделить всё

table[5].a="kosyak"; 
не канает.
а второй раз писать

Код: Выделить всё

struct MY_TAB table[1]={"sinhrofazotron","100",12};
- не выход из ситуации и не катит че-то.
помогите пожалуйста.
радиоэлектроника - жизнь моя...
Аватара пользователя
demonchik
Встал на лапы
Сообщения: 94
Зарегистрирован: Вт апр 07, 2009 13:39:13
Откуда: одесса
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение demonchik »

просто инициализировать сразу все структуры в массиве можно.... но а вдруг захочу менять в программе содержимое строк? вот и лажа. хочется разобраться. спасибо
да, и еще: CVAVR говорит что индексы массивов вне диапазона

Код: Выделить всё

table[2].data=12;     //    я

table[3].data=35;     //   учуся так

и этого не пойму
радиоэлектроника - жизнь моя...
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

в Си нельзя оператором присваивания копировать содержимое строк, для этого есть функции memcpy, strcpy и ряд других.

Код: Выделить всё

strcpy(table[5].a,"kosyak"); // вот так можно задать новое значение строки
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
asteroid7
Опытный кот
Сообщения: 703
Зарегистрирован: Вс янв 18, 2009 21:12:49

Re: Вопросы по С/С++ (СИ)

Сообщение asteroid7 »

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 типа где угодно и инициализировать её:

Код: Выделить всё

//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[] = {
{"...", "...", ...},
{"...", "...", ...},
...
 };
Аватара пользователя
demonchik
Встал на лапы
Сообщения: 94
Зарегистрирован: Вт апр 07, 2009 13:39:13
Откуда: одесса
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение demonchik »

ого... вы открыли мне глаза! спасибо большое! :idea:
радиоэлектроника - жизнь моя...
truebest
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Ср авг 26, 2009 17:04:34
Откуда: СПБ

Re: Вопросы по С/С++ (СИ)

Сообщение 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 
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

truebest писал(а):проблема в том что вывод DATABUF %s",&FlashDataBuf[0]); меня не радует, выплевывается почему-то только 16байт а не все 256...пробовал по разному никак
еще бы оно вас радовало... вы не забывайте, что не смотря на то, что в Си СТРОКА - ЭТО МАССИВ БАЙТОВ, обратное утверждение неверно: МАССИВ БАЙТОВ - ЭТО НЕ СТРОКА!!!! поэтому выводить массив, пользуясь строковыми средствами - НЕВЕРНО! кстати, в вашей строке я красным выделил ЛИШНЕЕ.

вам поможет простейшее средство, что-то типа такого:

Код: Выделить всё

char *ptr = FlashDataBuf;
for(int i=0; i<=255; i++) printf("%c",*ptr++);
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
md5sum
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

неопределенный результат

Сообщение 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’ может дать неопределенный результат
Но, что-то мне не приходит в голову: При КАКИХ условиях и КАК может быть неопределенный результат?
— Не говорите мне что делать и я не скажу куда Вам идти...
ellioh
Встал на лапы
Сообщения: 100
Зарегистрирован: Сб янв 22, 2011 16:57:45

Re: неопределенный результат

Сообщение ellioh »

md5sum писал(а):

Код: Выделить всё

gps_led=(++gps_led) % 10;



Я бы написал по-простому:

Код: Выделить всё

gps_led=(gps_led+1) % 10;

или уже

Код: Выделить всё

gps_led++; gps_led %= 10;


Неопределённого результата быть, правда, всё равно, сдаётся мне, не должно, но сам код с операцией инкремента довольно странный, поскольку (++gps_led) эквивалентно (gps_led+=1). Не стоит в правой части модифицировать то, что и так будет затёрто при присваивании.
Клоподавер упрыгхт
Аватара пользователя
md5sum
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Re: неопределенный результат

Сообщение md5sum »

ellioh писал(а): (++gps_led) эквивалентно (gps_led+=1). Не стоит в правой части модифицировать то, что и так будет затёрто при присваивании.
Точно!!! Мне-ж нафиг не нужно gps_led+=1 в правой части, а интересует только остаток от деления числа на 1 больше текущего...
Надо отучать себя от конструкций a++, b--, --a, --b и писать конкретно: a=a+1; тогда и таких ляпов гораздо меньше будет...
Спасибо!
— Не говорите мне что делать и я не скажу куда Вам идти...
ellioh
Встал на лапы
Сообщения: 100
Зарегистрирован: Сб янв 22, 2011 16:57:45

Re: неопределенный результат

Сообщение ellioh »

md5sum писал(а):Надо отучать себя от конструкций a++, b--, --a, --b и писать конкретно: a=a+1

Да ну, не надо. Половина прелести C уйдёт. Без конструкций вида a[i++] и *++p жизнь тосклива. :)
Просто один раз запомнить: "++" != "+1" :)
Клоподавер упрыгхт
Аватара пользователя
Goodefine
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Re: неопределенный результат

Сообщение Goodefine »

md5sum писал(а):... При КАКИХ условиях и КАК может быть неопределенный результат?

Скорее всего, это связано с особенностями внутренней реализации указанных операций компилятором...
Попробуйте так:

Код: Выделить всё

    ...
    static char gps_led=0;
   ++gps_led;
    gps_led%=10;
    if (gps_led<3)....

А, вообще, можно было счетчик до 9 и попроще реализовать... Без взятия остатка...
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

Re: неопределенный результат

Сообщение avreal »

md5sum писал(а):

Код: Выделить всё

 gps_led=(++gps_led) % 10;

При КАКИХ условиях и КАК может быть неопределенный результат?
В языке С есть понятие "точка следования" (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! между точками следования порядок не определён
Вот он тут и предупреждает, что в зависимости от настроения оптимизатора порядок записи может сгулять, не в этой версии компилятора, так в следующей. А от этого изменится результат. Но он не виноват.
Классика жанра - вопрос "сколько будет"

Код: Выделить всё

  i = 5;
  i = ++i + ++i;

http://lurkmore.ru/%2B%2Bi_%2B_%2B%2Bi

p.s. А в данном случае (как уже намекнули) писать надо было вообще такой код

Код: Выделить всё

  if( ++gps_led > 9) gps_led = 0;
(скобки вокруг под-IF-нутого выражения - тоже точка следования, тут всё честно)
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
ellioh
Встал на лапы
Сообщения: 100
Зарегистрирован: Сб янв 22, 2011 16:57:45

Re: Вопросы по С/С++ (СИ)

Сообщение ellioh »

Хо-хо, век живи -- век учись. Как-то термин sequence point прошёл мимо меня. http://en.wikipedia.org/wiki/Sequence_point
Действительно, никто не гарантирует, что к моменту выполнения собственно присваивания все последствия вычисления выражения в левой и правой частях присваивания уже наступят.

Классический-то пример некорректности из Кернигана и Ричи (http://lib.ru/CTOTOR/kernigan.txt, 2.12. Старшинство и порядок вычисления) проще:

Код: Выделить всё

A[I] = I++;


Но в примере понятно, тут никто не запрещает вычислить левое I ни до, ни после того, как выполнится I++

В любом случае, так писать просто не надо, достаточно один раз это запомнить. :-)
Клоподавер упрыгхт
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение ARV »

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

Мой уютный бложик... заходите!
Ответить

Вернуться в «Разные вопросы по МК»