Subprogramas II
6619: Tecnologias e Sistemas de Informação
Cap. 9 — Subprogramas II: Passagem de Parâmetros
Sumário:
• Revisitação ao modelo de comunicação entre funções
• Entrada e saída de dados de/para uma função
• Modelo de comunicação entre funções
• Tipos de argumentos
• Métodos de passagem de parâmetros
• Métodos de passagem de parâmetros em C
• Alteração do valor duma variável exterior dentro duma função em C
O que já sabemos sobre comunicação entre funções
• Passagem de parâmetros / argumentos
• É uma operação de entrada de dados.
• Atribuição 1:1 de cada parâmetro concreto (ou valor) a um parâmetro formal (que é uma variável).
• Retorno/Devolução de valor
• É uma operação de saída de dados.
• Uma função devolve sempre um valor ou nada (void).
5
main n quadrado
25 q r
Exemplo:
#include <stdio.h>
int quadrado(int);
main() { int r;
r = quadrado(5);
printf(”QUAD=%i",r);
}
int quadrado(int n) {
int q;
q = n * n;
return q;
}
main
printf quadrado
5
main n quadrado
25 q r
main 25 printf
r
QUAD=
Entrada e saída de dados para/de uma função: situação actual
• Dados de entrada: N
• Dados de saída: 1
• PROBLEMA:
– Será que não é possível ter mais do que 1 dado de saída?
• SOLUÇÃO:
– Definir dados de entrada que sejam também de saída
Modelo de comunicação entre funções
• Em princípio, todas as linguagens suportam o seguinte modelo de comunicação entre funções:
i entradas e j saídas em que i,j=0, 1,… ,n
Tipos de parâmetros/argumentos
• Nas várias linguagens de programação, podemos encontrar 3 tipos de argumentos:
– ENTRADA – SAÍDA
– ENTRADA e SAÍDA
• Os dados de entrada para uma função são designados por parâmetros
efectivos ou concretos. Estes parâmetros pertencem ao domínio da função invocadora.
• As variáveis do protótipo da função que recebem dados de entrada ou que retornam resultados (ou dados de saída) são designadas por parâmetros formais. Estes parâmetros pertencem ao domínio da função invocada.
• Na linguagem C, só temos parâmetros de entrada, embora haja linguagens que admitem os 3 tipos de parâmetros (p.ex., a linguagem Pascal).
• No entanto, em C, é possível emular parâmetros de saída e parâmetros de entrada/saída através de variáveis apontadoras que os referenciam.
Passagem de um parâmetro por VALOR
• Como funciona?:
– a função invocadora F chama a função f passando-lhe um VALOR;
– o VALOR pode ser um literal ou o valor duma variável (que designamos por parâmetro efectivo);
– A função invocada f recebe o VALOR e armazena-o numa variável (que é o parâmetro formal) do seu domínio.
• É um mecanismo uni-direccional de comunicação de dados entre funções.
– Porquê? Porque os parâmetros formais da função invocada recebem valores, mas não retornam quaisquer valores.
– O retorno só pode ser feito por via da instrução return, não através dum parâmetro formal.
– Em suma, a passagem de parâmetros por valor é um mecanismo de comunicação uni-direccional de F para f, ao passo que a utilização da instrução return é um mecanismo de comunicação uni- direccional de f para F
Passagem por valor: LITERAL
• No exemplo ao lado, temos:
– função invocadora: main – função invocada: quadrado
• A função main invoca a função quadrado, passando-lhe o literal inteiro 5;
• A função quadrado recebe o literal 5 e armazena-o na variável inteira n do seu domínio.
#include <stdio.h>
int quadrado(int);
main() { int r;
r = quadrado(5);
printf(”QUAD=%i",r);
}
int quadrado(int n) { int q;
q = n * n;
return q;
5 }
main n quadrado
25 q r
Passagem por valor: VALOR DE VARIÁVEL
• No exemplo ao lado, temos:
– função invocadora: main – função invocada: quadrado
• A função main invoca a função
quadrado, passando-lhe o valor da variável inteira p que é 5;
• A função quadrado recebe o valor inteiro 5 e armazena-o na variável inteira n do seu domínio.
#include <stdio.h>
int quadrado(int);
main()
{ int r, p=5;
r = quadrado(p);
printf(”QUAD=%i",r);
}
int quadrado(int n) { int q;
q = n * n;
return q;
5 }
main n quadrado
25 q r
p
Métodos de passagem de parâmetros
11
¨ POR VALOR:
É o único mecanismo de passagem de parâmetros em C, o que significa que os parâmetros são todos de entrada (de valores).
Os parâmetros efectivos pertencem ao domínio da função invocadora.
Os parâmetros formais pertencem ao domínio da função invocada.
Ideia base : qualquer alteração no valor dum parâmetro formal não provoca alteração no valor parâmetro efectivo correspondente.
¨ POR REFERÊNCIA:
Ideia base: Passar a própria variável em vez do seu valor. Isto implica que alterar o valor dum parâmetro formal implica alteração idêntica no parâmetro efectivo.
Não existe em C (só em C++) um mecanismo formal/sintáctico de passagem de parâmetros por referência.
O que se faz é simular este mecanismo através de passagem de parâmetros por valor dum endereço, ou seja, através de apontadores.
Exemplo incorrecto: troca de valores de 2 variáveis
#include <stdio.h>
void swap(int, int);
int main() {
int a=20, b=30;
swap(a,b);
printf(“a=%d e b=%d”,a,b);
return 0;
}
void swap(int x, int y) {
int aux;
aux=x; x=y; y=aux;
return;
}
y swap
void
a x b
a 20 30 b
x 20 30 y
20
aux
30 20
em C
13
Estratégia:
Em vez de passar o valor duma variável, passa-se o o valor do seu endereço (através do operador &), que como se sabe é inalterável.
Se se passa um endereço, há que o receber dentro da função através duma variável endereçadora.
Se dentro da função se usa uma variável endereçadora, podemos alterar a variável por ela endereçada, isto é, uma variável do domínio da função
invocadora (que é normalmente a função main).
Exemplo correcto: troca de valores de 2 variáveis
#include <stdio.h>
void swap(int*, int*);
int main() {
int a=20, b=30;
swap(&a,&b);
printf(“a=%d e b=%d”,a,b);
return 0;
}
void swap(int *x, int *y) {
int aux;
aux=*x; *x=*y; *y=aux;
return;
}
y swap
void
&a x
&b
4048 20 4052
a
30
b
x 4048 4052 y
20
aux
30
20
FIM