Двумерный массив. Help.

 

Хочу проделать такую вещь: присвоить второй размерности массива одно значение, и вывести значения в журнал.

И не получается. Выводит в журнал 0.

Мозг кипит. Не пойму, где ошибка.

//+------------------------------------------------------------------+
//|                                                  тест массив.mq4 |
//|                                                            Pavel |
//|                                              pingvin-man@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Pavel"
#property link      "pingvin-man@mail.ru"
int КолШаг=11;
double  НачальныйРаб=0.1,РабСхема[2][22];
 
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
 
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
 
       for (int t=0; t<КолШаг*2;t++)
      { 
      РабСхема[2][t]=НачальныйРаб;
      Print("РабСхема[2][",t,"]=",РабСхема[2][t]);}  
//----
   return(0);
  }
//+------------------------------------------------------------------+

И сразу же второй вопрос: возможно ли при объявлении одного из измерений массива указывать размер в виде ранее объявленной переменной?

double РабСхема[2][КолШаг*2];

 
Pingvin-man писал (а):

....

НачальныйРаб=0.1,РабСхема[2][22];

.....

РабСхема[2][t]=НачальныйРаб;
Print("РабСхема[2][",t,"]=",РабСхема[2][t]);}
//----
return(0);
}
//+------------------------------------------------------------------+

И сразу же второй вопрос: возможно ли при объявлении одного из измерений массива указывать размер в виде ранее объявленной переменной?

double РабСхема[2][КолШаг*2];

В 1-м измерении размерность массива 2. А вы пытаетесь в 3-е присвоить, т.к. индексация начинается с 0.
 
Talex:
В 1-м измерении размерность массива 2. А вы пытаетесь в 3-е присвоить, т.к. индексация начинается с 0.

Совсем запутаете :) Не в "в 3-е ", а в 3-й (элемент). Которого нет.

Другими словами:

инциализируя массив как

double РабСхема[2][22];


Вы имеете возможность ссылаться на 2 его элемента РабСхема[0][n] и РабСхема[1][n] в первом измерении (имеющем индекс 0),
и 22 элемента от РабСхема[k][0] до РабСхема[k][21] во втором измерении (индекс 1).

Pingvin-man писал (а):

И сразу же второй вопрос: возможно ли при объявлении одного из измерений массива указывать размер в виде ранее объявленной переменной?

double РабСхема[2][КолШаг*2];

Имо, нет.

RTFM - Инициализация переменных:

Массивы (в том числе и объявленные на локальном уровне) могут инициализироваться только константами.

Инициализируйте, а потом:

int ArrayResize( object &array[], int new_size)

Устанавливает новый размер в первом измерении массива.

Вы могли бы и сами проэкспериментировать :)

int start()
{
int i;

i = 3;

string saTemp[i];

saTemp[0] = "1-st";
saTemp[1] = "2-nd";
saTemp[2] = "3-rd";

return(0);
}

Компилятор выдает: 'i' - integer number expected

 

Ну вот, млин! Теперь сам запутался! Теперь - мне Help!

А почему эта фигня работает?

int start()
{
int i, k;
string saChange[2];

i = 10;

//saChange[0] = "1-st";
//saChange[1] = "2-nd";
//saChange[2] = "3-rd";
//saChange[3] = "4-rd";

for (k = 0; k <= i; k++)
{
saChange[k] = StringConcatenate(k + 1, " element");
Print(saChange[k]);
}

return(0);
}


******************
2008.05.26 07:05:37 dd EURGBP,H1: removed
2008.05.26 07:05:37 dd EURGBP,H1: uninit reason 0
2008.05.26 07:05:37 dd EURGBP,H1: 11 element
2008.05.26 07:05:37 dd EURGBP,H1: 10 element
2008.05.26 07:05:37 dd EURGBP,H1: 9 element
2008.05.26 07:05:37 dd EURGBP,H1: 8 element
2008.05.26 07:05:37 dd EURGBP,H1: 7 element
2008.05.26 07:05:37 dd EURGBP,H1: 6 element
2008.05.26 07:05:37 dd EURGBP,H1: 5 element
2008.05.26 07:05:37 dd EURGBP,H1: 4 element
2008.05.26 07:05:37 dd EURGBP,H1: 3 element
2008.05.26 07:05:37 dd EURGBP,H1: 2 element
2008.05.26 07:05:37 dd EURGBP,H1: 1 element
2008.05.26 07:05:37 dd EURGBP,H1: loaded successfully
2008.05.26 07:05:33 Compiling 'dd'
 
Babay:

Ну вот, млин! Теперь сам запутался! Теперь - мне Help!

А что именно тебе не нравитцо?

Задал печатать 11 элементов, они и распечатались.

Если хотел 10, убери знак равно.

Не понял, что не работает.

 
Pingvin-man писал (а):
Babay:

Ну вот, млин! Теперь сам запутался! Теперь - мне Help!

А что именно тебе не нравитцо?

Задал печатать 11 элементов, они и распечатались.

Если хотел 10, убери знак равно.

Не понял, что не работает.

Ну как? В массиве всего два элемента string saChange[2]; , а попытки присвоить значение элементу с номером k , бОльшим, чем объявлено, получаются удачными... Так же, как и их чтение.

Именно то, что у тебя не получалось - обратиться к третьему элементу при объявленных двух.

Чой-то я манов перекурил :)

.

 

У тебя же идёт присвоение следующему элементу очередного значения, и массив получает его, автоматически увеличивая размер.

А у меня был обращение (не присвоение) к несуществующему элементу.

Попробуй убери коменты

//saChange[0] = "1-st";
//saChange[1] = "2-nd";
//saChange[2] = "3-rd";
//saChange[3] = "4-rd";

и в цикле убери операцию присвоения : saChange[k] = StringConcatenate(k + 1, " element");

И получишь ошибку обращения к несуществующему элементу.

 
Pingvin-man писал (а):

...автоматически увеличивая размер...

Хм... И это документированно? Ткни пальцем, плз, где почитать.

Pingvin-man писал (а):

...А у меня был обращение (не присвоение) к несуществующему элементу....

Ну вот, совсем примитивно:

int start()
{
string saChange[2], sTmp;
int i;
saChange[0] = "1-st";
saChange[1] = "2-nd";

Print("ArraySize: ", ArraySize(saChange));

sTmp = saChange[1288];
Print("Why not: ' ", sTmp, " '");

i = StringLen(saChange[1288]);
Print("StringLen: ", i);
Print("StringGetChar: ", StringGetChar(sTmp, i - 1));
Print("StringGetChar: ", StringGetChar(sTmp, 1));

Print("ArraySize: ", ArraySize(saChange));

return(0);
}

2008.05.26 12:44:33 ff EURGBP,H1: removed
2008.05.26 12:44:33 ff EURGBP,H1: uninit reason 0
2008.05.26 12:44:33 ff EURGBP,H1: ArraySize: 2
2008.05.26 12:44:33 ff EURGBP,H1: StringGetChar: 0
2008.05.26 12:44:33 ff EURGBP,H1: StringGetChar: 0
2008.05.26 12:44:33 ff EURGBP,H1: StringLen: 0
2008.05.26 12:44:33 ff EURGBP,H1: Why not: ' '
2008.05.26 12:44:33 ff EURGBP,H1: ArraySize: 2
2008.05.26 12:44:33 ff EURGBP,H1: loaded successfully
2008.05.26 12:44:30 Compiling 'ff'

Вот - успешное обращение к несуществующему элементу без предварительной попытки присвоить ему значение. При этом ArraySize и до этой операции, и после показывает 2. При этом этот элемент нулевой длины принимает значение с кодом 0. Что обычно и происходит с неявно инициализированными строковыми массивами.

(Примечание: В таблице ASCII есть элемент с кодом 0. И строковая переменная, содержащая только этот символ, должна иметь длину 1, а не 0. Но это - особенность MQL, про это писАли и про необходимость явной инициализации тоже.)

 
Pingvin-man писал (а):

... Попробуй убери коменты

//saChange[0] = "1-st";
//saChange[1] = "2-nd";
//saChange[2] = "3-rd";
//saChange[3] = "4-rd";

и в цикле убери операцию присвоения : saChange[k] = StringConcatenate(k + 1, " element");

И получишь ошибку обращения к несуществующему элементу.

Сделал:

int start()
{
int i, k;
string saChange[2], sTmp;

ArrayResize(saChange, 2);

Print("ArraySize(0) = ", ArraySize(saChange));
Print("ArrRange(0) = ", ArrayRange(saChange, 0));
Print("ArrRange(1) = ", ArrayRange(saChange, 1));
Print("ArrRange(2) = ", ArrayRange(saChange, 2));

i = 10;

saChange[0] = "1-st";
saChange[1] = "2-nd";
saChange[2] = "3-rd";
saChange[3] = "4-rd";

for (k = 0; k <= i; k++)
{
//saChange[k] = StringConcatenate(k +1, " element");
sTmp = StringConcatenate("Itter ", k, ": ", saChange[k]);
Print(sTmp);
}
return(0);
}

Вот результат :((

2008.05.26 12:59:47 dd EURGBP,H1: removed
2008.05.26 12:59:47 dd EURGBP,H1: uninit reason 0
2008.05.26 12:59:47 dd EURGBP,H1: Itter 10: 4-rd
2008.05.26 12:59:47 dd EURGBP,H1: Itter 9: 4-rd
2008.05.26 12:59:47 dd EURGBP,H1: Itter 8: 4-rd
2008.05.26 12:59:47 dd EURGBP,H1: Itter 7: 4-rd
2008.05.26 12:59:47 dd EURGBP,H1: Itter 6: 4-rd
2008.05.26 12:59:47 dd EURGBP,H1: Itter 5: 4-rd
2008.05.26 12:59:47 dd EURGBP,H1: Itter 4: 4-rd
2008.05.26 12:59:47 dd EURGBP,H1: Itter 3: 4-rd
2008.05.26 12:59:47 dd EURGBP,H1: Itter 2: 4-rd
2008.05.26 12:59:47 dd EURGBP,H1: Itter 1: 2-nd
2008.05.26 12:59:47 dd EURGBP,H1: Itter 0: 1-st
2008.05.26 12:59:47 dd EURGBP,H1: ArrRange(2) = -1
2008.05.26 12:59:47 dd EURGBP,H1: range number 2 for ArrayRange function is incorrect
2008.05.26 12:59:47 dd EURGBP,H1: ArrRange(1) = -1
2008.05.26 12:59:47 dd EURGBP,H1: range number 1 for ArrayRange function is incorrect
2008.05.26 12:59:47 dd EURGBP,H1: ArrRange(0) = 2
2008.05.26 12:59:47 dd EURGBP,H1: ArraySize(0) = 2
2008.05.26 12:59:47 dd EURGBP,H1: loaded successfully
2008.05.26 12:59:42 Compiling 'dd'

Ваще бред...

 

Уважаемое MQL сообщество, ТАК должно быть? Что за хитрости со строковыми массивами? Хотелось бы и разработчиков услышать.

 

Уважаемое MQL сообщество видимо занято поиском граалей и тех, кому спихнуть уже найденные... Жаль.

Уважаемые разработчики, я уже к вам обращался. Повторно прошу ответить, что это? Баг или фича? Или это у меня в чане баг? Где я ошибаюсь? Если вам некогда - скажите. Я подожду.

Вот код:

int start()
{
int i, k;
string saChange[2]; // декларируем одномерный массив с тремя элементами
string sTmp, sErr;

// изменяем кол-во эл-в в 1-м изм массива (на всякий случай)
ArrayResize(saChange, 3);

Print("Проверяем неинициализированный массив");
Print("Кол-во эл-в массива: ", ArraySize(saChange));
Print("Элементов в 1-м изм: ", ArrayRange(saChange, 0));
Print("");
Print("Убеждаемся, что в массиве только одно изм-е (на всякий случай)");
Print("Элементов во 2-м изм (ош): ", ArrayRange(saChange, 1));
Print("Элементов в 3-м изм (ош): ", ArrayRange(saChange, 2));

i = 10; // от фонаря

Print("");
Print("Проверяем эл-ты массива объявленные и нет");
for (k = 0; k < i; k++)
{
sTmp = StringConcatenate(
"Итерация ", k, ": ' ",
saChange[k], " '");
Print(sTmp);
}

//Print("");
//Print("Присваиваем знач-я эл-м массива объявленным и нет");
for (k = 0; k < 10; k++)
{
saChange[k] = StringConcatenate(k + 1, " эл-т");
}

Print("");
Print("Проверяем знач-я эл-ов массива объявленные и нет");
for (k = 0; k < i; k++)
{
sTmp = StringConcatenate(
"Итерация ", k, ": ' ",
saChange[k], " '");
switch (k < 3)
{
case true:
sTmp = StringConcatenate(sTmp, "; OK");
break;
case false:
sTmp = StringConcatenate(
sTmp, "; Не должно быть вообще; ",
"присваивалось ' ", k + 1, " эл-т", " '");
break;
}
Print(sTmp);
}
return(0);
}

Вот отчет:

2008.06.03 22:45:27 dd EURGBP,H1: removed
2008.06.03 22:45:27 dd EURGBP,H1: uninit reason 0
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 9: ' 10 эл-т '; Не должно быть вообще; присваивалось ' 10 эл-т '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 8: ' 10 эл-т '; Не должно быть вообще; присваивалось ' 9 эл-т '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 7: ' 10 эл-т '; Не должно быть вообще; присваивалось ' 8 эл-т '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 6: ' 10 эл-т '; Не должно быть вообще; присваивалось ' 7 эл-т '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 5: ' 10 эл-т '; Не должно быть вообще; присваивалось ' 6 эл-т '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 4: ' 10 эл-т '; Не должно быть вообще; присваивалось ' 5 эл-т '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 3: ' 10 эл-т '; Не должно быть вообще; присваивалось ' 4 эл-т '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 2: ' 3 эл-т '; OK
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 1: ' 2 эл-т '; OK
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 0: ' 1 эл-т '; OK
2008.06.03 22:45:27 dd EURGBP,H1: Проверяем знач-я эл-ов массива объявленные и нет
2008.06.03 22:45:27 dd EURGBP,H1:
2008.06.03 22:45:27 dd EURGBP,H1: Присваиваем знач-я эл-м массива объявленным и нет
2008.06.03 22:45:27 dd EURGBP,H1:
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 9: ' '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 8: ' '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 7: ' '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 6: ' '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 5: ' '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 4: ' '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 3: ' '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 2: ' '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 1: ' '
2008.06.03 22:45:27 dd EURGBP,H1: Итерация 0: ' '
2008.06.03 22:45:27 dd EURGBP,H1: Проверяем эл-ты массива объявленные и нет
2008.06.03 22:45:27 dd EURGBP,H1:
2008.06.03 22:45:27 dd EURGBP,H1: Элементов в 3-м изм (ош): -1
2008.06.03 22:45:27 dd EURGBP,H1: range number 2 for ArrayRange function is incorrect
2008.06.03 22:45:27 dd EURGBP,H1: Элементов во 2-м изм (ош): -1
2008.06.03 22:45:27 dd EURGBP,H1: range number 1 for ArrayRange function is incorrect
2008.06.03 22:45:27 dd EURGBP,H1: Убеждаемся, что в массиве только одно изм-е (на всякий случай)
2008.06.03 22:45:27 dd EURGBP,H1:
2008.06.03 22:45:27 dd EURGBP,H1: Элементов в 1-м изм: 3
2008.06.03 22:45:27 dd EURGBP,H1: Кол-во эл-в массива: 3
2008.06.03 22:45:27 dd EURGBP,H1: Проверяем неинициализированный массив
2008.06.03 22:45:27 dd EURGBP,H1: loaded successfully
2008.06.03 22:45:22 Compiling 'dd'

Причина обращения: