IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

6 страниц V  1 2 3 > »   
Closed Topic Открыть новую тему 
> Задачи на знание ООП, (только для Турбо-Паскаля 7.0)
сообщение
Сообщение #1


Гость






Приветствую всех, зашедших в эту тему...

Такая мысль у меня зрела давно, но вот сегодня (по мотивам одного из топиков в разделе Дельфи) я все-таки решил ее материализовать... Если понравится - продолжу smile.gif

Тема создана для того, чтобы помочь начинающим программировать обратить внимание на особенности ООП, которые при написании программы и (казалось бы) "неправильной" ее работе могут вызвать недоумение.

Говорю сразу, сложных задач здесь выкладывать не буду, будут простые задачки с подвохом ( или без, это уже на мое усмотрение smile.gif ), поэтому огромная просьба: НЕ запускайте компилятор... Внимательно посмотрите на код, и попробуйте определить, что будет выведено на экран при его выполнении... Объяснения, почему Вам кажется, что будет именно так, только присветствуются. Но скрывайте посты тегом [SPОILER], чтобы своим ответом не сбивать остальных smile.gif

Значит, задача №1:

type
TA = object
constructor init;

procedure print; virtual;
end;

TB = object(TA)
constructor init;

procedure print; virtual;
end;

constructor TA.init;
begin
writeln('TA.init');
end;
procedure TA.print;
begin
writeln('TA type object');
end;

constructor TB.init;
begin
inherited Init;
writeln('TB.init');
end;
procedure TB.print;
begin
writeln('TB type object');
end;

procedure print(X: TA);
begin
X.print;
end;
procedure print_const(const X: TA);
begin
X.print;
end;
procedure print_var(var X: TA);
begin
X.print;
end;

var obj: TB;
begin
obj.init;
print(obj);
print_const(obj);
print_var(obj);
end.
Запускаем, и на экране появляется...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Профи
****

Группа: Пользователи
Сообщений: 660
Пол: Мужской
Реальное имя: Михаил

Репутация: -  11  +


Можно и усложнить ;)
добавив:
type PTA=^TA;

procedure print_ptr(X: PTA);
begin
X^.print;
end;



--------------------
Никогда не жадничай. Свои проблемы с любовью дари людям!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Вот мое предположение:

Спойлер (Показать/Скрыть)


Пойду проверять smile.gif


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


ИМХО:
Спойлер (Показать/Скрыть)


volvo, насчет "понравится ли" - какие могут быть сомнения? smile.gif
только в той темке, которая про Делфи, вопрос не закрытый какой-то...

Сообщение отредактировано: мисс_граффити -


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Спойлер (Показать/Скрыть)


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Андрей, внимательнее... Ты не там ошибся smile.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Perl. Just code it!
******

Группа: Пользователи
Сообщений: 4 100
Пол: Мужской
Реальное имя: Андрей

Репутация: -  44  +


Ну да это я перепутал мальца, но смысл то остается тотже
Спойлер (Показать/Скрыть)


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Так... Хорошо. Тогда еще одна...

Задача №2:
smile.gif Что можете сказать по поводу этого кода? Любые комментарии (без компилирования и запуска) приветствуются...
type
PT = ^T;
T = object
end;

PTint = ^Tint;
Tint = object(T)
value: integer;

procedure init(X: integer);
procedure print;
end;

PTfloat = ^Tfloat;
Tfloat = object(T)
value: double;

procedure init(X: double);
procedure print;
end;

procedure Tint.init(X: integer);
begin value := X end;
procedure Tint.print;
begin write(value:4) end;

procedure Tfloat.init(X: double);
begin value := X end;
procedure Tfloat.print;
begin write(value:8:4) end;

const
maxSize = 100;
type
TArr = object
arr: array[1 .. maxSize] of PT;

constructor init;
procedure set_index(i: integer; p: PT);

procedure count_each(var p: PT);
end;

constructor TArr.init;
begin end;
procedure TArr.set_index(i: integer; p: PT);
begin if i <= maxSize then arr[i] := p; end;

procedure TArr.count_each(var p: PT);
var i, count: integer;
begin
count := 0;
for i := 1 to maxSize do
if typeof(arr[i]^) = typeof(p^) then inc(count);
writeln('count = ', count);
end;


var
obj_int: ^Tint;
obj_float: ^Tfloat;
any_arr: TArr;
begin
any_arr.init;
obj_int := new(PTint); obj_int^.value := 3;
any_arr.set_index(1, obj_int);
obj_float := new(PTfloat); obj_float^.value := 3.5;
any_arr.set_index(2, obj_float);
end.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Классная тема! good.gif
Цитата
Что можете сказать по поводу этого кода?

Т.е. что выведет процедура TArr.count_each(var p: PT) если ее вставить перед последним end'ом?


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






Что выведет, например,
any_arr.count_each(new(PTfloat));

, если это вставить перед последним end-ом? smile.gif В частности, что ВООБЩЕ делает эта процедура count_each?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Цитата
В частности, что ВООБЩЕ делает эта процедура count_each?

Она считает количество элементов в массиве any_arr.arr у которых тип такой как и у передаваемого аргумента. Хотя с типом аргумента не уверен, так как вместо указателя на объект-родитель ты даешь указатель на объект-наследник.
Вопрос: считать, что при вызове проги все элементы этого массива равны nill?
Спойлер (Показать/Скрыть)


Сообщение отредактировано: Bokul -


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


В общем не выдержал я решил попробовать скомпилировать (не запуская) код.
Компилятору не понравилось две строчки:
1-ая

procedure Tfloat.init(X: double);
begin value := X end; {Must be in 8087 mode to compile this}


Я поставил директиву {$N+}, помогло.

2-ая

procedure TArr.count_each(var p: PT);
var i, count: integer;
begin
count := 0;
for i := 1 to maxSize do
if typeof(arr[i]^) = typeof(p^) then {Object type expected}
inc(count);
writeln('count = ', count);
end;


Тут я не понимаю в чем проблема...

volvo у тебя все нормально компилировалось?


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Гость






А я предупреждал:
Цитата(volvo @ 23.11.2006 9:01)
будут простые задачки с подвохом ( или без, это уже на мое усмотрение smile.gif )
Здесь как раз и было интересно, будет ли кто-то смотреть на код, и пробовать его анализировать, или код будет скопирован, и Atl+F9... Нет. Этот код не должен компилироваться. Следующим моим вопросом должен был быть вопрос "А как, собственно, заставить эту программу компилироваться", но...

В-общем, я так понимаю, что это никому не интересно кроме Bokul-а, ну что-ж... Дело ваше... Складывать числа, табулировать вывод данных и в тысячный раз делать процедуру сортировки "пузырьком" как видно, интереснее... Тему открепляю, пускай уходит вниз... Искусственно поддерживать "живучесть" я не намерен...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


просто человек
******

Группа: Пользователи
Сообщений: 3 641
Пол: Женский
Реальное имя: Юлия

Репутация: -  55  +


и мне интересно.
просто в тысячный раз скинуть пузырек можно и между делом, а здесь надо посидеть подумать.
*эт я пытаюсь себя заставить зачетную работу по философии делать.... уже забила.
volvo, следующий вопрос должен был быть "как заставить компилироваться" или "как заставить выдать определенный результат, имеющий какое-то значение"?
компилироваться, думаю, будет вот так:
({$N+} не вставляла как не относящееся к названной теме)
type
PT = ^T;
T = object
{
добавляем конструктор в родительский класс - остальные пусть наследуют...
при желании можно было просто переделать init....
}
constructor create;
end;

PTint = ^Tint;
Tint = object(T)
value: integer;
procedure init(X: integer);
procedure print;
end;

PTfloat = ^Tfloat;
Tfloat = object(T)
value: double;
procedure init(X: double);
procedure print;
end;

procedure Tint.init(X: integer);
begin value := X end;
procedure Tint.print;
begin write(value:4) end;

procedure Tfloat.init(X: double);
begin value := X end;
procedure Tfloat.print;
begin write(value:8:4) end;

const
maxSize = 100;
type
TArr = object
arr: array[1 .. maxSize] of PT;

constructor init;
procedure set_index(i: integer; p: PT);

procedure count_each(p: PT); {убираем var... почему - см.ответ на предыдущий вопрос}
end;

constructor TArr.init;
begin end;
procedure TArr.set_index(i: integer; p: PT);
begin if i <= maxSize then arr[i] := p; end;

procedure TArr.count_each(p: PT);
var i, count: integer;
begin
count := 0;
for i := 1 to maxSize do
if typeof(arr[i]^) = typeof(p^) then inc(count);
writeln('count = ', count);
end;

constructor T.Create;
begin end;

var
obj_int: ^Tint;
obj_float: ^Tfloat;
any_arr: TArr;
begin
any_arr.init;
obj_int := new(PTint);
obj_int^.Create;
obj_int^.value := 3;
any_arr.set_index(1, obj_int);
obj_float := new(PTfloat);
obj_float^.create;
obj_float^.value := 3.5;
any_arr.set_index(2, obj_float);
any_arr.count_each(new(PTfloat));
end.


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


    
obj_int := new(PTint);
obj_int^.Create;


Можно заменить на
  obj_int := new(PTint,Create);

Значит я был прав насчет VMT таблицы? Выходит что компилятор сам может "вылавить" такую ошибку?

Сообщение отредактировано: Bokul -


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Гость






Цитата
Выходит что компилятор сам может "вылавить" такую ошибку?
Не совсем... Компилятор делает медвежью услугу... С одной стороны, он контролирует в Compile-Time, что у типа, к которому применяется TypeOf, вообще НЕ МОЖЕТ быть VMT, следовательно, он не может использовать TypeOf, а с другой...

Берем код мисс_граффити... Вопрос на засыпку: будет работать корректно, или нет? smile.gif Если ДА - то что будет напечатано, если НЕТ - где будет сбой...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Цитата
procedure count_each(p: PT); {убираем var... почему - см.ответ на предыдущий вопрос}

А это имеет значения в данном случае? Мне кажется что нет, мы же передаем не объект, а указатель на него, а значит нам все-равно будет ли он копироваться или нет. ИМХО.


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Гость






Цитата
передаем не объект, а указатель на него, а значит нам все-равно будет ли он копироваться или нет
Ага... Только вот не скомпилируется у тебя с Var программа, а без Var или с Const - это будет компилироваться... Объяснить, почему?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Гуру
*****

Группа: Пользователи
Сообщений: 1 117
Пол: Мужской
Реальное имя: Богдан

Репутация: -  11  +


Цитата
Ага... Только вот не скомпилируется у тебя с Var программа, а без Var или с Const - это будет компилироваться...

А я уже ответ хотел писать опираясь на это...
Цитата
Объяснить, почему?

Да.


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Гость






Потому, что при описании
procedure count_each(Var p: PT);
компилятор ждет передачи адреса переменной, которую можно менять, то есть, не просто адреса чего-то там в памяти, а именно адрес переменной... А вот Const означает, что можно передать любой адрес, изменять-то по нему ничего нельзя, тем более - вообще БЕЗ спецификатора, можно передавать как адрес переменной, так и просто адрес, он все равно скопируется в стек, и никаких действий с объектом, на который он указывает, производиться не будет...

А теперь смотрим, КАК вызывается count_each:
any_arr.count_each(new(PTfloat));
Что передается? Адрес... Переменной-то нет... Так что с Var-ом нельзя... Внимательнее смотри не только на объявление процедуры, но и на вызов...
 К началу страницы 
+ Ответить 

6 страниц V  1 2 3 > » 
Closed Topic Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 23.09.2020 11:36
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name