Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.98/50: Рейтинг темы: голосов - 50, средняя оценка - 4.98
8 / 3 / 2
Регистрация: 12.02.2013
Сообщений: 68

ф-ция реверса строки

14.05.2013, 10:51. Показов 11014. Ответов 110
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
был вчера на собеседовании, попросили написать ф-цию реверса строки (поменять местами 1й и последний символы, 2й и предпоследний и т.д.), но ф-ция должна принимать параметром указатель на char т.е. на начало строки и все. я там немного тупанул но написал, вот хочу узнать есть ли решение получше моего.
вот код (писал в Embarcadero RAD Studio (Borland)):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//ф-ция принимает указатель на массив char с символом окончания строки '\0'
//и производит реверс полученного массива
void TForm1::reverce(char *str)
{
    char* end_str = &str[0];
 
    while (*end_str != '\0') ++end_str;
    
    char  buf;
    while (end_str > str)
    {
        --end_str;
        buf      = *str;
        *str     = *end_str;
        *end_str = buf;
        ++str;  
    }
}
кто захочет проверить, выносим кнопку, лабел и эдит на форму и в ивент на клик кнопки пишем:
C++
1
2
3
4
5
AnsiString str = Edit1->Text.c_str();
 
    reverce(str.c_str());
 
    Label1->Caption = str;
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.05.2013, 10:51
Ответы с готовыми решениями:

Функция реверса строки
На собеседовании в одну компанию меня попросили на бумажке написать функцию реверса строки. Буквально парой дней раньше я услышал о том...

Написание программы реверса строки
Не могу понять в чем ошибка выдаёт (2 3 3 3 3 3 3 3 3 3) Прошу помощи в нахождении ошибки. #include "stdafx.h" #include...

Какая ф-ция в VC++ определяет длину строки???
Здравствуйте ... не могу разобраться со строками в VC++ помогите пожалуйста

110
8 / 3 / 2
Регистрация: 12.02.2013
Сообщений: 68
14.05.2013, 16:38  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от ninja2 Посмотреть сообщение
А с начала стека можно?

А чо нельзя ошибка будет? Или оно половину удалит, а половину оставит?
delete и delete[], на сколько я знаю вызывается только для указателей (delete[] - для указателей на массивы)
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
14.05.2013, 16:55
Цитата Сообщение от igor001 Посмотреть сообщение
только для указателей
на объект в динамической памяти (куче). Например так делать нельзя:
C++
1
2
3
4
5
int main() {
   int i;
   delete &i; // ошибка выполнения
   return 0;
}
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
14.05.2013, 16:57
Tulosba, Я бы сказал, что это UB, а будет-ли это ошибкой выполнения (или форматированием жесткого диска) зависит от реализации
0
14.05.2013, 17:09

Не по теме:

Цитата Сообщение от ForEveR Посмотреть сообщение
Я бы сказал, что это UB, а будет-ли это ошибкой выполнения (или форматированием жесткого диска) зависит от реализации
Мне повезло. У меня просто ошибка выполнения :)

0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
14.05.2013, 17:19
Цитата Сообщение от ForEveR Посмотреть сообщение
Я бы сказал, что это UB, а будет-ли это ошибкой выполнения (или форматированием жесткого диска)
А диск то здесь при чём? В худшем случае порча инфы в памяти.
0
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
14.05.2013, 17:25
taras atavin,
In the first alternative (delete object), the value of the operand of delete may be a null pointer
value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8)
representing a base class of such an object (Clause 10). If not, the behavior is undefined.
undefined behavior
behavior for which this International Standard imposes no requirements
Мы ведь говорим про С++? Стандарт С++ не регламентирует, что может произойти в случае UB. Следовательно быть может все что угодно. Вы погуглите, ради интереса, многое найдете.
0
 Аватар для сайфонг
0 / 0 / 0
Регистрация: 13.05.2013
Сообщений: 6
14.05.2013, 17:25
не могу исправит ошибку в вижел студии что надо для этого сделать
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
14.05.2013, 17:35

Не по теме:

Цитата Сообщение от сайфонг Посмотреть сообщение
не могу исправит ошибку в вижел студии что надо для этого сделать
расставить знаки препинания для начала



Добавлено через 2 минуты
Цитата Сообщение от ForEveR Посмотреть сообщение
If not, the behavior is undefined.
Но тут не стоит забывать и о корреляции. Сомнительно, скажем, чтобы запущенный в виртуалке компилятор смог отформатировать реальный диск, несмотря на все возможности UB
0
4866 / 3287 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
15.05.2013, 02:00
Цитата Сообщение от igor001 Посмотреть сообщение
в случае пустой строки, указатель end_str указывает на область памяти перед 1м эл-том соответственно в цикл прога не заходит
при циклической реализации "область памяти перед первым элементом" может оказаться с другой стороны
по стандарту правильный результат сравнения указателей гарантируется только для адресов элементов одного массива
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,469
15.05.2013, 09:10
Цитата Сообщение от accept Посмотреть сообщение
может оказаться с другой стороны
вот поэтому нужно что бы это был указатель на последний элемент. в случае пустой строки этот указатель останется равным началу строки и заход в цикл не произойдет по условию "меньше" так как указатели будут равны
0
8 / 3 / 2
Регистрация: 12.02.2013
Сообщений: 68
15.05.2013, 09:56  [ТС]
Цитата Сообщение от accept Посмотреть сообщение
при циклической реализации "область памяти перед первым элементом" может оказаться с другой стороны
по стандарту правильный результат сравнения указателей гарантируется только для адресов элементов одного массива
я немного неправильно изложил мысль. я имел в виду что в случае пустой строки указатель end_str будет указывать на ячейку памяти перед символом окончания строки, т.е. туда, где был бы 1й символ строки. Полагаю можно это сравнить с итераторами в том же векторе, когда end() возвращает указатель на ячейку памяти за последним элементом массива, в нашем случае это символ окончания строки.
в общем получился следующий код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//ф-ция принимает указатель на массив char с символом окончания строки ('\0')
//и производит реверс полученного массива
//возвращает true в случае успешного выполнения
//возвращает false в случае передачи "нулевого указателя" либо указателя на пустую строку
bool TForm1::reverse(char *str)
{
    if(!str || !*str) return false;     
 
    char* end_str = &str[0];    
 
    while (*++end_str);     
 
    while (--end_str > str)     
    {
        register char buf = *str;   
        *str              = *end_str;
        *end_str          = buf;
        ++str;
    }
 
    return true;
}
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,469
15.05.2013, 10:14
Цитата Сообщение от igor001 Посмотреть сообщение
следующий код
возврат false для пустой строки - спорный вопрос. вполне можно вернуть true - попробуйте докажите что мы не обратили строку ?
еще раз хотелось бы отметить что
C++
1
char* end_str = &str[0];
рационально записать как
C++
1
char* end_str = str;
+ в 1001 раз хотелось бы обратить ваше внимание что увлечение инкрементом поставленным перед указателем приводит к тому что вы начинаете поиск конца строки со второго символа. это совсем ни к чему. во всяком случае когда я такое вижу начинаю нервничать - вроде бы ничего не случилось (поскольку мы отсекаем случай пустой строки на входе) но тревожное состояние уже наступило кроме того можно выкинуть условия проверки пустой строки если пользоваться инкрементом после указателя.
1
8 / 3 / 2
Регистрация: 12.02.2013
Сообщений: 68
15.05.2013, 10:38  [ТС]
vxg, полностью с Вами согласен, это не очень хороший стиль программирования. А сделать чтобы ф-ция возвращала булево значение я решил следуя из тех соображений, что таким образом ф-ция может еще и проверить пустая ли строка и указывает ли указатель на строку вообще, хотя это сокрее всего тоже не есть хорошо, так как работа этой ф-ции лишь изменить строку в соответствии с требованиями.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void TForm1::reverse(char *str)
{
    if(!str) return;
 
    char* end_str = str;
 
    while (*end_str) ++end_str;
 
    while (--end_str > str)
    {
        register char buf = *str;
        *str              = *end_str;
        *end_str          = buf;
        ++str;
    }
}
ЗЫ: в первоначальной версии почти так "while (*end_str) ++end_str;" и было))
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,469
15.05.2013, 10:46
Цитата Сообщение от igor001 Посмотреть сообщение
не
вы уменьшаете end_str в цикле перестановки. если строка пустая, то, в случае если end_str равно str и указывает на "начало" памяти при уменьшении вы получите "конец" памяти то есть указатель больший чем str и войдете в цикл. это не гуд

Добавлено через 1 минуту
...кроме того теперь в этом нет нужды - раньше вы были вынуждены так делать потому что после подсчета строки получали end_str указывающий на символ после конца строки. теперь в цикле перестановки вы просто можете делать декремент в теле
0
8 / 3 / 2
Регистрация: 12.02.2013
Сообщений: 68
15.05.2013, 11:05  [ТС]
vxg, а вот теперь Вы неправы

Цитата Сообщение от vxg Посмотреть сообщение
вы уменьшаете end_str в цикле перестановки. если строка пустая, то, в случае если end_str равно str и указывает на "начало" памяти при уменьшении вы получите "конец" памяти то есть указатель больший чем str и войдете в цикл. это не гуд
в начале выполняется проверка указателя и если он указывает на 0, на сколько я помню там быть ничего не должно, то будет реторн из ф-ции, к тому же массивы располагаются в памяти строго последовательно, а это означает что Ваше следующее заключение так же неверно

Цитата Сообщение от vxg Посмотреть сообщение
кроме того теперь в этом нет нужды - раньше вы были вынуждены так делать потому что после подсчета строки получали end_str указывающий на символ после конца строки. теперь в цикле перестановки вы просто можете делать декремент в теле
указатель end_str сдвигается вперед и не может выйти за пределы массива, т.к. символ окончания строки является его частью. т.е.:
while(символ)
символ?
да
указатель ++ (сдвинулись и сейчас end_str указывает на '\0')
символ?
нет
break

Добавлено через 2 минуты
хотя посмотрев в дебагере все еще лучше. В случае пустой строки по указателю находится сразу символ окончания строки, так что оба цикла пропускаются, т.к. условия входа в них не выполняются

Добавлено через 4 минуты
мб я не очень хорошо умею излагать свои мысли, за это уж простите))
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,469
15.05.2013, 11:15
Цитата Сообщение от igor001 Посмотреть сообщение
к тому же массивы располагаются в памяти строго последовательно, а это означает что Ваше следующее заключение так же неверно
не знаю что вы этим хотите сказать. вот у нас строка. вот у нас оперативная память. ячейки оперативной памяти имеют адреса от 100 (что бы вы не зацикливались на числе 0 - не нужно жестко ассоциировать 0 и NULL) до 200 (ну пускай). строка расположена по адресу 100. мы делаем декремент и получаем 200 (такое вот свойство у арифметики). хотя может я чего то и не выткаю но просто привык к тому что такое может случаться: если что то уменьшаешь ниже пола будь готов что оно может выпрыгнуть тебе на голову.
Цитата Сообщение от igor001 Посмотреть сообщение
не может выйти за пределы массива
имелся ввиду выход за пределы перестановочной части. у вас раньше был инкремент в условии и вы всегда завышали значение указателя.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
15.05.2013, 11:23
Цитата Сообщение от vxg Посмотреть сообщение
возврат false для пустой строки - спорный вопрос. вполне можно вернуть true - попробуйте докажите что мы не обратили строку
А нужно ли вообще возвращаться какое-то значение?
Кстати, вот, если еще не видели.
0
8 / 3 / 2
Регистрация: 12.02.2013
Сообщений: 68
15.05.2013, 11:48  [ТС]
я понял что Вы имели в виду. сначала выполняется "while (*end_str) ++end_str;" т.е. указатель продвигается по массиву до тех пор пока не достигнет терминального нуля, а лишь потом выполняется операция декремента указателя "while (--end_str > str)", т.е. в этом цикле указатели "двигаются" в пределах массива навстречу друг другу (а в пределах массива сравнение указателей по стандарту гарантировано, на сколько я знаю). так что все в порядке

Добавлено через 21 минуту
Tulosba, по ссылке в принципе то же самое, но, конечно, с битовыми операциями сильно)) минус переменная. правда все-таки в варианте, который здесь написан, по моему мнению, если сделать переброску символов не через переменную, а битовыми операциями, лучше

Добавлено через 3 минуты
получается что-то вроде следующего:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void reverse(char *str)
{
    if(!str) return;
 
    char* end_str = str;
 
    while (*end_str) ++end_str;
 
    while (--end_str > str)
    {
        *str     ^= *end_str;
        *end_str ^= *str;
        *str     ^= *end_str;
        ++str;
    }
}
0
Модератор
 Аватар для vxg
3410 / 2182 / 354
Регистрация: 13.01.2012
Сообщений: 8,469
15.05.2013, 11:54
Цитата Сообщение от igor001 Посмотреть сообщение
так что все в порядке
тогда уж как раньше народ предлагал
C++
1
    if(!str || !*str) return;
Добавлено через 55 секунд
иначе
C++
1
while (--end_str > str)
может погнать
0
8 / 3 / 2
Регистрация: 12.02.2013
Сообщений: 68
15.05.2013, 11:59  [ТС]
vxg, запусти у себя эту ф-цию и попробуй сломать, посмотри через дебаг. лично я никаких траблов не смог найти
а проверка указателя нужна на тот случай если кто-нибудь додумается передать в ф-цию нулевой указатель, а все строки в С стиле заканчиваются терминальным нулем, так что передача нулевого указателя в ф-цию это самое опасное что может произойти, по идее))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.05.2013, 11:59

Программа реверса строки: почему на экран выводится мусор, вместо нужного текста?
Пишу программу реверса строки (меняет местами первый символ и последний, второй и предпоследний и т.д.). На экран выводится мусор, вместо...

Защита от реверса ( md5 )
Люди посоветуйте как сделать проверку по md5 файла. Всё работает, НО. Я когда считаю хэш и вставляю его в исходники, хэш уже билда сразу...

Реализация реверса массива
Первый и последний элемент массива трогать не надо. Как его толком перевернуть? По-разному пробовал уже, не хотят циферки по серединке...

Защита от реверса проекта
Подскажите, в какую сторону копать, хочу, чтобы программа не могла быть запущена в отладчике?

Ошибка в создании реверса массива
#include <iostream> #include <Windows.h> #include <conio.h> #include <stdlib.h> #include <time.h> using namespace std; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
Алиса нашла кучу ошибок компиляции и запуска в проекте, который без проблем компилировался и запускался)))
anaschu 30.06.2026
Я пока посмеюся, но завтра проверю. А вообще интерсно. Дал алисе файл, в котором точно нет ошибок компиляции и запуска, и попросил их найти. Нашла кучу))) Критические ошибки, мешающие компиляции и. . .
сукцессия 16. Общий обзор, в основном что бы другие ии поняли
anaschu 29.06.2026
# Передаточный документ: модель микоризной сукцессии (для нового чата) Этот документ предназначен для того, чтобы новый чат Claude мог продолжить работу без необходимости заново разбираться в. . .
сукцессия 15 неявная схема
anaschu 29.06.2026
Алиса Калибровка параметров симбиотической модели: технический обзор Содержание: Введение Постановка проблемы Технические аспекты реализации Процесс внедрения изменений
сукцессия 14. Обновленная схема модели
anaschu 28.06.2026
ГЛОБАЛЬНАЯ ОПИСАТЕЛЬНАЯ СПЕЦИФИКАЦИЯ ЭКОСИСТЕМНОЙ МОДЕЛИ «SOIL CHEMISTRY & MYCORRHIZA 2. 0» https:/ / ibb. co/ NnkGpfMd Представленная интегрированная схема описывает непрерывную нелинейную. . .
сукцессия 13. Питон модель трехзонного мицелия, пока что в основном арбускулярного
anaschu 28.06.2026
## Разработка агентной модели микоризной сукцессии: от выявления артефактов к созданию комплексной системы ### Аннотация Представлено исследование по разработке агентной модели микоризной. . .
сукцессия 12. краткий список проверок модели перед запуском.
anaschu 27.06.2026
Скрытые отказы в моделях систем динамики (SD-models) экологических систем: два случая из практики Контекст Разбирался прототип модели систем динамики (SD-модели) микоризной сукцессии: пять. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru