2014-11-28 3 views
-2

Во время процесса просмотра более старого программного кода возник следующий вопрос: все локальные переменные в методе инициализируются сразу после начала. Обычно локальные переменные не инициализируются. Но у нас есть процедура, в которой все переменные инициализируются равными 0. Есть ли у кого-нибудь идея, как это может произойти?Локальная переменная, инициализированная в delphi?

Пример:

type 
    TPrices = array[0..10, 0..5] of Integer; 

procedure DoSomething(); 
var 
    mPrices : TPrices; 
    mValue : Integer; 
begin 
    if (mPrices[0,0] = 0) then 
    MessageDlg('Zero', mtInformation, [mbOK], 0); 
    if (mValue = 0) then 
    MessageDlg('Zero Integer', mtInformation, [mbOK], 0); 
end; 
+0

Действительно ли это обман Q @TLama? –

+0

@ Давид, у него есть ответ. Но хорошо, например. ['this one'] (http://stackoverflow.com/q/861045/960757) лучше. Их будет больше ... [Я открою этот файл] – TLama

+0

@TLama Этот вопрос «этот» не относится к локальным переменным в методе/процедуре, а о глобальных переменных. Мне очень нравится тот, который используется для дубликата лучше. –

ответ

5

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

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

Рассмотрим эту программу:

{$APPTYPE CONSOLE} 

type 
    TPrices = array[0..10, 0..5] of Integer; 

procedure Foo; 
var 
    mPrices: TPrices; 
begin 
    Writeln(mPrices[0,0]); 
end; 

begin 
    Foo; 
end. 

Когда я бегу на моей машине, выход:

 
1638012 

Теперь рассмотрим эту программу:

{$APPTYPE CONSOLE} 

type 
    TPrices = array[0..10, 0..5] of Integer; 

procedure Foo; 
var 
    mPrices: TPrices; 
begin 
    Writeln(mPrices[0,0]); 
    FillChar(mPrices, SizeOf(mPrices), 0); 
end; 

procedure Bar; 
var 
    mPrices: TPrices; 
begin 
    Writeln(mPrices[0,0]); 
end; 

begin 
    Foo; 
    Bar; 
end. 

На этот раз выход :

 
1638012 
0 

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

Или попробовать эту программу:

{$APPTYPE CONSOLE} 

type 
    TPrices = array[0..10, 0..5] of Integer; 

procedure Foo; 
var 
    mPrices: TPrices; 
begin 
    Writeln(mPrices[0,0]); 
    FillChar(mPrices, SizeOf(mPrices), 0); 
    mPrices[0,0] := 666; 
end; 

procedure Bar; 
var 
    mPrices: TPrices; 
begin 
    Writeln(mPrices[0,0]); 
    Writeln(mPrices[0,1]); 
end; 

begin 
    Foo; 
    Bar; 
end. 

Теперь выход:

 
1638012 
666 
0 

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

+0

Я также использовал для получения разных значений инициализации, но когда я добавляю реальный большой массив (2000x100), все значения массива инициализируются и на ноль. Очень нереалистично для неинициализированной переменной. Additionaly Я добавил метод непосредственно перед вызовом вышеуказанного метода, где я инициализировал массив (размер 100x100) с помощью $ FF. И еще раз: все в вышеуказанном методе было 0. – elite

+0

Я не знаю, что делать с этим комментарием. Это почти так, как будто ты мне не веришь. –

+0

@elite Что нереально?Неужели неудивительно, что когда ваша машина выключена, в ОЗУ нет тока. Поэтому, когда вы включаете его, большая часть вашего RAm находится в состоянии по умолчанию всех нулей? Неужели нереально, что перед запуском вашей программы что-то случилось, чтобы очистить блок памяти, где теперь выделен ваш столбец? (ОС может инициализировать стек вызовов, прежде чем запускать приложение, но это произойдет ** только один раз ** - вот почему вы не можете полагаться на него. И если ОС действительно пытается инициализировать столбец - это может измениться.) –

Смежные вопросы