é PHP e C ++ os únicos dois lugares que é preciso cuidado com o que se parece com passagem por valor é realmente passar por referência?
-
06-09-2019 - |
Pergunta
é PHP e C ++ os únicos dois lugares que é preciso cuidado com o passar uma variável tipo de dados simples como um argumento da função eo valor pode ser alterado?
como
$count = 2;
foo($count);
echo $count;
e a 3ª linha, echo $ exibição algo contagem diferente de 2. Eu só sei de PHP e C ++ onde isso pode acontecer. Existe algum outro lugar onde isso pode acontecer?
Update: que é, o que parece ser "passar por valor" é na verdade "passar por referência". Se for passando um objecto em Java, Perl, PHP, Python e Ruby, ele é automaticamente passar por referência e os valores do objecto as variáveis ??de instância pode ser alterado. Que tal passar em não-objeto?
Solução
Muitos outros idiomas suportam tais "passar por referência" - Perl, Fortran, Pascal, Visual Basic, ...
Quais você se preocupa, bem, é difícil para nós dizer! -)
Edit: Em sua atualização, você coloca Java e Python na mesma categoria, mas isso está errado: você não pode reproduzir o seu exemplo, com (Java):
int count = 2;
whatever(count);
/* count here is CERTAIN to be still 2 */
ou (Python):
count = 2
whatever(count)
# count here is CERTAIN to be still 2
estilo O Python e Java às vezes é conhecido como "de referência de objeto" (em oposição a "por referência variável"): o que é passado (ou atribuído) é uma referência para o objeto (por isso, se o objeto tem mutators o receptor pode invocar esses modificadores e, assim, alterar o objecto), não a uma "variável" (de modo que, após a chamada a variável, se houver algum, utilizados para transmitir o argumento, ainda se refere para o mesmo objecto, nunca mais outro objectivo). Esta distinção é mais clara para ver com objetos imutáveis, como (em ambos Java e Python) números e strings.
Outras dicas
Você não pode alterar uma variável em C ++ a menos que você explicitamente defini-lo como uma referência. Se você tiver argumentos (não referência) regulares, eles são cópias e pode não ser alterado. Se você ler e compreender a API, então não há necessidade de ser cuidado em passar uma variável do tipo de dados simples como uma função argumentos .
void func(type & arg);
pode ser alterada e
void func(type arg);
não pode. E geralmente em C ++ não será um argumento de referência a menos que a falta API é o valor a ser alterado na (parâmetro de saída) primeiro lugar.
E, como Alex já mencionado, há muitas línguas que suportam o passar por referência idioma.
Você só precisa ter cuidado se um idioma faz com que não clara se uma variável é passada por valor ou por referência .
De volta aos velhos dias, Fortran passou constantes por referência. Você poderia passar a constante 2 a uma sub-rotina ea sub-rotina pode atribuir 3 a ele. Em seguida, depois de voltar, este código
x = 2 + 2
iria definir x para 6. Eu não sei se modernos compiladores Fortran permitir que isso aconteça.
Na sequência da discussão acima, recentemente eu aprendi que o uso de design de linguagem de programação y do termo "pass-by-reference" é bastante muito rigoroso, e por exemplo, em java é na verdade apenas passar por valor, estritamente.
De qualquer, você passa um primitivo por valor (claro para todo mundo que eu deveria) ou você passar uma referência a um objeto por valor. Ok que eu entendo agora ainda considere o seguinte código perl.
sub addFoo {
my ($arrayRef) = @_;
push @{$arrayRef},"foo";
}
my @array = (1,2,3);
my $arrayRef; # FUTURE reference (equivalent to pointer C) to @array.
addFoo($arrayref = \@array); #1.
addFoo(\@array); #2.
addFoo($arrayRef); #3.
print join(" ",@array),"\n"; # result "1 2 3 foo foo foo\n";
A minha pergunta se qual das três chamadas alternativas para addFoo, é considerado passagem por referência ao invés de passar-A-referência? Parece que a resposta é clara para o número três, mas eu não posso dizer com número # 1. # 2. como estão fazendo exatamente o mesmo. Pelo menos o número 2 é considerado explicitamente como passar por referência em algumas páginas man perl e web-sites.