| |
|
|
| | Честно признаюсь. Искал и не нашел ничего по этой теме в поиске. Извините меня, может плохо искал. И напишу то что я действительно часто не могу подружится с вашим поисковиком.
Вот данная задача по этой теме:
1-ый скрипт:
<?php
function degree($x, $y)
{
if($y)
{
return $x * degree($x, $y-1);
}
return 1;
}
echo(degree(2, 4));
?>
|
Результат 16.
1. Вот как получилось 16 ?
2. На каком этапе происходит тормозиловка скрипта?
3. Что он вычисляет там?
Если можно объясните поподробнее об этом скрипте. (Пожалуйста пошагово).
2-ой скрипт (Итерационный вариант этого вычисления):
<?php
function degree($x, $y)
{
for($result = 1; $y > 0; --$y)
{
$result *= $x;
}
return $result;
}
echo (degree(2,4));
?>
|
Здесь намного легче код понять, но все равно не въезжаю. :-(
Только вижу что этот скрипт быстрее выполняется.
Вот for цикл:
for($i=0; $i <= 5; $i++) // Выводит от 0 до 5. Понятьно все.
|
for($result = 1; $y > 0; --$y) // А вот это, блин ... Ступор.
|
Заранее спасибо. | |
| |
|
|
| |
|
|
| |
для: Wita1y
(06.05.2006 в 14:26)
| | | Лучше переписать более понятно
<?php
function degree($x, $y)
{
if($y) return $x * degree($x, $y-1);
return 1;
}
echo(degree(2, 4));
?>
|
1. Вот как получилось 16 ?
2. На каком этапе происходит тормозиловка скрипта?
3. Что он вычисляет там?
<?php
// 0 - это false, всё что олично от нуля - true
if(4) return 2*degree(2, 3);
// degree(2, 3)
if(3) return 2*degree(2, 2);
// degree(2, 2)
if(2) return 2*degree(2, 1);
// degree(2, 1)
if(1) return 2*degree(2, 0);
// degree(2, 0)
if(0) return 2*degree(2, -1); // А вот это уже не срабатывает 0 - это false
return 1;
// Переходим в degree(2, 1) и degree(2, 0) = 1
if(1) return 2*1;
// Переходим в degree(2, 2) и degree(2, 1) = 2
if(2) return 2*2;
// Переходим в degree(2, 3) и degree(2, 2) = 4
if(3) return 2*4;
// Переходим в degree(2, 4) и degree(2, 3) = 8
if(4) return 2*8; // 16
?>
|
| |
| |
|
|
| |
|
|
| |
для: cheops
(06.05.2006 в 14:40)
| | | Почти исчерпающий ответ но все же остались вопросы по этому скрипту:
<?php
function degree($x, $y)
{
if($y) return $x * degree($x, $y-1);
return 1;
}
echo(degree(2, 4));
?>
|
> // 0 - это false, всё что отлично от нуля - true
1. Где написано, что функция по умолчанию имеет значение false а не true?
> if(0) return 2*degree(2, -1); // А вот это уже не
>срабатывает 0 - это false
2. Здесь мне предполагается то что это исчезает из цикла так как он не оправдал true.
> return 1;
3. Почему return возвращает цифру а не переменную?
Каким боком он влияет на вывод результата?
И если я поменяю на -1(то будет -16) или 2 (то будет 32).
Он лишь должен выполнять возвращение значения или я что-то путаю. :-(
Мне думается когда до дошел 0 цикл то он возвращается обратно с назначенной ему 1 и только после этого идет решения уже к готовому результату.
И само это число на что в итоге влияет?
4. То что он доходит до 4 и выдает результат, это понятно.
Мне не понятен смысл самого решения уже после.
<?php
// Переходим в degree(2, 1) и degree(2, 0) = 1
if(1) return 2*1;
// Переходим в degree(2, 2) и degree(2, 1) = 2
if(2) return 2*2;
// Переходим в degree(2, 3) и degree(2, 2) = 4
if(3) return 2*4;
// Переходим в degree(2, 4) и degree(2, 3) = 8
if(4) return 2*8; // 16
<?
|
Извиняйте меня еще раз если вам приходится мне разжевывать досконально. | |
| |
|
|
| |
|
|
| |
для: Wita1y
(06.05.2006 в 18:29)
| | |
<?php
function degree($x, $y)
{
if($y) return $x * degree($x, $y-1);
return 1;
}
echo(degree(2, 4));
?>
|
Этот код имеет смысл слегка видоизменить, и читать так:
<?php
function degree($x, $y) // функция degree предназначена для
{ // вычисления $x в степени $y
// причем степень предполагается целая неотрицательная
if($y == 0) // при возведении в нулевую степень мы получаем
return 1; // в результате единицу независимо от того, что возводим
// более высокую степень можно вычислить,
// если домножить на $x степень с
// показателем на единицу меньше,
// (напр. куб х = х * квадрат х)
return degree($x, $y-1) * $x; // при условии, если мы знаем,как её вычислить.
}
echo(degree(2, 4)); // а это попытка вычислить 2 в степени 4
// и вывести результат c помощью echo
?>
|
рекурсивный вариант тратит больше времени хотя бы потому, что на каждый вызов функции нужно создать набор локальных переменных, а по завершении вызова этот набор уничтожить. Правда я сильно сомневаюсь, что на вызове degree(2,4) Вы смогли заметить разницу в быстродействии. | |
| |
|
|
| |
|
|
| |
для: Wita1y
(06.05.2006 в 18:29)
| | | 1) Это старое правило - родилось оно в C - там нет булевого типа и ключевых слов true и false, поэтому false - это 0, а true - это всё отличное от нуля. Так как добрая половина языков программирования это C-подобные языки, то они придерживаются этого же правила, хотя в них давно уже ввели булевый тип вместе с true и false.
2) Не понял, требуются ли какие-либо комментарии и если требуются, то какие?
3) Этим я хотел показать, что переменная принимает значение 1
>Мне думается когда до дошел 0 цикл то он возвращается обратно с назначенной ему 1 и только
>после этого идет решения уже к готовому результату.
Да, вы всё правильно поняли.
4) Не очень понятно, что вызывает затрудение, если назначение функции, то без контекста она у любого вызовет недоумнее, так как итеративным путём можно получить результат быстрее - мне кажется это просто демонстрация рекурсии. | |
| |
|
|
| |
|
|
| |
для: Wita1y
(06.05.2006 в 14:26)
| | |
for($result = 1; $y > 0; --$y) // А вот это, блин ... Ступор.
|
Цикл for - очень гибкий, в нём может быть несколько переменных, не быть тела цикла - правда плата за это низкая читабельность.
Приведённый выше цикл говорит о следующем - нужно на каждом этапе цикла переменной $result присваивать 1, и выполнять цикл до тех пор, пока $y > 0, при этом на каждом этапе отнимать от $y единицу.
Циклы for могут быть достаточно изощрёнными, например,
<?php
for($i = 0, $j = 10; $i != $j; $i++, $j--, print("$i - $j<br>"));
?>
|
выведет
1 - 9
2 - 8
3 - 7
4 - 6
5 - 5
|
только лучше не употреблять их без надобности - это дурной тон. | |
| |
|
|
| |
|
|
| |
для: cheops
(06.05.2006 в 14:46)
| | | где можно почитать про операцию "запятая" ?
заголовок for( ... ; ... ; ... ) - единственный контекст, в котором её можно применять?
P.S. comma - my lovely C-operator .... | |
| |
|
|
| |
|
|
| |
для: Trianon
(06.05.2006 в 16:02)
| | | Можно использовать запятые:
<?php
$k = 10;
for ( $i = 1, $s = 0; $i <= $k; $s += ++$i * $i );
print $s;
for ( $i = 1, $s = 1, $k = 15; $i < $k; $i++, $s *= 2 ) {
print '$i='.$i.'; $s='.$s.';<br/>';
}
?>
|
| |
| |
|
|
| |
|
|
| |
для: Саня
(06.05.2006 в 17:09)
| | | Я больше скажу - во втором выражении for (в условии повтора) их тоже можно использовать.
for (
$r = 0,
$query = "SELECT * FROM tab",
$res = mysql_query($query),
$rowno = mysql_num_rows($res)
;
$rows = mysql_fetch_array($res),
$rows != null
;
$r++
)
{
echo "$r .";
print_r($rows);
}
|
Меня же интересует, где описаны правила, определяющие, когда можно применять эту операцию, а когда нельзя. Потому что по всему выходит, что нельзя её упреблять практически нигде. | |
| |
|
|
| |
|
|
| |
для: Trianon
(06.05.2006 в 17:21)
| | | Меня же интересует, где описаны правила...
В документации ничего такого не сказано. Я узнал о возможности использовать запятую в циклах из книги о Си++. Думаю правила использования этого оператора идентичны правилам в си. | |
| |
|
|
| |
|
|
| |
для: Саня
(06.05.2006 в 17:29)
| | | Есть одно упоминание. В разделе с таблицей приоритетов и направлениями ассоциативности операций. Других я не видел.
До поста cheops'a я думал, что её вообще забыли реализовать, а таблица осталась слизанной с оригиналов пера K&R. Но сейчас вообще ничего не понимаю. Нельзя же реализовать операцию в for и случайно забыть о ней во всех остальных местах? | |
| |
|
|
| |
|
|
| |
для: Trianon
(06.05.2006 в 18:08)
| | | Все описания в справочниках по C и Perl - PHP описан очень безобразно - хуже мануала, я больше нигде не видел. Да нормально вообще говоря запятая действует, помимо for, только в таком контексте (могу врать - может ещё где срабатывает)
<?php
echo "Hello ", "world!";
?>
|
| |
| |
|
|
| |
|
|
| |
для: cheops
(06.05.2006 в 21:28)
| | | В этом контексте она тоже не действует. Точнее действует семантически ненормально.
Запятая, как операция, а не как разделитель параметров, должна вычислить и тут же выкинуть значение своего левого операнда, а затем заняться правым.
echo 1,2 с позиций С-подобного языка, должно напечатать двойку.
Ничего подобного не происходит. Печатается 12. Возникает впечатление, что языковая конструкция echo воспринимает любое количество аргументов и выводит последовательно один за другим.
Но не тут-то было. Стоит взять этот список аргументов в скобки, написав echo(1,2); и тут же оказывается, что тогда echo считает, что у нее один аргумент. С ошибочным синтаксисом: parse error, unexpected ',' . | |
| |
|
|
| |
|
|
| |
для: Trianon
(06.05.2006 в 21:47)
| | | Согласен... с позиции целостности языка лучше бы разработчики PHP вообще больше кроме как в for запятую не использовали - так как ни к чему кроме как запутанному коду она не приведёт. | |
| |
|
|
| |
|
|
| |
для: cheops
(06.05.2006 в 21:28)
| | | >Все описания в справочниках по C и Perl - PHP описан очень
>безобразно - хуже мануала, я больше нигде не видел. Да
>нормально вообще говоря запятая действует, помимо for,
>только в таком контексте (могу врать - может ещё где
>срабатывает)
И все-таки.
1. Что будет правильнее: запятая(без скобок) или точка(со скобками)?
2. И как это может повлиять в дальнейшем?
<?php
echo "Hello ", "world!"; // так?
echo "<br>";
echo ("Hello ". "world!"); // или так?
?>
|
| |
| |
|
|
| |
|
|
| |
для: Wita1y
(08.05.2006 в 11:15)
| | | Лучше использовать точку - увидеть её ожидают 90% программистов, даже те кто знаком с запятой - будут ворчать. | |
| |
|
|
| |
|
|
| |
для: cheops
(06.05.2006 в 14:46)
| | |
<?php
function degree($x, $y)
{
for($result = 1; $y > 0; --$y)
{
$result *= $x;
}
return $result;
}
echo (degree(2,4));
?>
|
Если я правильно понял, то вычисление происходит таким образом:
<?php
for ($result = 1; 4 > 0; 3)
1 = 1*2; // $result = 2
for ($result = 1; 3 > 0; 2)
1 = 1*2; // снова $result = 2
for ($result = 1; 2 > 0; 1)
1 = 1*2; // опять $result = 2
for ($result = 1; 1 > 0; 0)
1 = 1*2; // тоже самое $result = 2
for ($result = 1; 0 > 0; -1) // !true
1 = 1*2; // и оно же $result = 2
return 2;
// Далее пошло вычисление результата.
return 2*1; // = 2
return 2*2; // = 4
return 2*4; // = 8
return 2*8; // = 16
echo
?>
|
Прокоментируйте пожалуйста и укажите на мои ошибки, если конечно же имеются.
Всем спасибо. | |
| |
|
|
| |
|
|
| |
для: Wita1y
(07.05.2006 в 13:25)
| | | то, что переменной $result присваивается 1 на каждом шаге итерации - полный бред
в цикле for(a;b;c)
a выполняется один раз на этапе инициализации цикла,
b - условие, которое проверяется каждый раз при входе на следующую итерацию, и если оно не выполняется, то цикл завершается,
c выполняется на каждой итерации в самом конце
а вообще никого не слушай - проверь сам:
<?php
function degree($x, $y)
{
for($result = 1; $y > 0; --$y)
{
echo "x = $x; y = $y; result = $result<br>";
$result *= $x;
}
return $result;
}
echo (degree(2,4));
?>
|
это тебе даст информацию по каждому шагу цикла
удачи,
Надя | |
| |
|
|
|