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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение pokk »

Здравствуйте, не могу понять почему не работает.

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

p1trr123=perevod_NUL123(NetConf123.port,&templen);
send(s,p1trr123,templen);

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

unsigned char buf_perevod[6];
unsigned char templen;
unsigned char *p1trr123=buf_perevod;
в первой функции я разбиваю число на разряды и что бы отбросить нули я возвращаю указатель смещённый на количество нулей в начале получается он указывает на сами числа. В качестве ещё одного выходного параметра является переменная templen в ней указывается длина массива.
Спойлер

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

unsigned char* perevod_NUL123 (int a,unsigned char *len)
{
    unsigned char *ptr;
    unsigned char buf[5];
    ptr=buf;
    *len=5;
    buf[0]=0x30;
    buf[1]=0x30;
    buf[2]=0x30;
    buf[3]=0x30;
    buf[4]=0;
      while (a >= 10000)
  {
    a -= 10000;
    ++buf[0];
  }

    while (a >= 1000)
  {
    a -= 1000;
    ++buf[1];
  }
  while (a >= 100)
  {
    a -= 100;
    ++buf[2];
  }
  while (a >= 10)
  {
    a -= 10;
    ++buf[3];
  }
  buf[4]=0x30+a;
//  buf[5]=0;

  if(buf[0]==0x30){
    ptr++;
    *len=*len-1;
  }
  else{
    return ptr;
  }
  if(buf[1]==0x30){
    ptr++;
    *len=*len-1;
  }
  else{
    return ptr;
  }
    if(buf[2]==0x30){
    ptr++;
    *len=*len-1;
  }
  else{
    return ptr;
  }
  if(buf[3]==0x30){
    ptr++;
    *len=*len-1;
  }
  else{
    return ptr;
  }
    if(buf[4]==0x30){
    ptr++;
    *len=*len-1;
  }
  else{
    return ptr;
  }
return ptr;
}

Это всё нормально выдаёт.
Дальше мне надо просто передать значение которые находятся в указателе p1trr123 в функцию send
Но вот после того как я захожу в функцию send всё что находилось в p1trr123 сразу сбрасывается на какой-то муссор. Почему ?
Спойлер

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

unsigned int send(
	unsigned char s, 		/**< the socket index */
	 unsigned char * buf, 	/**< a pointer to data */
	unsigned int len		/**< the data size to be send */
	)
{
	unsigned char status=0;
        unsigned int ret=0;
        unsigned int freesize=0;

  ..................
}

если передавать в send не указатель а массив к примеру так

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

send(s,buf_perevod,templen);
То всё работает нормально.

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

unsigned char buf_perevod[6];
Чего я не правильно понимаю ?
Реклама
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

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

Сообщение BCluster »

Пока что скажу что ваша функция разложения числа на разряды просто адовейший ад :) Почему не работает, сейчас попробую вникнуть)

Вы объявили локальный указатель и массив в вашей функции. Кстати зачем нужно и то и другое неясно. Потом вы возвращаете этот указатель. Но указывает он на какую-то область стека, выделенную для локальных переменных данной функции, которая после выхода из функции доступна не будет. Для того чтобы такого не происходило, передавайте указатель в качестве аргумента, а возвращайте длину. А не наоборот как сейчас.

Для того, чтобы таких вопросов не возникало, стоит разобраться что такое указатель вообще. И время жизни переменных.
Реклама
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение pokk »

Пока что скажу что ваша функция разложения числа на разряды просто адовейший ад
Что улучшить можно?
Ну без убирания начальных нулей выглядело нормально. Хотел я это всё вместе сделать типа разбивание на разряды и проверка на ноль но там как-то не сильно вышло да и потом опять столько же условий будет поэтому сделал в лоб.
Пока ехал в автобусе уже сам допёр где накосячил :) Так и думал что ошибка как-то элементарная.
Для того чтобы такого не происходило, передавайте указатель в качестве аргумента, а возвращайте длину. А не наоборот как сейчас.

Блин ну надо же было мне всё испортить =) изначально примерно всё так и было только я передавал в функцию не указатель а массив. Из за этого адрес нельзя было выдать другой.

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

Для того, чтобы таких вопросов не возникало, стоит разобраться что такое указатель вообще. И время жизни переменных.
Меня сбило с толку то что из функции всё выдавалось правильно. И я искал ошибку дальше.
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

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

Сообщение BCluster »

Указатель от массива ничем не отличается. И то и то адрес.
Насчет улучшений - я не понимаю что вы имеете ввиду под убиранием начальнных нулей. Кажется понял. Надо чтобы в первом элементе массива было первое ненулевое значение?

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

int IntToDigit(int value, char* buf)
{
char idx = 0;
buf[idx] = value/10000;
if (buf[idx] != 0) idx++;
value = value%10000;
buf[idx] = value/1000;
if (buf[idx] != 0) idx++;
value = value%1000;
buf[idx] = value/100;
if (buf[idx] != 0) idx++;
value = value%100;
buf[idx] = value/10;
if (buf[idx] != 0) idx++;
buf[idx] = value%10;
return idx; // это будет длина
}

Это если влоб. Зато понятно
А зачем вы 0х30 добавляете? :)
Реклама
Эиком - электронные компоненты и радиодетали
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение pokk »

У делением мне сказали про такое забыть вообще и не вспоминать =) (типа долгий алгоритм)
Надо чтобы в первом элементе массива было первое ненулевое значение?
Да да именно.
А зачем вы 0х30 добавляете? :)
Это сразу перевод в ascii.

А что будет с числом 403 вместо него появится 43 ?
Был у меня примерно такой же вариант но там получилось что он и последние нули удаляет. По этому я решил найти первое не нулевое значение в массиве buf и просто выдать адрес его (начало числа) что бы не тратить время на копирование и сдвиги.
Реклама
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

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

Сообщение YS »

делением мне сказали про такое забыть вообще и не вспоминать =) (типа долгий алгоритм)
А что за кристалл (вы же под МК пишете)?

Не такой и долгий, на самом деле.

Я в свое время писал так:
Спойлер

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

/*
This function converts an integer value into its character
representation and stores these characters into 'numstr's
next 6 or 'NumDgt' (see note below) characters from 'StartPos'.

'num'       -   integer to convert to string;

'numstr'    -   target string;

'StartPos'  -   the next 6 characters from 'StartPos' will
                be used for storing 'num' characters. The best
                way is to fill them with spaces before calling
                PutIntToStrEx().
                NOTE:
                If 'NumDgt' is zero, function will always use
                exactly 6 characters.

'NumDgt'    -   Optional number of digits to convert to characters.
                If 'NumDgt' is not zero, only 'NumDgt' charaters
                will be converted and placed to 'numstr'. If 'num'
                has less digits than specified in 'NumDgt', leading
                zeroes will be added.
                NOTE:
                If 'num' is negative, function will use one extra
                character to store sign.
*/
void PutIntToStrEx(int num,char numstr[],int StartPos,char NumDgt)
{
    int i;
    char sign=' ';

    if (num<0)
    {
        num=-num;
        sign='-';
    }

    if (!NumDgt)
    {
        if (sign==' ')
            i=StartPos+5;
        else
            i=StartPos+6;

        do
        {
            --i;
            numstr[i]=(num % 10) | 0x30;
        }while (num/=10);

        --i;

        numstr[i]=sign;
    }
    else
    {
        if (sign==' ')
            i=StartPos+NumDgt;
        else
        {
            i=StartPos+NumDgt+1;
            numstr[StartPos]=sign;
            ++StartPos;
        }

        do
        {
            --i;
            numstr[i]=(num % 10) | 0x30;
            num/=10;
        }while (i>StartPos);
    }
}
Это очень бодро работало на MSP430G2231 при тактировании ~15 МГц. Вообще, поскольку подобные функции нужны в основном для обслуживания интерфейса пользователя, то слишком уж оптимизировать их нет особого смысла. Человеку что 100 мс, что 10 мс - все кажется мгновенным. :)

Разумеется, вызывать такие расчеты в прерывании - плохая идея.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Реклама
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

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

Сообщение oleg110592 »

pokk писал(а): делением мне сказали про такое забыть вообще и не вспоминать =) (типа долгий алгоритм)
красивое решение тут, имхо: http://kazus.ru/forums/showpost.php?p=7 ... ostcount=8

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

uint32_t Bin2BCD(uint32_t value, uint8_t *Res)
{
uint8_t *n = Res;

while (value > 0)
 {
 *Res++ = value % 10;
 value /= 10;
 }
return (uint32_t)(Res - n);
}
например деление на 10 в листинге си компилятора для stm8 выливается в одну команду ассемблера:

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

        ;value /= 10;
       	ldw	x,(OFST+1,sp)
       	ld	a,#10
       	div	x,a
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

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

Сообщение BCluster »

Долго. Но вы не делаете это каждые 10мкс же. Поэтому совершенно пофиг. Кристалл там какой-то кортекс вроде. Так что точно ничего страшного.

Решения с циклами, предложенные уважаемыми котами совершенно верные. Однако я сделал без циклов специально для наглядности.
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

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

Сообщение YS »

Кристалл там какой-то кортекс вроде.
Тогда вообще пофиг. Там может еще и аппаратный блок деления есть.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

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

Сообщение BCluster »

По опыту скажу - у нас есть проект, достаточно нагружен сильно процессор (причем это 51 ядро), и совершенно не стесняемся использовать деление и умножение :) Производительности хватает. Конечно, не в прерываниях как было указано выше.
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

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

Сообщение vitalik_1984 »

YS писал(а):Вообще, поскольку подобные функции нужны в основном для обслуживания интерфейса пользователя, то слишком уж оптимизировать их нет особого смысла. Человеку что 100 мс, что 10 мс - все кажется мгновенным. :)
Согласен :))) оптимизировать имеет смысл только логическим анализом того сколько раз действительно необходимо вызвать это деление. Чем меньше преобразований, тем эффективнее остальная часть программы.
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

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

Сообщение YS »

причем это 51 ядро
Пятьдесят одно ядро? :)))

Уточню на всякий случай, что ув. BCluster имел в виду MCS-51. :)) А то читается неоднозначно. :)
Разница между теорией и практикой на практике гораздо больше, чем в теории.
pokk
Вымогатель припоя
Сообщения: 574
Зарегистрирован: Вт ноя 02, 2010 17:46:37

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

Сообщение pokk »

YS писал(а): А что за кристалл (вы же под МК пишете)?
...
Пока пишу для STM32F407VGT6 позже будет STM32F103 а потом avr поэтому что бы не парится решил сделать без деления что бы в avr не тупить.
YS писал(а): ...
Вообще, поскольку подобные функции нужны в основном для обслуживания интерфейса пользователя, то слишком уж оптимизировать их нет особого смысла. Человеку что 100 мс, что 10 мс - все кажется мгновенным. :)
Я оптимизирую её для того что бы эта функция не задерживало всё остальное. А вызывается она достаточно часто около 40-60 раз последовательно.
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

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

Сообщение YS »

Скажу по опыту, деление - не самая страшная операция. Вот что реально тормозит программу до последней стадии - так это использование вещественных чисел, если в МК нет FPU.

Спецом проверил. Деление 32 bit/32 bit на AVR выполняется за 19 тактов, или 2.4 мкс при тактировании 8 МГц. 16 bit / 16 bit - 11 тактов и 1.4 мкс соответственно.

Тестовый код:
Спойлер

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

volatile uint32_t a,b,c;

void main(void)
{
	a=100500;
	b=10;

	c=a/b;

	c=0;

	while (1);

}
А вызывается она достаточно часто около 40-60 раз последовательно.
Э-э-э, зачем столько?
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Аватара пользователя
BCluster
Собутыльник Кота
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев
Контактная информация:

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

Сообщение BCluster »

YS, Там человек что-то типа часов делает :) Но судя по всему, перемудрил.
pokk, Вы бы задачу сказали, вам бы посоветовали как это правильно сделать :)
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

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

Сообщение coredumped »

pokk писал(а):Пока пишу для STM32F407VGT6 позже будет STM32F103 а потом avr поэтому что бы не парится решил сделать без деления что бы в avr не тупить.
Если сделаете на STM32F103, за каким хреном Вам этот издыхающий AVR? При чем AVR еще и дороже. Если потянуло на винтаж, то делайте уж на лампах:
http://www.jogis-roehrenbude.de/Leserbr ... renuhr.htm
Все будет только лучше, в крайнем случае - хуже.
Аватара пользователя
YS
Друг Кота
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05
Контактная информация:

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

Сообщение YS »

YS, Там человек что-то типа часов делает
:shock:
:shock:

Ппц. Я когда про шестидесятикратный вызов услышал, то подумал как миниум про самописную ОС. Ну или суровый GUI на какой-то RTOS.

Часы на STM32F4 - это очень, очень сильно. :shock: :)))
за каким хреном Вам этот издыхающий AVR?
Не такой уж он и издыхающий последнее время, кстати.
AVR еще и дороже
Цены на контроллеры от ST здоровски прыгают в зависимости от расположения духа их маркетологов. И то, что сегодня продается по 30 р. (явный демпинг), через неделю может стоить 200 р. (свою нормальную цену). Так уже случилось с серией STM32F1.

Вот за это я, кстати, и недолюбливаю ST - агрессивный маркетинг и непредсказуемый демпинг. Невозможно строить какие-то долговременные планы. С ценами просто смех и свинство.

Это если мы про розницу. А если про опт (ну там, штук от 500 хотя бы) - там разница имеет тенденцию стираться.

Мне, кстати, нравятся MSP430 G-серии. Никакого демпинга, никакого принуждения к собственным библиотекам. TI просто тихо делают дешевые контроллеры и продают. Жалко купить их можно в основном от 1000 шт. :)))
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

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

Сообщение coredumped »

YS писал(а):последнее время, кстати.
:))) последнее время - это точно сказано
У ST вменяемые менеджеры, давно работаем с этой компанией. Всегда можно договориться о хороших оптовых ценах. Зря Вы на них обижаетесь.
Насчет библиотек - Вы тоже неправы. Никто Вас не заставляет использовать SPL - исползуйте только CMSIS от ARM - его более чем достаточно для всех случаев жизни.
Против TI ничего плохого сказать не могу, вполне вменяемая контора, однако ST чуть дешевле, что при больших партиях существенно. Не хочу холиварить, но сейчас мне проще поставить маленький Cortex вместо AVR - тупо дешевле. Что касается MSP - они прошли как-то мимо. Я пришел, по пути наименьшего сопротивления, к одной архитектуре, одному программатору, одному тулчейну и не вижу смысла разводить зоопарк, как это было раньше.
Все будет только лучше, в крайнем случае - хуже.
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

YS писал(а):Мне, кстати, нравятся MSP430 G-серии.
Уродливая серия, уродливая периферия и уродливые цены... может просто привычка??? :))
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

Да что-то и в ST не все гладко - понадобилось мне юсб хост замутить, заказал в космодроме 2 штуки STM32F105R8T6.
Впаял первую - что-то не дышит и не определяется - ну ладно, думаю, статика, перегрев, возможны варианты, сдуваю, ставлю следующую - у второй резет к плюсу не подтягивается. Тут я понял, что купил брак. Пишу на космодром письмо - что-то не то в смысле, раньше за вами такого не наблюдалось - ни ответа, ни привета. А 100, 103 серия, что у них брал одновременно или раньше - никаких проблем, все заводится.
Хорошо, что 2 купил, а если бы 200 ? Печалька была бы.
Ответить

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