|
процедура с указателем на строку в памяти программ, помогите разобраться |
|
|
|
Dec 24 2008, 14:39
|

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

|
Здраствуйте. Ткните где не так кто знает пожалуйста Код unsigned char blabla[] = "blablabla"; /// текст и все такое void find (unsigned char *findbuff) { unsigned int i; while (*findbuff != '\0') { USART0_OutBuf[i++] = *findbuff; findbuff++; } } int main (void) { find (blabla); } т.е. программа какие то данные из ОЗУ грузит в процедуру и что то так с ними делает Скажите пожалуйста как такое же провернуть со строкой типа Код unsigned char PROGMEM blabla[] = "blablabla"; Спасибо
|
|
|
|
|
 |
Ответов
|
Dec 24 2008, 16:27
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(chief_olimp @ Dec 24 2008, 19:39)  Скажите пожалуйста как такое же провернуть со строкой типа Код unsigned char PROGMEM blabla[] = "blablabla"; Во-первых, строка должна заканчиваться завершающим нулем. Код unsigned char PROGMEM blabla[] = "blablabla\0"; А во-вторых, перед выводом нужно указателю присвоить значение ее адреса, явно сделав преобразование типа. Код findbuff=(unsigned char *)&blabla[0];
|
|
|
|
|
Dec 24 2008, 18:21
|

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

|
Цитата(rezident @ Dec 24 2008, 19:27)  Во-первых, строка должна заканчиваться завершающим нулем. Код unsigned char PROGMEM blabla[] = "blablabla\0"; А во-вторых, перед выводом нужно указателю присвоить значение ее адреса, явно сделав преобразование типа. Код findbuff=(unsigned char *)&blabla[0]; Ни во-первых ни во-вторых делать не надо. Все СИ строки имеют завершающий ноль по определению. Имя одномерного масссива также является указателем на его первый элемент, так зачем же плодить промежуточные переменные. Приводить тип не надо, а надо использовать тип char для строк и char* для аргумента функции (ну или const char как в данном случае). На мой взгляд unsigned char следует использовать только как альтернативу uint8_t, а элементы строк, т.е. буквы-символы в подавляющем большинстве имеют тип char, на то он и нужен.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Dec 24 2008, 19:49
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(demiurg_spb @ Dec 24 2008, 23:21)  Ни во-первых ни во-вторых делать не надо. Все СИ строки имеют завершающий ноль по определению. Имя одномерного масссива также является указателем на его первый элемент, так зачем же плодить промежуточные переменные. Приводить тип не надо, а надо использовать тип char для строк и char* для аргумента функции (ну или const char как в данном случае). На мой взгляд unsigned char следует использовать только как альтернативу uint8_t, а элементы строк, т.е. буквы-символы в подавляющем большинстве имеют тип char, на то он и нужен. Теоретически вы правы. На практике могут проявиться нюансы. Как-то, приведение типа указателя без операции извлечения адреса не работает. А приведение типа в данном случае необходимо, т.к. указатель и массив имеют разный тип. IAR, например, сругался бы без приведения типа. Насчет char и unsigned char нужно опять же смотреть опции компилятора. Либо твердо помнить, что в строковых переменных используем только KOI-7 и/или только латиницу.
|
|
|
|
|
Dec 25 2008, 10:24
|

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

|
Цитата(rezident @ Dec 24 2008, 22:49)  Теоретически вы правы. На практике могут проявиться нюансы. Как-то, приведение типа указателя без операции извлечения адреса не работает. А приведение типа в данном случае необходимо, т.к. указатель и массив имеют разный тип. IAR, например, сругался бы без приведения типа. Насчет char и unsigned char нужно опять же смотреть опции компилятора. Либо твердо помнить, что в строковых переменных используем только KOI-7 и/или только латиницу. Я хочу сказать, что при грамотном проектировании программы приводить типы проактически не требуется - это загромождает программу. У автора ошибка в проектировании он почему-то решил применять разные типы данных для сущности и передачи указателя в функцию на эту сущность. Мне это совершенно не ясно. И это при том, что сущность едина в "двух лицах" - это строка типа чар. Вся таблица ascii прекрасно ложится в тип чар (это минимум 8 бит в нынешнем понимании, а иногда и немного больше) и пусть этот чар будет хоть со знаком, хот без - это может варьироваться от системы или опций компилятора. Повторюсь ещё раз строки должны состоять из обычных чаров - всё остальное от лукавого  Вот мой аргумент: Код const char slovo[] = "slovo"; if (slovo[0]=='s') { } Видите тип 's' - это char (я така понимаю). Поэтому я правомерно могу писать такой код. Комар носа не подточит. Ну а если ваш компилятор ругается на строки с символами код которых боьше 127 (gcc не ругается, bc и msvc тоже), то надо просто покопаться в опциях компилятора.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Dec 25 2008, 12:35
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(demiurg_spb @ Dec 25 2008, 15:24)  Я хочу сказать, что при грамотном проектировании программы приводить типы проактически не требуется - это загромождает программу. Я с вами согласен, что нужно писать так, чтобы типы приводить не приходилось. Но я-то писал в применении к конкретному коду, а не к коду "вообще" или "в принципе". Цитата(demiurg_spb @ Dec 25 2008, 15:24)  Вот мой аргумент: Код const char slovo[] = "slovo"; if (slovo[0]=='s') { } Видите тип 's' - это char (я така понимаю). Поэтому я правомерно могу писать такой код. Комар носа не подточит. Именно тут - да, можете. А что произойдет в случае сравнения на больше/меньше? Тоже будете уповать на то, что по-умолчанию char как unsigned char используется? Цитата(demiurg_spb @ Dec 25 2008, 15:24)  Ну а если ваш компилятор ругается на строки с символами код которых боьше 127 (gcc не ругается, bc и msvc тоже), то надо просто покопаться в опциях компилятора. Ага! Так все-таки "стоит покопаться в опциях"
|
|
|
|
|
Dec 25 2008, 13:37
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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++) {} Но осознанно создавать неопределённое поведение программы - это по меньшей мере неблагоразумно.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Dec 25 2008, 15:00
|
Гуру
     
Группа: Свой
Сообщений: 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 (хотя здесь могу и ошибаться, т.к. я не слишком большой знаток истории развития языка Си).
|
|
|
|
|
Dec 25 2008, 16:38
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Dec 25 2008, 17:27
|

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

|
Цитата(zltigo @ Dec 25 2008, 19:54)  Само собой  . Посему подыщите в <stdint.h> более подходящий тип. Хотя  , по личному опыту бывают варианты, посему спокойнее использовать "свой" у меня он bint - "базовый int" не менее чем байт. На что Вы намекаете?  В <stdint.h> я не смог найти ничего более подходящего для AVR чем uint8_t. Для AVR Ваш bint = unsigned char? Или Вы уже совсем их (AVR) не используете по понятным причинам...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Dec 25 2008, 17:34
|

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

|
Цитата(demiurg_spb @ Dec 25 2008, 20:27)  На что Вы намекаете?  В <stdint.h> я не смог найти ничего более подходящего для AVR чем uint8_t. Естественно на uint_least8_t и/или uint_fast8_t при этом речь я вел о подходящем вообще для портирования кода, а не подходящим только к AVR Цитата Для AVR Ваш bint = unsigned char? Да для всех восьмибитоваков unsigned char. Для все остальных int Цитата Или Вы уже совсем их (AVR) не используете по понятным причинам... Использую  иначе у меня просто не было-бы bint за полной его ненадобностью на 16/32/64 платформах.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Dec 25 2008, 17:43
|

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

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

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

|
Цитата(zltigo @ Dec 26 2008, 16:54)  Не понимаю вопроса  Поскольку есть разница и отнюдь не "малейшая" между знаковыми и беззнаковыми представлениями чисел, то и "вред" от необдуманной замены одного другим может быть отнюдь не "малейшим". Вам ведь не все равно будет если компилятор посчитает число которое Вы полагаете равным 128 меньшим чем, например, число 1. Это мне прекрасно понятно. Я уточню вопрос. Тут кто-то говорил что будут проблемы с русской кодировкой или что-то в этом духе. Так вот я немогу понять где эти проблемы? Я не говорю о типе char как о типе данных для представления чисел (с этим всё кристально ясно), я говорю лишь о строках и символах. При работе с буковками я никогда не думаю об их "цифровом коде" - это вредно для мозга  , я думаю лишь об их взаимном расположении в кодовой таблице. Ведь ряд чисел для типа char со знаком получается такой: 0,1,...126,127,-128,-127,...-2,-1 И даже если я попытаюсь сравнить символ на попадание в диапазон, границы которого лежат в левой и правой половинках ряда, то всё будет хорошо. Псевдокод: if (ch>126)&&(ch<-127) {} - это полностью соответствует if (ch>126)&&(ch<129) {} в случае когда char без знака. И если в этих выражения стоят не конкретные числа, а как я уже говорил у меня там _всегда_ что то типа 'А' и 'Я' - то всё будет хорошо  А меня пытаются убеждать в обратном, но я не сдаюсь.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
Сообщений в этой теме
chief_olimp процедура с указателем на строку в памяти программ Dec 24 2008, 14:39 rokhan И что ты хочешь найти?
Если ты хочешь найти стро... Dec 24 2008, 15:03    HARMHARM Цитата(demiurg_spb @ Dec 25 2008, 12:24) ... Dec 25 2008, 11:14     zltigo Цитата(HARMHARM @ Dec 25 2008, 14:14) Бол... Dec 25 2008, 11:37     demiurg_spb Цитата(HARMHARM @ Dec 25 2008, 14:14) Бол... Dec 25 2008, 12:11      HARMHARM Цитата(demiurg_spb @ Dec 25 2008, 14:11) ... Dec 25 2008, 12:49      zltigo Цитата(demiurg_spb @ Dec 25 2008, 16:37) ... Dec 25 2008, 14:31       demiurg_spb Цитата(zltigo @ Dec 25 2008, 17:31) И за ... Dec 25 2008, 16:50        zltigo Цитата(demiurg_spb @ Dec 25 2008, 19:38) ... Dec 25 2008, 16:49              Сергей Борщ Цитата(demiurg_spb @ Dec 27 2008, 12:03) ... Dec 27 2008, 11:15               demiurg_spb Цитата(Сергей Борщ @ Dec 27 2008, 14:15) ... Dec 28 2008, 22:04              rezident Цитата(demiurg_spb @ Dec 27 2008, 15:03) ... Dec 27 2008, 22:00   alx2 Цитата(rezident @ Dec 25 2008, 00:49) Тео... Dec 25 2008, 11:15 Tiro Чип AVR с компилятором WinAVR?
Тогда прочтите здес... Dec 24 2008, 16:42 chief_olimp дело в том что я хочу каждый раз используя одну и ... Dec 24 2008, 16:49 defunct Цитата(chief_olimp @ Dec 24 2008, 18:49) ... Dec 24 2008, 17:02 WHALE Я решал вашу задачу так:
Кодflash char *flash STRI... Dec 24 2008, 17:34 chief_olimp в вашем случае насколько я понял сравниваются стро... Dec 24 2008, 17:43 WHALE Цитата(chief_olimp @ Dec 24 2008, 20:43) ... Dec 24 2008, 20:03 _Pasha Код#define Str const unsigned char PROGMEM
Str bla... Dec 24 2008, 18:24 demiurg_spb Цитата(_Pasha @ Dec 24 2008, 21:24) Код#d... Dec 24 2008, 18:31 rokhan 2chief_olimp : простите. но то что вы написали - э... Dec 24 2008, 18:28 chief_olimp Цитата(rokhan @ Dec 24 2008, 22:28) 2chie... Dec 24 2008, 20:15 _Pasha Цитата(demiurg_spb @ Dec 24 2008, 22:31) ... Dec 24 2008, 18:49 rokhan Я просто в шоке.
думаю мои и быстрее и веселее
Ц... Dec 25 2008, 08:23 zltigo Цитата(rokhan @ Dec 25 2008, 11:23) думаю... Dec 25 2008, 08:54 chief_olimp Кодvoid find(char* inb)
{
fndOK=-1;
char i... Dec 25 2008, 11:44  Сергей Борщ Цитата(chief_olimp @ Dec 25 2008, 13:44) ... Dec 25 2008, 12:05   chief_olimp Документацию я как раз читаю. Только напоминаю я н... Dec 25 2008, 12:18    Сергей Борщ Цитата(chief_olimp @ Dec 25 2008, 14:18) ... Dec 25 2008, 13:44     chief_olimp Обращение есть.
CODEvoid find (const void *findbuf... Dec 25 2008, 14:22   alx2 Цитата(Сергей Борщ @ Dec 25 2008, 17:05) ... Dec 26 2008, 10:36    Сергей Борщ Цитата(alx2 @ Dec 26 2008, 12:36) Во врем... Dec 26 2008, 15:32     Сергей Борщ Цитата(Сергей Борщ @ Dec 26 2008, 17:32) ... Dec 26 2008, 17:48 rokhan Спасибо вы нашли опечатку.
КодНа счет тегов могли ... Dec 25 2008, 09:00 zltigo Цитата(rokhan @ Dec 25 2008, 12:00) У авт... Dec 25 2008, 09:48 chief_olimp т.е. каждый раз при очередном сравнивании данные с... Dec 25 2008, 09:15
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|