![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() ![]() |
![]() |
Вячеслав Л. |
![]()
Сообщение
#1
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 227 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
Как надо написать в var'e, когда необходимо выделить некоторое количество ячеек для массива?
Код var a:array[1..?] of integer; ... write('kakoe koli4estvo simvolov bydet v massive'); readln(n); for i:=1 to n do {zapolnenie masiva lyubym sposobom} Если место ? написать n, вылетает ошибка, тогда что должно быть место вопросительного занка? Нельзя же просто писать максимальную цифру от фонаря, типа 9999? -------------------- Само знание есть сила
|
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
Цитата Нельзя же просто писать максимальную цифру от фонаря, типа 9999? Смотря что тебе надо, сколько элементов будет храниться в массиве. Если ты это знаешь заранее - столько и выделяй, если не знаешь - используй динамические массивы (GetMem + FreeMem). Хотя да, сейчас начнется "я это не знаю, мне надо как я умею." Нельзя как ты умеешь. Либо ты хочешь учиться программировать, либо нет. Если хочешь - то учись, направление для поисков я тебе обозначил, где искать - тоже могу подсказать: форум FAQ, тема - "Динамические массивы и матрицы". Если нет - так и скажи, будем тебе предлагать решения "неправильно, но чтоб работало". Например, выделять сразу столько памяти, сколько максимально может пригодиться. |
Вячеслав Л. |
![]()
Сообщение
#3
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 227 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
Цитата Если ты это знаешь заранее - столько и выделяй, если не знаешь - используй динамические массивы (GetMem + FreeMem). Вопрос был именно для случая, когда заранее неизвестно из скольки элементов состоит массив, то есть это число вводится пользователем или задается рандомно. Понятно, если предполагаешь массив из 20 элементов, то в описании и пишешь 20.Цитата Хотя да, сейчас начнется "я это не знаю, мне надо как я умею." Не надо так говорить ![]() Цитата где искать - тоже могу подсказать: форум FAQ, тема - "Динамические массивы и матрицы". Я читал эту тему, проги, данные там я не понял, просто не понимаю целые части в них.Цитата Например, выделять сразу столько памяти, сколько максимально может пригодиться. Так что ли, ты предлагаешь? <см. 1ый пост этой темы> Цитата писать максимальную цифру от фонаря, типа 9999? . Скажи тогда, ты ответил на вопрос?-------------------- Само знание есть сила
|
Lapp |
![]()
Сообщение
#4
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Код var a:array[1..?] of integer; ... write('kakoe koli4estvo simvolov bydet v massive'); readln(n); for i:=1 to n do {zapolnenie masiva lyubym sposobom} Если место ? написать n, вылетает ошибка, тогда что должно быть место вопросительного занка? Нельзя же просто писать максимальную цифру от фонаря, типа 9999? const- а в программе допускать использование только тех значений n, которые не превосходят m. m при этом - константа, ее изменять нельзя. Это позволяет сделать программу немного проще изменяемой, но вообще-то проблемы не решает. Если ты хочешь выделять под массив ровно столько памяти, сколько нужно, то есть, грубо говоря, два способа: 1. использовать динамическую память; 2. использовать динамические массивы. Насколько я помню (давно ТР не запускал уже), динамических массивов (то есть п.2) в ТурбоПаскале нет. Есть же они, например, в FreePascal. Поэтому, вопрос: что конкретно ты используешь? Добавлю, что способ 1 посложнее в понимании, и в нем больше писанины, но он предоставляет практически полные возможности по управлению памятью. Способ 2 предоставляет более высокий уровень, он скрывает манипуляции с памятью (компилятор берет их на себя); во многих случаях он удобнее. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Вячеслав Л. |
![]()
Сообщение
#5
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 227 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
constПо моему, тут мы просто так же от фонаря пишем 100 (а можно было 9999). Ничего не изменилось, только по-другому выглядит, смысл тот же самый. Цитата Поэтому, вопрос: что конкретно ты используешь? Я ничего не использую. Я просто пока не знаю как их использовать. Сейчас читаю учебник насчет этого.-------------------- Само знание есть сила
|
Lapp |
![]()
Сообщение
#6
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
По моему, тут мы просто так же от фонаря пишем 100 (а можно было 9999). Ничего не изменилось, только по-другому выглядит, смысл тот же самый. Да, именно так, о чем я тебе и написал уже. Хотя, программа стала более читабельной и гибкой.Я ничего не использую. Я просто пока не знаю как их использовать. Сейчас читаю учебник насчет этого. Хм, странно.. Выходит, вот это:Если место ? написать n, вылетает ошибка, - мне приснилось? ![]() Ошибка ГДЕ вылетает? Не в компиляторе разве? Из объектива, как птичка?.. Я тебя спросил, каким компилятором ты пользуешься. Читай внимательнее то, что тебе пишут! и отвечай на вопросы, которые задают, а не на те, которые тебе мерещутся при беглом просмотре.. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Вячеслав Л. |
![]()
Сообщение
#7
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 227 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
Цитата - мне приснилось? Я не правильно понял "вопрос: что конкретно ты используешь?" Думал, это про динамические массивы и динамическую память. Отсюда, и ответ, откуда мне знать, что имелся в виду мой компилятор. Что, касается компилятора, я использовал PascalABC, сейчас качаю FreePascal. Ошибка ГДЕ вылетает? Не в компиляторе разве? Из объектива, как птичка?.. Я тебя спросил, каким компилятором ты пользуешься. Читай внимательнее то, что тебе пишут! и отвечай на вопросы, которые задают, а не на те, которые тебе мерещутся при беглом просмотре.. Цитата Читай внимательнее то, что тебе пишут! и отвечай на вопросы, которые задают, а не на те, которые тебе мерещутся при беглом просмотре.. Вот насчет этого не надо, всегда стараюсь, отвечать на вопросы, которые мне задают и отвечать по существу. "При беглом просмотре" мне вопросы не мерещутся.-------------------- Само знание есть сила
|
Lapp |
![]()
Сообщение
#8
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Вот насчет этого не надо, всегда стараюсь, отвечать на вопросы, которые мне задают и отвечать по существу. "При беглом просмотре" мне вопросы не мерещутся. "Надо, Федя, надо." (С) ![]() Если ты все читал бы внимательно, то не ушел бы от необходимости трактовать мое слово "Поэтому" (которое ты аккуратно опустил в цитате). Извини, но я трачу достаточно времени на точный подбор слов и переделку после перепрочтения, чтобы иметь основания на ожидание внимательного отношения к моим мессаджам. Впрочем, спасибо за адекватную реакцию)). FreePascal - это лучший вариант из всего, я бы сказал. Про динамические массивы ты вряд ли найдешь в книгах про Турбо. Когда скачаешь - спрашивай)). -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Вячеслав Л. |
![]()
Сообщение
#9
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 227 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
![]() Цитата Если ты все читал бы внимательно, то не ушел бы от необходимости трактовать мое слово "Поэтому" (которое ты аккуратно опустил в цитате). Тогда, извиняюсь, "поэтому" я действительно не заметил, но если и опустил в цитате, то не намеренно.Цитата Извини, но я трачу достаточно времени на точный подбор слов и переделку после перепрочтения, чтобы иметь основания на ожидание внимательного отношения к моим мессаджам. Все видят это.Цитата Когда скачаешь - спрашивай)). Спасибо за помощь. Буду этим заниматься уже на выходных. -------------------- Само знание есть сила
|
Вячеслав Л. |
![]()
Сообщение
#10
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 227 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
Насчет динамических массивов:
я нашел немного, сам разобраться не смогу. Привожу текст: Цитата <общие слова про динамические переменные> Что это значит? (эту строчку я не понял) Объяните, пожалуйста.<говорится что есть такие процедуры и функции как: New, Dispose, GetMem, FreeMem, Mark, Release и т. д.> <рассказывается про каждую из них отдельно> <привожу только то что касается нужной FreeMem> "Процедура FreeMem( var p: Pointer; size: Word ) освобождает участок памяти, адрес начала которого определен указателем p, а размер - параметром size. Значение указателя p становится неопределенным." -------------------- Само знание есть сила
|
andriano |
![]()
Сообщение
#11
|
Гуру ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 168 Пол: Мужской Реальное имя: Сергей Андрианов Репутация: ![]() ![]() ![]() |
Которую из приведенных 5 строчек ты не понял?
Если имеется в виду 5-я строка, а предыдущие 4 должны означать краткий конспект предыдущего изложения, то непонимание тобой 5-й строки говорит о том, что ты невнимательно прочитал или не понял где-то выше по тексту, т.е. то, что скрывается за предыдущими 4-мя строками. Невозможно ничего объяснить, не опираясь на что-то из того, что человеку уже известно. Поэтому расскажи, что ты знаешь о работе с памятью в компьютере. |
TarasBer |
![]()
Сообщение
#12
|
![]() Злостный любитель ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 755 Пол: Мужской Репутация: ![]() ![]() ![]() |
2. использовать динамические массивы. Насколько я помню (давно ТР не запускал уже), динамических массивов (то есть п.2) в ТурбоПаскале нет. Ну просто array of написать не получится. Но можно сделать так:
-------------------- |
Lapp |
![]()
Сообщение
#13
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Насчет динамических массивов: Нет, ты нашел совсем не то. Слав, я тебе от души советую: научись придавать значение каждому слову в том, что читаешь. Я с чего начал? С того, что есть два способа, причем один из них доступен практически во всех компиляторах (ТР, например), и этот метод называется динамической памятью, а второй есть только в продвинутых компиляторах (FPC, например, который ты скачал - да?), и он называется динамические массивы (dynamic array). То, что ты привел - это работа с динамической памятью. Ошибиться довольно легко, потому что в сети масса недоразумений по этому поводу.я нашел немного, Если ты теперь действительно являешься счастливым обладателем FPC, и тебе не нужна совместимость с ТР, то я рекомендую работать именно с динамическими массивами. Повторяю: это НЕ ТО, что ты нашел. Я расскажу сейчас именно про динамические масивы. Ну просто array of написать не получится. TarasBer, внимательнее читай тему перед ответом, пожалуйста.Итак, в FPC ты имеешь полное право написать так: a: array of integer; Размер такого массива не определен (то есть равен нулю, грубо говоря, если не считать описывающей массив структуры) до использования SetLength. После этого массив будет иметь столько элементом, сколько назначено, причем отсчет начинается с нуля. Освободить память можно посредством назначения нулевой длины. Например: SetLength(a,10); Процедура SetLength имеет такое же название, как аналогичная процедура для типа String. Конечно, и действие ее аналогично, но нельзя забывать и о различиях - название одинаковое, но вещи разные. Этого средства (dynamic arrays) достаточно для огромного количества нужд. Поэтому лчень может статься, что в ближайшее время тебе не понадобится работа с динамической памятью. Если же все же возникнет нужда - скажи, объясним )). ой, блин, просрочил паркинг - этот мессадж мне стоил доллар.. )))))))) -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
Вячеслав Л. |
![]()
Сообщение
#14
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 227 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
Цитата то непонимание тобой 5-й строки говорит о том, что ты невнимательно прочитал или не понял где-то выше по тексту, т.е. то, что скрывается за предыдущими 4-мя строками. Специально, чтобы не было таких предложений, я привел краткий конспект вышесказанного. Про "Процедура FreeMem( var p: Pointer; size: Word ) ... " я там объяснения не нашел.Цитата Невозможно ничего объяснить, не опираясь на что-то из того, что человеку уже известно. Поэтому расскажи, что ты знаешь о работе с памятью в компьютере. Что именно тебя интересует? Одна ячейка памяти - это один бит, байт это 8 бит, ... 1 Кб = 1024 Байт и т. д. Касаемо памяти в Паскале, знаю только общие фразы из учебника (типа: каждой переменной должна быть присвоена определенная ячека памяти, тип Integer ограничивается таким-то числом, тип Longint ограничивается таким-то числом - краткий пересказ, не придирайтесь : ))Цитата Ну просто array of написать не получится. Смотри посты выше.Но можно сделать так: Цитата Слав, я тебе от души советую: научись придавать значение каждому слову в том, что читаешь. Буду стараться...Нда, тогда действительно у меня возникает путаница. В строчке Цитата Насчет Тогда есть ошибка, имелось в виду, насчет динамической памяти. Я так понимаю FreeMem образовано от английского Free Memory (свободная память), соответственно, я нашел немного не насчет динамических массивов, а насчет динамической памяти. я нашел немного, сам разобраться не смогу. Цитата Ошибиться довольно легко, потому что в сети масса недоразумений по этому поводу. Согласен.Цитата Если ты теперь действительно являешься счастливым обладателем FPC, Действительно, являюсь - FPC 2.2.2Что значит вот это Цитата c: array of record и вот это Цитата d: double; ?SetLength я, так, понял действует только для динамических массивов и во FPC? Строчка SetLength(a,10) - означает присвоить массиву a память под 10 элементов. То есть если бы пользователь сам вводил количество элеметов массива для которых он хотел решать задачу, то было бы: ...Или нет? Цитата Процедура SetLength имеет такое же название, как аналогичная процедура для типа String. Такой процедурой не пользовался : ( - мне это ни о чем не говорит...Цитата Если же все же возникнет нужда - скажи, объясним )). Нужда, кажется, возникнет: в основном в учебниках я встречаю FreeMem, хотелось бы знать конкретнее. Все таки интересно, что это значит ?Цитата "Процедура FreeMem( var p: Pointer; size: Word ) освобождает участок памяти, адрес начала которого определен указателем p, а размер - параметром size. Значение указателя p становится неопределенным." -------------------- Само знание есть сила
|
Lapp |
![]()
Сообщение
#15
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Сначала о простом:
double - это один из вещественных типов. Занимает в паямяти 8 байт. Используется для расчетов повышенной точности (по сравнению с single, 4 байта, и real, 6 байт). record - тип "запись", представляющий набор полей (переменных разных типов), сейчас рассказывать не буду, пройдешь позже. Извини, что упомянул. краткий пересказ, не придирайтесь Дело не в краткости. Дело в том, что ты не упомянул такое понятие, как адресация, а оно тут ключевое. Организация памяти - побайтовая, у каждого байта - адрес (грубо говоря, его номер). Если мы имеем дело с многобайтовой структурой (integer, string..), то ее адресом является адрес первого байта. Адреса всех объявленных переменных зашиты намертво в программу. Но если мы хотим в программе использовать дополнительную память, то мы должны запросить ее у системы (ОС). Если у ОС память есть, она выделяет запрошенное нам количество байт (и записывает себе, что они теперь в деле) и выдает нам адрес начала этого куска. Эту память (начиная с выделенного адреса, и столько, сколько запросили) мы можем использовать (как - скажу ниже). Когда мы закончили работу с выделенной нам памятью, мы ее можем освободить, то есть сказать ОС, что кусок такой-то длины начиная с такого-то адреса теперь свободен. В Паскале есть понятие pointer - переменная такого типа просто содержит адрес. Сначала рассмотрим две процедуры: GetMem и FreeMem. Они в точности соответствуют тому. что я сказал выше. Первая запрашивает память, вторая - освобождает. Длина участка памяти в них задается в байтах. Например: var Этот пример не несет большого смысла. Смысл появится ниже.. Кроме простого указателя pointer в Паскале есть указатели на переменные. По сути - это точно такие же пойнтеры, то есть содержат адрес некоторой области. Но в программе есть информация, с каким типом каждый такой указатель ассоциирован. Например, var В этом примере мы берем память (2 байта) и используем ее для целых вычислений. Появился небольшой смысл, но совсем маленький. Есть две непонятки: 1. почему бы нам сразу не сделать целую переменную i. Но это ясно - просто, чтоб изучить дин.память. 2. зачем нам был нужен пойнтер p? Ведь можно было просто так: var- так проще и лучше. Пока еще остается все-таки одна сложность: нам нужно "вручную" вычислять количество необходимой памяти в байтах. В принципе, с этим можно побороться так: var- вот, мы избавились от двойки. Можно еще универсальнее сделать: В этом виде программа имеет то преимущество, что если нам станет мало типа integer и мы захотим перейти на LongInt, то нужно будет подредатировать всего одну строчку (тип). Но все же неудобно тащить за собой SizeOf. И вот тут приходит на помощь пара процедур New и Release. Думаю, чтоб ты разобрался, достаточно будет привести пример - все та же наша прога, только с парой New/Release вместо пары GetMem/ FreeMem. Тут нам вообще не нужно было связываться с длиной области - компилятор освободил нас от этой работы. Пока хватит, спрашивай, что неясно. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
-volvo- |
![]()
Сообщение
#16
|
Гость ![]() |
Цитата Все таки интересно, что это значит ? Это значит только одно: Как только тебе не нужна больше память, адресуемая указателем P (закончил ты работать с этой переменной, нужно ее удалить), ты ее удаляешь вызовом процедуры FreeMem При этом разрушается связь между ранее выделенной памятью и указателем. Указатель (как пишется в большинстве книг) становится НЕвалидным. Если ты после вызова FreeMem(p, {размер_переменной}); попытаешься вновь обратиться к P^, тебя ждет сюрприз - программа с большой степенью вероятности выбросит тебе Segmentation Fault (пока не спрашивай, что это, если потом где встретишься и заинтересуешься - расскажу. "На сейчас" - рассматривай это как аварийное завершение работы программы), а даже если этого и не произойдет - результатам ее работы все равно доверять нельзя. Поэтому еще одно замечание: ВСЕГДА, после того как вызвал FreeMem, добавь еще одну строку в программу:Цитата "Процедура FreeMem( var p: Pointer; size: Word ) освобождает участок памяти, адрес начала которого определен указателем p, а размер - параметром size. Значение указателя p становится неопределенным." FreeMem(p, {размер_переменной});, тогда программа у тебя гарантированно вылетит при попытке обратиться к освобожденной уже памяти (по ошибке, например, мало ли что). Это лучше, чем псевдоправильные результаты... |
Вячеслав Л. |
![]()
Сообщение
#17
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 227 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
Извиняюсь, маленько отвлекся.
За объяснения спасибо, вроде бы все ясно. Хотелось бы поработать на эту тему еще. Поищу задания, как будет желание. Все таки, что касается вот этого: Цитата Строчка SetLength(a,10) - означает присвоить массиву a память под 10 элементов. То есть если бы пользователь сам вводил количество элеметов массива для которых он хотел решать задачу, то было бы: ... Или нет? -------------------- Само знание есть сила
|
Lapp |
![]()
Сообщение
#18
|
![]() Уникум ![]() ![]() ![]() ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 6 823 Пол: Мужской Реальное имя: Лопáрь (Андрей) Репутация: ![]() ![]() ![]() |
Строчка SetLength(a,10) - означает присвоить массиву a память под 10 элементов. То есть если бы пользователь сам вводил количество элеметов массива для которых он хотел решать задачу, то было бы: ... Или нет? Да. После этого ты можешь пользоваться ячейками массива с a[0] по a[n-1]. Только не нужно говорить "присвоить массиву память", это неправильно. Правильно так: "выделить память под массив". Извини, это не мелочи. Правильное употребление слов способствует правильному пониманию вопроса. -------------------- я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой |
andriano |
![]()
Сообщение
#19
|
Гуру ![]() ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 1 168 Пол: Мужской Реальное имя: Сергей Андрианов Репутация: ![]() ![]() ![]() |
Ну да.
Аналогия: Тебе выдали пачку чистой бумаги - выделили память. Ты наисовал на бумаге свои каракули - присвоил листам некоторые значения. Если бумагу выдали уже исписанную - это константы: если карандашом - типизированные, шариковой ручкой - обычные. |
Вячеслав Л. |
![]()
Сообщение
#20
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 227 Пол: Мужской Реальное имя: Вячеслав Репутация: ![]() ![]() ![]() |
Все понял, спасибо.
-------------------- Само знание есть сила
|
![]() ![]() |
![]() |
Текстовая версия | 18.07.2025 15:09 |