Перейти к содержанию
    

demiurg_spb, мне не очень понравилось. читаемость отвалилась, а скилов не добавилось как по мне.

Профит есть 2 строчки кода с хорошей читаемостью вместо 6..9 строк кода в другой реализации.

Вы это поймёте, когда будете писать большие программы, в которых становится важна не только выразительность отдельно взятой процедуры, а модуля целиком... Всему своё время.

 

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;
}

Кстати:) В этом кусочке кода три ошибки (три лишних символа &).

А вы говорите хорошая читаемость... Чем лаконичнее, тем ИМХО профессиональнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ищу самую правильную и изящную реализацию, хочу вот именно так и не иначе.

Если речь идет о первом вопросе, то логичнее не попадать в такую ситуацию. Строки не сами по себе появляются в программе. Вот в момент создания и заносить символы в нужном порядке.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

давайте его допилим и

Чо там пилить?

void reverse(char *s)
{
 if(s == NULL) return;
 char *end = s;
 while(*end) end++;
 while(s < end)
 {
   char c = *s;
   *s++ = *(--end);
   *end = c;
 }
}

Упс... может, они это имели в виду, что при передаче не-указателя не нужно его проверять?

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

по поводу тройной пересылки мы еще поговорим, а вот второй буфер не айс однозначно. во первых b[j--] => a[i++] в 2 раза больше нужно а во вторых место под буфер.

Я бы поспорил насчет в два раза, и про место под буфер

Так что удачи...

Изменено пользователем telix

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Давайте в первом чтении вот такую версию ЗАДАЧИ А от _Pasha обсудим?

#include <string.h>
void reverse ( char *s ) {

   char *beg = s;
   char *end = &s[strlen(s)];
   char c;

   while(beg < end) {
       c = *beg;
      *beg++ = *--end; // благодаря префиксному декременту end терминатор строки '\0' останется на своем месте
      *end = c;
   }
}

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для нелюбителей тройных пересылок есть одна бяка

while(beg < end)
{
  *beg++ = *(--end);
  *end = *beg;
}

Строка "сползает", но ее можно искусственно расширить и передать указ. не на начало, а на s[1]

Бред, в общем случае, но.. если у нас не char а нечто более существенное, пересылки могут доставить

ЗЫ вот только для чего эти сферокони, не пойму :)

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для нелюбителей тройных пересылок есть одна бяка

...

Строка "сползает"

Так вы потеряете первый символ строки... и т.д.

++ инкрементирует указатель после использования.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так вы потеряете первый символ строки... и т.д.

А не надо его терять. Первый символ !=0 и всё, а сама строка начинается со второго. Ассемблерные заморочки :)

Кстати, такая штуковина со "сползанием и перестановкой" может в графике пригодиться

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А не надо его терять. Первый символ !=0 и всё, а сама строка начинается со второго. Ассемблерные заморочки :)

Кстати, такая штуковина со "сползанием и перестановкой" может в графике пригодиться

Т.е. начать переносить на 1 символ левее строки? Тогда в середине появится разрыв. :laughing:

По-моему, без промежуточной переменной - никак!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот немного "заоптимизировал". Теперь переменной "с" нет, но есть 3 дополнительные арифметич. действия. Какие есть мысли, соображения? Спасбио!

#include <string.h>
void reverse ( char *s ) {

   char *beg = s;
   char *end = &s[strlen(s)-1];

      do {
         *end -= *beg;
         *beg += *end;
         *end = *beg - *end;
      } while (++beg < --end);
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Т.е. начать переносить на 1 символ левее строки? Тогда в середине появится разрыв. :laughing:

По-моему, без промежуточной переменной - никак!

Ага, ошибочка вышла. Да простит меня высокое собрание.

 

Какие есть мысли, соображения? Спасбио!

На общеприменяемых архитектурах будет хуже. Потому что "лишний" char c есть регистровая переменная. А так - добавляются операции, такие же переменные неявно выделяются компилятором, но самое обидное будет если у нас не char, а long например.

В принципе, вместо + - как у Вас надо бы

поменять местами A,B
A ^= B;
B ^= A;
A ^= B;

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ага, ошибочка вышла. Да простит меня высокое собрание.

 

 

На общеприменяемых архитектурах будет хуже. Потому что "лишний" char c есть регистровая переменная. А так - добавляются операции, такие же переменные неявно выделяются компилятором, но самое обидное будет если у нас не char, а long например.

В принципе, вместо + - как у Вас надо бы

поменять местами A,B
A ^= B;
B ^= A;
A ^= B;

 

с исключающим или мне не очень, хотя красиво конечно a ^= b ^= a ^= b;

 

Вот еще вариантец, только проверить нужно. Кстати как можно простенькие такие программки потестить? Например в самом ИАРе? Как в отладочное окно выводить результаты всяких printf? Спрашивал однажды и запамятовал к сож(

#include <string.h>
void reverse ( char *s ) {

   char *beg = s;
   char *end = &s[strlen(s)-1];

    do 
       *beg += *end - (*end = *beg);
    while (++beg < --end);
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, верно, с исключающим или можно обойтись без промежуточной переменной (знал, но забыл). Но это не будет эффективнее, чем использовать еще один регистр.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот еще вариантец, только проверить нужно. Кстати как можно простенькие такие программки потестить?

У меня три вивария, с чем работаю, симуляторы

1. C::B + Proteus для аврок - всё в два клика, но создать проект под АРМ - муки творчества, ибо визардов нормальных нету, поэтому

2. Кейл, там тоже элементарно, исключительно из-за stm32 и at91sam7s

3. Mplab

Сыр-бор весь только чтобы глянуть листинг.

Изменено пользователем _Pasha

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кстати как можно простенькие такие программки потестить? Например в самом ИАРе? Как в отладочное окно выводить результаты всяких printf?

C:\user\My documents>echo "#include <stdio.h>\
int main()\
{\
      printf (\"Hello, world\");\
      return 0;\
}\
" > test.c

C:\user\My documents>gcc test.c -o test.exe
C:\user\My documents>test.exe
Hello, world
C:\user\My documents>

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...