Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> проблем с выводом результата функции 
:(
    Опции темы
Kinch
  Дата 13.1.2009, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 13.1.2009

Репутация: -1
Всего: -1



народ помоги пжлст!!

Задача такая
Написать Функцию которая переводит заданный одномерный массив в зеркальное отображение и выводит его на экран.

вот код

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}

проблема такая-как заставить функцию вывести получившийся массив на экран?
по элементам в цикле нельзя((( smile 


помогите пжлст, срочно нуна!!)) smile 
PM MAIL   Вверх
jonie
Дата 13.1.2009, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118




Код


for(int i=0;i<SIZE;++i){
  std::cout<<array[i]<<' ';
}




--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Kinch
Дата 13.1.2009, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 13.1.2009

Репутация: -1
Всего: -1



спс)) ща проверю))
PM MAIL   Вверх
Kinch
Дата 13.1.2009, 19:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 13.1.2009

Репутация: -1
Всего: -1



нехочет((( помогите пжлст!!!
PM MAIL   Вверх
Kinch
Дата 13.1.2009, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 13.1.2009

Репутация: -1
Всего: -1



Код

//---------------------------------------------------------------------------

#pragma hdrstop
#include <iostream>
#include <math.h>
#include <conio>
//---------------------------------------------------------------------------

#pragma argsused
 int z (int*a, size_t s) {
int*b=new int [s];
int k=(s-1); int i=0;
while ((i<s)&&(k=0))
{
b[k]=a[i];
--k; ++i;
}


                           }

using namespace std;
int main()

{
int i,k;
cout<<endl<<"n=";
int n;
cin>>n;
if(n<1) return -1;
int*a=new int[n];
for(i=0;i<n;i++)
{
cout<<"a["<<i<<"]=";
cin>>a[i];
}

z(&a[i], n);
for(int i=0;i<s;++i){
  std::cout<<a[i]<<' ';
}
getch ();

        return 0;
}
//---------------------------------------------------------------------------



вот код полностью(( он робит((
PM MAIL   Вверх
pan2004
Дата 13.1.2009, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 357
Регистрация: 28.7.2007

Репутация: 2
Всего: 9



Два вопроса:
1. Что это за ... такое?
Код

z(&a[i], n);

2. Тут что-то явно не так. Смотреть разницу между = и == (в C это разные вещи, примерно как := и = в Паскале)
Код

while ((i<s)&&(k=0))



--------------------
Qt4/C++ fan
WinXP SP3: MSVC++2005 Qt4.5.1 Boost1.39
сыграем в дурака?
PM MAIL   Вверх
Kinch
Дата 13.1.2009, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 13.1.2009

Репутация: -1
Всего: -1



Цитата

1. Что это за ... такое?


z(&a[i], n);


вызов функции, разве не так?


Цитата

2. Тут что-то явно не так. Смотреть разницу между = и == (в C это разные вещи, примерно как := и = в Паскале)

    
while ((i<s)&&(k=0))


исправил)
PM MAIL   Вверх
pan2004
Дата 13.1.2009, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 357
Регистрация: 28.7.2007

Репутация: 2
Всего: 9



Цитата(Kinch @  13.1.2009,  20:38 Найти цитируемый пост)
вызов функции, разве не так?

И что, работает?
Если нет, подумай, чему равно i. И почему не написано просто z(a, n).


--------------------
Qt4/C++ fan
WinXP SP3: MSVC++2005 Qt4.5.1 Boost1.39
сыграем в дурака?
PM MAIL   Вверх
mes
Дата 13.1.2009, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250




Цитата(Kinch @  13.1.2009,  16:15 Найти цитируемый пост)
Написать Функцию которая переводит заданный одномерный массив в зеркальное отображение и выводит его на экран.

Вроде так :
Код

void mirror (int * begin, int * end) 
{
   for (--end; begin<end; ++begin, --end)
   std::swap (*begin, *end);
}

int main
{
// mas - массив
// size размер массива

    for (int i=0; i<size; ++i)  std::cout <<mas[i] << " ";  // Предварительный вывод
    std:cout << std::endl;

    mirror (mas, mas+size); // Отражаем массив

    for (int i=0; i<size; ++i)  std::cout <<mas[i] << " "; // Контрольный вывод
    std:cout << std::endl;

    return 0;
}

Проверяйте. smile

Это сообщение отредактировал(а) mes - 13.1.2009, 21:01


--------------------
PM MAIL WWW   Вверх
cutwater
Дата 13.1.2009, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 592
Регистрация: 24.6.2008

Репутация: 2
Всего: 10



Цитата(Kinch @  13.1.2009,  20:38 Найти цитируемый пост)
z(&a[i], n);

Вопрос не в этом... объясните весь кармический смысл взятия адреса итого элемента массива, при чем после цикла i == n
следовательно Вы берете адрес на не выделенную область памяти.

Вопрос второй, Вы выделяете в функции z память под еще один массив. Во-первых не удаляете один из них ( по логике старый). во-вторых этот новый массив с "зеркальным отражением" по выполнении функции попросту исчезает, то есть смысл его создавать 0
И 3 можно было бы организовать в один цикл без выделения памяти под еще один массив...
И короче говоря если я правильно понял задачу, то вот мой вариант.

Код

void z ( int * mas, int size)
{
    for(int i = 0; i  < size / 2; i++)
    {
         int tmp = mas[i];
         mas[i] = mas[size - i - 1];
         mas[size - i - 1] = mas[i];
    }
}


Честно говоря голова после рабочего дня отказывается работать, так что если где не прав или не понял задания прошу извинить


--------------------
user posted image
PM MAIL   Вверх
baldina
Дата 13.1.2009, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



 for (--end; begin<end; ++begin, --end)

PM MAIL   Вверх
cutwater
Дата 13.1.2009, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 592
Регистрация: 24.6.2008

Репутация: 2
Всего: 10



2 mes
У Вас, признаюсь, более красивое решение, хотелось бы только чтобы человек научился думать, ибо посмотрев в код очевидно что необходимо понимать что пишешь.

Это сообщение отредактировал(а) cutwater - 13.1.2009, 21:02


--------------------
user posted image
PM MAIL   Вверх
mes
Дата 13.1.2009, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(baldina @  13.1.2009,  19:57 Найти цитируемый пост)
 for (--end; begin<end; ++begin, --end)

 smile  исправил 


--------------------
PM MAIL WWW   Вверх
baldina
Дата 13.1.2009, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



у mes и более универсальное, если параметризовать тип в последовательности
PM MAIL   Вверх
Kinch
Дата 13.1.2009, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 13.1.2009

Репутация: -1
Всего: -1



mes, а Вы можете пошагово пояснить что вы делали и написать код полность,?)) а то я ничо не понял((

Это сообщение отредактировал(а) Kinch - 13.1.2009, 21:19
PM MAIL   Вверх
mes
Дата 13.1.2009, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Kinch @  13.1.2009,  20:19 Найти цитируемый пост)
можете пошагово пояснить 


Код

void mirror (
             int * begin,  // начало массива
             int * end     // конец (последний+1) массива 
            )    
{
    for ( //  цикл :
          --end // инициализация: устанавливаем на последний элемент
          ;
          begin<end // условие: ждем пока не встретятся
          ;
          ++begin, --end // счетчик: идем навстречу 
        )
        std::swap (*begin, *end); // действие: меняем местами текущие начальный и конечный элементы
}



Цитата(Kinch @  13.1.2009,  20:19 Найти цитируемый пост)
написать код полность

код по полноте более, чем достаточен. 
подробнее писать принципиально не буду.  smile


Это сообщение отредактировал(а) mes - 13.1.2009, 21:59


--------------------
PM MAIL WWW   Вверх
Kinch
Дата 13.1.2009, 21:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 13.1.2009

Репутация: -1
Всего: -1



mes,  премнога благодарен
PM MAIL   Вверх
UnrealMan
Дата 13.1.2009, 23:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(Kinch @  13.1.2009,  17:15 Найти цитируемый пост)
Написать Функцию которая переводит заданный одномерный массив в зеркальное отображение и выводит его на экран.

Код
#include <algorithm>
#include <iostream>

template <class T>
void print_reversed_array(T *first, T *last)
{
    std::reverse(first, last);
    std::copy(first, last, std::ostream_iterator<T>(std::cout, "\n"));
}


Добавлено через 58 секунд
Цитата(mes @  13.1.2009,  21:49 Найти цитируемый пост)
--end // инициализация: устанавливаем на последний элемент

А если массив пустой? smile 
PM MAIL   Вверх
mes
Дата 14.1.2009, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(UnrealMan @  13.1.2009,  22:53 Найти цитируемый пост)
А если массив пустой? smile  

Хм.. Не понял намека.
То end станет меньше begin и цикл не выполнится.

Проблема будет в том случае, если переданный указатель будет ноль.
Но это в рамки задачи не входит.

aa.. или Вы для случая с итeраторами ?  
В этом случае да.. но дополнительные проверки делать не хотел, чтоб не путать логику.
Опять же это ,имхо, не входит в рамки задачи. 

Это сообщение отредактировал(а) mes - 14.1.2009, 00:29


--------------------
PM MAIL WWW   Вверх
UnrealMan
Дата 14.1.2009, 00:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(mes @  14.1.2009,  00:22 Найти цитируемый пост)
То end станет меньше begin

По стандарту это undefined behavior.
PM MAIL   Вверх
jonie
Дата 14.1.2009, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



UnrealMan ну эт у тебя "написано до нас")
никто не спорит, что можно написать и так:
Код

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <functional>

template <typename T>
struct swapper :  public std::binary_function<T**, T, void>
{
    typedef typename first_argument_type first_argument_type;
    typedef typename second_argument_type second_argument_type;
    typedef typename result_type result_type;

    result_type operator()(const first_argument_type& v1, /*const*/ second_argument_type& v2) const
    {
        v2 = **v1;
        (*v1)--;
    }
};

template <typename T,
          const size_t size>
void mirror(T (&array)[size], T (&result)[size])
{
    T* parray = &array[0]+size-1;
    std::for_each(result, 
        &result[0]+size,
        std::bind1st(swapper<T>(), &parray)
        );
}

template <
typename _E, typename _Tr, template <typename, typename> class O,
typename T, const size_t size>
O<_E,_Tr>& operator << (O<_E,_Tr>& os, T (&arr)[size])
{
    std::copy(arr, &arr[0]+size, std::ostream_iterator<T>(os, " "));
    return (os);
}

int _tmain(int argc, _TCHAR* argv[])
{
    int a[3] = {1,2,3};
    int b[3];

    std::cout<<"a { "<<a<<"} \n";
    mirror(a,b);
    std::cout<<"b { "<<b<<"}";

    return 0;
}



но нахрена так усложнять процесс.. если достаточно:
Код

void mirrorA(int* a, int*b, size_t s){
    for (int i=0;i<s;++i)
    {
        b[s-i-1] = a[i];
    }
}

конечно, первое неимоверно "круто", но удобно имхо только если это "черный ящик"....



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
mes
Дата 14.1.2009, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(UnrealMan @  13.1.2009,  23:35 Найти цитируемый пост)
По стандарту это undefined behavior. 

При арифметике указателей ??  smile 

ну ладно..подправляю :

Код

void mirror (int * begin, int * end) 
{
   if (end<=begin) return;
   for (--end; begin<end; ++begin, --end)
     std::swap (*begin, *end);
}



Это сообщение отредактировал(а) mes - 14.1.2009, 10:47


--------------------
PM MAIL WWW   Вверх
vinter
Дата 14.1.2009, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(mes @  14.1.2009,  11:36 Найти цитируемый пост)
ну ладно..подправляю :

зря правил, нет там UB для голых указателей


--------------------
Мой блог
PM MAIL WWW   Вверх
baldina
Дата 14.1.2009, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(UnrealMan @ 13.1.2009,  23:53)
Цитата(mes @  13.1.2009,  21:49 Найти цитируемый пост)
--end // инициализация: устанавливаем на последний элемент

А если массив пустой? smile

в общем случае (итераторы) правильно было бы использовать для сравнения не "меньше", а "не равно". и с точки зрения --end и с точки зрения требований к итераторам в данном алгоритме
Код

template <typename BidirectIt>
void mirror (BidirectIt first, BidirectIt last)
{
  while (first != last && first != --last)
  {
     std::swap (*first, *last);
     ++first;
  }
}

PM MAIL   Вверх
UnrealMan
Дата 14.1.2009, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(vinter @  14.1.2009,  10:56 Найти цитируемый пост)
зря правил, нет там UB для голых указателей 

Откуда такая уверенность? Ты прочитал в стандарте все правила, касающиеся префиксного декремента указателей?

Цитата(jonie @  14.1.2009,  10:12 Найти цитируемый пост)
конечно, первое неимоверно "круто", 

Я что-то не понял, в чём там заключается неимоверная крутизна и о чём вообще этот твой пост smile

Цитата(baldina @  14.1.2009,  10:59 Найти цитируемый пост)
 while (first != last && first != --last)

Два сравнения в цикле - это излишество.

Это сообщение отредактировал(а) UnrealMan - 14.1.2009, 12:07
PM MAIL   Вверх
baldina
Дата 14.1.2009, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата
Два сравнения в цикле - это излишество.


есть альтернативные предложения? хотелось бы увидеть...
пожалуйста, с учетом, что first и last это bidirectional iterator

Добавлено через 2 минуты и 42 секунды
для обычных указателей все гораздо проще

Код

template <typename RandIt>
void mirror (RandIt first, RandIt last)
{
  while (first < last)
     std::swap (*first++, *--last);
}


Добавлено через 7 минут и 8 секунд
Цитата

По стандарту это undefined behavior. 


Что именно "это"?
PM MAIL   Вверх
mes
Дата 14.1.2009, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(baldina @  14.1.2009,  11:45 Найти цитируемый пост)
для обычных указателей все гораздо проще
...     std::swap (*first++, *--last);

либо -- не там, либо один лишний swap smile (условие гораздо дешевле, даже просто для логики, чем swap)



--------------------
PM MAIL WWW   Вверх
UnrealMan
Дата 14.1.2009, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(baldina @  14.1.2009,  12:45 Найти цитируемый пост)
first и last это bidirectional iterator 

Итераторы произвольного доступа являются двунаправленными, но это не мешает использовать для них оператор <.

Цитата(baldina @  14.1.2009,  12:45 Найти цитируемый пост)
есть альтернативные предложения?

Можно сделать две отдельные реализации для итераторов произвольного доступа и для других двунаправленных итераторов, вместо того чтобы следовать твоему тезису

Цитата(baldina @  14.1.2009,  10:59 Найти цитируемый пост)
в общем случае (итераторы) правильно было бы использовать для сравнения не "меньше", а "не равно".


Цитата(baldina @  14.1.2009,  12:45 Найти цитируемый пост)
хотелось бы увидеть...

Посмотри любую современную реализацию std::reverse в STL от VC++, GCC  или в STLport. Наверняка там не будет использоваться единый алгоритм для всех двунаправленных итераторов.

Цитата(baldina @  14.1.2009,  12:45 Найти цитируемый пост)
Что именно "это"? 

Если в функцию в качестве параметра end передаётся указатель на конец массива, одновременно являющийся его началом (такой массив может быть создан посредством new T[0]), а потом к end пытаются применить декремент, то такая попытка влечёт undefined behavior.

Это сообщение отредактировал(а) UnrealMan - 14.1.2009, 13:55
PM MAIL   Вверх
jonie
Дата 14.1.2009, 13:33 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



Цитата

Я что-то не понял, в чём там заключается неимоверная крутизна и о чём вообще этот твой пост smile

UnrealMan я про то, что чет вы тут сейчас накрутите сложностей, которые автор топика не поймет... смысл тогда от них сомнителен.


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
UnrealMan
Дата 14.1.2009, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(jonie @  14.1.2009,  13:33 Найти цитируемый пост)
я про то, что чет вы тут сейчас накрутите сложностей

Каких сложностей? Я привёл простейшую реализацию функции, описанной в первом посте темы.

Это сообщение отредактировал(а) UnrealMan - 14.1.2009, 13:46
PM MAIL   Вверх
vinter
Дата 14.1.2009, 14:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(UnrealMan @  14.1.2009,  14:33 Найти цитируемый пост)
то такая попытка влечёт undefined behavior.

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


--------------------
Мой блог
PM MAIL WWW   Вверх
baldina
Дата 14.1.2009, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



UnrealMan, ты невнимательно читал меня.
естественно для разных типов итераторов эффективный код будет разный. и не удивлюсь, если в конкретной реализации STL  он будет похож на то, что я написал для bidirectional и random access соответственно  smile
я как раз имел в виду, что для bidirectional (не random) нет эффективной реализации distance. я пока не вижу более эффективной реализации для этого вида итераторов, т.е. без двух сравнений в цикле.

не поленюсь после поста посмотреть в исходники STL...

Цитата

Если в функцию в качестве параметра end передаётся указатель на конец массива, одновременно являющийся его началом (такой массив может быть создан посредством new T[0]), а потом к end пытаются применить декремент, то такая попытка влечёт undefined behavior.


в чем undefined behavior? разадресовывать его бессмысленно, но изменение самого указателя - вполне осмысленная операция. причем гарантируется, что ++(--p) == p

Добавлено через 3 минуты и 2 секунды
посмотрел. вот результат:

STLPort
Код

template <class _BidirectionalIter>
_STLP_INLINE_LOOP void
__reverse(_BidirectionalIter __first, _BidirectionalIter __last, const bidirectional_iterator_tag &) {
  for (; __first != __last && __first != --__last; ++__first)
    iter_swap(__first,__last);
}


template <class _RandomAccessIter>
_STLP_INLINE_LOOP void
__reverse(_RandomAccessIter __first, _RandomAccessIter __last, const random_access_iterator_tag &) {
  for (; __first < __last; ++__first)
    iter_swap(__first, --__last);
}



VC++ 7.1
Код

template<class _BidIt> inline
    void _Reverse(_BidIt _First, _BidIt _Last, bidirectional_iterator_tag)
    {    // reverse elements in [_First, _Last), bidirectional iterators
    for (; _First != _Last && _First != --_Last; ++_First)
        std::iter_swap(_First, _Last);
    }

template<class _RanIt> inline
    void _Reverse(_RanIt _First, _RanIt _Last, random_access_iterator_tag)
    {    // reverse elements in [_First, _Last), random-access iterators
    for (; _First < _Last; ++_First)
        std::iter_swap(_First, --_Last);
    }


я не удивлен...

PM MAIL   Вверх
UnrealMan
Дата 14.1.2009, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(vinter @  14.1.2009,  14:15 Найти цитируемый пост)
на каком основании?

На таком, что это следует из текста стандарта.

Цитата(vinter @  14.1.2009,  14:15 Найти цитируемый пост)
Как по твоему декремент указатель может быть UB?

Возможно, есть специфические архитектуры, где декремент указателя может привести к переполнению. Но даже на широкоиспользуемых платформах можно поиметь неприятность: при отладке программы под профилировщиком может быть выдано предупреждение, а выискивать среди "ненужных" сообщений профилировщика те, которые свидетельствуют о реальных багах, мало кто любит.

Цитата(vinter @  14.1.2009,  14:15 Найти цитируемый пост)
Пожалуйста пункт из стандарта

А давай наоброт: ты покажешь весь абзац в стандарте, где изложена информация по поводу того, куда в таком случае должен указывать результирующий указатель, а я тебе тогда покажу, где в этом абзаце сказано, когда наступает undefined behavior smile Или тут только я должен всё основательно разжёвывать и доказывать правоту своих слов?

Это сообщение отредактировал(а) UnrealMan - 14.1.2009, 15:16
PM MAIL   Вверх
baldina
Дата 14.1.2009, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата(mes @ 14.1.2009,  13:16)
Цитата(baldina @  14.1.2009,  11:45 Найти цитируемый пост)
для обычных указателей все гораздо проще
...     std::swap (*first++, *--last);

либо -- не там, либо один лишний swap smile (условие гораздо дешевле, даже просто для логики, чем swap)

mes, практические накладные расходы на один swap ничтожно малы. и его оптимизация имхо не оправдывает усложнения кода. а так все просто и понятно.
ЗЫ: лишний swap будет только для последовательностей с нечетным числом элементов
PM MAIL   Вверх
mes
Дата 14.1.2009, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(baldina @  14.1.2009,  14:18 Найти цитируемый пост)
практические накладные расходы на один swap ничтожно малы. и его оптимизация имхо не оправдывает усложнения кода. а так все просто и понятно.

я специально добавил уточнение :

Цитата(baldina @  14.1.2009,  14:18 Найти цитируемый пост)
условие гораздо дешевле, даже просто для логики, чем swap


имхо,  в данном случае это не оптимизация, а правильный набор условий.

Добавлено @ 15:25
Цитата(baldina @  14.1.2009,  14:18 Найти цитируемый пост)
ЗЫ: лишний swap будет только для последовательностей с нечетным числом элементов 

неважно, главное он вызывает напряг и заставляет подумать, а не будет ли последствий от этого smile

но в целом наверное это дело вкуса..  

Это сообщение отредактировал(а) mes - 14.1.2009, 15:26


--------------------
PM MAIL WWW   Вверх
UnrealMan
Дата 14.1.2009, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(baldina @  14.1.2009,  15:06 Найти цитируемый пост)
UnrealMan, ты невнимательно читал меня.

Цитата(baldina @  14.1.2009,  15:06 Найти цитируемый пост)
я как раз имел в виду, что для bidirectional (не random) 

Ткни пальцем, где конкретно там у тебя говорилось про итераторы, не являющиеся random access.

Это сообщение отредактировал(а) UnrealMan - 14.1.2009, 15:27
PM MAIL   Вверх
mes
Дата 14.1.2009, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата

При чём тут distance?

Это он к тому, что (грубо) для не-RandomAccess итераторов операция < (реализованная через distance) является "тяжелой".

Это сообщение отредактировал(а) mes - 14.1.2009, 15:30


--------------------
PM MAIL WWW   Вверх
baldina
Дата 14.1.2009, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата

А давай наоброт: ты покажешь весь абзац в стандарте, где изложена информация по поводу того, куда в таком случае должен указывать результирующий указатель, а я тебе тогда покажу, где в этом абзаце сказано, когда наступает undefined behavior smile Или тут только я должен всё основательно разжёвывать и доказывать правоту своих слов?


да, UnrealMan, свою правоту нужно доказывать  smile
в нашем случае совершенно неважно, куда он будет указывать. важно лишь то, что он не перестает быть указателем с осмысленным значением, к нему можно применять инкремент, декремент, сравнивать с другими указателями. в этом смысле здесь вполне specific behavior.
PM MAIL   Вверх
UnrealMan
Дата 14.1.2009, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(baldina @  14.1.2009,  15:29 Найти цитируемый пост)
в нашем случае совершенно неважно, куда он будет указывать.

Сможешь подтвердить свои домыслы выдержками из стандарта C++?
PM MAIL   Вверх
baldina
Дата 14.1.2009, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



Цитата

Код

template <typename BidirectIt>
void mirror (BidirectIt first, BidirectIt last)
{
  while (first != last && first != --last)
  {
     std::swap (*first, *last);
     ++first;
  }
}



Цитата

есть альтернативные предложения? хотелось бы увидеть...
пожалуйста, с учетом, что first и last это bidirectional iterator


я написал версию именно для bidirectional iterators. 
мне казалось template <typename BidirectIt> довольно однозначно говорит об этом. потом я сказал это открытым текстом.

Добавлено через 1 минуту и 2 секунды
Цитата

Сможешь подтвердить свои домыслы выдержками из стандарта C++? 

UnrealMan, Стандарту ничего неизвестно о нашем конкретном приложении  smile 
PM MAIL   Вверх
UnrealMan
Дата 14.1.2009, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(baldina @  14.1.2009,  15:59 Найти цитируемый пост)
я написал версию именно для bidirectional iterators. 
мне казалось template <typename BidirectIt> довольно однозначно говорит об этом. 

Вот так выглядит объявление std::reverse в стандарте:

Цитата(C++03 пункт 25.2.9 Reverse)
Код
template<class BidirectionalIterator>
  void reverse(BidirectionalIterator first, BidirectionalIterator last);

И что отсюда следует? Что она не годится для работы с итераторами произвольного доступа?
PM MAIL   Вверх
baldina
Дата 14.1.2009, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



она-то годится. а вот версия для произвольного доступа не годится для двунаправленных.
PM MAIL   Вверх
vinter
Дата 14.1.2009, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(UnrealMan @  14.1.2009,  16:14 Найти цитируемый пост)
А давай наоброт: ты покажешь весь абзац в стандарте, где изложена информация по поводу того, куда в таком случае должен указывать результирующий указатель, а я тебе тогда покажу, где в этом абзаце сказано, когда наступает undefined behavior

Цитата

The operand of prefix -- is modified by subtracting 1. The operand shall not be of type bool. The requirements on
the operand of prefix -- and the properties of its result are otherwise the same as those of prefix ++. [ Note: For postfix
increment and decrement, see 5.2.6. —end note ]

Цитата

The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to
a complete object type.

где тут хоть слово про UB?

Цитата(UnrealMan @  14.1.2009,  16:14 Найти цитируемый пост)
Возможно, есть специфические архитектуры, где декремент указателя может привести к переполнению

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

Цитата(UnrealMan @  14.1.2009,  16:14 Найти цитируемый пост)
при отладке программы под профилировщиком может быть выдано предупреждение, а выискивать среди "ненужных" сообщений профилировщика те, которые свидетельствуют о реальных багах, мало кто любит.

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


--------------------
Мой блог
PM MAIL WWW   Вверх
baldina
Дата 14.1.2009, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



короче мы походу запутались. распутываю:
UnrealMan указал, что два сравнения в цикле неэффективно.
1. я сказал, что если это Bidirectional Iterator (а я именно его и имел в виду), то вряд ли этот код можно улучшить.
поглядев в STL можно увидеть, что там реализации для Bidirectional и для Random Access практически идентичны моим.

2. требования к Bidirectional Iterator слабее, чем к Random Access, поэтому версия для Bidirectional Iterator более общая, она может работать и с Bidirectional и с Random Access. но не наоборот.

3. нигде в коде не происходит разадресации недействительного указателя, потому рассуждения о UB не имеют смысла
PM MAIL   Вверх
UnrealMan
Дата 14.1.2009, 16:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(baldina @  14.1.2009,  16:16 Найти цитируемый пост)
она-то годится.

Ну, значит, из одного такого объявления не очевидно, что функция предназначена для работы с двунаправленными итераторами, не являющимися итераторами произвольного доступа. Какие тогда ко мне претензии?

Это сообщение отредактировал(а) UnrealMan - 14.1.2009, 16:23
PM MAIL   Вверх
UnrealMan
Дата 14.1.2009, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(vinter @  14.1.2009,  16:19 Найти цитируемый пост)
где тут хоть слово про UB?

Ты мало процитировал. Что такое вычитание 1 из указателя? Куда будет указывать результирующий указатель? Стандарт описывает это.
Ты пропустил важное предложение

Цитата
If x is not of type bool, the expression ++x is equivalent to x+=1

(аналогичное справедливо для декремента: для объектов встроенных типов --x - эквивалент x-=1). Копай дальше.

Это сообщение отредактировал(а) UnrealMan - 14.1.2009, 16:57
PM MAIL   Вверх
vinter
Дата 14.1.2009, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата
Moreover, if the expression P points to the last element of an
array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one
past the last element of an array object, the expression (Q)-1 points to the last element of the array object. If both the
pointer operand and the result point to elements of the same array object, or one past the last element of the array object,
the evaluation shall not produce an overflow; otherwise, the behavior is undefined.


UnrealMan, извиняюсь, был не прав. Дибильное правило не поддающееся логике.


--------------------
Мой блог
PM MAIL WWW   Вверх
UnrealMan
Дата 14.1.2009, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 5
Всего: 32



Цитата(vinter @  14.1.2009,  16:57 Найти цитируемый пост)
UnrealMan, извиняюсь, был не прав. 

Исход этого спора был предрешён: в вопросах, касающихся стандарта, я очень редко бываю неправ smile 
PM MAIL   Вверх
jonie
Дата 14.1.2009, 22:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



пологаю что подобное может быть связано с неописанием работы менеджера памяти, который может не захотеть пускать вас в, возможно, служебную (или иначе "не вашу") память в случае простых массивов или действительно неопределенностью, в случаях более сложных типов ... хотя, мб есть и иные доводы.


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.2217 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.