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

 
 
> Си
Буратино
сообщение Jan 24 2013, 19:24
Сообщение #1


Профессионал
*****

Группа: Свой
Сообщений: 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. Какие есть варианты реализации функции.

Спасибо!


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Буратино
сообщение Jan 28 2013, 14:11
Сообщение #2


Профессионал
*****

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



Вот еще вариант. В основе смелая идея (уже ранее высказанная) о том чтоб испоьзовать буфер, но я немного переосмыслил это дело sm.gif

Код
#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;
}


--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jan 28 2013, 15:04
Сообщение #3


Нечётный пользователь.
******

Группа: Свой
Сообщений: 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];
}
Да, лучше внутри функции.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
xemul
сообщение Jan 28 2013, 16:10
Сообщение #4



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(ReAl @ Jan 28 2013, 19:04) *
Я надеюсь, высказывание касается только того, что перед реверсом либо в процессе оного не проверияется длина строки.

Безусловно.
Т.к. в условии задачи не сказано, что исходная строка должна сохраниться, я бы делал реверс на месте. Цена вопроса - один strlen(). (оно, конечно, не спасёт, если строка вдруг окажется без '\0')
Цитата
Само по себе наличие промежуточного буфера фиксированного размера к ошибкам переполнения буфера не приводит.

К переполнению, естественно, не приведёт. Но если память (опять же вдруг) закончится...

За жисть. У меня K&R был первого советского издания (в мягком переплёте, голубая обложка), не помню в нём таких упражнений. Хотя, может опять склероз буйствует.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jan 29 2013, 08:24
Сообщение #5


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(xemul @ Jan 28 2013, 19:10) *
У меня K&R был первого советского издания (в мягком переплёте, голубая обложка), не помню в нём таких упражнений. Хотя, может опять склероз буйствует.

Во втором издании (в мягком переплете, белая обложка, голубая буква С) есть упражнения по переворачиванию строки.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Буратино   Си   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 страниц V   1 2 3 >


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

 


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


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