對陣列兩次foreach的使用陷阱

2021-09-19 09:41:25 字數 1956 閱讀 5842

對陣列兩次foreach的使用陷阱

對同乙個陣列兩次foreach備註

這個問題是做小論壇的時候碰見的

如果單純的對乙個陣列兩次foreach是沒什麼問題的

輸出:如果在第一次foreach的時候,加了引用呢?

輸出:第二次的結果是 a b b,並不是陣列的值

也就是說這種情況下,foreach迴圈最後一次的值和陣列倒數第二個的值是一樣的

輸出:為什麼第二次結果是a b b呢?

foreach迴圈時,是通過移動陣列內部指標來實現的

第一次foreach迴圈時,$v為引用變數

因而$v 與 $arr[2] 指向了同乙個位址空間(共享變數值)

所以之後對$v的任何修改都會直接影響$arr

第二次foreach的第一次迴圈時,$v被賦值為$arr[0],也就是a

而在第一次foreach結束時,$v最終指向了$arr[2],他們指向同乙個位址空間

所以第二次foreach的第一次迴圈時,$v的值成了a,$arr[2]也就變成了a

第二次foreach的第二次迴圈時,$v的值成了b,$arr[2]也就變成了b

所以,陣列$arr的值就成了a b b

所以第三次迴圈時,$v的值就成了b

上面說的明白,不過···

第二次foreach迴圈時,$v=$arr[0],按照之前說的,$v的指向不是指向了$arr[0]嗎?

也就是說$v和$arr[0]指向同一記憶體位址,因為$arr和$v都沒有發生值的變化

這裡我們需要先了解乙個知識點:

結果:12

結果:22

2主要是這**的執行結果:

我以為上面的**中$v和$b應該指向同一zval,而$a的值不會被改變,但事實並非這樣

是不是說乙個變數的引用(&)沒有消失,對這個變數重新賦值(非引用)其它變數的時候,其記憶體位址不會發生變化,也就是該變數的引用、指向記憶體位址的那條線不會改變,只是值變化

結果:12

結果:12

2所以,結果才會這樣

輸出:

那現在又有這樣乙個疑慮,理論上在第二次foreach迴圈中,不會拷貝陣列,這裡$arr的值雖然發生了變化,但並不是直接通過$arr[$k]這樣的方式去改變的,而是$v的值被改變,$v是個臨時變數,間接的影響到了$arr陣列的值,所以陣列不會拷貝

(目前沒想到更有說服力的理由)

三種解決方案:

① 第二次foreach迴圈,別用$v了

② 第二次foreach迴圈之前,unset($v)

$v的引用在 foreach 迴圈之後仍會保留。建議使用unset()將其銷毀

③ 第二次迴圈也用&

PHP對陣列兩次foreach的使用陷阱

1.兩次迴圈如果不實用引用列印結果沒有任何問題 array a b c foreach array as value foreach array as value var dump array 執行結果 array 3 2.當第一次迴圈使用引用後會出現如下bug 如下 array a b c for...

listview 重新整理兩次的問題

遇到個奇怪的現象,listview每次都重新整理兩次,在網上查詢了好久,無果,後來看見一片部落格中提到 的getview會重複執行多次,這次因為布局比較複雜,所以在測試的時候去斷點跟蹤,發現同一條資料不斷的重複執行 listview是根據布局來確定當錢重新整理的item並確定是否重新整理完畢,我按照...

Tomcat 啟動兩次的問題

1 存在某個應用 hello 3 tomcat的server.xml部分配置資訊如下 這麼做的目的就是為了將hello應用設為根,訪問ip時就直接訪問該應用 4 hello下有乙個 servlet 目的是為了系統在啟動時執行某些初始化的操作 該servlet裡存在init 方法,目前該方法裡只列印 ...