Пару задач от Яндекса

vital

Больной Компом Детектед
29.01.2006
2 432
33
#1
Нижеприведенные задания яндекс дает только для того что бы решить - стоит смотреть ваше резюме или нет. Не то что бы я туда собирался, просто задания интересные.. ТОЛЬКО Я НИХРЕНА НЕ ВИЖУ ЧТО НЕ ТАК?

Код:
 Всегда ли будет корректно работать приведенный код?

type

PSomeRecord = ^TSomeRecord;
TSomeRecord = record

F1: Byte;
F2: DWORD;

end;

function GetSomeRecord: PSomeRecord;
var

A: Byte;
B: DWORD;
begin

A := 1;
B := 2;
GetMem(Result, SizeOf(A) + SizeOf(B));
Result^.F1 := A;
Result^.F2 := B;
end;
Тут я не знаю. И на первый взгляд и при проверке все прекрасно компилируется и работает.

Код:
Всегда ли функция GetMonotoniousTime будет выдавать монотонный отсчет времени?

var
LastTime: TDateTime = 0;

function GetMonotoniousTime: TDateTime;
var
SysTime: TSystemTime;
begin
GetSystemTime(SysTime);
Result := SystemTimeToDateTime(SysTime);
if Result = LastTime then Result := Result + 1;
LastTime := Result;
end;
Ради интереса дописал в конец ф-и 2 строчки:
showmessage(timerostr(result));
getmonotoniustime;// И получил кучу окошек в к-х постепенно шло время. Все. Имхо, и ничто это не изменит.

Код:
Всегда ли правомерен и безопасен приведенный код:

procedure Foo(Args: array of string);
var
I: Cardinal;
begin
for I := Low(Args) to High(Args) do
Windows.MessageBox(0, PChar(Args[I]), nil, 0);
end;
Тут сначала было подумал что если передать массив с отрицательными индексами то будет ошибка(кардинал начинается от 0). Передал сделал что-то в духе
var
ar:array[-5..0] of string;
////
foo(ar);

Но все прекрасно заработало. И вот тут я удивляюсь - почему?? Вставил ещё строчку showmessage(inttostr(Low(ar)); И увидел не -5 а 0... За этим я ещё слажу в хелп. но в чем тогда здесь загвостка?
Вот, хреновый из меня программЁр. Расскажите кто-нить что тут и как.
 
Z

zubr

#2
В первой задаче правильно будет если структура будет объявлена как пакед рекорд: TSomeRecord = packed record. Проверь, возьми SizeOf(TSomeRecord) в обоих случаях.

Во второй задаче, на мой взгляд, не совсем корректное условие. Однозначно, условие if Result = LastTime then Result := Result + 1; не будет выполняться никогда.

В третьей задаче нет проверки, создан ли массив. Правильнее будет так:
Код:
procedure Foo(Args: array of string);
var
I: Cardinal;
begin
If Length(args)=0 then
exit;
for I := Low(Args) to High(Args) do
Windows.MessageBox(0, PChar(Args[I]), nil, 0);
end;
Или хотя бы перехватывать исключение.
 
Z

zubr

#5
В общем случае SizeOf(TSomeRecord) <> Sum(SizeOf(составляющие)), компилятор без packed расширяет до границы двойного слова, а с packed - как в старом добром паскале.
Но всеравно я бы не стал уповать на packed.
Ну если не упаковывать, то тогда надо GetMem(Result, SizeOf(TSomeRecord));
А работает программа, потому что память выделяется под один элемент структуры. А если выделить память под несколько элементов и пытаться получить значения элементов через указатель? Думаю в лучшем случае программа будет работать неправильно, в худшем - аксесс виолейшн.
 
04.09.2006
2 566
3
#6
<!--QuoteBegin-sax_ol+23:01:2008, 10:49 -->
<span class="vbquote">(sax_ol @ 23:01:2008, 10:49 )</span><!--QuoteEBegin-->вот что значит давно не держать в руках Delphi
[snapback]94659" rel="nofollow" target="_blank[/snapback]​
[/quote]
Давно не держать в руках Дельфи, это когда как я пытаешся вспомнить, что это за крышки (^) в коде
 

vital

Больной Компом Детектед
29.01.2006
2 432
33
#7
2sax_ol
<!--QuoteBegin-sax_ol+23:01:2008, 10:23 -->
<span class="vbquote">(sax_ol @ 23:01:2008, 10:23 )</span><!--QuoteEBegin-->как в старом добром паскале
[snapback]94643" rel="nofollow" target="_blank[/snapback]​
[/quote]
Это как?
PS.
Топик стартеру стыдно..
 
P

Pasha

#8
Для: vital
Когда файлы были большие, а дискеты - маленькие. В паскале под дос, до того как 32-битные системы получили широкое распространение, структуры выравнивались по границе слова или байта.
 
G

GRLEX

#9
Привет народ, я по поводу второй задачи.
Код:
.....
Result := SystemTimeToDateTime(SysTime);
if Result = LastTime then Result := Result + 1;
LastTime := Result;
.......
насколько я знаю в делфи после присваения значения переменной Result происходит возврат из функции.
тоесть смысла в условии которое стоит ниже нет вообще.
поправьте если не прав
 
Z
#10
Для: GRLEX
Не путай return C и Result Delphi. Данный код не будет выполняться по другой причине, потому, что как в одну и ту же реку нельзя войти дважды, так и результат получения времени в разных запросах функции будет разный.
 
G

GRLEX

#11
Согласен, сам проверил, не возвращается. Странно, я реально думал все время, что Result работает по аналогии return. Теперь буду знать :)