Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Неинициализированная переменная, Как узнать, инициализирована она или нет 
:(
    Опции темы
shmelina
Дата 27.1.2010, 02:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 5.6.2009

Репутация: нет
Всего: нет



Часто бывает нужно, для самоконтроля, чтобы если забыл инициализировать переменную, то при попытке использования этой переменной, программа тебе ошибку выдаст.

Например, есть переменная типа Integer. По своему алгоритму я ее должен инициализировать (установить какое-то значение). Но могу ведь и забыть. А там ведь число уже какое-то есть. Было бы здорово, если бы там Null был. Ну или что-то подобное. Было так же хорошо, чтобы я мог сбросить установленное ранее значение, чтобы переменная снова стала неинициализированной (как бы Null установить).

Сейчас я использую для этих целей типом Variant. Но он больно тяжеловат. Да и туда кроме Integer можно и сроку и указатель запихнуть. А хотелось бы только (в данном случае) Integer или Null.

Другой пример: Моя программа активно общается с базой данных. Мне нужно считать значение внешнего ключа и запихнуть в переменную. Но внешний ключ не Not Null и там спокойно может быть Null.

Только тип Variant? Может какой тип данных для этого есть, а я его не знаю?
PM MAIL   Вверх
Alexeis
Дата 27.1.2010, 10:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(shmelina @  27.1.2010,  01:32 Найти цитируемый пост)
Часто бывает нужно, для самоконтроля, чтобы если забыл инициализировать переменную, то при попытке использования этой переменной, программа тебе ошибку выдаст.

  Делфи это объектно ориентированный язык. Все самое вкусное через объекты. Любой объект при создании зануляет все свое содержимое в том числе и записи и строки и массивы указатели, не говоря уже про простые числа.
  Создал объект можешь забыть про зануление его полей. Другое дело нуль не всегда правильная инициализация. В этом случае нужно в конструкторе объекта присваивать начальные значения (если они должны быть отличными от нуля).


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Frees
Дата 27.1.2010, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 16
Всего: 54



Цитата(shmelina @  27.1.2010,  05:32 Найти цитируемый пост)
Например, есть переменная типа Integer. По своему алгоритму я ее должен инициализировать (установить какое-то значение). Но могу ведь и забыть. А там ведь число уже какое-то есть. Было бы здорово, если бы там Null был.

NULL может быть только у variant


--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
CodeMonkey
Дата 27.1.2010, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 29
Всего: 89



Ну, напрямую такое не поддерживается, но можно делать хаками.

Например. Или так.

Добавлено через 58 секунд
А вот ещё.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Dom
Дата 27.1.2010, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 3
Всего: 4



Напомню, что у числовых значений может быть значение NAN (not a number).
Возможно это будет полезным в вашем случае. Только с ним аккуратно работать надо, а то могут быть грабли.
PM MAIL   Вверх
RomanEEP
Дата 28.1.2010, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 424
Регистрация: 18.5.2006
Где: Коломна

Репутация: 1
Всего: 8



NAN - только у чисел с плавающей точкой, у Integer его нет
PM MAIL   Вверх
shmelina
Дата 28.1.2010, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 5.6.2009

Репутация: нет
Всего: нет



Цитата(Alexeis @  27.1.2010,  10:47 Найти цитируемый пост)
Делфи это объектно ориентированный язык. Все самое вкусное через объекты. Любой объект при создании зануляет все свое содержимое в том числе и записи и строки и массивы указатели, не говоря уже про простые числа.
  Создал объект можешь забыть про зануление его полей. Другое дело нуль не всегда правильная инициализация. В этом случае нужно в конструкторе объекта присваивать начальные значения (если они должны быть отличными от нуля).

Это я все понимаю. Но 0 в типе Integer, это уже наличие значения. А мне нужно как в объектах - или есть значение или нет его (nil). Если значения нет и пытаешься сделать Form.Close, то выдается ошибка. Я так же и простым типом Integer хочу.

Цитата(Frees @  27.1.2010,  11:10 Найти цитируемый пост)
NULL может быть только у variant 

:(

Цитата(CodeMonkey @  27.1.2010,  12:27 Найти цитируемый пост)
Ну, напрямую такое не поддерживается, но можно делать хаками.
Например. Или так.
Добавлено через 58 секунд
А вот ещё. 

Идею понял. Но не понял как обнулять (сбрасывать) значение. Еще вопрос, что более быстро работает эта идея с дженериками (Nullable<Integer>) или тупо Variant? Плохо, что это не родной для Delphi тип и имеются некоторые ограничения при использовании по сравнению с Integer.

Цитата(Dom @  27.1.2010,  14:05 Найти цитируемый пост)
Напомню, что у числовых значений может быть значение NAN (not a number).
Возможно это будет полезным в вашем случае. Только с ним аккуратно работать надо, а то могут быть грабли. 

Спасибо. Не знал. Но он ошибок не выдает при использовании. А в результате вычисления с неинициализированной переменной видим NAN. Где ошибка была - не понятно.

Цитата(RomanEEP @  28.1.2010,  12:16 Найти цитируемый пост)
NAN - только у чисел с плавающей точкой, у Integer его нет 

Угу.

Жаль нет NullableInteger.

Использовать Variant и не парится?

Это сообщение отредактировал(а) shmelina - 28.1.2010, 20:28
PM MAIL   Вверх
Frees
Дата 28.1.2010, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 16
Всего: 54



Цитата(shmelina @  28.1.2010,  23:27 Найти цитируемый пост)
Использовать Variant и не парится?

будешь парится в другом месте

например:


это исключение
Код

var v: variant; i : integer;

v := NULL;
i := v;



а это нет
Код

var v: variant; i : integer;

v := 0;
i := v;


Это сообщение отредактировал(а) Frees - 28.1.2010, 20:58


--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
shmelina
Дата 28.1.2010, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 5.6.2009

Репутация: нет
Всего: нет



Цитата(Frees @  28.1.2010,  20:56 Найти цитируемый пост)
например

Ты что мне хотел этими примерами показать? Это, конечно же, я понимаю.
PM MAIL   Вверх
Frees
Дата 28.1.2010, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 16
Всего: 54



Цитата(shmelina @  29.1.2010,  01:02 Найти цитируемый пост)
Ты что мне хотел этими примерами показать


если хочеш интеджер поменять на вариант то это шило на мыло(одни грабли на другие)



--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
CodeMonkey
Дата 29.1.2010, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 29
Всего: 89



Цитата(shmelina @  28.1.2010,  20:27 Найти цитируемый пост)
Но не понял как обнулять (сбрасывать) значение.

Смотря какой способ. В общем случае это надо сделать доп. метод.

Пример с adv. records:

Код
type
  ENullError = class(Exception);

  NullableInteger = record
  private
    FNotNull: String;
    FValue: Integer;
    function GetIsNull: Boolean;
    function GetValue: Integer;
    procedure SetValue(const AValue: Integer);
  public
    property Value: Integer read GetValue write SetValue;
    property IsNull: Boolean read GetIsNull;
    procedure Clear;
    class operator Implicit(const AValue: Integer): NullableInteger;
    class operator Explicit(const AValue: Integer): NullableInteger;
    class operator Implicit(const AValue: NullableInteger): Integer;
    class operator Explicit(const AValue: NullableInteger): Integer;
  end;

resourcestring
  rsNullValue = 'Value is NULL';

{ NullableInteger }

procedure NullableInteger.Clear;
begin
  FNotNull := '';
end;

function NullableInteger.GetIsNull: Boolean;
begin
  Result := (FNotNull = '');
end;

function NullableInteger.GetValue: Integer;
begin
  if IsNull then
    raise ENullError.Create(rsNullValue);
  Result := FValue;
end;

procedure NullableInteger.SetValue(const AValue: Integer);
begin
  FNotNull := '1';
  FValue := AValue;
end;

class operator NullableInteger.Implicit(const AValue: Integer): NullableInteger;
begin
  Result.Value := AValue;
end;

class operator NullableInteger.Implicit(const AValue: NullableInteger): Integer;
begin
  Result := AValue.Value;
end;

class operator NullableInteger.Explicit(const AValue: Integer): NullableInteger;
begin
  Result.Value := AValue;
end;

class operator NullableInteger.Explicit(const AValue: NullableInteger): Integer;
begin
  Result := AValue.Value;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  I: NullableInteger;
begin
  Caption := BoolToStr(I.IsNull, True);

  I := 5;
  Caption := Caption + ' ' + IntToStr(I);

  I.Clear;
  Caption := Caption + ' ' + IntToStr(I);
end;


По аналогии и с генериками.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
sCreator
Дата 29.1.2010, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 20.8.2009
Где: Московская област ь

Репутация: нет
Всего: 5



А использование ссылки на integer не подойдет ?
Код

i = ^Integer;

не инициализированная ссылка имее значение nil ( только надо остарожно с локальными переменными ) 
и i^ если i = nil должно дать исключение
Но придется возиться с динамическим выделением памяти - зато остальное быстро.
PM   Вверх
shmelina
Дата 29.1.2010, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 5.6.2009

Репутация: нет
Всего: нет



В общем буду вариантом пользоваться. Все остальное сложно.
Всем спасибо за помощь в этом вопросе. Узнал кое-что новое.
PM MAIL   Вверх
Frees
Дата 29.1.2010, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 16
Всего: 54



Цитата(shmelina @  29.1.2010,  17:09 Найти цитируемый пост)
В общем буду вариантом пользоваться. 

про VarisNULL и VarIsEmpty не забывай )))


--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
shmelina
Дата 29.1.2010, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 5.6.2009

Репутация: нет
Всего: нет



Цитата(Frees @  29.1.2010,  14:12 Найти цитируемый пост)
про VarisNULL и VarIsEmpty не забывай ))) 

Я обычно сразу Null присваиваю.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0630 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.