Буратино 0 24 января, 2013 Опубликовано 24 января, 2013 · Жалоба ЗАДАЧА А Есть функция (K&R), которая обращает порядок символов в строке. Вот она: #include <string.h> void reverse (char s[]) { int c, i, j; for (i = 0, j = strlen(s) - 1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; } } Вопросы: 1. Какие слабые места у данной реализации. 2. Как можно оптимизировать код. И что конкретно это даст. 3. Какие есть варианты реализации функции. Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
telix 0 24 января, 2013 Опубликовано 24 января, 2013 (изменено) · Жалоба В коде ошибка поставьте j-- :) Изменено 24 января, 2013 пользователем telix Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Буратино 0 24 января, 2013 Опубликовано 24 января, 2013 · Жалоба В коде ошибка поставьте j-- :) да ,сори. ЗАДАЧА Б Есть реализация функции перевода "типа" bool в строку. char *b2s (char b) { static char *name[] = {"Out Of Range", "False", "True"}; return (b < 0 || b > 1) ? name[0] : name [b+1]; } Вопросы: 1. Какие слабые/ошибочные места у данной реализации. 2. Как можно оптимизировать код. И что конкретно это даст. 3. Какие есть варианты реализации функции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 24 января, 2013 Опубликовано 24 января, 2013 · Жалоба В смысле AVR, может выглядеть так #include <avr/io.h> #include <string.h> void reverse(char s[]) { char *beg = (char *)&(s[0]); char *end = (char *)&(s[strlen(s)]); while(beg < end) { char c = *beg; *beg++ = *(--end); *end = c; } } 82: fc 01 movw r30, r24 84: 01 90 ld r0, Z+ 86: 00 20 and r0, r0 88: e9 f7 brne .-6 ; 0x84 <reverse+0x2> 8a: 31 97 sbiw r30, 0x01 ; 1 8c: e8 1b sub r30, r24 8e: f9 0b sbc r31, r25 90: e8 0f add r30, r24 92: f9 1f adc r31, r25 94: dc 01 movw r26, r24 96: 04 c0 rjmp .+8 ; 0xa0 <reverse+0x1e> 98: 8c 91 ld r24, X 9a: 92 91 ld r25, -Z 9c: 9d 93 st X+, r25 9e: 80 83 st Z, r24 a0: ae 17 cp r26, r30 a2: bf 07 cpc r27, r31 a4: c8 f3 brcs .-14 ; 0x98 <reverse+0x16> a6: 08 95 ret Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 25 января, 2013 Опубликовано 25 января, 2013 (изменено) · Жалоба По задаче Б. переменная типа bool принимает значение 0 и !0 (не 0). В зависимости от реализации компиляторе !0 может выглядеть любым целым числом, поэтому "Out Of Range" - некоррекное заявление. Изменено 25 января, 2013 пользователем редактор Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 25 января, 2013 Опубликовано 25 января, 2013 · Жалоба По задаче Б. переменная типа bool принимает значение 0 и !0 (не 0). В зависимости от реализации компиляторе !0 может выглядеть любым целым числом, поэтому "Out Of Range" - некоррекное заявление. Неправда! Область значений, согласно stdbool.h -это true,false. Отсюда static const char strue[]="TRUE"; static const char sfalse[]="FALSE"; static const char sndef[]="OUT OF RANGE"; switch(boolean) { case true: return &strue; case false: return &sfalse; default: return &sndef; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
msalov 0 25 января, 2013 Опубликовано 25 января, 2013 · Жалоба Неправда! Область значений, согласно stdbool.h -это true,false. Исходя из того, что в Си bool это всего лишь костыль для пришедших из других языков, и любое не 0-ое значение является истиной для условных операторов, то, ИМХО редактор прав. Задачу А можно оптимизировать сильнее всего исходя из контекста. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 25 января, 2013 Опубликовано 25 января, 2013 · Жалоба и любое не 0-ое значение является истиной для условных операторов, то, ИМХО редактор прав. if(0) - выражение в скобках сейчас == 0 if(!0) - выражение в скобках сейчас == 1 Ы? Задачу А можно оптимизировать сильнее всего исходя из контекста. Работа непосредственно с двумя указателями выигрывает на любых pic/avr/arm/x51 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrewlekar 0 25 января, 2013 Опубликовано 25 января, 2013 · Жалоба В задаче А вижу только один недостаток - это нет проверки на пустую строку. Если длина будет 0, то произойдёт переполнение и запись за пределы строки. По производительности тоже проблем не наблюдаю - можно было бы сделать какой-нибудь ассемблерный SWAP или хотя бы промежуточную переменную поместить в регистр, но это от архитектуры зависит. В задаче Б всякая жесть. Тип заявлен bool, а передаётся char. Сравнение почему-то с 0 и 1, хотя false и true может быть определена иначе. Нужно сравнивать с настоящими false и true, теми которые используются вашим компилятором. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 25 января, 2013 Опубликовано 25 января, 2013 · Жалоба грубовато... const char* b2s (unsigned char b) { static const char* name[] = {"False", "True", "Out Of Range", "Out Of Range"}; return name[b&3]; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 25 января, 2013 Опубликовано 25 января, 2013 · Жалоба return name[b&3]; Ага, щаз! А если b например... b=0x0C Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
msalov 0 25 января, 2013 Опубликовано 25 января, 2013 · Жалоба if(0) - выражение в скобках сейчас == 0 if(!0) - выражение в скобках сейчас == 1 Ы? Я имел ввиду немного другое if (42) { printf("True\n"); } else { printf("False\n"); } Какая ветка условного оператора будет выполнена? Третьего "outofrange" не дано, увы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 25 января, 2013 Опубликовано 25 января, 2013 · Жалоба Я имел ввиду немного другое Дык это несовместимость типов. :laughing: Почему к случаям явного приведения int к указателю всегда люди относятся настороженно, а к "притягиванию" bool к char - типа что это нормально? Примеров привести не могу, у меня не очень богатый сишный опыт. Только анекдот #define true false // собаки, ковыряйтесь теперь сами :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 25 января, 2013 Опубликовано 25 января, 2013 · Жалоба Ага, щаз! А если b например... b=0x0CНу так я и сказал что грубовато:) const char* b2s (unsigned char b) { static const char* name[] = {"False", "True", "Out Of Range"}; return name[(b>1)? 2:b]; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 25 января, 2013 Опубликовано 25 января, 2013 · Жалоба В армоводческом смысле reverse() с указателями 0x0800024A B570 PUSH {r4-r6,lr} 0x0800024C 4605 MOV r5,r0 0x0800024E 462C MOV r4,r5 0x08000250 4628 MOV r0,r5 0x08000252 F000F84F BL.W strlen (0x080002F4) 0x08000256 1946 ADDS r6,r0,r5 0x08000258 E007 B 0x0800026A 0x0800025A 7820 LDRB r0,[r4,#0x00] 0x0800025C 1E71 SUBS r1,r6,#1 0x0800025E 460E MOV r6,r1 0x08000260 7809 LDRB r1,[r1,#0x00] 0x08000262 F8041B01 STRB r1,[r4],#0x01 0x08000266 7030 STRB r0,[r6,#0x00] 0x08000268 BF00 NOP 0x0800026A 42B4 CMP r4,r6 0x0800026C D3F5 BCC 0x0800025A 0x0800026E BD70 POP {r4-r6,pc} Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться