Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.11.2014, 21:23   #1
Леньчик
 
Регистрация: 20.11.2014
Сообщений: 7
По умолчанию Вопрос по поводу процедуры

Уважаемые друзья!

Помогите, пожалуйста, разобраться. )))

Я в самом начале, но уже возникли сложности.

Высылаю Вам две небольшие программы, созданные в среде Free Pascal.

Обе работают и выдают одинаковый результат.

Разница в том, что мне понятен второй вариант, а первый – нет.

Собственно, в этом и весь вопрос.


Первый вариант.

Код:

Program Proc_1;
Uses crt;
Var a, b : integer;
SumNum : integer;

Procedure summa (var x : integer; a, b : integer);
Begin
x:=a+b;
End;

Begin
Clrscr;
A:=12; B:=15;
summa (SumNum,a,b);
writeln (SumNum);

Readln;
End.
Давайте начнём со второго варианта. )))

Второй вариант.

Код:

Program Proc_2;
Uses crt;
Var a, b : integer;
SumNum : integer;

Procedure summa (x : integer; a, b : integer);
Begin
x:=a+b;
SumNum:=x;
End;

Begin
Clrscr;
A:=12; B:=15;

summa (SumNum,a,b);
writeln (SumNum);

Readln;
End.
SumNum:=x; - Вот в этой строке, переменной SumNum идёт присваивание
основной переменной значение переменной x, объявленной в процедуре.
Это понятно.

В первом варианте, в процедуре объявляется переменная x.
var x : integer; - В этой строке.
Но в теле программы нигде нет обращения к этой переменной.
А также нет присваивания переменной SumNum значения переменной x.
Тем не менее, программа выдаёт правильный результат.

Так как же взаимодействуют эти две переменные в первом варианте?
Леньчик вне форума Ответить с цитированием
Старый 20.11.2014, 22:23   #2
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,499
По умолчанию

А я наоборот, первый вариант сразу понял, а второй - не сразу. Второй сделан как-то странно.

В первом варианте в процедуре summa переменная x - формальный параметр. При вызове summa вместо формального параметра x подставляется фактический SumNum . То есть программа работает, как если бы внутри вместо x была бы SumNum

Почитайте про формальные и фактические параметры (аргументы).

PS В случае a,b - тут просто совпадают имена формальных и фактических параметров. Совпадение допускается и ни к чему не обязывает.

Последний раз редактировалось type_Oleg; 20.11.2014 в 22:26.
type_Oleg вне форума Ответить с цитированием
Старый 20.11.2014, 23:02   #3
ViktorR
Старожил
 
Регистрация: 23.10.2010
Сообщений: 2,309
По умолчанию

По очереди приведенных примеров:
1.
Procedure summa (var x : integer; a, b : integer);
В данном описании x, a, b - параметры процедуры. Вместо них могут фигурировать и другие имена переменных.
Передача параметров выполняется через стек, который представляет собой память, адресация к которой выполняется через специальный регистр.

Запись var x : integer; означает, что в стек будет записан адрес, по которому будет размещаться переменная, подставленная вместо "x" в вызове процедуры.
Так, в первом примере вызов представлен так:
Код:
summa (SumNum,a,b);
SumNum - некоторая переменная, которая размещается в памяти данных по известному для компилятора адресу. Вот этот адрес и передается, при вызове, в стек.
Параметры a и b передаются по значению. Т.е. в стек передаются только значения, которые хранятся в переменных a и b.
Если заглянуть в область памяти, где хранятся параметры, то можно было бы увидеть примерно следующее (естественно это условно так):
Код:
Память данных (по два байта на тип integer):
Имя             Адрес         Значение
SumNum        00AA:1CCD            0
a             00AA:1CCF            15
b             00AA:1CD1            12

Область стека (порядок следования не учитываем):
Адрес             Значание
 ABC0:2234           00AA:1CCD      - адрес
 ABC0:2236      12             - значение
 ABC0:2238      15             - значение

Т.о. из процедуры видна область памяти в которой хранится переменная SumNum.
2.
В этом примере переменная SumNum описана в самом начале программы, до описания процедуры. Она видна в процедуре.
Попробуйте описать ее пониже, перед началом программы.
Этот пример работает так:
При вызове процедуры
Код:
summa (SumNum,a,b);
в стеке организуется место для хранения значения, в данном случае того значения, которое хранится в переменной SumNum. В начале программы там ноль. При вычислении нового значения, как суммы двух значений, эта область используется как временная область для хранения результата (эта область из программы прямо не видна).
Затем результат из этой области передается в область памяти SumNum.
Код:
Имя             Адрес         Значение
SumNum        00AA:1CCD            0
a             00AA:1CCF            15
b             00AA:1CD1            12

В стеке (порядок следования не учитываем):
Адрес        Значание
 ABC0:2234      0              - значение
 ABC0:2236      12             - значение
 ABC0:2238      15             - значение

после вычисления x:
Адрес        Значание
 ABC0:2234      27              - значение
 ABC0:2236      12             - значение
 ABC0:2238      15             - значение
Еще раз. Во втором примере переменная SumNum видна внутри процедуры. Она описана до процедуры.
Как другой вариант для пробы. Опиши переменную SumNum внутри процедуры, оставив ее описание в голове программы.
Код:
Var a, b : integer;
SumNum : integer;

Procedure summa (x : integer; a, b : integer);
Var SumNum : integer;

Begin
x:=a+b;
SumNum:=x;
End;
Что получается?


Как-то так, ...
PS: Второй пример плох. Это только некоторая случайность, которая позволила получить верный результат.
Как-то так, ...
ViktorR вне форума Ответить с цитированием
Старый 21.11.2014, 00:31   #4
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Правильно когда-то наш старый пердун препод говорил: увижу глобальную переменную там, где без неё можно обойтись – получите подсрачник и на пересдачу!

Как же дед был прав!

По делу: убери все глобальные переменные и всё сразу станет понятно.
Совет: именуй формальные параметры так, чтобы было понятно, что это формальные параметры. Я использую букву «А». Например:
Код:
    function SendBufferToMacAddress(const AMac: TMacAddress; // посылка буфера данных по заданному МАС-адресу
                                    const AData; const ASize: DWORD): Boolean;
    function SendTextToMacAddress(const AMac: TMacAddress; // посылка строки текста по заданному МАС-адресу
                                  const AText: string): Boolean;
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 21.11.2014, 08:33   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
По делу: убери все глобальные переменные и всё сразу станет понятно.
+1

кстати, в Паскале в подобном коде использование глобальных переменных ОЧЕНЬ просто выявляется.
Нужно блок VAR перенести ПОСЛЕ всех функций и процедур:
Код:
Program Proc_2;
Uses crt;

Procedure summa (x : integer; a, b : integer);
Begin
x:=a+b;
SumNum:=x;
End;

Var a, b : integer;
SumNum : integer;
И компилятор сразу "заголосит", что в процедуре используется переменная, про которую он ничего не знает!
Вот от неё и надо избавляться!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 21.11.2014, 08:45   #6
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
кстати, в Паскале в подобном коде использование глобальных переменных ОЧЕНЬ просто выявляется.
Нужно блок VAR перенести ПОСЛЕ всех функций и процедур
Это понятно. Но лучше всё ж не перемещать блок var, а удалить его совсем. Очень много досадных ляпсусов сразу самоликвидируются.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 22.11.2014, 10:35   #7
Леньчик
 
Регистрация: 20.11.2014
Сообщений: 7
По умолчанию

Дорогие друзья! Спасибо Вам за помощь! Вы прислали мне очень много интересной и полезной информации! Обязательно разберусь! Самой, конечно, трудно организовать процесс самообучения, к тому же я вижу, что мои знания очень и очень невелики. Я хотела узнать ещё насчёт возможности дополнительного обучения. Но я не знаю, вправе ли я спрашивать это здесь? Если нет, то прошу меня извинить. Может быть, эту тему можно создать в другом разделе? Прошу меня простить, если я что-то нарушила. В любом случае я очень благодарна всем Вам за то, что прислали мне столько откликов! Спасибо!!!
Леньчик вне форума Ответить с цитированием
Старый 22.11.2014, 14:03   #8
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Сообщение от Леньчик Посмотреть сообщение
Дорогие друзья! Спасибо Вам за помощь! Вы прислали мне очень много интересной и полезной информации! Обязательно разберусь! Самой, конечно, трудно организовать процесс самообучения, к тому же я вижу, что мои знания очень и очень невелики. Я хотела узнать ещё насчёт возможности дополнительного обучения. Но я не знаю, вправе ли я спрашивать это здесь? Если нет, то прошу меня извинить. Может быть, эту тему можно создать в другом разделе? Прошу меня простить, если я что-то нарушила. В любом случае я очень благодарна всем Вам за то, что прислали мне столько откликов! Спасибо!!!
Ой не надо! Ой щекотно!!!
Совет: скачай годную хорошую книжку и прочитай для начала первые 5-6 глав. Будет хорошо. Если появится желание читать дальше, то есть вероятность стать начинающим программистомЪ...
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Старый 22.11.2014, 16:11   #9
Леньчик
 
Регистрация: 20.11.2014
Сообщений: 7
По умолчанию Ответ

Цитата:
Сообщение от min@y™ Посмотреть сообщение
Ой не надо! Ой щекотно!!!
Совет: скачай годную хорошую книжку и прочитай для начала первые 5-6 глав. Будет хорошо. Если появится желание читать дальше, то есть вероятность стать начинающим программистомЪ...
Из твоего предыдущего сообщения видно, что тебя обучал преподаватель. Значит тебе дали какую-то базу знаний. Тебе было на что опираться, поэтому тебе легко давать такие советы.
Мы не в равных условиях.
Я же просто хотела узнать – есть ли возможность обучиться факультативом или как-нибудь ещё.
Леньчик вне форума Ответить с цитированием
Старый 22.11.2014, 16:22   #10
min@y™
Цифровой кот
Старожил
 
Аватар для min@y™
 
Регистрация: 29.08.2014
Сообщений: 7,629
По умолчанию

Цитата:
Из твоего предыдущего сообщения видно, что тебя обучал преподаватель. Значит тебе дали какую-то базу знаний. Тебе было на что опираться, поэтому тебе легко давать такие советы.
Ты ошибаешься. Препод был, но он не обучал. Он помогал советами (интернетов тогда было мало) и принимал лабы, курсачи, зачёты и экзамены. И по диплому я не программист, а инженер-конструктор ЭВА. Программированию нельзя научить, это не таблица умножения. Программированию можно только научиться.
Цитата:
Мы не в равных условиях.
Хых... и не поспоришь. Разве должно быть по-другому?
Цитата:
Я же просто хотела узнать – есть ли возможность обучиться факультативом или как-нибудь ещё.
Только если есть желание.
Расскажу я вам, дружочки, как выращивать грибочки: нужно в поле утром рано сдвинуть два куска урана...
min@y™ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вопрос по поводу getch() Тёма_) Общие вопросы C/C++ 4 27.02.2013 19:07
Вопрос по поводу граббинга. egorzenit Общие вопросы Delphi 1 13.04.2012 02:11
Вопрос по поводу StringList(а) KAMENYKA Компоненты Delphi 4 07.12.2007 13:01
Вопрос по поводу типов werser Помощь студентам 4 23.06.2007 14:18