PHP: В чем разница между статической переменной внутри цикла for и нестатической переменной вне цикла for? - PullRequest
3 голосов
/ 27 февраля 2011

Например, в чем разница между

$foobar = 0
for ($i=0; $i<20; $i++) {
    //do something using $foobar
    $foobar++;
}

и

for ($i=0; $i<20; $i++) {
    static $foobar = 0
    //do something using $foobar
    $foobar++;
}

???

Оба приведенных выше примера имеют разные результаты, чем следующие:

for ($i=0; $i<20; $i++) {
    $foobar = 0
    //do something using $foobar
    $foobar++;
}

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

Для справки, вот мой фактический код (алгоритм еще не завершен). Я пометил цикл for (), который заставляет меня задуматься над этой темой:

function combine($charArr, $k) {

    $currentsize = sizeof($charArr);
    static $combs = array();
    static $originalsize = "unset";
    if ($originalsize === "unset") $originalsize = $currentsize;
    static $firstcall = true;

    if ($originalsize >= $k) {

        $comb = '';
        if ($firstcall === true) { 
            for ($i = $originalsize-$k; $i < $originalsize; $i++) {
                $comb .= $charArr[$i];
            }
            $combs[] = $comb; 
            $firstcall = false; 
        }
        if ($currentsize > $k) { 

            $comb = ''; //reset
            for ($i=0; $i<$k; $i++) { 
                $comb .= $charArr[$i];
            }
            $combs[] = $comb;

            //########### THE FOR LOOP IN QUESTION ###########              
            for ($i = $k-1; $i >= 0; $i--) { 
            static $range_adj = 0;
                for ( $j = $i+1; $j < $currentsize-$range_adj; $j++ ) { 
                    if ( !($i == 0 and $j == $currentsize-$range_adj-1) ) { 
                        $comb = substr_replace($comb, $charArr[$j], $i, 1); 
                        $combs[] = $comb;
                    }
                }
                $range_adj++;
            }
            if ($currentsize-1 > $k) { 
                array_splice($charArr, 0, 1); 
                combine($charArr, $k); 
            }
        }
        $output = array_values( $combs );
        unset($combs);
        return $output;
    }
    else {
        return false;
    }
}

Если я удаляю переменную $range_adj из цикла for и помещаю ее прямо перед циклом for как переменную none- static, то результат моей функции будет , а не . Вот как будет выглядеть модифицированный цикл:

            $range_adj = 0;
            for ($i = $k-1; $i >= 0; $i--) { 
                for ( $j = $i+1; $j < $currentsize-$range_adj; $j++ ) { 
                    if ( !($i == 0 and $j == $currentsize-$range_adj-1) ) { 
                        $comb = substr_replace($comb, $charArr[$j], $i, 1); 
                        $combs[] = $comb;
                    }
                }
                $range_adj++;
            }

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

Для вашего удобства вот оригинальный метод:

            for ($i = $k-1; $i >= 0; $i--) { 
                static $range_adj = 0;
                for ( $j = $i+1; $j < $currentsize-$range_adj; $j++ ) { 
                    if ( !($i == 0 and $j == $currentsize-$range_adj-1) ) { 
                        $comb = substr_replace($comb, $charArr[$j], $i, 1); 
                        $combs[] = $comb;
                    }
                }
                $range_adj++;
            }
* +1032 * ???

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

Ответы [ 4 ]

2 голосов
/ 27 февраля 2011

Первый и второй циклы, кажется, делают то же самое. Это потому, что, как и в случае любой другой статически инициализированной переменной, static означает, что вы инициализируете ее только один раз. Он сохраняет свое значение при попытке доступа к нему снова. Вы обнаружите, что статический $foobar все еще будет существовать вне области цикла, где бы вы его ни объявили / инициализировали; это связано с природой PHP и не имеет ничего общего со статической переменной.

Различие становится понятным только при попытке доступа к $foobar перед циклом: он не будет объявлен во втором фрагменте, поскольку вы создаете его только внутри цикла, поэтому вы можете получить уведомление о неопределенной переменной .

1 голос
/ 27 февраля 2011

static $foobar = 0;
инициализация один раз, другой запуск static $foobar = 0 ничего не делает с переменной $ foobar

0 голосов
/ 27 февраля 2011

Вы можете использовать static таким образом, чтобы предотвратить повторную инициализацию переменной в цикле .

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

Оба результата имеют одинаковый приоритет: http://codepad.org/evilks4R

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

использование ключевого слова static позволяет передавать аргументы для второго вызова со значениями, которые были получены в третьем значении.

вот пример передачи статических членов впоследние проходы вызова функции: http://codepad.org/gChjx7Om

, если вы сделали:

$foo_bar = 0;
for(.....)

thisбудет в функции, так что $foo_bar будет сбрасываться на 0 каждый раз, когда вызывается функция, поэтому перезаписывает вычисления последних вызовов.

, если вы переместили $foo_bar за пределыфункция, а затем, где это необходимо, в добавленной вами функции:

global $foo_bar

вы получите те же результаты.

http://www.cprogramming.com/tutorial/statickeyword.html

0 голосов
/ 27 февраля 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...