Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Задачка на PASCAL (http://forum.oszone.net/showthread.php?t=29489)

Crazy Wolf 09-01-2003 21:48 204133

Приветствую ALL

Недавно подкинули задачу на Паскале.. помогите решить плиз

С помощью ООП составить описание объектного типа TMatrix обеспечивающего размещение матрицы произвольного размера с вариантностью изменения числа строки  столюцов и вывода на экран подматрицы любого размера и всей матрицы

Я сам потихоньу изучаю Си и как это сделать на Си++ в принципе знаю... (я надеюсь) но как это сделать на Паскале?

vasketsov 10-01-2003 12:56 204134

Crazy Wolf
Цитата:

но как это сделать на Паскале?
Точно так же.

XXXX Pro 12-01-2003 12:43 204135

Чтобы матрица была произвольного размера, память для нее надо выделять динамически, и адреса подсчитывать вручную. (Т.е. к смещению базового адреса прибавить (номер строки-1)*(число столбцов)*размер элемента+(номер столбца-1)*размер элемента)
Все остальное - примерно также, как и в C.

Crazy Wolf 12-01-2003 17:16 204136

XXXX Pro
А попдробнее....как в Паскале с адресами работать.. если можно кусок любого кода для примера....

Crew 14-01-2003 06:54 204137

Если это учебная программа должна быть написана под ДОС, то мои соболезнования.
Сейчас языки срастаются потихоньку, дерут друг у друга самое ороше, а вот Паскаль 7.... там например выделение памяти через new совсем не так как в С работает.

В С как просто было

char *str = new char[20];
//не нужно стало
delete []str;

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

Crazy Wolf 14-01-2003 16:40 204138

Ну тогда рискуя вызвать общий гнев попрошу привести кусок кода с использованием ООП в ПАСКАЛЕ....

Добавлено:

Т.е. я так понимаю что в Паскале нужно создать подобие класса в Си++.... как это делать?

vasketsov 14-01-2003 18:33 204139

type
TElement = Integer;

TRow = class
 Items:array of TElement;
end;

TMatrix = class
 Rows:array of TRow;
end;

Вот примерно так.

Crew 15-01-2003 08:12 204140

Я извиняюсь, конечно, это работать будет только в Delphi мне кажется, потому что границы массива не определены. (учитывая стиль T??????, тем более)
а под ДОС можно было *в функцию передавать массив без границ, только он его извлекать не хотел.
Crazy Wolf
А на чем писать надо, может "мой" досовский паскаль и не нужен?


[s]Исправлено: Crew, 8:14 15-01-2003[/s]

shurikan 15-01-2003 09:09 204141

Crew
Цитата:

(учитывая стиль T??????, тем более)
Не факт, что это Delphi. Нормальное Поскакальное обьявление. Похоже на стандарт Delphi - да, но и только.

vasketsov
А это тягомотно. Можно проще, правда без функций-членов:
Crazy Wolf
(допустим, тебя попросили в данный момент создать матрицу 6x7)

Код:

TMatrix = class
public:
 *V: Variant;
 *constructor Create(const Bounds: array of Integer);
end;

constructor TMatrix.Create(const Bounds: array of Integer);
begin
 *V := VarArrayCreate(Bounds, varInteger);
end;


Matrix: TMatrix;

begin
 *Matrix.Create([1,6,1,7]); {Первая пара нач. и конеч. индексы первого измерения,
 вторая пара - соотв для второго. Нумеруются от 1 до 6 и от 1 до 7}

 *Matrix.V[1,1] := 1; {и т.д.}
end.



[s]Исправлено: shurikan, 9:12 15-01-2003[/s]

Да! Это на Delphi



[s]Исправлено: shurikan, 9:17 15-01-2003[/s]

Crazy Wolf 15-01-2003 20:22 204142

Crew
Цитата:

А на чем писать надо, может "мой" досовский паскаль и не нужен?
Как я понял он то и нужен.... поэтому и затеял эту дискуссию... Просто не слышал что бы в обычном Паскале такие вещи вершить можно.....

Animal 15-01-2003 23:29 204143

Crazy Wolf
На обычном досовском Паскале можно, но я тебе примерчик без ООП сделал, просто по работе с динам. памятью:
uses crt,dos;
Type
pint=^integer;
pbyte=^byte;
pstring=^string;
Var
x,y,i,j,N,temp:integer;
size:longint;
Matrix:pointer;
{А вот это универсальная функция, позволяющая}
{работать с динам. данными, как с обычным массивом}
{p - имя динам. переменной, V - размер одного элемента в матрице в байтах, N - число столбцов, i - координата по вертикали, j - координата по горизонтали}
{координаты считаются от единицы!}
function GetElem(var p:pointer;N,V,i,j:integer):pointer;
var adr:longint;
* * p1:pointer;
begin
adr:=((i-1)*N+(j-1))*V;
p1:=pointer(longint(p)+adr);
GetElem:=p1;
end;

BEGIN
clrscr;
{спросим размерность матрицы}
readln(x);{число столбцов}
readln(y);{число строк}
N:=x
{Допустим матрица со значениями типа integer
в досевом паскале переменная типа integer занимает 2 байта,
в Delphi - 4 байта}
{Выделяем динамич. память}
size:=(x)*(y)*2;
getmem(Matrix,size);

//Пример бестолковой работы с матрицей
i:=3;{номер строки}
j:=4;{номер столбца}
pint(GetElem(Matrix,N,2,i,j))^:=temp;
temp := pint(GetElem(Matrix,N,2,i,j))^;

{Освобождаем динамич. память}
freemem(Matrix,size);{можно не делать, если конец программы}
END.

Успешной сдачи!

[s]Исправлено: Animal, 23:34 15-01-2003[/s]

Crew 16-01-2003 02:47 204144

Animal
Этот даже я себе скопирую, пригодится :bow:

shurikan 16-01-2003 03:57 204145

Animal
Цитата:

{Выделяем динамич. память}
size:=(x)*(y)*2;
getmem(Matrix,size);
Я бы не стал использовать константу, представляющую в д. случае размер типа Integer. Лучше использовать sizeof

Animal 16-01-2003 09:38 204146

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

vasketsov 16-01-2003 12:52 204147

shurikan
Тем более что он будет равен 4, если в Win32.

Crazy Wolf 17-01-2003 00:28 204148

2ALL
Большое сенкс...дошло до меня теперь....
Будете в Славном городе Стерлитамаке, что в Башкирии
:beer: :oszone:

shurikan 17-01-2003 04:06 204149

Animal
Цитата:

использование функции вместо константы замедлит работу.
sizeof вовсе не функция, если применяется для типа, вместо неё компилятор подставляет константу. В случае DOS - это будет 2, ну а для Win32, как правильно заметил vasketsov - 4. И не в красоте дело, просто её использование позволяет писать переносимый код. :)

shurikan 17-01-2003 07:38 204150

Я тут глянул и понял, что немного облажался: :(
Код:

Matrix.Create([1,6,1,7]); {Первая пара нач. и конеч. индексы первого измерения,
 *вторая пара - соотв для второго. Нумеруются от 1 до 6 и от 1 до 7}

Должно быть так:
Код:

Matrix := TMatrix.Create([1,6,1,7]);
Поскольку конструктор - функция класса.
Извините...:shuffle:


[s]Исправлено: shurikan, 7:39 17-01-2003[/s]

vasketsov 17-01-2003 14:51 204151

shurikan
Animal
В случае .NET вообще sizeof запрещено как небезопасный код.

Animal 17-01-2003 22:13 204152

shurikan
Да знал я, знал, что в Win32 тип integer 4 байта, в коментариях ведь написано в моем первом посте - почитай! Смысл то примера - простая работа с динам. памятью на стандартном паскале DOS и только.
vasketsov
Странно, что может быть небезопасного в функции sizeof. Это ни к тому, что я тебе не верю, просто любопытно.

Crew 18-01-2003 03:52 204153

Animal
Они наверное типы данных определили как интеллектуальную собственность.
vasketsov
Мне тоже интересно

paladin 11-08-2004 15:25 204154

Задачка такого плана: "шаг в for"
тоисть с помощю for(!) сделать так:

мне надо чтобы паскаль брал каждый раз "i" не 1 а допустим 0,5
тоисть стандартно у не каждий раз прибавляеться 1 а мне надо 0,5. (стандартно=1 2 3 4 5 .. 50, а мне надо *1 1,5 2 2,5 .. 50)


Dimon 11-08-2004 22:29 204155

paladinzluka
ЕМНИП это делается так: for i:=1 to 50 step=0.5 do

Volvo 12-08-2004 00:41 204156

Dimon

Это в Паскале не пройдет. По определению - в операторе FOR должен быть ЦЕЛЫЙ параметр, и изменяться он может только с шагом 1 или -1. Для другого шага - WHILE или REPEAT.



[s]Исправлено: Volvo, 0:42 12-08-2004[/s]

paladin 12-08-2004 16:06 204157

Volvo
Спасибо, я так думал всегда, но поступила такая задачка и решить ее надо только через for. Вот тут я и начал думать и спросил на форуме. Теперь прийдеться сказать что либо использовать надо WHILE или REPEAT или перейти на другой язик программирования.
* * * * * * * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * Еще раз всем спасибо :oszone:

d dem 30-08-2004 14:27 204158

Цикл с шагом 0.5

( аналог for i:=0 to 100 step 0.5 do )

for z:=0 to 200 do begin
    i:=z div 2;
( или i:=z shr 1 :) )
end;

Volvo 31-08-2004 12:10 204159

d dem

Ты хорошо подумал?

Ну и какого типа у тебя должна быть "i" ?


[s]Исправлено: Volvo, 12:12 31-08-2004[/s]

d dem 31-08-2004 12:27 204160

Пардон, увлекся !

for i:=0 to 100 step 0.5
( мля, бейсик с нами ! :) )

program loop;

var z:integer;
      i:real;
begin

for z:=0 to 100 * 2  do begin
   i:=z / 2;
   writeln( i );
end;

end.


Время: 16:18.

Время: 16:18.
© OSzone.net 2001-