Помощь - Поиск - Пользователи - Календарь
Полная версия: функция
Форум «Всё о Паскале» > Pascal, Object Pascal > Теоретические вопросы
Client
не могу понять в зависимости от чего Z получает значение в тексте программы.
подскажите почему

uses crt;
label 0; {описываем метку}
var
rez:real;
m,n:longint; {описали глобальные переменные, используемые в программе}
function fact(z: longint): real; {заголовок функции с формальным параметром-
значением, типом}
var
y: real; {описали локальную переменную}
begin
y:=1; {для получения результата необходимо присвоить у значение 1. также
при помощи этого реализуется вычисление 0! и 1!}
while z>1 do {запускаем цикл в обратную сторону, для упрощения опустим
множитель 1}
begin
y:=y*z;
z:=z-1
end;
fact:=y{вычисляем факториал, присваиваем его значение функции}
end; {конец функции}
begin{начало тела программы}
writeln('введите неотрицательные числа'); {для удобства пользователя просим
ввести числа}
0:readln(m,n); {в память вводятся числа}
if m or n <0 then begin
writeln(‘вы ошиблись, вводите неотрицательные числа’);
goto 0 {при ошибке пользователя предотвращаем выдачу неверного результата}
end;
rez:=(fact(m)+fact(n))/fact(m+n); {вычисляется значение данного выражения}
writeln('результат: ',rez) {выводим на экран результаты счета}
readkey
end.

volvo
Z - это формальный параметр, с которым работает подпрограмма.

Ты передаешь в функцию какое-то значение, внутри функции оно доступно под именем Z.
Client
так я же ни где z н присваиваю значение. А Z здесь параметр-переменная или параметр-константа?
2ral
если хочешь что бы функция не давала никакого значения Z просто обнули его в самом начале.
volvo
Цитата
А Z здесь параметр-переменная или параметр-константа?
Просто параметр... Был бы параметр-переменная, его изменение передалось бы в основную программу - этого не происходит. Был бы параметр-константа, ты бы вообще не откомпилировал программу, потому как нельзя менять константу, ты меняешь - значит, не константа...

Цитата
я же ни где z н присваиваю значение.
Повторяю: ты передаешь значение (неважно какое, КАКОЕ-ТО) в функцию? Вот функция ПРИНИМАЕТ его как Z (ты не должен ничего присваивать, за тебя это делает компилятор)
Client
спасибо за помощь
У меня еще вопрос
Почему эти 2 примера работают одинаково
uses crt;
var
x,y:byte;
z:real;
function qw(a:byte):real;
begin
z:=(x+y)*2/y;
qw:=z;
writeln(z:0:9)
end;
begin
clrscr;
write(' vvwdite a i b ');
read(x,y);
qw(x);
writeln(' (x+y)*2/y= ',qw(x):0:13);
readkey
end.


и
Добавлено через 5 мин.

uses crt;
var
x,y:byte;
z:real;
function qw{(a:byte)}:real;
begin
z:=(x+y)*2/y;
qw:=z;
writeln(z:0:9)
end;
begin
clrscr;
write(' vvwdite a i b ');
read(x,y);
qw;
writeln(' (x+y)*2/y= ',qw:0:9);
readkey
end.



Если у кого-нибудь есть материал про функции и процедуры, просьба, дайте ссылку
Lapp
Цитата(Client @ 11.11.2007 7:17) *

Почему эти 2 примера работают одинаково
Потому что ты не используешь формальный параметр а в функции. Поэтому неважно, передаешь ты что-то через него или нет. Что касается х, то эта переменная глобальная и доступна в функции.
Client
Цитата
writeln(' (x+y)*2/y= ',qw(x):0:13);

вот здесь опять вызывается функция? или нет
Lapp
Цитата(Client @ 11.11.2007 8:20) *

вот здесь опять вызывается функция? или нет

Да.
Иначе говоря, предыдущий вызов (на отдельной строчке) - лишний.
Client
я вот понимаю функцию так: в теле функции пишем операторы, имени функции присваиваем значение. потом при вызове функции используется ее значение. Вот например я делал программу, там надо найти дату на к дней назад с учетом висогного года. Значит можно сделать функцию логического типа и если год високосный то ей присвоить значение TRUE иначе FALSE. а потом в самой программе при проверке условия просто подтавляем
IF ИМЯ ФУНКЦИИ THEN в феврале 29 дней...
я правильно понял?
volvo
Цитата
я правильно понял?
В основном... Только надо бы еще функции передать год, который ты собрался проверять на високосность, вот тогда будет совсем правильно...
Client
function visgod:longint{хотя можно integer};
begin
if (god mod 4=0) and not((god mod 100=0) and (god mod 400<>0)) then
visgod:=god;
end
Вроде того?
volvo
Я вот тут: помогите плиз
тебе уже показывал, КАК ИМЕННО, а не "вроде того"...
Client
всегда прокалываюся здесь
еще в тетради записывал, что не надо логич переменной присваивать значение с промощью условного оператора.
эх..
спасибо за ответы
Client
у меня еще вопрос
Function f(a:'a'..'z'):boolean;
Почему так нельзя описывать параметры?? Обязательно надо создать свой диапазонный тип??
volvo
Цитата
Почему так нельзя описывать параметры??
Потому что Паскаль (Турбо и Object, помнится, что Extended вроде бы все-же разрешает) не позволяет конструировать типы в заголовках подпрограмм, а ты именно это и пытаешься сделать...
Client
не позволяет конструировать типы в заголовках подпрограмм
Ясно, т.е. можно использовать только уже описанные типы. А вот здесь
procedure(const A: array of mas_type; const size: integer);
при описание массива?? И еще, как еще можно описать параметры, кроме как через VAR,CONST?? или это все способы??
volvo
А вот здесь - ты не конструируешь новый тип, ты используешь открытый массив - их возможно использовать только в качестве параметров подпрограммы. Даже если в 32-битных компиляторах ты создашь динамический массив через
type
T = array of integer;

, то это будет совсем не то, что
procedure p(var arr: array of integer);


Цитата
как еще можно описать параметры, кроме как через VAR,CONST??
Можно вообще без ничего передавать, "по значению". Можно сделать бестиповый параметр:
procedure p(var v);
begin
end;

, тогда туда можно передать все, что угодно (фактически - это указатель (нетипизированный, pointer) на область памяти, занимаемой объектом). Пример использования я приводил здесь: Задача... вообщем не пойму на что
Client
Спасибо volvo
помог как всегда smile.gif
Client
Можно еще вопрос?
Вот в основной программе можно сделать так
n:=f(z);
А в самой функции f как-нибудь можно написать
k:=f;
Чтоб в К лежало значение этой функции, но чтоб при этом не было рекурсии, чтоб здесь компилятор не просил параметр. Если можно, то как?
volvo
Если имя функции написано справа от знака присваивания - то это в любом случае трактуется компилятором как рекурсия. Для решения данной проблемы можно описать переменную result (которая уже есть в более новых компиляторах), и пользоваться ей, и только в самом конце присвоить ее значение имени функции, НО...

Возникает вопрос: а зачем тебе это? Зачем понадобилось внутри функции получать ее же значение? А если оно еще не вычислено до конца, тогда что?
Client
Цитата
Для решения данной проблемы можно описать переменную result
А можно пример, если не трудно?
Цитата
Возникает вопрос: а зачем тебе это?
Например, есть рекурсия по нахождению факториала и мне надо вывести промежуточные значения этого факториала, или одно из значений функции понадобилось 2-3 раза (что-то вроде такого примера, из-за чего и возник этот вопрос).
volvo
Я так и не понял, зачем тебе внутри функции ее же значение понадобилось несколько раз? Ну, ладно...

var i: integer;

function f(value: integer): integer;
var result: integer;
begin
result := value + 30; { <--- Предварительный результат функции }
{ ... }
i := result; { <--- Запоминаем }

{ ... }
result := result * 3; { пришлось еще ДОвычислить }
f := result; { <--- окончательный результат }
end;

begin
writeln('function = ', f(12)); { <--- Печатаем окончательный результат }
writeln('i = ', i) { <--- А это - промежуточный }
end.

Хотя опять же - я бы так делать не стал: во-первый, глобальные переменные не люблю, а во вторых - не могу представить, КАК это может понадобиться. Пример (конкретный, а не "допустим, нам понадобится") - в студию... Что именно понадобится, для чего надо сохранять значение ЭТОЙ же функции???

Цитата
Например, есть рекурсия по нахождению факториала и мне надо вывести промежуточные значения этого факториала
Я, кажется, уже написал, что если у тебя рекурсия по нахождению факториалов - то она должна их находить, а не печатать. Это не ее задача, понимаешь? А понадобилось печатать - оберни эту функцию еще одной, или напиши новую, тебе же будет проще потом отлаживать...
Client
function f(n:integer):byte;
var
k:byte;
begin
k:=0;
repeat
n:=n div 10;
inc(k)
until n<=0;
f:=k
end;
Функция подсчета количества цифр в числе.
Цитата
Я так и не понял, зачем тебе внутри функции ее же значение понадобилось несколько раз
Лучше всего завести переменную (в этой функции-К) и делать с ней все что угодно, а потом это значение присвоить функции, но у меня почему-то всегда появляются такие вопросы: А что если так? А что если...
Спасибо за пример и обяснение good.gif
volvo
Цитата
Функция подсчета количества цифр в числе.
элементарно переписывается вообще без этой самой доп. переменной:
function f(n: integer): byte;
begin
if n < 10 then f := 1
else f := 1 + f(n div 10);
end;
, если что smile.gif
Client
Цитата
если что smile.gif
А так куда лучше yes2.gif
Еще раз СПАСИБО!
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.