| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > проблем с выводом результата функции |
| Автор: Kinch 13.1.2009, 17:15 |
| народ помоги пжлст!! Задача такая Написать Функцию которая переводит заданный одномерный массив в зеркальное отображение и выводит его на экран. вот код int z (int*a, size_t s) { int*b=newint [s]; int k=(s-1); int i=0; while ((i<s)&&(k=0)) {b[k]=a[i]; --k; ++i} проблема такая-как заставить функцию вывести получившийся массив на экран? по элементам в цикле нельзя((( помогите пжлст, срочно нуна!!)) |
| Автор: jonie 13.1.2009, 18:07 | ||
|
| Автор: Kinch 13.1.2009, 18:48 |
| спс)) ща проверю)) |
| Автор: Kinch 13.1.2009, 19:09 |
| нехочет((( помогите пжлст!!! |
| Автор: Kinch 13.1.2009, 19:35 | ||
вот код полностью(( он робит(( |
| Автор: pan2004 13.1.2009, 20:31 | ||||
| Два вопроса: 1. Что это за ... такое?
2. Тут что-то явно не так. Смотреть разницу между = и == (в C это разные вещи, примерно как := и = в Паскале)
|
| Автор: Kinch 13.1.2009, 20:38 | ||||
вызов функции, разве не так?
исправил) |
| Автор: pan2004 13.1.2009, 20:43 |
И что, работает? Если нет, подумай, чему равно i. И почему не написано просто z(a, n). |
| Автор: cutwater 13.1.2009, 20:56 | ||
Вопрос не в этом... объясните весь кармический смысл взятия адреса итого элемента массива, при чем после цикла i == n следовательно Вы берете адрес на не выделенную область памяти. Вопрос второй, Вы выделяете в функции z память под еще один массив. Во-первых не удаляете один из них ( по логике старый). во-вторых этот новый массив с "зеркальным отражением" по выполнении функции попросту исчезает, то есть смысл его создавать 0 И 3 можно было бы организовать в один цикл без выделения памяти под еще один массив... И короче говоря если я правильно понял задачу, то вот мой вариант.
Честно говоря голова после рабочего дня отказывается работать, так что если где не прав или не понял задания прошу извинить |
| Автор: baldina 13.1.2009, 20:57 |
| for (--end; begin<end; ++begin, --end) |
| Автор: cutwater 13.1.2009, 20:58 |
| 2 mes У Вас, признаюсь, более красивое решение, хотелось бы только чтобы человек научился думать, ибо посмотрев в код очевидно что необходимо понимать что пишешь. |
| Автор: mes 13.1.2009, 21:01 |
| Автор: baldina 13.1.2009, 21:02 |
| у mes и более универсальное, если параметризовать тип в последовательности |
| Автор: Kinch 13.1.2009, 21:19 |
| mes, а Вы можете пошагово пояснить что вы делали и написать код полность,?)) а то я ничо не понял(( |
| Автор: mes 13.1.2009, 21:49 | ||
код по полноте более, чем достаточен. подробнее писать принципиально не буду. |
| Автор: Kinch 13.1.2009, 21:53 |
| mes, премнога благодарен |
| Автор: UnrealMan 13.1.2009, 23:53 | ||||
Добавлено через 58 секунд А если массив пустой? |
| Автор: mes 14.1.2009, 00:22 |
Хм.. Не понял намека. То end станет меньше begin и цикл не выполнится. Проблема будет в том случае, если переданный указатель будет ноль. Но это в рамки задачи не входит. aa.. или Вы для случая с итeраторами ? В этом случае да.. но дополнительные проверки делать не хотел, чтоб не путать логику. Опять же это ,имхо, не входит в рамки задачи. |
| Автор: UnrealMan 14.1.2009, 00:35 |
По стандарту это undefined behavior. |
| Автор: jonie 14.1.2009, 10:12 | ||||
| UnrealMan ну эт у тебя "написано до нас") никто не спорит, что можно написать и так:
но нахрена так усложнять процесс.. если достаточно:
конечно, первое неимоверно "круто", но удобно имхо только если это "черный ящик".... |
| Автор: mes 14.1.2009, 10:36 | ||
При арифметике указателей ?? ну ладно..подправляю :
|
| Автор: vinter 14.1.2009, 10:56 |
зря правил, нет там UB для голых указателей |
| Автор: baldina 14.1.2009, 10:59 | ||||
в общем случае (итераторы) правильно было бы использовать для сравнения не "меньше", а "не равно". и с точки зрения --end и с точки зрения требований к итераторам в данном алгоритме
|
| Автор: UnrealMan 14.1.2009, 11:53 |
Откуда такая уверенность? Ты прочитал в стандарте все правила, касающиеся префиксного декремента указателей? Я что-то не понял, в чём там заключается неимоверная крутизна и о чём вообще этот твой пост Два сравнения в цикле - это излишество. |
| Автор: baldina 14.1.2009, 12:45 | ||||||
есть альтернативные предложения? хотелось бы увидеть... пожалуйста, с учетом, что first и last это bidirectional iterator Добавлено через 2 минуты и 42 секунды для обычных указателей все гораздо проще
Добавлено через 7 минут и 8 секунд
Что именно "это"? |
| Автор: mes 14.1.2009, 13:16 | ||
либо -- не там, либо один лишний swap |
| Автор: UnrealMan 14.1.2009, 13:33 | ||
Итераторы произвольного доступа являются двунаправленными, но это не мешает использовать для них оператор <. Можно сделать две отдельные реализации для итераторов произвольного доступа и для других двунаправленных итераторов, вместо того чтобы следовать твоему тезису
Посмотри любую современную реализацию std::reverse в STL от VC++, GCC или в STLport. Наверняка там не будет использоваться единый алгоритм для всех двунаправленных итераторов. Если в функцию в качестве параметра end передаётся указатель на конец массива, одновременно являющийся его началом (такой массив может быть создан посредством new T[0]), а потом к end пытаются применить декремент, то такая попытка влечёт undefined behavior. |
| Автор: jonie 14.1.2009, 13:33 | ||
UnrealMan я про то, что чет вы тут сейчас накрутите сложностей, которые автор топика не поймет... смысл тогда от них сомнителен. |
| Автор: UnrealMan 14.1.2009, 13:42 |
Каких сложностей? Я привёл простейшую реализацию функции, описанной в первом посте темы. |
| Автор: vinter 14.1.2009, 14:15 |
на каком основании? Пожалуйста пункт из стандарта, да и логику рассуждений неплохо бы расписать. Как по твоему декремент указатель может быть UB? |
| Автор: baldina 14.1.2009, 15:06 | ||||||
| UnrealMan, ты невнимательно читал меня. естественно для разных типов итераторов эффективный код будет разный. и не удивлюсь, если в конкретной реализации STL он будет похож на то, что я написал для bidirectional и random access соответственно я как раз имел в виду, что для bidirectional (не random) нет эффективной реализации distance. я пока не вижу более эффективной реализации для этого вида итераторов, т.е. без двух сравнений в цикле. не поленюсь после поста посмотреть в исходники STL...
в чем undefined behavior? разадресовывать его бессмысленно, но изменение самого указателя - вполне осмысленная операция. причем гарантируется, что ++(--p) == p Добавлено через 3 минуты и 2 секунды посмотрел. вот результат: STLPort
VC++ 7.1
я не удивлен... |
| Автор: UnrealMan 14.1.2009, 15:14 |
На таком, что это следует из текста стандарта. Возможно, есть специфические архитектуры, где декремент указателя может привести к переполнению. Но даже на широкоиспользуемых платформах можно поиметь неприятность: при отладке программы под профилировщиком может быть выдано предупреждение, а выискивать среди "ненужных" сообщений профилировщика те, которые свидетельствуют о реальных багах, мало кто любит. А давай наоброт: ты покажешь весь абзац в стандарте, где изложена информация по поводу того, куда в таком случае должен указывать результирующий указатель, а я тебе тогда покажу, где в этом абзаце сказано, когда наступает undefined behavior |
| Автор: baldina 14.1.2009, 15:18 | ||||
mes, практические накладные расходы на один swap ничтожно малы. и его оптимизация имхо не оправдывает усложнения кода. а так все просто и понятно. ЗЫ: лишний swap будет только для последовательностей с нечетным числом элементов |
| Автор: mes 14.1.2009, 15:23 | ||||
я специально добавил уточнение : имхо, в данном случае это не оптимизация, а правильный набор условий. Добавлено @ 15:25
неважно, главное он вызывает напряг и заставляет подумать, а не будет ли последствий от этого но в целом наверное это дело вкуса.. |
| Автор: UnrealMan 14.1.2009, 15:25 |
Ткни пальцем, где конкретно там у тебя говорилось про итераторы, не являющиеся random access. |
| Автор: mes 14.1.2009, 15:26 | ||
Это он к тому, что (грубо) для не-RandomAccess итераторов операция < (реализованная через distance) является "тяжелой". |
| Автор: baldina 14.1.2009, 15:29 | ||
да, UnrealMan, свою правоту нужно доказывать в нашем случае совершенно неважно, куда он будет указывать. важно лишь то, что он не перестает быть указателем с осмысленным значением, к нему можно применять инкремент, декремент, сравнивать с другими указателями. в этом смысле здесь вполне specific behavior. |
| Автор: UnrealMan 14.1.2009, 15:34 |
Сможешь подтвердить свои домыслы выдержками из стандарта C++? |
| Автор: baldina 14.1.2009, 15:59 | ||||||||
я написал версию именно для bidirectional iterators. мне казалось template <typename BidirectIt> довольно однозначно говорит об этом. потом я сказал это открытым текстом. Добавлено через 1 минуту и 2 секунды
UnrealMan, Стандарту ничего неизвестно о нашем конкретном приложении |
| Автор: UnrealMan 14.1.2009, 16:12 | ||||||
Вот так выглядит объявление std::reverse в стандарте:
И что отсюда следует? Что она не годится для работы с итераторами произвольного доступа? |
| Автор: baldina 14.1.2009, 16:16 |
| она-то годится. а вот версия для произвольного доступа не годится для двунаправленных. |
| Автор: vinter 14.1.2009, 16:19 | ||||||||||
где тут хоть слово про UB?
возможно когда мы сидим у нас за спинами сидят слоны, а когда мы поворачиваемся то слоны прячутся. Я вижу лишь одну потенциальную проблему, это когда указатель будет указыватть на нулевой адрес.
бесспорно, но это никакого отношения к языку не имеет. К тому же это из головы или реально были траблы такие с профайлерами? С чего бы ему ругатся? границы не нарушены, разыменовывания не происходит |
| Автор: baldina 14.1.2009, 16:21 |
| короче мы походу запутались. распутываю: UnrealMan указал, что два сравнения в цикле неэффективно. 1. я сказал, что если это Bidirectional Iterator (а я именно его и имел в виду), то вряд ли этот код можно улучшить. поглядев в STL можно увидеть, что там реализации для Bidirectional и для Random Access практически идентичны моим. 2. требования к Bidirectional Iterator слабее, чем к Random Access, поэтому версия для Bidirectional Iterator более общая, она может работать и с Bidirectional и с Random Access. но не наоборот. 3. нигде в коде не происходит разадресации недействительного указателя, потому рассуждения о UB не имеют смысла |
| Автор: UnrealMan 14.1.2009, 16:22 |
Ну, значит, из одного такого объявления не очевидно, что функция предназначена для работы с двунаправленными итераторами, не являющимися итераторами произвольного доступа. Какие тогда ко мне претензии? |
| Автор: UnrealMan 14.1.2009, 16:44 | ||
Ты мало процитировал. Что такое вычитание 1 из указателя? Куда будет указывать результирующий указатель? Стандарт описывает это. Ты пропустил важное предложение
(аналогичное справедливо для декремента: для объектов встроенных типов --x - эквивалент x-=1). Копай дальше. |
| Автор: vinter 14.1.2009, 16:57 | ||
UnrealMan, извиняюсь, был не прав. Дибильное правило не поддающееся логике. |
| Автор: UnrealMan 14.1.2009, 17:10 |
Исход этого спора был предрешён: в вопросах, касающихся стандарта, я очень редко бываю неправ |
| Автор: jonie 14.1.2009, 22:27 |
| пологаю что подобное может быть связано с неописанием работы менеджера памяти, который может не захотеть пускать вас в, возможно, служебную (или иначе "не вашу") память в случае простых массивов или действительно неопределенностью, в случаях более сложных типов ... хотя, мб есть и иные доводы. |