簡體   English   中英

PHP:for循環中的靜態變量和for循環外的非靜態變量之間有什么區別?

[英]PHP: What's the difference between static variable inside a for loop and a non-static variable outside the for loop?

例如,有什么區別

$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++;
}

所有三種變化都有不同的結果。 據我所知,在三個示例的第一個中,$ 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;
    }
}

如果我從for循環中刪除$range_adj變量並將其放在所述for循環之前作為非static變量,那么我的函數結果就不一樣了。 這是修改后的for循環的樣子:

            $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++;
            }

???

在我看來,結果應該完全相同,但事實並非如此。 如果運行我的函數,您會注意到for循環的每個方法都得到了不同的結果。

第一個和第二個循環似乎做同樣的事情。 這是因為,與任何其他靜態初始化變量一樣, static意味着您只需初始化一次。 當您嘗試再次訪問它時,它會保留其價值。 你會發現靜態$foobar仍然存在於你聲明/初始化它的循環范圍之外; 這是由於PHP的本質,與靜態變量無關。

只有當您嘗試在循環之前訪問$foobar才會明確區別:它不會在第二個代碼段中聲明,因為您只在循環中創建它,因此您可能會收到未定義變量通知。

static $foobar = 0;
初始化一次,其他執行static $foobar = 0不用$ foobar變量做任何事情

以上兩個編程具有相同的輸出,但您的最后編程具有在每個循環期間重置的變量。 當你使用“靜態”關鍵字進行任何變量初始化時,它會保留,直到你不破壞它......或者不破壞你的程序會話。

您可以以這種方式使用static來防止變量在循環內重新初始化

在第一次迭代中,如果靜態變量未初始化,那么它將創建它並將其保留在外部上下文中,在每次其他迭代時,PHP將跳過它,因為它已經被初始化。

兩種結果都是相同的: http//codepad.org/evilks4R

它在你的函數中有所不同的原因是你的函數是遞歸的,這意味着函數組合調用自身內部的組合,當在第二次調用combine時取出靜態關鍵字時,變量正在重新初始化,從而使結果不同。

使用static關鍵字允許您將參數傳遞給第二個調用,其中包含在第三個值中生成的值。

這是一個將靜態成員傳遞給函數調用的后一個傳遞的示例: http//codepad.org/gChjx7Om

如果你做了:

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

這將在一個函數內,這樣每次調用函數時$foo_bar都會重置為0 ,因此會覆蓋最后的調用計算。

如果您將$foo_bar移到函數外部,然后在您添加的函數中需要的位置:

global $foo_bar

你會得到相同的結果。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM