|
Си |
|
|
|
Jan 24 2013, 19:24
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
ЗАДАЧА АЕсть функция (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. Какие есть варианты реализации функции. Спасибо!
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
 |
Ответов
|
Jan 28 2013, 14:11
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Вот еще вариант. В основе смелая идея (уже ранее высказанная) о том чтоб испоьзовать буфер, но я немного переосмыслил это дело  Код #include <stdio.h> #define MAX_LEN 100
char * reverse ( char *s ) { static char buf[MAX_LEN]; char *buf_pointer = &buf[MAX_LEN-1];
while ( (*buf_pointer-- = *s++) ) // компилятор попросил о 2х скобках, ну раз ему так легче, то пусть будут:) ; return buf_pointer+2; }
int main() { char s[]= "Hello World!"; printf("%s\n", reverse (s) );
} Код stdout: !dlroW olleH Итак, я считаю что с задачей А мы справились. Плавно переходим к задаче Б.. Задача Б В этой реализации мне не нравится, что в случае дефолта сначала проверится один кейс, затем другой и только потом собственно выполнится подходящее действие! Что если нужно например месяца из чисел в названия переводить или там справочные данные какие? Потом мне непонятно почему нужно static const char strue[]="бла-бла-бла"; делать!? Это в смысле что строки в памяти программ расположатся? Как с доступом к таким значениям? не будет страдать производительность? Код 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; }
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
Jan 28 2013, 15:04
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(Буратино @ Jan 28 2013, 16:11)  Итак, я считаю что с задачей А мы справились. Поосторожнее… А то сейчас набегут спецы, которые сначала скажут, что возвращать указатель на внутренний статический буфер нельзя, потом скажут, что они имели ввиду, что оно-то можно, но глюкодром. А на вопрос, чем именно Код const char *foo() { static char buf[10]; ... return buf; } глюкодромее Код const char *moo() { return "bla-bla-bla"; } просто не будут отвечать по существу. Недостаток у способа один: Код char str1[] = "String 1"; char str2[] = "String 2"; printf("%s %s\n", reverse(str1), reverse(str2)); Впрочем, для таких случаев мои функции подобного типа принимают второй аргумент (со значением по умолчанию в C++), которым программа, имеющая желание в одни заход получить несколько строк, обязан апередать буфер достаточного размера: Код const char *reverse(const char *src, char *tmpbuf = 0) { static char inernal_buf[сикоку_не_жаль]; if (!tmpbuf) tmpbuf = internal_buf; … return tmpbuf; // или что там надо по алгоритму } В итоге в большинстве случаев вызывается reverse(some_string); (второй аргумент по умолчанию подставляется 0), и только в отдельных случаях подставляется доп. буфер. Однако задача в некотором смысле не решена и не может быть решена без уточнения условий и целей. Например, если цель — скорость, а строки преимущественно «достаточно длинные», а процессор Cortex-M3 или другой, имеющий команду реверся байтов в 32-битном слове (i486+), то стоит подумать о зачитывании по 32 бита, реверсе порядка байтов соответствующей командой и т.п. Соответственно, с выделением места под буфер кратно 4 байтам + под концевой 0, спецобработкой хвоста из 1..3 символов и возвратом указателя на tmp_buf с нужным смещением. «Если Вы не указали цель оптимизации, то Вам всё равно, как писать код» © Чеширсикй Кот – программист. Цитата(Буратино @ Jan 28 2013, 16:11)  Это в смысле что строки в памяти программ расположатся? Как с доступом к таким значениям? не будет страдать производительность? По простому const объекты расположатся в памяти программ только у тех процессоров, у которых память программ и память данных находятся в одном и том же адресном пространстве. ( чтобы не повторяться) А в таком случае производительность, в первом приближении, не пострадает. Цитата(xemul @ Jan 28 2013, 16:46)  Для таких программ потом и пишут заплатки на тему переполнения какого-нить буфера. Я надеюсь, высказывание касается только того, что перед реверсом либо в процессе оного не проверияется длина строки. Само по себе наличие промежуточного буфера фиксированного размера к ошибкам переполнения буфера не приводит. Цитата(Буратино @ Jan 28 2013, 16:52)  Вот у меня тоже static, но при этом данные в массиве указателей описаны внутри функции, вроде так логичнее получается ,зачем выносить их наружу меняя область действия? Код char *b2s (char b) { static char *name[] = {"Out Of Range", "False", "True"}; return (b < 0 || b > 1) ? name[0] : name [b+1]; } Да, лучше внутри функции.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jan 28 2013, 16:10
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(ReAl @ Jan 28 2013, 19:04)  Я надеюсь, высказывание касается только того, что перед реверсом либо в процессе оного не проверияется длина строки. Безусловно. Т.к. в условии задачи не сказано, что исходная строка должна сохраниться, я бы делал реверс на месте. Цена вопроса - один strlen(). (оно, конечно, не спасёт, если строка вдруг окажется без '\0') Цитата Само по себе наличие промежуточного буфера фиксированного размера к ошибкам переполнения буфера не приводит. К переполнению, естественно, не приведёт. Но если память (опять же вдруг) закончится... За жисть. У меня K&R был первого советского издания (в мягком переплёте, голубая обложка), не помню в нём таких упражнений. Хотя, может опять склероз буйствует.
|
|
|
|
Сообщений в этой теме
Буратино Си Jan 24 2013, 19:24 telix В коде ошибка поставьте j-- Jan 24 2013, 19:37 Буратино Цитата(telix @ Jan 24 2013, 22:37) В коде... Jan 24 2013, 20:15  Herz Цитата(Буратино @ Jan 24 2013, 22:15) Воп... Jan 25 2013, 06:39 _Pasha В смысле AVR, может выглядеть так
CODE#include ... Jan 24 2013, 20:31 Буратино Цитата(_Pasha @ Jan 24 2013, 23:31) В смы... Jan 25 2013, 08:31  gotty Цитата(Буратино @ Jan 25 2013, 11:31) Выб... Jan 25 2013, 08:46  MrYuran Цитата(Буратино @ Jan 25 2013, 12:31) А п... Jan 25 2013, 09:12   Буратино Цитата(MrYuran @ Jan 25 2013, 12:12) Во-п... Jan 25 2013, 09:28    ViKo Цитата(Буратино @ Jan 25 2013, 12:28) * t... Jan 25 2013, 09:45     _Pasha Цитата(ViKo @ Jan 25 2013, 12:45) Я выпис... Jan 25 2013, 09:52    MrYuran Цитата(Буратино @ Jan 25 2013, 13:28) а к... Jan 25 2013, 09:48     Буратино Цитата(MrYuran @ Jan 25 2013, 12:48) жи э... Jan 25 2013, 09:53      ViKo Цитата(Буратино @ Jan 25 2013, 12:53) Ищу... Jan 25 2013, 10:00  _Pasha Цитата(Буратино @ Jan 25 2013, 11:31) А з... Jan 25 2013, 09:38   Буратино Цитата(_Pasha @ Jan 25 2013, 12:38) 1. Во... Jan 25 2013, 09:48    _Pasha Цитата(Буратино @ Jan 25 2013, 12:48) дав... Jan 25 2013, 10:04  demiurg_spb Цитата(Буратино @ Jan 25 2013, 12:31) dem... Jan 25 2013, 09:59 редактор По задаче Б.
переменная типа bool принимает значе... Jan 25 2013, 05:16 _Pasha Цитата(редактор @ Jan 25 2013, 08:16) По ... Jan 25 2013, 05:23  gotty Цитата(_Pasha @ Jan 25 2013, 08:23) Непра... Jan 25 2013, 05:38   _Pasha Цитата(gotty @ Jan 25 2013, 08:38) и любо... Jan 25 2013, 05:49    demiurg_spb грубовато...
Кодconst char* b2s (unsigned char... Jan 25 2013, 05:59     _Pasha Цитата(demiurg_spb @ Jan 25 2013, 08:59) ... Jan 25 2013, 06:04      demiurg_spb Цитата(_Pasha @ Jan 25 2013, 10:04) Ага, ... Jan 25 2013, 06:31    gotty Цитата(_Pasha @ Jan 25 2013, 08:49)
if(... Jan 25 2013, 06:08     _Pasha Цитата(gotty @ Jan 25 2013, 09:08) Я имел... Jan 25 2013, 06:16      gotty Цитата(_Pasha @ Jan 25 2013, 09:16) Дык э... Jan 25 2013, 06:33       ReAl Цитата(gotty @ Jan 25 2013, 08:33) Моё ИМ... Jan 25 2013, 07:29 andrewlekar В задаче А вижу только один недостаток - это нет п... Jan 25 2013, 05:59 _Pasha В армоводческом смысле reverse() с указателями
CO... Jan 25 2013, 06:33 telix Я б пример А оптимизировал за счет второго буфера.... Jan 25 2013, 09:29 Буратино Цитата(telix @ Jan 25 2013, 12:29) Я б пр... Jan 25 2013, 09:35  telix Цитата(Буратино @ Jan 25 2013, 13:35) по ... Jan 25 2013, 10:06 Буратино Давайте в первом чтении вот такую версию ЗАДАЧИ А ... Jan 25 2013, 10:06 _Pasha Для нелюбителей тройных пересылок есть одна бяка
К... Jan 25 2013, 10:17 ViKo Цитата(_Pasha @ Jan 25 2013, 13:17) Для н... Jan 25 2013, 10:20  _Pasha Цитата(ViKo @ Jan 25 2013, 13:20) Так вы ... Jan 25 2013, 10:23   ViKo Цитата(_Pasha @ Jan 25 2013, 13:23) А не ... Jan 25 2013, 10:29    _Pasha Цитата(ViKo @ Jan 25 2013, 13:29) Т.е. на... Jan 25 2013, 11:00     Буратино Цитата(_Pasha @ Jan 25 2013, 14:00) Ага, ... Jan 25 2013, 11:11      _Pasha Цитата(Буратино @ Jan 25 2013, 15:11) Вот... Jan 25 2013, 11:35      Сергей Борщ QUOTE (Буратино @ Jan 25 2013, 13:11) Кст... Jan 25 2013, 11:55      ReAl Цитата(Буратино @ Jan 25 2013, 13:11) с и... Jan 25 2013, 12:48 Буратино Вот немного "заоптимизировал". Теперь пе... Jan 25 2013, 10:53 ViKo Да, верно, с исключающим или можно обойтись без пр... Jan 25 2013, 11:11 ViKo Что еще за UB? Мы ж так не UBьемся!
Последоват... Jan 25 2013, 12:54 Буратино что такое UB? что такое в пределах sequence point?... Jan 25 2013, 12:58 ReAl Да вроде всегда была определена последовательность... Jan 25 2013, 13:20 _Pasha Гнаться за мнимым весом строки - позор Jan 25 2013, 13:23 ReAl Хех.
Цитата(С99)6.5.16 Assignment operators
Syntax... Jan 25 2013, 13:43 ViKo Наверное, цитата по ссылке
At the end of a full ex... Jan 25 2013, 14:07 ReAl Не говорит. В "например" определяющей яв... Jan 25 2013, 16:10 xemul Цитата(Буратино @ Jan 28 2013, 18:11) Ита... Jan 28 2013, 14:46  Буратино Цитата(xemul @ Jan 28 2013, 18:46) Для та... Jan 28 2013, 14:52   ReAl Цитата(xemul @ Jan 28 2013, 18:10) Т.к. в... Jan 28 2013, 18:45 Буратино Задача А. Работа над ошибками так сказать..
В этой... Jan 29 2013, 14:52 _Pasha О майн Готт! Вы на листинг этого чуда хоть смо... Jan 29 2013, 15:16 Буратино Цитата(_Pasha @ Jan 29 2013, 18:16) О май... Jan 29 2013, 15:43  _Pasha Цитата(Буратино @ Jan 29 2013, 19:43) неа... Jan 29 2013, 15:55 xemul K&R всплакнули бы от умиления...
Есть такая пр... Jan 29 2013, 16:01 Буратино _Pasha , функция работает в двух так сказать режим... Jan 29 2013, 16:25 xemul Кодint main() {
char s[]= ... Jan 29 2013, 16:33 Буратино Код#define LEN_BUF 10
stdout:
4WTAtI6xjZc=v... Jan 29 2013, 17:09 Буратино Есть указатель на указатель на char:
Кодchar **ar... Feb 27 2013, 20:10  igorle обычно это имя переменной, которую получает main. ... Feb 27 2013, 21:03 toweroff Да поправят меня, если не прав
Указатель передает... Feb 27 2013, 21:08 Lotor Цитата(toweroff @ Feb 28 2013, 01:08) Да ... Feb 28 2013, 04:17 igorle Цитата(toweroff @ Feb 28 2013, 01:08) Да ... Feb 28 2013, 06:45  demiurg_spb Цитата(igorle @ Feb 28 2013, 10:45) То чт... Feb 28 2013, 07:06   igorle Цитата(demiurg_spb @ Feb 28 2013, 10:06) ... Feb 28 2013, 07:37    demiurg_spb На платформе АVR и так и сяк будет двойной расход ... Feb 28 2013, 07:39     igorle Цитата(demiurg_spb @ Feb 28 2013, 10:39) ... Feb 28 2013, 07:45      demiurg_spb Цитата(igorle @ Feb 28 2013, 11:45) На MS... Feb 28 2013, 07:58       igorle Цитата(demiurg_spb @ Feb 28 2013, 10:58) ... Feb 28 2013, 08:27        toweroff Цитата(igorle @ Feb 28 2013, 12:27) Я так... Feb 28 2013, 08:48     XVR Цитата(demiurg_spb @ Feb 28 2013, 11:39) ... Feb 28 2013, 08:29      demiurg_spb Цитата(XVR @ Feb 28 2013, 12:29) О! В... Feb 28 2013, 08:33 Буратино igorle ,вы привели программу
Кодvoid foo1(int ... Feb 28 2013, 12:11 igorle ЦитатаМне кажется, что argv не указатель на указат... Feb 28 2013, 13:49 Буратино Не думаю, что массив и указатель одно и то же. Ука... Feb 28 2013, 14:33 igorle Указатель и массив - это не одно и то же. Но имя м... Feb 28 2013, 14:52  Tahoe Цитата(igorle @ Feb 28 2013, 18:52) Указа... Mar 1 2013, 02:45   ReAl Цитата(Tahoe @ Mar 1 2013, 04:45) Дьявол ... Mar 3 2013, 07:16    Tahoe Цитата(ReAl @ Mar 3 2013, 11:16) Имя масс... Mar 3 2013, 08:53     ReAl Цитата(Tahoe @ Mar 3 2013, 10:53) Ещё раз... Mar 3 2013, 09:56 Буратино Я вот думаю, что указатель на указатель использует... Mar 2 2013, 08:01 igorle Цитата(Буратино @ Mar 2 2013, 11:01) Скаж... Mar 2 2013, 10:41 XVR Цитата(Буратино @ Mar 2 2013, 12:01) Я во... Mar 2 2013, 14:39  igorle Цитата(XVR @ Mar 2 2013, 18:39) Код int d... Mar 2 2013, 14:51   XVR Цитата(igorle @ Mar 2 2013, 18:51) Забавн... Mar 2 2013, 19:43 Буратино Да, оч. интересно! Правда не совсем ппонимаю,... Mar 2 2013, 22:07 ReAl Цитата(Буратино @ Mar 3 2013, 00:07) Да, ... Mar 3 2013, 07:25 igorle Цитата(XVR @ Mar 2 2013, 23:43) Это один ... Mar 3 2013, 07:22 ReAl Цитата(igorle @ Mar 3 2013, 09:22) это дв... Mar 3 2013, 08:13 igorle ЦитатаЕсли я использую библиотечные функции, ну на... Mar 3 2013, 07:38
3 страниц
1 2 3 >
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|