Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Скриптовые языки программирования > PHP
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.01.2012, 00:42   #1
iankov
Форумчанин
 
Регистрация: 04.01.2009
Сообщений: 188
По умолчанию Интересная проблема с указателями

пхп 5.2, 5.3

PHP код:
$data = array('aaa''bbb''ccc''ddd''eee');
foreach(
$data as &$row){

}

foreach(
$data as $key => $row){
    echo 
$key.' - '.$row.'<br />';
}

echo 
'---------------<br />';

foreach(
$data as $key => $row2){
    echo 
$key.' - '.$row2.'<br />';
}

echo 
'---------------<br />';

for(
$i 0$i count($data); $i++){
    echo 
$data[$i].'<br />';

почему последние 2 строки одинаковые при выводе?
0 - aaa
1 - bbb
2 - ccc
3 - ddd
4 - ddd
---------------
0 - aaa
1 - bbb
2 - ccc
3 - ddd
4 - ddd
---------------
aaa
bbb
ccc
ddd
ddd

первый цикл если вырезать, то дальнейшие циклы уже правильно выводят данные.
PHP код:
$data = array('aaa''bbb''ccc''ddd''eee');
foreach(
$data as &$row){

}

echo 
'---------------<br />';

foreach(
$data as $key => $row2){
    echo 
$key.' - '.$row2.'<br />';
}

echo 
'---------------<br />';

for(
$i 0$i count($data); $i++){
    echo 
$data[$i].'<br />';

---------------
0 - aaa
1 - bbb
2 - ccc
3 - ddd
4 - eee
---------------
aaa
bbb
ccc
ddd
eee

или же если переменную удалить, то вывод даже первым циклом будет как ожидаем
PHP код:
$data = array('aaa''bbb''ccc''ddd''eee');
foreach(
$data as &$row){

}

unset(
$row);

foreach(
$data as $key => $row){
    echo 
$key.' - '.$row.'<br />';

0 - aaa
1 - bbb
2 - ccc
3 - ddd
4 - eee

Кто-нибудь растолкуйте что происходит?

Последний раз редактировалось iankov; 15.01.2012 в 00:47.
iankov вне форума Ответить с цитированием
Старый 15.01.2012, 01:09   #2
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

Смею предположить, что тип переменно $row сохраняется и когда следующий foreach выполняется, то при назначении $row элемент массива, то идет именно присвоение указателя на элемент.(Хотя немного до конца не врубаюсь)
Ситуацию удалось промоделировать обычным for
PHP код:
for($i 0$i count($data); $i++){ 
    
$row $data[$i];
    echo 
$row.'<br />'

О! Вкурил! )))
Мы меняем указатель последнего элемента на все остальные по очереди, и по сути на предпоследней операции указатель указывает на предпоследний элемент, а на последней итерации, он просто сам себе и присваивается($i = $i), т.е. также указывает на предпоследний элемент.
PHP код:
$row $data[0];
$row $data[1];
$row $data[2];
$row $data[3];
$row $data[4]; 

Последний раз редактировалось Kostia; 15.01.2012 в 01:17.
Kostia вне форума Ответить с цитированием
Старый 15.01.2012, 01:29   #3
iankov
Форумчанин
 
Регистрация: 04.01.2009
Сообщений: 188
По умолчанию

for($i = 0; $i < count($data); $i++){
$row = $data[$i];
echo $row.'<br />';
}

что-то не понял. $row - это указатель, он в первой итерации указывает на первый элемент массива. во второй на второй. в четвертой указатель = $data[3]. А почему же в пятой, последнее указатель = указатель? должен же указатель показывать на $data[4] ? там же четко написано в цикле $row = $data[$i]. при $i = 4 $row = $data[4] ?
iankov вне форума Ответить с цитированием
Старый 15.01.2012, 01:43   #4
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

Оу, я наврал, дело не в указателях(ссылках), а в присвоении значений. Мы не указатели присваиваем последней ячейке, а значения предыдущих ячеек по очереди, поэтому предыдущее значение последней ячей каждый раз перезаписывается.

Чёт жестко тупанул=))) уже 4:40, пора спать, в понедельник очередной экзамен))
Kostia вне форума Ответить с цитированием
Старый 15.01.2012, 02:00   #5
iankov
Форумчанин
 
Регистрация: 04.01.2009
Сообщений: 188
По умолчанию

Вот теперь понял, спасибо. Еще раз растолкую подробнее, может еще кому интересно будет)

PHP код:
$data = array('aaa''bbb''ccc''ddd''eee');

foreach(
$data as &$row){


после этого цикла наш $row ссылается на последний элемент массива

PHP код:
for($i 0$i count($data); $i++){ 
    
$row $data[$i];
    echo 
$row.'<br />'

и теперь когда мы делаем $row = $data[0] например то по сути мы присваиваем последнему элементу массива $data[4] = $data[0], так как $row ссылается на последний элемент и делая операции с ним, делаются операции с переменной с которой он связан.
по этому в предпоследней итерации получается $data[4] = $data[3];
и в последней итерации уже получается $row = $data[4], а $data[4] в свою очередь была переопределена на каждом этапе цикла, а в последний раз получила значение предпоследнего элемента.

Так вроде должно быть всем ясно )

P.s. у меня было 23.40 Так что спать еще рано )
iankov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
проблема с указателями mihailvolk Общие вопросы C/C++ 3 07.05.2011 13:40
проблема с указателями raspberry Помощь студентам 2 20.04.2010 23:04
Проблема с указателями 3D Hunter Общие вопросы Delphi 8 14.03.2009 06:55
Проблема с указателями novicer Общие вопросы Delphi 5 17.06.2007 00:21