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

ЗАДАЧА А

Есть функция (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. Какие есть варианты реализации функции.

 

Спасибо!

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


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

 

В коде ошибка поставьте j-- :)

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

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


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

В коде ошибка поставьте 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. Какие есть варианты реализации функции.

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


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

В смысле 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

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


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

По задаче Б.

переменная типа bool принимает значение 0 и !0 (не 0). В зависимости от реализации компиляторе !0 может выглядеть любым целым числом, поэтому "Out Of Range" - некоррекное заявление.

Изменено пользователем редактор

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


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

По задаче Б.

переменная типа 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;
}

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


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

Неправда! Область значений, согласно stdbool.h -это true,false.

Исходя из того, что в Си bool это всего лишь костыль для пришедших из других языков, и любое не 0-ое значение является истиной для условных операторов, то, ИМХО редактор прав.

 

Задачу А можно оптимизировать сильнее всего исходя из контекста.

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


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

и любое не 0-ое значение является истиной для условных операторов, то, ИМХО редактор прав.

:biggrin:

if(0) - выражение в скобках сейчас == 0

if(!0) - выражение в скобках сейчас == 1

Ы?

 

Задачу А можно оптимизировать сильнее всего исходя из контекста.

Работа непосредственно с двумя указателями выигрывает на любых pic/avr/arm/x51

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


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

В задаче А вижу только один недостаток - это нет проверки на пустую строку. Если длина будет 0, то произойдёт переполнение и запись за пределы строки. По производительности тоже проблем не наблюдаю - можно было бы сделать какой-нибудь ассемблерный SWAP или хотя бы промежуточную переменную поместить в регистр, но это от архитектуры зависит.

В задаче Б всякая жесть. Тип заявлен bool, а передаётся char. Сравнение почему-то с 0 и 1, хотя false и true может быть определена иначе. Нужно сравнивать с настоящими false и true, теми которые используются вашим компилятором.

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


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

грубовато...

const char* b2s (unsigned char b) {
   static const char* name[] = {"False", "True", "Out Of Range", "Out Of Range"};
   return name[b&3];
}

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


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

:biggrin:

if(0) - выражение в скобках сейчас == 0

if(!0) - выражение в скобках сейчас == 1

Ы?

Я имел ввиду немного другое

    if (42)
    {
        printf("True\n");
    }
    else
    {
        printf("False\n");
    }

Какая ветка условного оператора будет выполнена? Третьего "outofrange" не дано, увы.

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


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

Я имел ввиду немного другое

Дык это несовместимость типов. :laughing: Почему к случаям явного приведения int к указателю всегда люди относятся настороженно, а к "притягиванию" bool к char - типа что это нормально?

Примеров привести не могу, у меня не очень богатый сишный опыт. Только анекдот

#define true false // собаки, ковыряйтесь теперь сами

 

:)

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


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

Ага, щаз! А если b например... b=0x0C
Ну так я и сказал что грубовато:)

const char* b2s (unsigned char b) {
   static const char* name[] = {"False", "True", "Out Of Range"};
   return name[(b>1)? 2:b];
}

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


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

В армоводческом смысле 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}

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


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

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

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

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

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

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

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

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

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

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