С Новым годом! Форум программистов, компьютерный форум, киберфорум
PHP для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.84/25: Рейтинг темы: голосов - 25, средняя оценка - 4.84
24 / 24 / 10
Регистрация: 22.12.2012
Сообщений: 2,712

Почему тут нужен амперсанд (&) ?

12.09.2016, 05:26. Показов 4940. Ответов 14

Студворк — интернет-сервис помощи студентам
Вопрос по foreach , а точнее, по амперсанду (&) в foreach:

Есть цикл:

PHP
1
2
3
4
$nums = [1, 2, 3, 4, 5]; 
foreach($nums as $v)
$v = $v * 10; 
print_r($nums);
print_r выведет:

PHP
1
2
3
4
5
6
7
8
Array 
( 
    [0] => 1 
    [1] => 2 
    [2] => 3 
    [3] => 4 
    [4] => 5 
)
Есть другой цикл:
PHP
1
2
3
4
$nums = [1, 2, 3, 4, 5]; 
foreach($nums as &$v) 
$v = $v * 10; 
print_r($nums);
print_r выведет:

PHP
1
2
3
4
5
6
7
8
Array 
( 
    [0] => 10 
    [1] => 20 
    [2] => 30 
    [3] => 40 
    [4] => 50 
)
.

Какая принципиальная разница в том, копирует ли foreach ячейки массива или ссылается на них напрямую?
Почему умножение копии не приводит к результату, а умножение оригинала приводит?
Спасибо.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.09.2016, 05:26
Ответы с готовыми решениями:

Что значит амперсанд(&) в вычислении?
В документации как то ни чего не сказано (либо я слишком слеп). В одном из примеров увидел: ord($data) & 127 И теперь мучает...

Зачем тут нужен амперсанд "&"?
Программа с помощью контейнера сортирует строки из входного файла по алфавиту и преобразует их к верхнему регистру. Вопрос: зачем в строке...

Нужен драйвера, код PCI\VEN_1039&DEV_7012&SUBSYS_0C98105B&REV_A0\3&B1BFB68&0&17
всем привет !! уменя нет звука нужен драйвер код PCI\VEN_1039&DEV_7012&SUBSYS_0C98105B&REV_A0\3&B1BFB68&0&17 скачал прогу их много ...

14
Эксперт PHP
5755 / 4134 / 1508
Регистрация: 06.01.2011
Сообщений: 11,276
12.09.2016, 06:50
Цитата Сообщение от morda77 Посмотреть сообщение
Почему умножение копии не приводит к результату, а умножение оригинала приводит?
Потому что копия не имеет никакого отношения к оригинальным значениям. А при указании амперсанда как раз формируется ссылка на оригинальное значение.
0
24 / 24 / 10
Регистрация: 22.12.2012
Сообщений: 2,712
12.09.2016, 16:51  [ТС]
Para bellum, ведь если я копирую файл в Windows, то создается его полная копия со всеми его свойствами, а не ярлык.
Может в PHP по умолчанию создаются ярлыки, а не копии?
0
 Аватар для Зверушь
461 / 369 / 94
Регистрация: 01.05.2010
Сообщений: 1,761
12.09.2016, 17:00
morda77, вам же сказали, что в foreach передается копия переменной. Чтобы передать ссылку на переменную как раз и используют амперсанд. Копирование файлов в Windows вообще не имеет никакого отношения к перебору целых чисел в foreach.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
$a = array(10, 20, 30);
$b = array(10, 20, 30);
 
foreach ($a as $v) {
    $v = $v * 2;
}
foreach ($b as &$v) {
    $v = $v * 2;
}
 
var_dump($a);
var_dump($b);
Проверьте этот код. Даны два одинаковых массива содержащих 10, 20 и 30. Так как второй обработан по ссылке, то его значения увеличаться в два раза. Первый останется без изменений.
0
12.09.2016, 17:14

Не по теме:

Цитата Сообщение от morda77 Посмотреть сообщение
Может в PHP по умолчанию создаются ярлыки, а не копии?
Какие ярлыки, о чем ты ??? :D:yahoo:

0
Эксперт PHP
5755 / 4134 / 1508
Регистрация: 06.01.2011
Сообщений: 11,276
12.09.2016, 18:59
Цитата Сообщение от morda77 Посмотреть сообщение
Может в PHP по умолчанию создаются ярлыки, а не копии?
Как раз по умолчанию в foreaсh создаются копии. Указав амперсанд, Вы создаёте "ярлык", как Вы выразились. То есть ссылку на оригинальное значение.
0
24 / 24 / 10
Регистрация: 22.12.2012
Сообщений: 2,712
12.09.2016, 19:39  [ТС]
Цитата Сообщение от Para bellum Посмотреть сообщение
Как раз по умолчанию в foreaсh создаются копии. Указав амперсанд, Вы создаёте "ярлык", как Вы выразились. То есть ссылку на оригинальное значение.
Ясно. А почему копия не умножается-то?
0
Эксперт PHP
5755 / 4134 / 1508
Регистрация: 06.01.2011
Сообщений: 11,276
12.09.2016, 19:42
Цитата Сообщение от morda77 Посмотреть сообщение
А почему копия не умножается-то?
Нет, она умножается. Вы же изменённое значение ищете в исходном массиве, а нужно смотреть в переменной в теле цикла:
PHP
1
2
3
4
5
6
$nums = [1, 2, 3, 4, 5]; 
foreach($nums as $v){
$v = $v * 10; 
 
var_dump($v);
}
0
24 / 24 / 10
Регистрация: 22.12.2012
Сообщений: 2,712
12.09.2016, 19:43  [ТС]
Зверушь, можете объяснить "на пальцах"? На примере яблок.)
0
1943 / 1768 / 825
Регистрация: 23.01.2014
Сообщений: 6,230
12.09.2016, 21:32
Цитата Сообщение от morda77 Посмотреть сообщение
ведь если я копирую файл в Windows, то создается его полная копия со всеми его свойствами, а не ярлык.
Правильно. Но если Вы измените эту копию файла в Windows, это ведь не значит что изменится и оригинал? Также и тут. Копию Вы меняете, а оригинал остается.

А вот если добавить амперсанд, то это будет ссылка на оригинал, а не копия. То есть работая с ней вы работаете с оригиналом, просто обращаетесь к нему, можно сказать, через ярлык.

Цитата Сообщение от morda77 Посмотреть сообщение
можете объяснить "на пальцах"? На примере яблок.)
Это проще понять на обычных функциях, чем на сложных конструкциях типа foreach. Например:
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
function foo($x)
{
    $x += 1;
    echo '$x внутри функции foo() = '.$x."<br>".PHP_EOL;
}
function fooRef(&$x)
{
    $x += 1;
    echo '$x внутри функции fooRef() = '.$x."<br>".PHP_EOL;
}
 
$x = 1;
echo '$x до функции foo() = '.$x."<br>".PHP_EOL;
foo($x);
echo '$x после функции foo() = '.$x."<br><br>".PHP_EOL;
$x = 1;
echo '$x до функции fooRef() = '.$x."<br>".PHP_EOL;
fooRef($x);
echo '$x после функции fooRef() = '.$x."<br>".PHP_EOL;
Результат:
$x до функции foo() = 1
$x внутри функции foo() = 2
$x после функции foo() = 1

$x до функции fooRef() = 1
$x внутри функции fooRef() = 2
$x после функции fooRef() = 2
0
Фрилансер
Эксперт PythonЭксперт JSЭксперт PHP
 Аватар для Azdeman
1871 / 1362 / 604
Регистрация: 12.01.2011
Сообщений: 5,470
12.09.2016, 21:42
Цитата Сообщение от morda77 Посмотреть сообщение
На примере яблок.)
Попробую объяснить, у меня это конечно плоховато получается...

Купил ты 2 яблока. Дал 1 другу... друг откусил яблоко, у тебя оно откусанное? Нет, потому что у тебя оригинал яблоко а у него копия , тобишь 2-е яблоко (назовём его копией).

У тебя 1 яблоко, ты даёшь его другу у него оригинальное яблоко, тобишь твоё, которое ты ему дал, он его откусил, и получилось так что ваше на двоих яблоко теперь откусанное. Потому что вы 2-ем ссылаетесь на одно и тоже яблоко(на оригинал).

Так же само и с амперсантом и без..
Без амперсанта вы даёте копию .. То есть 2-е яблоко(копию), а с амперсантом , вы пользуетесь 1-м яблоком (на 2-е у вас денег не хватило).

Добавлено через 6 минут
Цитата Сообщение от pav1uxa Посмотреть сообщение
Это проще понять на обычных функциях
А еще проще на обычных переменных
PHP
1
2
3
4
$drug_ = 'Яблоко 1';//Саше мама дала яблоко
$drug2_ = &$drug_; // Саша дал яблоко другу
$drug2_ = 'Лёха Съел Яблоко 1'; // Лёха его на крысу съел 
echo $drug_; // Саша увидел что Лёха съел яблоко
1
 Аватар для Зверушь
461 / 369 / 94
Регистрация: 01.05.2010
Сообщений: 1,761
13.09.2016, 11:29
Цитата Сообщение от morda77 Посмотреть сообщение
Зверушь, можете объяснить "на пальцах"? На примере яблок.)
Эх, на яблоках не могу. попробую все же на переменных
Ну вот смотри. Есть у тебя массив $a. Этот массив хранится где-гнибудь в определенном месте оперативной памяти. У этой области памяти есть свой адрес. Каждый раз, когда ты обращаешся к массиву $a, php идет по адресу к этому участку памяти и берет из него значения элементов массива.
Но вот ты передаешь массив в foreach. Не указав никакой амерсанд. Просто foreach ($a as $v). Без указания амперсанда php идет по адресу, где хранится массив $a, копирует его куда-нибудь в другое место оперативной памяти, и копию засовывает в foreach. Когда foreach отработает, то эта копия будет удалена из оперативной памяти. Как следствие, исходный массив $a изменен не будет. Если же мы передадим массив по ссылке (указав амперсанд), то php не будет помещать копию в foreach, а будет работать со ссылкаой, то есть с оригинальным сначением. С той областью оперативной памяти, где хранится массив $a.
Это понятно?
0
24 / 24 / 10
Регистрация: 22.12.2012
Сообщений: 2,712
13.09.2016, 16:38  [ТС]
Зверушь, вроде да. Спасибо.
А только foreach таким балуется? Зачем ему это?

Добавлено через 13 минут
Зверушь, какой вообще смысл в том, чтобы взять массив, сделать копию, "побаловаться" и удалить?
0
Эксперт PHP
4925 / 3920 / 1620
Регистрация: 24.04.2014
Сообщений: 11,441
13.09.2016, 16:50
Цитата Сообщение от morda77 Посмотреть сообщение
какой вообще смысл в том, чтобы взять массив, сделать копию, "побаловаться" и удалить?
Все самое интересное когда оригинальный массив меняется. Если итерировать по копии массива с добавлением новых значений foreach пройдет лишь по оригинальным
PHP
1
2
3
4
5
$a = [1, 2, 3];
foreach ($a as $v) {
    $a[] = $v;
}
var_dump($a);
Если же не использовать копию цикл становится бесконечным (если его самому принудительно не прервать, как в следующем примере)
PHP
1
2
3
4
5
6
7
$a = [1, 2, 3];
$i = 0;
foreach ($a as &$v) {
    if (++$i > 1000) break;
    $a[] = $v;
}
var_dump($a);
0
 Аватар для Зверушь
461 / 369 / 94
Регистрация: 01.05.2010
Сообщений: 1,761
13.09.2016, 17:17
morda77, это еще и безопасность. Зачастую массивы нужно перебирать, на их основе строить новые данные, а сам исходный массив не изменять. Если передать по ссылке, то можно случайно затереть основной массив там, где это не нужно. В итоге программа может отработать не выдав ни единой ошибки, а вот итоговые данные будут не веры.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.09.2016, 17:17
Помогаю со студенческими работами здесь

Амперсанд (&)
Доброго времени суток!!! Для чего этот амперсанд при выполнении команд?

Почему нужен &nbsp; в данном случае?
Привет всем!Собственно такой вопрос:Почему в данном случае нужен &amp;nbsp; ? И у меня при написании дескриптора &lt;wbr&gt;строка...

Перегружаемый оператор присваивания, зачем нужен амперсанд?
Вот программа: #include &lt;iostream&gt; using namespace std; class alpha { private: int data; public: alpha(){}

Почему friend ostrem& operator <<(ostream& outs, const Rational&); - invalid function declaration?
Пытаюсь скомпилировать программу пишет friend ostrem&amp; operator &lt;&lt;(ostream&amp; outs, const Rational&amp;); - invalid function declaration. ...

Для чего нужен амперсанд в параметре ф-ции modf() ?
Для чего нужен амперсанд в параметре ф-ции modf() и почему без него ф-ция не работает? Как быть если мне не нужна целая часть и я не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru