Post on 26-Jan-2019
Subprogramas II
Programação11543: Engenharia Informática
6619: Tecnologias e Sistemas de Informação
Cap. 9 — Subprogramas II: Passagem de Parâmetros
Subprogramas: 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
Subprogramas: passagem de parâmetros
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 é umavariá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 quadradon
q25r
Subprogramas: passagem de parâmetros
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
printfquadrado
5
main quadradon
q25r
main printf25r
QUAD=
Subprogramas: passagem de parâmetros
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
Subprogramas: passagem de parâmetros
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ídasem que i,j=0, 1,… ,n
Subprogramas: passagem de parâmetros
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.
Subprogramas: passagem de parâmetros
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
Subprogramas: passagem de parâmetros
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 quadradon
q25r
Subprogramas: passagem de parâmetros
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 quadradon
q25r
p
Subprogramas: passagem de parâmetros
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.
Subprogramas: passagem de parâmetros
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;
}
swapy
void
xab
20a 30 b
20x 30 y
20aux
30 20
Subprogramas: passagem de parâmetros
Alteração do valor duma variável exterior dentro duma função 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).
Subprogramas: passagem de parâmetros
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;
}
swapy
void
x&a&b
4048 405220
a
30
b
4048x 4052 y
20aux
30
20
FIM