paulo1205
(usa Ubuntu)
Enviado em 16/11/2012 - 06:37h
Em C, os argumentos de funções são sempre passados por valor, com cópias dos valores originais, e isso vale inclusive para argumentos que são de um tipo "ponteiro para
alguma coisa". No caso de argumentos do tipo ponteiro, cabe a você garantir que tais argumentos são efetivamente endereços de dados de um tipo compatível com o do protótipo da função.
O trabalho com referências em C se faz sempre explicitamente, por meio dos operadores
& e
*, que obtêm, respectivamente, o endereço de uma variável e o acesso ao dado contido num endereço. Desse modo, sendo
var uma variável de um tipo qualquer (desde que não seja
volatile nem array), é garantido que
*&var==var, e, sendo
p um ponteiro para dado válido, é verdade que
&*p==p.
Um conceito interessante usado pela linguagem C é o de
lvalue. Simplificadamente, um
lvalue é uma expressão que pode aparecer do lado esquerdo de uma operação de atribuição, porque tal expressão resulta em algo que tem um endereço próprio na memória, que pode ser obtido com o operador
& (leia mais sobre
lvalue na Wikipedia, por exemplo, ou outra referência mais específica).
Se você tiver uma variável
var do tipo
X, o tipo de
&var será "ponteiro para
X". No código abaixo, isso fica claro.
int i=0;
int * p_i=&i; /* "X" é int */
int ** p_p_i=&p_i; /* "X" é (int *) */
int *** p_p_p_i=&p_p_i; /* "X" é (int **) */
i++; /* i==1 */
(*p_i)++; /* i==2 */
(**p_p_i)++; /* i==3 */
(***p_p_i)++; /* i==4 */
int a_i[2]={1, 2};
p_i=a_i; /* a_i não é lvalue, mas é sinônimo de "&a[0]"
(a[0] é lvalue) */
(*p_i)++; /* a[0]==2 */
(*p_p_i)++; /* p_i++, ou seja: p_i==&a[1] */
(*p_i)--; /* a[1]==1 */