реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> процедура с указателем на строку в памяти программ, помогите разобраться
HARMHARM
сообщение Dec 25 2008, 12:49
Сообщение #31


читатель даташитов
****

Группа: Свой
Сообщений: 853
Регистрация: 5-11-06
Из: Днепропетровск
Пользователь №: 21 999



Цитата(demiurg_spb @ Dec 25 2008, 14:11) *
Примеры компиляторов? Это небось только узкоспециализированные и заточенные под мало разрядные MCU. Я солидарен с zltigo и в основном всегда char знаковый. Проведите аналогию с int.
Да, полностью согласен с Вами и Zltigo. Это мое воинствующее невежество выстрелило sad.gif
Чтобы закрыть тему с char приведу цитату из описания на gcc:
Цитата
Each kind of machine has a default for what `char' should be. It
is either like `unsigned char' by default or like `signed char' by
default.

Ideally, a portable program should always use `signed char' or
`unsigned char' when it depends on the signedness of an object.
But many programs have been written to use plain `char' and expect
it to be signed, or expect it to be unsigned, depending on the
machines they were written for. This option, and its inverse, let
you make such a program work with the opposite default.

The type `char' is always a distinct type from each of `signed
char' or `unsigned char', even though its behavior is always just
like one of those two.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 25 2008, 13:37
Сообщение #32


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(rezident @ Dec 25 2008, 15:35) *
Я с вами согласен, что нужно писать так, чтобы типы приводить не приходилось. Но я-то писал в применении к конкретному коду, а не к коду "вообще" или "в принципе".
Именно тут - да, можете. А что произойдет в случае сравнения на больше/меньше? Тоже будете уповать на то, что по-умолчанию char как unsigned char используется?

Я уповать не буду. Мне вообще всё равно что за тип char (со знаком или без) и всем остальным это должно быть тоже безразлично. Ибо его надо использовать только для работы с текстовыми строками и символами. Я легко и непринуждённо буду писать
Код
char ch = '0'; .... ch++; ... if ((ch>='0')&&(ch<='9')) {}
и даже не вспомню о надуманной проблеме знака. Все прекрасно будет работать и именно так как я хочу.
В развитие темы хочу добавить, что когда я вижу код
Код
for (char i=0; i<N; i++)  {} // так писать нельзя
я никак не могу избавится от желания отшлёпать автора такого кода. Лень написать unsigned char так используйте тип uint8_t.
Код
#include <stdint.h>
for (uint8_t i=0; i<N; i++)  {}
Но осознанно создавать неопределённое поведение программы - это по меньшей мере неблагоразумно.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 25 2008, 13:44
Сообщение #33


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(chief_olimp @ Dec 25 2008, 14:18) *
Скажите у Вас у самого код что сверху работает со словами из FLASH?
Конкретно этот не проверял, но если в pgmspace.h описан прототип extern char *strstr_P(const char *, PGM_P); то у меня нет основания сомневаться в том, что первый агрумент - указатель на строку в ОЗУ, а второй - на строку в flash. Описание стандартной функции strstr гласит:
Цитата
Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
А это именно то, что требуется, судя по вашему исходнику.
Цитата(chief_olimp @ Dec 25 2008, 14:18) *
Мой код у меня работает и меня лично вполне устаивает.
Весьма сомнительно - в вашем коде нет обращения к flash.
Цитата(chief_olimp @ Dec 25 2008, 14:18) *
Код что выше у меня не работает, и выдает ошибку что не понимает аттрибута функции.
Тренировки в телепатии, безусловно, полезны. Но пока мы не достигли совершенства в этой области неплохо было бы приводить конкретную строку, на которую выдается ошибка и конкретный текст ошибки. Мой код прекрасно компилируется:
CODE
main.cpp:
#include <avr\pgmspace.h>
char USART0_InBuf[10];
int fndOK;
void find(prog_char const * inb)
{
prog_char const * found = strstr_P(USART0_InBuf, inb);
if (!found)
fndOK=-1;
else
fndOK = found - USART0_InBuf;
}

main.lst:
531 .section .text._Z4findPKc,"ax",@progbits
532 .global _Z4findPKc
534 _Z4findPKc:
535 .LFB37:
536 .LSM79:
537 /* prologue: frame size=0 */
538 /* prologue end (size=0) */
539 .LVL13:
540 .LBB23:
541 .LSM80:
542 0000 BC01 movw r22,r24 ; inb, inb
543 0002 80E0 ldi r24,lo8(USART0_InBuf) ; ,
544 0004 90E0 ldi r25,hi8(USART0_InBuf) ; ,
545 .LVL14:
546 0006 00D0 rcall strstr_P ;
547 .LVL15:
548 .LSM81:
549 0008 0097 sbiw r24,0 ; found
550 .LVL16:
551 000a 01F4 brne .L64 ; ,
552 .LSM82:
553 000c 8FEF ldi r24,lo8(-1) ; tmp45,
554 000e 9FEF ldi r25,hi8(-1) ; tmp45,
555 .LVL17:
556 0010 00C0 rjmp .L68 ;
557 .LVL18:
558 .L64:
559 .LSM83:
560 0012 8050 subi r24,lo8(USART0_InBuf) ; found,
561 0014 9040 sbci r25,hi8(USART0_InBuf) ; found,
562 .L68:
563 0016 9093 0000 sts (fndOK)+1,r25 ; fndOK, found
564 001a 8093 0000 sts fndOK,r24 ; fndOK, found
565 001e 0895 ret
566 .LBE23:
567 /* epilogue: frame size=0 */
568 /* epilogue: noreturn */
569 /* epilogue end (size=0) */
570 /* function void find(const prog_char*) size 16 (16) */


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
chief_olimp
сообщение Dec 25 2008, 14:22
Сообщение #34


Местный
***

Группа: Участник
Сообщений: 249
Регистрация: 31-10-05
Из: Украина Нетешин
Пользователь №: 10 344



Обращение есть.
CODE
void find (const void *findbuff)
{
findOK = false;
unsigned int i=0;
unsigned char temp,j=0;
pointer = 0;
while(1)
{
temp = pgm_read_byte(findbuff++);
if(temp==0) break;
FIND[i++] = temp;
}
i=0;
while (i != USART0_InBufSize)
{
if (USART0_InBuf[i] == FIND[j])
{
i++;j++;findOK = true;
if (FIND[j] == 0x00)
{
pointer = i;
break;
}
}
else
{
i++;
if (findOK == true)
{
i = i-j; j=0;
findOK = false;
}
}
}
}

Но перед вами снимаю шляпу. Три страницы нужно было исписать что бы прийти к трем строчкам текста
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 25 2008, 14:31
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(demiurg_spb @ Dec 25 2008, 16:37) *
Я легко и непринуждённо буду писать...

И это правильно. Почти всегда правильно sad.gif без кирилицы...
Цитата
В развитие темы хочу добавить, что когда я вижу код
Код
for (char i=0; i<N; i++)  {} // так писать нельзя
я никак не могу избавится от желания отшлёпать автора такого кода. Лень написать unsigned char так используйте тип uint8_t.
Код
#include <stdint.h>
for (uint8_t i=0; i<N; i++)  {}

И за то, что Вы написали, надо больно шлепать, если это перенести не на восьмибитовик smile.gif. Исправитесь?


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
rezident
сообщение Dec 25 2008, 15:00
Сообщение #36


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(demiurg_spb @ Dec 25 2008, 18:37) *
и даже не вспомню о надуманной проблеме знака. Все прекрасно будет работать и именно так как я хочу.
Будет работать до тех пор, пока вы используете только первую половину ASCII или KOI-7 и не используете в строковых переменных кириллицу. О чем я выше уже упомянул.
Цитата(demiurg_spb @ Dec 25 2008, 18:37) *
Лень написать unsigned char так используйте тип uint8_t.
Вообще-то в качестве автоматических переменных цикла принято использовать тип int или unsigned int. А типы uint8_t, uint16_t и прочие подобные им не являются полностью стандартными, т.к. появились лишь как расширение в C99 и отсутствовали в ANSI C (хотя здесь могу и ошибаться, т.к. я не слишком большой знаток истории развития языка Си).
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 25 2008, 16:38
Сообщение #37


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(rezident @ Dec 25 2008, 18:00) *
Будет работать до тех пор, пока вы используете только первую половину ASCII или KOI-7 и не используете в строковых переменных кириллицу. О чем я выше уже упомянул.
Вообще-то в качестве автоматических переменных цикла принято использовать тип int или unsigned int. А типы uint8_t, uint16_t и прочие подобные им не являются полностью стандартными, т.к. появились лишь как расширение в C99 и отсутствовали в ANSI C (хотя здесь могу и ошибаться, т.к. я не слишком большой знаток истории развития языка Си).


Это программа для AVR и тут int не то чтобы сильно подходит.

Я использую не только первую половину ASCII...
Код
//=============================================================================
unsigned char is_rus_word(const char* str)
{
    char ch;    
    while ( (ch=*str++) )
    {
        if ((ch<'А')||(ch>'я'))
        {
            return 0;
        }
    }    
    return 1;
}
//=============================================================================
int main(void)
{
    const char buratino[] = "Буратино";    
    is_rus_word(buratino);
    return (0);
}


avr-gcc -c -mmcu=atmega64 -I. -gdwarf-2 -DF_CPU=14745600UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes....

Код
00003a2a <is_rus_word>:
3a2a:  fc 01  movw r30, r24
3a2c:  04 c0  rjmp    .+8
3a2e:  80 3c  cpi    r24, 0xC0
3a30:  10 f4  brcc    .+4
3a32:  80 e0  ldi    r24, 0x00
3a34:  08 95  ret
3a36:  81 91  ld    r24, Z+
3a38:  88 23  and    r24, r24
3a3a:  c9 f7  brne    .-14
3a3c:  81 e0  ldi    r24, 0x01
3a3e:  08 95  ret


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 25 2008, 16:49
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(demiurg_spb @ Dec 25 2008, 19:38) *
avr-gcc -c -mmcu=atmega64 -I. -gdwarf-2 -DF_CPU=14745600UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes....

И указание -funsigned-сhar компилятору теперь назывется
Цитата
Мне вообще всё равно что за тип char (со знаком или без) и всем остальным это должно быть тоже безразлично.

Если "безразлично" то поставьте уж signed smile.gif.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 25 2008, 16:50
Сообщение #39


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(zltigo @ Dec 25 2008, 17:31) *
И за то, что Вы написали, надо больно шлепать, если это перенести не на восьмибитовик smile.gif. Исправитесь?
Нет я пишу для AVR всегда только такsmile.gif Ну для x86 естественно использую родной int.

avr-gcc -c -mmcu=atmega64 -I. -gdwarf-2 -DF_CPU=14745600UL -Os -fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes....
Код
    3a2a:    fc 01           movw    r30, r24
    3a2c:    05 c0           rjmp    .+10
    3a2e:    80 5c           subi    r24, 0xC0; 192
    3a30:    80 34           cpi    r24, 0x40; 64
    3a32:    10 f0           brcs    .+4
    3a34:    80 e0           ldi    r24, 0x00
    3a36:    08 95           ret
    3a38:    81 91           ld    r24, Z+
    3a3a:    88 23           and    r24, r24
    3a3c:    c1 f7           brne    .-16
    3a3e:    81 e0           ldi    r24, 0x01
    3a40:    08 95           ret
Аналогичный результат если ничего не задавать ни fsigned-char ни funsigned-char, т.е. по умолчанию signed...
Исправим формулировку: мне уже не всё равно какой тип у char, т.к. через makefile он принудительно выбран как без знака.
Генри Форд: "Форд может быть любого цвета если он чёрный" звучит примерно такsmile.gif
Прошу заметить, что даже так программа будет работать правильно!


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 25 2008, 16:54
Сообщение #40


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(demiurg_spb @ Dec 25 2008, 19:38) *
Это программа для AVR и тут int не то чтобы сильно подходит.

Само собой smile.gif. Посему подыщите в <stdint.h> более подходящий тип. Хотя sad.gif, по личному опыту бывают варианты, посему спокойнее использовать "свой" у меня он bint - "базовый int" не менее чем байт.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 25 2008, 17:27
Сообщение #41


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(zltigo @ Dec 25 2008, 19:54) *
Само собой smile.gif. Посему подыщите в <stdint.h> более подходящий тип. Хотя sad.gif, по личному опыту бывают варианты, посему спокойнее использовать "свой" у меня он bint - "базовый int" не менее чем байт.

На что Вы намекаете?smile.gif
В <stdint.h> я не смог найти ничего более подходящего для AVR чем uint8_t.
Для AVR Ваш bint = unsigned char? Или Вы уже совсем их (AVR) не используете по понятным причинам...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 25 2008, 17:34
Сообщение #42


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(demiurg_spb @ Dec 25 2008, 20:27) *
На что Вы намекаете?smile.gif
В <stdint.h> я не смог найти ничего более подходящего для AVR чем uint8_t.

Естественно на uint_least8_t и/или uint_fast8_t при этом речь я вел о подходящем вообще для портирования кода, а не подходящим только к AVR
Цитата
Для AVR Ваш bint = unsigned char?

Да для всех восьмибитоваков unsigned char. Для все остальных int
Цитата
Или Вы уже совсем их (AVR) не используете по понятным причинам...

Использую smile.gif иначе у меня просто не было-бы bint за полной его ненадобностью на 16/32/64 платформах.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 25 2008, 17:43
Сообщение #43


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(zltigo @ Dec 25 2008, 20:34) *
Естественно на uint_least8_t и/или uint_fast8_t при этом речь я вел о подходящем вообще для портирования кода, а не подходящим только к AVR
Спасибо!
Но хочется всё-таки узнать, когда же есть хоть малейший вред в случае char со знаком.
Я так и не смог выдумать такого...
И мне что-то подсказывает, что это таки надуманная проблема...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
alx2
сообщение Dec 26 2008, 10:36
Сообщение #44


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(Сергей Борщ @ Dec 25 2008, 17:05) *
И должны понимать, что компилятор не может только по значению обычного указателя понимать, какую команду использовать. Иными словами, функции strlen(), memcmp() не могут работать и со строками в ОЗУ и со строками во флеше.
Во времена MCS-51, тоже имеющего много разных адресных пространств, компиляторы использовали "универсальные" трехбайтные указатели, в которых первый байт был селектором адресного пространства. Соответственно, и функции, принимавшие такие указатели, вполне успешно работали со строками хоть в памяти данных, хоть в памяти программ. И как раз для начинающих это понятно и удобно, ибо соответствует правилам языка. Продвинутые кодеры могли использовать нестандартные спецификаторы, если тредовалось уменьшить оверхед и/или размер указателей...


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 26 2008, 13:54
Сообщение #45


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(demiurg_spb @ Dec 25 2008, 20:43) *
Но хочется всё-таки узнать, когда же есть хоть малейший вред в случае char со знаком.

Не понимаю вопроса sad.gif Поскольку есть разница и отнюдь не "малейшая" между знаковыми и беззнаковыми представлениями чисел, то и "вред" от необдуманной замены одного другим может быть отнюдь не "малейшим". Вам ведь не все равно будет если компилятор посчитает число которое Вы полагаете равным 128 меньшим чем, например, число 1.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 15:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01544 секунд с 7
ELECTRONIX ©2004-2016