Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Вниз

Кака лучше?   Найти похожие ветки 

 
Fr   (2012-04-15 13:23) [0]

Практически везде в предоставляемых кусках кода есть такое:
for i:=0 to SL.Count-1 do ...

Почему вместо SL.Count-1 не используется Pred(SL.Count)?

В чем здесь подвох? Может одна операция действует быстрее другой? Или может возникнуть какая-нибудь проблема при использовании Pred(SL.Count)?


 
brother ©   (2012-04-15 13:24) [1]

какая такая кака???


 
Сергей М. ©   (2012-04-15 13:33) [2]

"Кака" - она в "Практически везде"


 
Fr   (2012-04-15 13:42) [3]


> какая такая кака???

Читать не "кака", а "как" :)  Не виноват я, что здесь отсутствует система исправления своих сообщений. Поэтому при наборе текста и возникают такие ошибки.

А что по существу вопроса?


 
RWolf ©   (2012-04-15 13:50) [4]

Пишется проще, читается легче, по скорости одинаково.


 
Anatoly Podgoretsky ©   (2012-04-15 16:01) [5]

Скомпилируй обе каки и сравни код.


 
Sha ©   (2012-04-15 17:56) [6]

вторая кака хуже - она заставляет думать


 
DVM ©   (2012-04-15 18:40) [7]


> вторая кака хуже - она заставляет думать

второй вариант более удобен в массивах

a: array[0..Pred(256)] of ...

Наглядно показывает количество элементов в массиве


 
Sha ©   (2012-04-15 19:43) [8]

на мой взгляд 255 удобнее


 
Fr   (2012-04-15 21:43) [9]

Спасибо всем. Насколько я понял, принципиальной разницы нет, как делать. все зависит от восприятия пишущего и читающего :)


 
CRLF   (2012-04-15 22:57) [10]

На мой взгляд array [Byte] of ... удобней, и с обязательным объявлением именованного типа.


 
Германн ©   (2012-04-16 01:59) [11]


> На мой взгляд array [Byte] of ... удобней

Но работает только для конкретного примера в DVM ©   (15.04.12 18:40) [7]


 
Германн ©   (2012-04-16 02:07) [12]

А в целом все эти функции/процедуры Pred, Succ, Inc, Dec, Include, Exclude (может и ещё какие-то были) были "временной оптимизацией скорости выполнения" в эпоху Турбо Паскаля и может быть в эпоху Д1. Сейчас они никакой оптимизации не добавляют. И как правило лишь мешают воспринимать код тем, кто начал заниматься программированием после вышеназванной эпохи.


 
CRLF   (2012-04-16 10:31) [13]


> Но работает только для конкретного примера в DVM
Ну да, в прочих случаях объявляем TIndex = IndexMin..IndexMax; TArray = array [TIndex] of TElement;


 
Ega23 ©   (2012-04-16 11:04) [14]


> Почему вместо  SL.Count-1 не используется Pred(SL.Count)?


С Савёловского вокзала до Белорусского в default city можно добраться:
1. На электричке
2. На такси.
3. Наземный транспорт (трамвай там какой-то ходил, вроде).

Почему большинство предпочитает всё-таки на метро добираться?


 
CRLF   (2012-04-16 11:55) [15]


> А в целом все эти функции/процедуры Pred, Succ, Inc, Dec,
>  Include, Exclude (может и ещё какие-то были) были "временной
> оптимизацией скорости выполнения" в эпоху Турбо Паскаля
> и может быть в эпоху Д1. Сейчас они никакой оптимизации
> не добавляют. И как правило лишь мешают воспринимать код
> тем, кто начал заниматься программированием после вышеназванной
> эпохи.
Неправда. Inc, Dec, Pred, Succ, Low, High работают с любыми перечислимыми типами. +-1 -- только с арифметическими.


 
Anatoly Podgoretsky ©   (2012-04-16 12:05) [16]


> Но работает только для конкретного примера в DVM ©   (15.
> 04.12 18:40) [7]

Работает с любыми перечислимыми типами


 
Юрий Зотов ©   (2012-04-16 16:07) [17]


> CRLF   (16.04.12 10:31) [13]
> в прочих случаях объявляем TIndex = IndexMin..IndexMax;
> TArray = array [TIndex] of TElement;

И получаем проблемы либо с несовместимостью типов, либо с выходом за диапазон.

const
 IndexMin = ...;
 IndexMax = ... ;

type
 TIndex = IndexMin..IndexMax;
 TArray = array [TIndex] of ...;

var
 i: integer;
 j: TIndex;
 a: TArray;
begin
 for i := IndeхMin to IndexMax do
   a[i] := ...; // Несовместимость типов
 for j := IndeхMin to IndexMax do ...; // Выход за диапазон
end;

Мне тоже нравится строгость Паскаля, она спасает от многих ошибок. Но любую полезную вещь можно превратить в бесполезную (или даже вредную), доведя ее до абсурда.


 
Омлет ©   (2012-04-16 16:18) [18]


> Юрий Зотов ©   (16.04.12 16:07) [17]
> либо с выходом за диапазон.

low, high спасают.


 
CRLF   (2012-04-16 16:48) [19]


> for j := IndeхMin to IndexMax do ...; // Выход за диапазон
Поясни, о каком выходе идёт речь.


 
Юрий Зотов ©   (2012-04-16 16:57) [20]


> CRLF   (16.04.12 16:48) [19]

После последнего витка цикла его счетчик еще раз инкрементируется и выходит за диапазон.


 
CRLF   (2012-04-16 17:06) [21]

Действительно, выход за пределы диапазона есть, в том числе и при использовании Low, High.
Но так как параметр цикла вне цикла имеет неопределённое значение и компилятор об этом предупреждает, вряд ли это можно считать проблемой.


 
RWolf ©   (2012-04-16 17:16) [22]


> Юрий Зотов ©   (16.04.12 16:07) [17]


> for j := IndeхMin to IndexMax do ...; // Выход за диапазон


> Действительно, выход за пределы диапазона есть


какой такой выход?
вы меня пугаете.


 
Юрий Зотов ©   (2012-04-16 17:19) [23]


> CRLF   (16.04.12 17:06) [21]
> вряд ли это можно считать проблемой.

Если контроль выхода за диапазон выключен, то да, не проблема. А у меня, например, есть привычка держать его включенным и отключать только при билде релиза. И если в коде есть подобные конструкции, то выскакивающие из-за них окошки исключений очень сильно мешают.


 
RWolf ©   (2012-04-16 17:23) [24]

вот прямо сейчас запустил код на Д7:

procedure TForm1.Button1Click(Sender: TObject);
const
 IndexMin = 11;
 IndexMax = 322;

type
 TIndex = IndexMin..IndexMax;
 TArray = array [TIndex] of byte;

var
 j: TIndex;
 a: TArray;
begin
 for j := IndexMin to IndexMax do
   caption:=caption+IntToStr(a[j]);
end;


Range checking включен, процедура работает без ошибок.


 
CRLF   (2012-04-16 17:30) [25]


> Юрий Зотов ©   (16.04.12 17:19) [23]
Специально проверял, range check error не возникает. Delphi XE2.


 
Юрий Зотов ©   (2012-04-16 17:35) [26]


> CRLF   (16.04.12 17:30) [25]
> RWolf ©   (16.04.12 17:23) [24]

Приду домой - проверю, сейчас Delphi нет под рукой.


 
Юрий Зотов ©   (2012-04-16 21:21) [27]

Проверил (D7) - ошибка действительно не возникает. Сорри.

Но возникает вопрос - откуда же я это взял, не из головы же придумал? Точно помню, что эти ошибки были.

Видимо, это было еще в Паскале, а на Delphi перенес по привычке.


 
Sha ©   (2012-04-17 01:23) [28]


type
 TNumber= 1..100;
 TRooms= array[TNumber] of integer;

function Volume(const Rooms: TRooms; First: TNumber; Count: integer): integer;
var
 Current: TNumber;
begin;
 Result:=0;
 for Current:=First to First+Count-1 do Result:=Result+Rooms[Current];
 end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Rooms: TRooms;
 Current: TNumber;
begin;
 for Current:=Low(Rooms) to High(Rooms) do Rooms[Current]:=2;
 Volume(Rooms,2,2);
 Volume(Rooms,2,0);
 Volume(Rooms,1,1);
 Volume(Rooms,1,0);
 end;


 
CRLF   (2012-04-17 07:43) [29]


> Sha ©   (17.04.12 01:23) [28]
Не совсем понятно, что ты хотел продемонстрировать, но... Во-первых, нужно проверять, что Count > 0. Во-вторых, смешивать TNumber и Integer потенциально опасно (что, видимо, пример и демонстрирует).


 
Sha ©   (2012-04-17 08:54) [30]

> CRLF   (17.04.12 07:43) [29]
> Не совсем понятно, что ты хотел продемонстрировать

1. То, что количество объектов (комнат, символов и т.п.) может быть получено в результате вычислений.
2. То, что 0 - это вполне корректное количество объектов (это не -1, не -2 и т.п.). Обычно его не надо предварительно ни при Copy, ни при Move и т.п., я привык не проверять. Ведь 1 я не проверяю.
3. То, что теперь мне не совсем понятно, как в моем случае должен выглядеть цикл с нулевым количеством повторений. Непонятно почему (ну, мне понятно почему) компилятору пофиг, если такой цикл начинается с любого элемента и не пофиг, если с первого.
4. Все это тем более непонятно, что обычно количество повторений цикла for компилятор вычисляет заранее.
5. То, прав Юрий Зотов: любую полезную вещь можно превратить в бесполезную (или даже вредную), доведя ее до абсурда.


 
Sha ©   (2012-04-17 08:57) [31]

Обычно его не надо предварительно проверять*


 
Anatoly Podgoretsky ©   (2012-04-17 09:00) [32]


> Юрий Зотов ©   (16.04.12 21:21) [27]

Померещилось конечно.
Причин для выхода нет совсем, когда границами является размерность массива. В Паскале тоже самое.
Более того я ранее обычно писал так, с использование констант границ и использованием из в виде индекса и размерности.
А выражение array x[TYPE] означает array x[Low(TYPE)..High(TYPE)] сокращеная форма.


 
Anatoly Podgoretsky ©   (2012-04-17 09:03) [33]


> Во-вторых, смешивать TNumber и Integer потенциально опасно
> (что, видимо, пример и демонстрирует).

А не надо смешивать, например как в [24]


 
CRLF   (2012-04-17 09:16) [34]


> как в [24]
как в [28] ;-)


 
Anatoly Podgoretsky ©   (2012-04-17 09:50) [35]

Там другой вариант, тоже правильно реализованый

Current: TNumber;


 
CRLF   (2012-04-17 10:00) [36]

Но ему присваивается результат от операции TNumber c Integer, что может быть некорректно. Не говоря уже о том, что "количество" в примере может быть отрицательным и это никак не проверяется.


 
Anatoly Podgoretsky ©   (2012-04-17 10:09) [37]

for Current:=Low(Rooms) to High(Rooms) do Rooms[Current]:=2;А Rooms это размерность TNumber, который является константой, а чем это станет зависит от использования, TNumber полностью совместим с Integer, поскольку является поддиапазоном последнего.

for Current:=Low(Rooms) to High(Rooms) do Rooms[Current]:=2;

Это является надежным аналогом

for Current:=1 to 100 do Rooms[Current]:=2;

Ясно же что константы и производные типы безопаснее и понятнее.


 
Anatoly Podgoretsky ©   (2012-04-17 10:11) [38]

[24] пошел в дальше, там уже использованы именованые константы диапазона, вместо 1..100


 
Sha ©   (2012-04-17 11:17) [39]

> CRLF
> Anatoly Podgoretsky

Вы немного не о том (корректно/некорректно).
Понятно, что формально неверно, но на практике надо.
Понятно, как исправить ценой усложнения кода, чтобы было формально верно.

Речь о другом немного.
О том, что тупое следование принципу типизации всего и вся приводит нас
либо к усложнению кода (нарушению другого известного принципа),
либо к появлению в коде почти незаметных ошибок,
которые являются таковыми только с точки зрения компилятора.


 
Anatoly Podgoretsky ©   (2012-04-17 11:20) [40]

> Sha  (17.04.2012 11:17:39)  [39]

Автор является последней инстанцией, как писать, что использовать, усложнять
или нет
Это я не обсуждаю, только приведеный код.


 
Sha ©   (2012-04-17 11:36) [41]

Да с кодом и так все ясно. Все придется переписать,
если вдруг приспичит сделать врхнюю границу массива переменной.


 
CRLF   (2012-04-17 11:40) [42]


> приводит нас либо к усложнению кода
Некоторое усложнение, конечно, есть, но...

type
TNumber= 1..100;
TRooms= array[TNumber] of integer;

function Volume(const Rooms: TRooms; First: TNumber; Count: integer): integer;

по большому счёту некорректен. Если уж типизируем, то нужно

type
TNumber= 1..Max;
TQuantity = 0..Max;
TRooms= array [TNumber] of integer;

function Volume(const Rooms: TRooms; First: TNumber; Count: TQuantity): integer;
var
Current: TNumber;
begin
 if First + Count > Max then
   raise ...;
 Result := 0;
 for Current := First to Pred(First + Count) do
   Result := Result + Rooms[Current];
end;


 
Anatoly Podgoretsky ©   (2012-04-17 11:40) [43]


> Sha ©   (17.04.12 11:36) [41]
> если вдруг приспичит сделать врхнюю границу массива переменной.

Не понял, поясни, а то я до сих пор считал, что нельзя определить массив, с граница с переменными.


 
Sha ©   (2012-04-17 11:49) [44]

> Anatoly Podgoretsky ©   (17.04.12 11:40) [43]

Конечно нельзя, поэтому и придется переписать


 
Sha ©   (2012-04-17 11:55) [45]

> CRLF   (17.04.12 11:40) [42]

Попался )
Засада там же: Count=0


 
CRLF   (2012-04-17 12:06) [46]

Попался в чём? Цикл не выполнится ни разу. То, что Pred(First + Count) будет иметь недопустимое для TNumber значение, — имеет ли смысл об этом говорить, если присвоения не будет никогда?


 
Sha ©   (2012-04-17 12:09) [47]

Вот-вот.
А компилятор, собака, об этом знает, но ERangeError поднимает.
Но мы бум молчать.


 
CRLF   (2012-04-17 12:11) [48]


> А компилятор, собака, об этом знает, но ERangeError поднимает.
Опять же, прогнал твой пример из [28] с моими доработками, никакого RangeError нету.


 
Sha ©   (2012-04-17 13:27) [49]

> CRLF   (17.04.12 12:11) [48]

Проверил на D7

Optimization Off
RangeChecking On
OverFlowChecking On

ERangeError есть


 
CRLF   (2012-04-17 13:50) [50]

Да, действительно, с range checking проблема есть.


 
Sha ©   (2012-04-17 13:57) [51]

Во.
И придется поизвращаться, чтобы этого избежать.
Спрашивается, нафига было типизировать?


 
CRLF   (2012-04-17 14:03) [52]

А в чём извращение? В добавлении одного if (лишнего, но, в принципе, повышающего читаемость)?


 
Sha ©   (2012-04-17 14:07) [53]

Спорим, одного не хватит?

P.S. меня бесят все эти if и raise...


 
Sha ©   (2012-04-17 14:10) [54]

Это не тот код, чтобы думать. Тут надо струячить. Думать надо редко.
При сплошном типизировании приходится думать непрерывно. Думалка может сломаться.


 
CRLF   (2012-04-17 14:24) [55]


> P.S. меня бесят все эти if и raise...
Неужели лучше, если через эн лет в проверенном годами коде изредка станет возникать ав по причине выхода за пределы массива?


 
Sha ©   (2012-04-17 14:26) [56]

разве эти вещи как-то связаны?


 
CRLF   (2012-04-17 14:35) [57]

А разве нет? Когда-нибудь First + Count станет больше High(Array), массив к тому времени будет динамическим и без лишней типизации, в 99% выход за пределы массива будет прощаться, но раз в полгода будет ав... :-)


> Это не тот код, чтобы думать. Тут надо струячить. Думать
> надо редко.
Ну да, это ведь "форумные этюды", а не реальная задача, в реальной вряд ли кто-то кроме преподавателя информатики станет без нужды поддиапазоны выделять.


 
Sha ©   (2012-04-17 14:40) [58]

> CRLF   (17.04.12 14:35) [57]
> Когда-нибудь First + Count станет больше High(Array)

есть if и if, почувствуй разницу

> в реальной вряд ли кто-то кроме преподавателя информатики
> станет без нужды поддиапазоны выделять

опять же (с) ЮЗ:
любую полезную вещь можно превратить в бесполезную (или даже вредную),
доведя ее до абсурда.



Страницы: 1 2 вся ветка

Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.59 MB
Время: 0.066 c
15-1327513350
alexdn
2012-01-25 21:42
2013.03.22
Сервер


15-1346298010
boriskb
2012-08-30 07:40
2013.03.22
Помогите выбрать планшетник


15-1354393802
Юрий
2012-12-02 00:30
2013.03.22
С днем рождения ! 2 декабря 2012 воскресенье


15-1342899092
без имени
2012-07-21 23:31
2013.03.22
Настройка в Delphi 7


15-1346911110
AV
2012-09-06 09:58
2013.03.22
Программистом я б пошел.. Пусть меня научат!





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский