Я бы поостерегся делать такие эксперименты. Воспользуйся лучше
буферным массивом.
Сделайте промежуточное копирование в служебный массив.
Если копирование идет слева направо, то нулевой элемент dest пойдет
в первый. Дальше первый пойдет во второй, но значение первого
уже изменилось.
В результате все заполнится нулевым элементом!
В результате все заполнится нулевым элементом!
alisa писал (а):
Если копирование идет слева направо, то нулевой элемент dest пойдет в первый. Дальше первый пойдет во второй, но значение первого уже изменилось.
В результате все заполнится нулевым элементом!
Если копирование идет слева направо, то нулевой элемент dest пойдет в первый. Дальше первый пойдет во второй, но значение первого уже изменилось.
В результате все заполнится нулевым элементом!
Об этом я собственно и написал в первом посте. Чтобы этого не происходило, копирование должно в таких случаях идти в обратном порядке. Думаю, что стоит исправить этот глюк.
Еще одна наколка с ArrayCopy(), которая явно неприятна - параметр count лажается на многомерных массивах, т.к. функция всегда интерпретирует его как число элементов одномерного массива. Приходится умножать его руками на соответствующие размерности - это очень неудобно и совершенно не логично.
Пример в студию с многомерным массивом! Как ты думаешь, логично ли копировать часть многомерного массива с помощью этой функции, не указывая явно порядок копирования?
Mathemat писал (а):
Пример в студию с многомерным массивом! Как ты думаешь, логично ли копировать часть многомерного массива с помощью этой функции, не указывая явно порядок копирования?
Пример в студию с многомерным массивом! Как ты думаешь, логично ли копировать часть многомерного массива с помощью этой функции, не указывая явно порядок копирования?
Не совсем понял вас.
Пример? Легко:
double A[ 10 ][ 2 ]; // Копирование первого элемента массива во второй ArrayCopy( A, A, 2, 0, 2 );Кстати, обратите внимание на двойки. Какой смысл при копировании многомерных массивов в ArrayCopy() указывать число всех копируемых элементов, включаю внутренние размерности? Если бы поддерживались срезы (slices), тогда это еще можно было бы понять. Но так как на них нет и намека, то гораздо логичнее было бы оперировать числом элементов в смысле "первой размерности", как это делает ArrayResize().
А теперь пожалуйста ваш пример в студию: как можно явно указать порядок копирования многомерного массива?
bstone, когда я говорил о порядке копирования, я не имел в виду число всех копируемых элементов. Мне тоже приходится работать с двумерными массивами и копировать их частично, в том числе и в двумерные тоже. Но я делаю это всегда через служебные массивы, не полагаясь на не известный нам механизм их копирования - и уж во всяком случае не пытаясь изменять исходный массив "на лету" (чрезвычайно ненадежная и непрозрачная операция).
Что касается slices, то это же очень просто реализовать с помощью функции с параметром, передаваемым по ссылке (см. ниже). А после этого "послойно" скопировать исходный массив в новый, а не в себя. Вот это и есть явное указание порядка копирования. Да, будет медленнее, но с точки зрения читаемости кода и его модификации безусловно удобнее. Ну а если так хочется реализовать быстрый алгоритм, тогда остается только писать dll на другом языке типа C++. А вообще, когда я пишу что-то, почти всегда из двух альтернатив - быстрота исполнения или надежность - выбираю вторую.
Вот, скажем, примерная реализация одномерного slice:
Что касается slices, то это же очень просто реализовать с помощью функции с параметром, передаваемым по ссылке (см. ниже). А после этого "послойно" скопировать исходный массив в новый, а не в себя. Вот это и есть явное указание порядка копирования. Да, будет медленнее, но с точки зрения читаемости кода и его модификации безусловно удобнее. Ну а если так хочется реализовать быстрый алгоритм, тогда остается только писать dll на другом языке типа C++. А вообще, когда я пишу что-то, почти всегда из двух альтернатив - быстрота исполнения или надежность - выбираю вторую.
Вот, скажем, примерная реализация одномерного slice:
// функция выделяет из двумерного массива source срез (одномерный массив dest),Парамер howmany можно вынести и в параметры функции, если очень хочется скопировать поменьше элементов.
// фиксируя первый индекс равным idx.
void slice( double source[][], double& dest[], int idx )
{
int howmany = ArrayRange( source, 1 ); // размер source по второму индексу
for( int i = 0; i < howmany; i++ ) dest[ i ] = source[ idx ][ i ];
return;
}
и уж во всяком случае не пытаясь изменять исходный массив "на лету" (чрезвычайно ненадежная и непрозрачная операция).
Не согласен. Это абсолютно надежная и прозрачная операция при условии правильной реализации ArrayCopy(). Для этого у процессора даже есть специальный набор инструкций (все операции по копированию/заполнению учатсков памяти поддерживают прямой и обратный порядок). И даже стандартные функции С типа memcpy() учитывают такие нюансы.Что касается slices, то это же очень просто реализовать с помощью функции с параметром, передаваемым по ссылке (см. ниже).
То что было приведено вами лишь очень частный случай "срезов". В общем случаи "срезы" - это механизм представления многомерных массивов посредством одномерных. Параметрами "среза" являются: начальный индекс, шаг и число элементов. Более подробно можно узнать о них в конкретных реализациях, напрямер заглянув в стандартную библиотеку языка С++.Ну а если так хочется реализовать быстрый алгоритм, тогда остается
только писать dll на другом языке типа C++.
Если бы речь шла о некотором сложном алгоритме, то я бы согласился. В данном случае речь идет о банальном копировании элементов массива :)
А вообще, когда я пишу что-то, почти всегда из двух альтернатив
- быстрота исполнения или надежность - выбираю вторую.
К сожалению, вторая альтернатива больно бьет по временным затратам на оптимизацию и анализу эффективности МТС на больших периодах истории.
В данном случае речь идет о банальном копировании элементов массива :)
Нет, bstone, это не банальное копирование - и Вы это точно должны понимать: сам массив оказывается и источником для копирования, и объектом модификации. Какое ж это копирование?! При таком "копировании" можно было бы не делать детей, а превращаться в них самим...bstone, имеем то, что имеем: MQL4 предоставляет все торговые функции плюс джентльменский набор (минимум) нетрейдерских функций, нужных, по мнению разработчиков, для помощи в трейдинге. Пользователи своими собственными силами разрабатывают нужные им библиотеки и выкладывают их в Code Base. Предъявлять к этому языку критерии, соответствующие языку программирования операционных систем, по меньшей мере неразумно.
Язык MQL4 ориентирован явно на специфичную аудиторию - на трейдеров, желающим тем или иным образом механизировать торговлю. Соответственно и акцент в строгости описания языка смещен больше в сторону трейдерских задач, а описание языка не может быть таким же строгим, как это специфицировано в ANSI-стандарте С++. Если Вы привыкли писать на С++, а MQL4 Вас не устраивает - никаких проблем: dll-то можно подключать!
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Вот пример:
В этом случае копирование будет отработано некорректно - все элементы массива будут заполнены одним значением.
Необходимо доработать ArrayCopy() - при копировании пересекающихся участков копирование должно выполняться в обратном порядке, чтобы уже копируемые элементы не затирали следующие за ними.