26.07.2013 Views

Passagem de Parâmetros e Estruturas

Passagem de Parâmetros e Estruturas

Passagem de Parâmetros e Estruturas

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!