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

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

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

6 страниц V  1 2 3 > »   
Closed Topic Открыть новую тему 
> Задачи на знание ООП, (только для Турбо-Паскаля 7.0)
volvo
сообщение 23.11.2006 10:01
Сообщение #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.
Запускаем, и на экране появляется...
 К началу страницы 
+ Ответить 
hiv
сообщение 23.11.2006 13:07
Сообщение #2


Профи
****

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

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


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

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



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


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

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

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


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

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


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


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


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

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

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


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


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

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


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


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

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

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


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


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


Гость






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


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

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

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


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


--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 24.11.2006 1:34
Сообщение #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.
 К началу страницы 
+ Ответить 
Bokul
сообщение 24.11.2006 2:43
Сообщение #9


Гуру
*****

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

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


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

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


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


Гость






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

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


Гуру
*****

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

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


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

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


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


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Bokul
сообщение 25.11.2006 22:33
Сообщение #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 
 К началу страницы 
+ Ответить 
volvo
сообщение 25.11.2006 22:43
Сообщение #13


Гость






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

В-общем, я так понимаю, что это никому не интересно кроме Bokul-а, ну что-ж... Дело ваше... Складывать числа, табулировать вывод данных и в тысячный раз делать процедуру сортировки "пузырьком" как видно, интереснее... Тему открепляю, пускай уходит вниз... Искусственно поддерживать "живучесть" я не намерен...
 К началу страницы 
+ Ответить 
мисс_граффити
сообщение 25.11.2006 23:41
Сообщение #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 
 К началу страницы 
+ Ответить 
Bokul
сообщение 26.11.2006 0:22
Сообщение #15


Гуру
*****

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

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


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


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

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

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


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


Гость






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

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


Гуру
*****

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

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


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

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


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


Гость






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


Гуру
*****

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

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


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

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

Да.


--------------------
Лао-Цзы :
Знать много и не выставлять себя знающим есть нравственная высота. Знать мало и выставлять себя знающим есть болезнь. Только понимая эту болезнь, мы можем избавиться от нее.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 26.11.2006 2:28
Сообщение #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

 



- Текстовая версия 29.04.2024 20:35
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"