Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 670

/ вопрос открыт /

Здравствуйте, эксперты!
Есть исходник программы. Там задан массив размерностью 8 (К) и заданы его значения. Как сделать так, чтобы можно было меня размерность массива и вводить свои значения через форму?
Спасибо.

К вопросу прикреплён файл. Загрузить » (срок хранения: 60 дней с момента отправки вопроса)

Drongo Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Drongo (статус: Посетитель)
Вопрос отправлен: 8 июня 2008, 16:26
Состояние вопроса: открыт, ответов: 3.

Ответ #1. Отвечает эксперт: Мережников Андрей

Здравствуйте, Drongo!
Используйте динамические массивы. Одномерный объявляется так: var k:array of integer; (integer - для примера). Перед использованием надо инициализировать с помощью функции setlength(k,<кол-во элементов>);Нумерация элементов начинается с 0; Двумерный объявляется так: var k:array of array of integer; Инициализация происходит следующим образом: сначала инициализируется первое измерение, например, кол-во столбцов Setlength(k,<кол-во столбцов>);Затем для КАЖДОГО столбца надо проинициализировать кол-во строк, например, для первого столбца:Setlength(k[0],<кол-во строк>);
Дальше используешь как обычный массив. Перед выходом из процедуры (или программы) делаешь Finalize(k), для освобождения памяти.

Ответ отправил: Мережников Андрей (статус: Абитуриент)
Время отправки: 8 июня 2008, 19:30

Ответ #2. Отвечает эксперт: Вадим К

Здравствуйте, Drongo!
Прочитав вопрос, я было подумал, что хочеться вводить массив с размерностью 8 и не мог представить что за задача. (это в коде выглядело где то так a[1,2,3,4,5,6,7,8]). Но всё гораздо проще.
Для прямоугольных матриц можно делать проще, чем написал Мережников Андрей. Функция SetLength относиться к розряду "магических" - то есть искать её реализацию в коде бессмысленно. Её генерирует компилятор. Именно по этой причине у неё можно писать переменное кол-во параметров. В вашем случае, для прямоугольной матрицы можно делать так

var a:array of array of integer;
begin
Setlength(a, 3,5);
a[2,3] := 3;
....
a := nil; //или SetLength(a, 0, 0); -указание компилятору на то, 
//что массив нам больше не нужен и можно 
//вставить код освобождения памяти.
И не надо генерировать цикл, что бы каждый столбец увеличивать.
Замечу, что динамические массивы появились с 4 делфи (да, некоторые ещё юзают 3). а вот SetLength с переменным кол-вом параметров точно есть в 2006-2007.

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 8 июня 2008, 19:56

Ответ #3. Отвечает эксперт: min@y™

Добавлю:

Цитата:


Как сделать так, чтобы можно было ... вводить свои значения через форму?


Для матриц испокон веков использовали компонент TStringGrid и его потомков.

Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 9 июня 2008, 08:18
Оценка за ответ: -1

Комментарий к оценке: Через форму - это значит вводить их самостоятельно, а в какой компонент не важно. Я в курсе, что здесь используется stringgrid и не только.

Мини-форум вопроса

Всего сообщений: 12; последнее сообщение — 10 июня 2008, 23:16; участников в обсуждении: 3.
Drongo

Drongo (статус: Посетитель), 9 июня 2008, 00:40 [#1]:

Так. Я вот попробовал вместо конструкции
const K = 8;
Mas:array[1..K, 1..K] of Integer =
((0, 12, 15, 0, 10, 0, 0, 0),
(0, 0, 0, 8, 15, 6, 0, 0),
(0, 0, 0, 0, 1, 0, 16, 0),
(0, 0, 0, 0, 0, 3, 0, 30),
(0, 0, 0, 0, 0, 8, 3, 2),
(0, 0, 0, 0, 0, 0, 0, 5),
(0, 0, 0, 0, 0, 0, 0, 25),
(0, 0, 0, 0, 0, 0, 0, 0));

Подставить то, что вы мне посоветовали. var k:array of integer;
Но теперь мне выдет ошибку дельфи в каждом массиве
Constant expression extended

Не могли бы Вы проверить все это дело у себя, а потом мне все объяснить?
Вадим К

Вадим К (статус: Академик), 9 июня 2008, 01:06 [#2]:

Ну логично, что оно у вас будет ругаться - дело в том, что у вас константный массив в программе. А он по определению не может не то что размеров менять, а и значений. По этому для начала надо сделать его переменной,а потом уже эксперементировать. Если посмотрите в тот кусочек кода, что я написал, то там всё это видно..
Галочка "подтверждения прочтения" - вселенское зло.
Drongo

Drongo (статус: Посетитель), 9 июня 2008, 16:35 [#3]:

Не, ниче не понятно.
Вот я подставил вместо константы прописал
K:array of array of integer;
и сразу же мне из другого массива
job_str:array[1..K, 1..K] of string;
вылетает ошибка, Constant expression extended
Как что нужно поменять??
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 9 июня 2008, 20:38 [#4]:

Нужно прочесть книгу по началам программирования...
Мережников Андрей

Мережников Андрей (статус: Абитуриент), 9 июня 2008, 20:46 [#5]:

Sorry, вырвалось. Прежде, чем что-то менять в программе, надо разобраться что и за что отвечает. В вашем конкретном случае, объявляется целочисленная константа K, в которой хранится размерность массивов. В своем ответе я приводил просто пример объявления динамического массива, поэтому не надо было вписывать его в программу буквально. В программе несколько массивов, каждый своего типа и размерности. Их все надо объявить как динамические. Конкретные примеры: var Mas:array of array of integer;job_str:array of array of string;
затем инициализировать их с помощью функции setlength, после этого только заполнять значениями и дальше работать так, как вам надо
Drongo

Drongo (статус: Посетитель), 9 июня 2008, 22:25 [#6]:

А можно с этого места поподробнее????
Я объявил все массивы одинаково.
Как их инициализировать???
И что дальше делать с константой К???
Дальше по коду она используется.
Как всеже закончить программу? В среду сдать нужно))) Помогите, plz.

P.S. Изучаю дельфи самостоятельно 3 года. Массивы одно из самых слабых мест (мест слабых хватает). По массивам не мешало бы почитать литературку.
Вадим К

Вадим К (статус: Академик), 9 июня 2008, 23:46 [#7]:

Константу К прийдётся делать переменной, иначе вводить размерность с "формы" не получиться.
то есть где то так
var K:integer;
Mas:array of array of Integer;
Где то в кнопке "Прочитать с стриггрида" такое
var i,j:integer;
begin
  k := strtoint(edit1.text);
  Setlength(mas, k,k);
  for i := 0 to k-1 do
    for j := 0  to k-1 do
      mas[i,j] := strtoint(StringGrid1.cells[j,i]);
Ну а дальше осталась обработка - массив то уже заполнен.
Только не надо забывать, что нумерация динамических массивов начинается с нуля!
Галочка "подтверждения прочтения" - вселенское зло.
Drongo

Drongo (статус: Посетитель), 10 июня 2008, 01:21 [#8]:

Вопрос. А на 0 везде менять где цикл от i=1 до К??? i тогда будет от 0? везде так прописывать нужно?
На форме уже есть один stringgrid, можно его использовать???

Когда все изменил, у меня во втором модуле (для графика)
ошибка
"Constant expression extended"
вот здесь
vertex[k].min;
P.S. Переделайте пожалуйста сами программу, чтобы уже наверняка была, а потом мне наводящими вопросами помочь решить её самому. Хочу во всем разобраться
Вадим К

Вадим К (статус: Академик), 10 июня 2008, 02:08 [#9]:

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

Цитата:


vertex[k].min;

А тут скорее всего писать надо vertex[k-1].min;, если конечно массив объявлен как Vertex:array of uzel;
А за циклические связи между юнитами, глобальные переменные-массивы - бить по пальзцам надо - такое вообще надо исключать в своей работе. Рзгребать такой код никому не хочеться - дернул в одном месте - разлезлось в другом
Галочка "подтверждения прочтения" - вселенское зло.
Drongo

Drongo (статус: Посетитель), 10 июня 2008, 12:36 [#10]:

Вадим К, Спасибо Вам большое за советы и помощь. Возможно в будущем я и разберу этот пример, да и в следующий раз думаю не будет такого срочного дела. Спасибо всем за советы)))
Drongo

Drongo (статус: Посетитель), 10 июня 2008, 12:55 [#11]:

Все же решил добить я программку.
С массивами все получилось, ошибок нет. Теперь появилась проблема с grid'ом. Там ведь тоже нужно что-то поменять? Когда я компилирую выдает ошибку
"Project Project1 raised exception class EAccessViolation with message 'AccessViolation at adress 004612B9' in module Project1.Process stopped. Use Step or Run to continue."......
вот в этой строке (строка вся выделена)
"for J:=I+1 to K-1 do Job_Str[I][J]:=Format('%d-->%d', [I, J]);"
Нажимаю ОК и опять F9. Пофвляется форма. ввожу в Edit значение К и нажимаю на кнопку.
Появляется ошибка
"Project Project1 raised exception class EConvertError with message "" is not a valid value.Process stopped. Use Step or Run to continue."......

Что еще нужно сделать? Это с гридом проблема?
Вадим К

Вадим К (статус: Академик), 10 июня 2008, 23:16 [#12]:

По поводу первой ошибки - это где то в FormCreate должно быть. Проблема у вас с индексами - обращаетесь к элементу, который не существует. Надо искать более аккуратнее. Можно например воспользоваться методом проверки значений. Если вы хорошо знаете свой код, то можете естественно составить условия для некоторых переменных, дать для них границы. Пишете в коде так
Assert(i>0, 'Упс, а почему i меньше/равно 0?');
Будет проверяться условие, и если оно ложно, выпрыгнет сообщение с вашим текстом и также будет указано номер строки и юнит, даже если программа запущена на другой машине, где нет делфи. Потом, когда программа отлажена, эти сообщения можно отключить одной галочкой в настройках проекта и перекомпилировать - они все будут просто игнориться компилятором.

По поводу второй ошибки - скорее всего вводите в один edit, а читаете с другого.
Галочка "подтверждения прочтения" - вселенское зло.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:39
Выполнено за 0.03 сек.