Passagem de Parâmetros e Estruturas
Passagem de Parâmetros e Estruturas Passagem de Parâmetros e Estruturas
Algoritmos e Estruturas de Dados I 01/2013 Passagem de Parâmetros e Estruturas Pedro O.S. Vaz de Melo
- Page 2 and 3: A passagem de parâmetros ● Toda
- Page 4 and 5: Passagem por valor ● Considere o
- Page 6 and 7: Passagem por referência ● Mas, e
- Page 8 and 9: Passagem por referência ● Consid
- Page 10 and 11: Passagem por referência ● Observ
- Page 12 and 13: Problema 1 ● Implementar uma calc
- Page 14 and 15: Análise do programa confuso e com
- Page 16 and 17: Definição de novos tipos de dados
- Page 18 and 19: Definição de novos tipos de dados
- Page 20 and 21: O comando typedef ● O Comando typ
- Page 22 and 23: O comando typedef • Observação:
- Page 24 and 25: Estruturas como parâmetros de fun
- Page 26 and 27: Estruturas como parâmetros de fun
- Page 28 and 29: Estruturas como parâmetros de fun
- Page 30: Estruturas como parâmetros de fun
Algoritmos e <strong>Estruturas</strong> <strong>de</strong> Dados I<br />
01/2013<br />
<strong>Passagem</strong> <strong>de</strong> <strong>Parâmetros</strong><br />
e<br />
<strong>Estruturas</strong><br />
Pedro O.S. Vaz <strong>de</strong> Melo
A passagem <strong>de</strong> parâmetros<br />
● Toda função <strong>de</strong>fine um processamento a ser realizado.<br />
● Este processamento <strong>de</strong>pen<strong>de</strong> dos valores dos parâmetros<br />
da função.<br />
● Assim, para usar uma função, um programa precisa<br />
fornecer a ela os parâmetros a<strong>de</strong>quados. Exemplo:<br />
● Para calcular o seno <strong>de</strong> 30º, escrevemos: sin(pi/6);<br />
● Para calcular o valor absoluto <strong>de</strong> a-b, escrevemos: abs(a-b);<br />
● Para calcular o mdc <strong>de</strong> 12 e 8, escrevemos: mdc(12,8);<br />
2
A passagem <strong>de</strong> parâmetros<br />
● O mecanismo <strong>de</strong> informar os valores a serem processados<br />
pela função chama-se passagem <strong>de</strong> parâmetros.<br />
● A Linguagem C <strong>de</strong>fine duas categorias <strong>de</strong> passagem <strong>de</strong><br />
parâmetros: passagem por valor e passagem por<br />
en<strong>de</strong>reço (ou passagem por referência).<br />
● Normalmente, a passagem <strong>de</strong> parâmetros a uma função<br />
é por valor.<br />
● Mas, como os parâmetros <strong>de</strong> uma função são variáveis<br />
locais, alguns aspectos <strong>de</strong>vem ser observados.<br />
3
<strong>Passagem</strong> por valor<br />
● Consi<strong>de</strong>re o exemplo abaixo:<br />
● O que este programa irá exibir? Valores recebidos ... 1, 2 e 3<br />
Valores alterados ... 2, 3 e 4<br />
Valores finais ......... 1, 2 e 3<br />
4
<strong>Passagem</strong> por valor<br />
● Observe que os valores das variáveis a, b e c não foram<br />
modificados na função alterar. Por quê?<br />
● O tipo <strong>de</strong> passagem <strong>de</strong> parâmetros utilizado é por valor.<br />
Ou seja, são feitas apenas cópias dos valores das<br />
variáveis a, b, e c nas variáveis x, y e z.<br />
Escopo: função main<br />
a<br />
b<br />
c<br />
1<br />
2<br />
3<br />
Escopo: função alterar<br />
x<br />
y<br />
z<br />
1<br />
2<br />
3<br />
x++<br />
y++<br />
z++<br />
2<br />
3<br />
4<br />
Apenas os<br />
conteúdos<br />
<strong>de</strong> x, y e z<br />
são alterados.<br />
5
<strong>Passagem</strong> por referência<br />
● Mas, e se quisermos que a função modifique os valores<br />
das variáveis a, b e c passadas a ela como parâmetros?<br />
● Neste caso, em vez <strong>de</strong> passar para a função os valores<br />
<strong>de</strong>stas variáveis, é preciso passar os seus en<strong>de</strong>reços.<br />
Como assim?<br />
● Consi<strong>de</strong>re, por exemplo, que as variáveis a, b e c<br />
correspon<strong>de</strong>m, respectivamente, aos en<strong>de</strong>reços<br />
(hexa<strong>de</strong>cimais) F000, F010 e F020.<br />
6
<strong>Passagem</strong> por referência<br />
● Ou seja:<br />
En<strong>de</strong>reço<br />
F000<br />
F010<br />
F020<br />
Conteúdo<br />
● Sabemos, portanto, que:<br />
&a = F000 (en<strong>de</strong>reço <strong>de</strong> a);<br />
&b = F010 (en<strong>de</strong>reço <strong>de</strong> b);<br />
&c = F020 (en<strong>de</strong>reço <strong>de</strong> c);<br />
a = 1, b = 2, c = 3 (valores das variáveis).<br />
1<br />
2<br />
3<br />
Variável<br />
a<br />
b<br />
c<br />
7
<strong>Passagem</strong> por referência<br />
● Consi<strong>de</strong>re uma variável <strong>de</strong>clarada como:<br />
● x é um ponteiro para int, ou seja, x é uma variável que<br />
armazena o en<strong>de</strong>reço <strong>de</strong> uma variável do tipo int.<br />
● Consi<strong>de</strong>re agora que:<br />
int *x;<br />
● Neste caso, x armazena o valor F000.<br />
x = &a;<br />
Define-se *x, como sendo o valor contido na posição <strong>de</strong><br />
memória apontada por x. Ou seja, *x vale 1.<br />
8
<strong>Passagem</strong> por referência<br />
● Consi<strong>de</strong>re agora o exemplo anterior reescrito como:<br />
● O que este programa irá exibir?<br />
Valores recebidos ... 1, 2 e 3<br />
Valores alterados ... 2, 3 e 4<br />
Valores finais ......... 2, 3 e 4<br />
9
<strong>Passagem</strong> por referência<br />
● Observe agora que os valores das variáveis a, b e c foram<br />
modificados na função alterar. Por quê?<br />
● O tipo <strong>de</strong> passagem <strong>de</strong> parâmetros utilizado é por<br />
referência. Ou seja, são passados os en<strong>de</strong>reços das<br />
variáveis a, b, e c para os ponteiros x, y e z.<br />
Escopo: função main<br />
a<br />
b<br />
c<br />
1<br />
2<br />
3<br />
F000<br />
F010<br />
F020<br />
Escopo: função alterar<br />
x<br />
y<br />
z<br />
F000<br />
F010<br />
F020<br />
*x++ é a++<br />
*y++ é b++<br />
*z++ é c++<br />
2<br />
3<br />
4<br />
Altera os<br />
conteúdos<br />
<strong>de</strong> a, b e c!<br />
10
<strong>Passagem</strong> por referência<br />
• Atenção!<br />
Consi<strong>de</strong>re que o en<strong>de</strong>reço <strong>de</strong> x é FFF1.<br />
Neste caso, teremos:<br />
Logo:<br />
Portanto:<br />
int x = 1;<br />
int *a;<br />
a = &x;<br />
a = FFF1 (en<strong>de</strong>reço <strong>de</strong> x)<br />
*a = 1 (pois *a = x = 1)<br />
&(*a) = &x = FFF1 = a<br />
&(*a) ≡ a<br />
11
Problema 1<br />
● Implementar uma calculadora para fazer operações sobre<br />
frações (ex: 1/3, 5/13 etc). A calculadora <strong>de</strong>ve ser capaz<br />
<strong>de</strong> realizar as seguintes operações:<br />
● somar<br />
● dividir<br />
● subtrair<br />
● multiplicar<br />
● simplificar<br />
12
Análise do programa<br />
13
Análise do programa<br />
confuso e com muitos parâmetros!<br />
14
Análise do programa<br />
Define um novo tipo <strong>de</strong><br />
dados. O tipo frac!<br />
O novo tipo po<strong>de</strong> ser<br />
usado nos parâmetros<br />
das funções<br />
15
Definição <strong>de</strong> novos tipos <strong>de</strong> dados<br />
● Se cada fração compreen<strong>de</strong> dois inteiros, como é possível<br />
fazer uma função para somar duas frações passando<br />
apenas dois parâmetros?<br />
● Isto é possível porque a linguagem C permite a <strong>de</strong>finição<br />
<strong>de</strong> novos tipos <strong>de</strong> dados com base nos tipos primitivos:<br />
char, int, float e double.<br />
● Estes novos tipos <strong>de</strong> dados, formados a partir dos tipos<br />
primitivos são chamados <strong>de</strong> tipos estruturados.<br />
16
Definição <strong>de</strong> novos tipos <strong>de</strong> dados<br />
● Uma variável <strong>de</strong> um <strong>de</strong>terminado tipo estruturado <strong>de</strong>finido<br />
pelo usuário é comumente chamada <strong>de</strong> uma estrutura.<br />
● Uma estrutura agrupa várias variáveis <strong>de</strong> diversos tipos<br />
em uma só variável.<br />
● Para criar uma estrutura usa-se o comando struct:<br />
struct nome_da_estrutura<br />
{<br />
tipo_1 variavel_1;<br />
...<br />
tipo_n variavel_n;<br />
};<br />
As variáveis que compõem<br />
a estrutura são chamadas<br />
<strong>de</strong> campos da estrutura.<br />
17
Definição <strong>de</strong> novos tipos <strong>de</strong> dados<br />
● Exemplos:<br />
struct ponto<br />
{<br />
float coord_x;<br />
float coord_y;<br />
};<br />
struct circulo<br />
{<br />
float raio;<br />
struct ponto centro;<br />
};<br />
struct cilindro<br />
{<br />
float altura;<br />
struct circulo base;<br />
};<br />
A <strong>de</strong>claração <strong>de</strong> variáveis <strong>de</strong> um<br />
tipo estruturado (estruturas) é feita<br />
da mesma forma que para um tipo<br />
simples.<br />
18
Definição <strong>de</strong> novos tipos <strong>de</strong> dados<br />
● Para se acessar os campos <strong>de</strong> uma estrutura, basta<br />
separar o nome da variável pelo símbolo ponto ( . ).<br />
● Para os exemplos anteriores:<br />
struct ponto<br />
{<br />
float coord_x;<br />
float coord_y;<br />
};<br />
struct circulo<br />
{<br />
float raio;<br />
struct ponto centro;<br />
};<br />
struct cilindro<br />
{<br />
float altura;<br />
struct circulo base;<br />
};<br />
struct cilindro d;<br />
d.altura = 3.0;<br />
d.base.raio = 5.5;<br />
d.base.centro.coord_x = 1.2;<br />
d.base.centro.coord_y = 3.8;<br />
19
O comando type<strong>de</strong>f<br />
● O Comando type<strong>de</strong>f permite ao programador <strong>de</strong>finir um<br />
novo nome para um <strong>de</strong>terminado tipo.<br />
● Sua forma geral é:<br />
● Exemplo:<br />
type<strong>de</strong>f nome_antigo nome_novo;<br />
Dando o nome inteiro para o tipo int:<br />
type<strong>de</strong>f int inteiro;<br />
inteiro num;<br />
20
O comando type<strong>de</strong>f<br />
● O comando type<strong>de</strong>f também po<strong>de</strong> ser utilizado para dar<br />
nome a tipos complexos como estruturas.<br />
● Exemplos:<br />
type<strong>de</strong>f struct tipo_en<strong>de</strong>reco<br />
{<br />
char rua[50];<br />
int numero;<br />
char bairro[20];<br />
char cida<strong>de</strong>[30];<br />
char sigla_estado[3];<br />
long int CEP;<br />
} TEn<strong>de</strong>reco;<br />
type<strong>de</strong>f struct frac<br />
{<br />
int num;<br />
int <strong>de</strong>n;<br />
} frac;<br />
Exemplo do programa p22.c<br />
21
O comando type<strong>de</strong>f<br />
• Observação:<br />
Utilizando-se o comando struct juntamente com o<br />
comando type<strong>de</strong>f, po<strong>de</strong>-se dispensar o uso da palavra<br />
struct na <strong>de</strong>claração da variável.<br />
● Exemplos:<br />
type<strong>de</strong>f struct ponto<br />
{<br />
float x;<br />
float y;<br />
} ponto;<br />
type<strong>de</strong>f struct circulo<br />
{<br />
float raio;<br />
ponto centro;<br />
} circulo;<br />
type<strong>de</strong>f struct cilindro<br />
{<br />
float altura;<br />
circulo base;<br />
} cilindro;<br />
22
<strong>Estruturas</strong> como parâmetros <strong>de</strong> funções<br />
● Funciona como qualquer outro tipo <strong>de</strong> variável<br />
type<strong>de</strong>f struct ponto<br />
{<br />
float x;<br />
float y;<br />
} ponto;<br />
float distancia_pontos(ponto p1, ponto p2) {<br />
float parte1 = pow(p1.x - p2.x,2);<br />
float parte2 = pow(p1.y - p2.y,2);<br />
return sqrt(parte1 + parte2);<br />
}<br />
void main() {<br />
ponto u, v;<br />
scanf("%f %f %f %f", &u.x, &u.y, &v.x, &v.y);<br />
printf("\n %f", distancia_pontos(u,v));<br />
}<br />
23
<strong>Estruturas</strong> como parâmetros <strong>de</strong> funções<br />
● E como faço para passar estruturas por referência?<br />
void le_coor<strong>de</strong>nada(ponto *p1) {<br />
float x, y;<br />
printf("Digite a coor<strong>de</strong>nada x e y\n");<br />
scanf("%f %f", &x, &y);<br />
p1->x = x;<br />
p1->y = y;<br />
}<br />
void main() {<br />
ponto u, v;<br />
le_coor<strong>de</strong>nada(&u);<br />
le_coor<strong>de</strong>nada(&v);<br />
printf("\n %f", distancia_pontos(u,v));<br />
getch();<br />
}<br />
24
<strong>Estruturas</strong> como parâmetros <strong>de</strong> funções<br />
void main() {<br />
ponto u, v;<br />
le_coor<strong>de</strong>nada(&u);<br />
le_coor<strong>de</strong>nada(&v);<br />
printf("\n %f", distancia_pontos(u,v));<br />
getch();<br />
}<br />
en<strong>de</strong>reço variável conteúdo<br />
F000 u | x<br />
F010 u | y<br />
F020 v | x<br />
F030 v | y<br />
F040<br />
F050<br />
F060<br />
F070<br />
25
<strong>Estruturas</strong> como parâmetros <strong>de</strong> funções<br />
void le_coor<strong>de</strong>nada(ponto *p1) {<br />
float x, y;<br />
printf("Digite a coor<strong>de</strong>nada x e y\n");<br />
scanf("%f %f", &x, &y);<br />
p1->x = x;<br />
p1->y = y;<br />
}<br />
en<strong>de</strong>reço variável conteúdo<br />
F000 u | x<br />
F010 u | y<br />
F020 v | x<br />
F030 v | y<br />
F040 p1 F000<br />
F050 x 1.5<br />
F060 y 2.0<br />
F070<br />
le_coor<strong>de</strong>nada(&u);<br />
26
<strong>Estruturas</strong> como parâmetros <strong>de</strong> funções<br />
void le_coor<strong>de</strong>nada(ponto *p1) {<br />
float x, y;<br />
printf("Digite a coor<strong>de</strong>nada x e y\n");<br />
scanf("%f %f", &x, &y);<br />
p1->x = x;<br />
p1->y = y;<br />
}<br />
en<strong>de</strong>reço variável conteúdo<br />
F000 u | x<br />
F010 u | y<br />
F020 v | x<br />
F030 v | y<br />
F040 p1 F000<br />
F050 x 1.5<br />
F060 y 2.0<br />
F070<br />
le_coor<strong>de</strong>nada(&u);<br />
Similar a vetores, &u<br />
dá o en<strong>de</strong>reço inicial<br />
que a estrutura está<br />
armazenada<br />
27
<strong>Estruturas</strong> como parâmetros <strong>de</strong> funções<br />
void le_coor<strong>de</strong>nada(ponto *p1) {<br />
float x, y;<br />
printf("Digite a coor<strong>de</strong>nada x e y\n");<br />
scanf("%f %f", &x, &y);<br />
p1->x = x;<br />
p1->y = y;<br />
}<br />
en<strong>de</strong>reço variável conteúdo<br />
F000 u | x 1.5<br />
F010 u | y 2.0<br />
F020 v | x<br />
F030 v | y<br />
F040 p1 F000<br />
F050 x 1.5<br />
F060 y 2.0<br />
F070<br />
le_coor<strong>de</strong>nada(&u);<br />
28
<strong>Estruturas</strong> como parâmetros <strong>de</strong> funções<br />
void le_coor<strong>de</strong>nada(ponto *p1) {<br />
float x, y;<br />
printf("Digite a coor<strong>de</strong>nada x e y\n");<br />
scanf("%f %f", &x, &y);<br />
p1->x = x;<br />
p1->y = y;<br />
}<br />
en<strong>de</strong>reço variável conteúdo<br />
F000 u | x 1.5<br />
F010 u | y 2.0<br />
F020 v | x 30.0<br />
F030 v | y 25.5<br />
F040 p1 F020<br />
F050 x 30.0<br />
F060 y 25.5<br />
F070<br />
le_coor<strong>de</strong>nada(&v);<br />
29
<strong>Estruturas</strong> como parâmetros <strong>de</strong> funções<br />
void main() {<br />
ponto u, v;<br />
le_coor<strong>de</strong>nada(&u);<br />
le_coor<strong>de</strong>nada(&v);<br />
printf("\n %f", distancia_pontos(u,v));<br />
getch();<br />
}<br />
en<strong>de</strong>reço variável conteúdo<br />
F000 u | x 1.5<br />
F010 u | y 2.0<br />
F020 v | x 30.0<br />
F030 v | y 25.5<br />
F040<br />
F050<br />
F060<br />
F070<br />
30