Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações...

78
Capítulo VIII – Capítulo VIII – Subprogramação Subprogramação 8.1 – Introdução 8.1 – Introdução 8.2 – Escopo de validade de 8.2 – Escopo de validade de declarações declarações 8.3 – Parâmetros e passagem de 8.3 – Parâmetros e passagem de argumentos argumentos 8.4 – Prototipação de subprogramas 8.4 – Prototipação de subprogramas 8.5 – Classes de alocação 8.5 – Classes de alocação 8.6 – Recursividade 8.6 – Recursividade

Transcript of Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações...

Page 1: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Capítulo VIII – Capítulo VIII – SubprogramaçãoSubprogramação

8.1 – Introdução8.1 – Introdução

8.2 – Escopo de validade de declarações8.2 – Escopo de validade de declarações

8.3 – Parâmetros e passagem de 8.3 – Parâmetros e passagem de argumentosargumentos

8.4 – Prototipação de subprogramas8.4 – Prototipação de subprogramas

8.5 – Classes de alocação8.5 – Classes de alocação

8.6 – Recursividade8.6 – Recursividade

Page 2: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.3 – Parâmetros e 8.3 – Parâmetros e Passagem de ArgumentosPassagem de Argumentos

8.3.1 – Importância do uso de parâmetros8.3.1 – Importância do uso de parâmetros

É comum É comum subprogramassubprogramas atuarem sobre um atuarem sobre um determinado determinado valorvalor ou uma determinada ou uma determinada variávelvariável para produzir um para produzir um resultadoresultado ou realizar uma ou realizar uma tarefatarefa

Exemplos:Exemplos:

Calcular o Calcular o fatorialfatorial do valor guardado numa do valor guardado numa variávelvariável

OrdenarOrdenar os elementos de um vetor os elementos de um vetor TrocarTrocar os valores de duas variáveis entre si os valores de duas variáveis entre si

Page 3: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Variáveis globaisVariáveis globais poderiam ser usadas poderiam ser usadas

Nos exemplos anteriores:Nos exemplos anteriores:

O valor cujo O valor cujo fatorialfatorial se deseja estaria numa se deseja estaria numa variável globalvariável global

O O vetorvetor a ser ordenado seria a ser ordenado seria globalglobal As variáveis para a As variáveis para a troca de valorestroca de valores seriam seriam

também globaistambém globais

■ Mas, e se forem Mas, e se forem muitos(as)muitos(as)::

As As variáveisvariáveis ou as ou as expressõesexpressões das quais se das quais se quer calcular o fatorial?quer calcular o fatorial?

Os Os vetoresvetores a serem ordenados? a serem ordenados? Os Os pares de variáveispares de variáveis a trocarem entre si a trocarem entre si

seus valores?seus valores?

Antes de cada chamada, as variáveis globais deveriam ser carregadas com os alvos do subprograma

Incômodo!!!

Page 4: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Para Para evitar esse carregamentoevitar esse carregamento a cada chamada, a cada chamada, usam-se usam-se parâmetros e argumentosparâmetros e argumentos

Como já foi visto, na Como já foi visto, na chamadachamada de um de um subprograma, os valores dos subprograma, os valores dos argumentosargumentos são são calculados e armazenados cada um em seu calculados e armazenados cada um em seu respectivo respectivo parâmetroparâmetro

ParâmetroParâmetro é uma variável local é uma variável local especial especial de um de um subprograma, também subprograma, também automáticaautomática, distinta de , distinta de suas outras variáveis locais suas outras variáveis locais

O O subprogramasubprograma então realiza sua tarefa, então realiza sua tarefa, atuandoatuando diretamente sobre seus diretamente sobre seus parâmetrosparâmetros

O programa do número de O programa do número de combinaçõescombinações usa usa parâmetros e argumentos, parâmetros e argumentos, dispensando variáveis dispensando variáveis globaisglobais

Page 5: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.3.2 – Modos de passagem de argumentos8.3.2 – Modos de passagem de argumentos

As As linguagens tradicionaislinguagens tradicionais de programação de programação apresentam dois importantes modos de apresentam dois importantes modos de passagem passagem de argumentosde argumentos aos respectivos aos respectivos parâmetrosparâmetros::

Passagem por valorPassagem por valor Passagem por referênciaPassagem por referência

Passagem por valor:Passagem por valor: o argumento é o o argumento é o valorvalor de de uma uma expressãoexpressão ou de uma ou de uma variávelvariável, valor esse , valor esse calculado e carregado no calculado e carregado no parâmetroparâmetro

Passagem por referênciaPassagem por referência: o argumento deve ser : o argumento deve ser uma uma variávelvariável, sendo que o respectivo , sendo que o respectivo parâmetroparâmetro é é alocado coincidindo com o alocado coincidindo com o endereçoendereço da mesma da mesma

Page 6: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Exemplo: passagem de argumentos em Exemplo: passagem de argumentos em PascalPascal

program ppp;program ppp;

var a, b: integer;var a, b: integer;

procedure xxx (x: integer; var y: integer);procedure xxx (x: integer; var y: integer);

beginbegin

x := x + 3; y := y + x;x := x + 3; y := y + x;

end;end;

beginbegin

a := 10; b := 20;a := 10; b := 20;

xxx (a, b);xxx (a, b);

write (“a = ”, a, “write (“a = ”, a, “; ; b = ”, b);b = ”, b);

end.end.

Comandos do programa ppp

Procedimento xxx embutido em ppp

A palavra var antes da declaração de y sinaliza que a passagem é por referência

Page 7: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Seja a execução deste programa:Seja a execução deste programa:

program ppp;program ppp;

var a, b: integer;var a, b: integer;

procedure xxx (x: integer; var y: integer);procedure xxx (x: integer; var y: integer);

beginbegin

x := x + 3; y := y + x;x := x + 3; y := y + x;

end;end;

beginbegin

a := 10; b := 20;a := 10; b := 20;

xxx (a, b);xxx (a, b);

write (“a = ”, a, “write (“a = ”, a, “; ; b = ”, b);b = ”, b);

end.end.

?a

?b

Page 8: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

program ppp;program ppp;

var a, b: integer;var a, b: integer;

procedure xxx (x: integer; var y: integer);procedure xxx (x: integer; var y: integer);

beginbegin

x := x + 3; y := y + x;x := x + 3; y := y + x;

end;end;

beginbegin

a := 10; b := 20;a := 10; b := 20;

xxx (a, b);xxx (a, b);

write (“a = ”, a, “write (“a = ”, a, “; ; b = ”, b);b = ”, b);

end.end.

?a

?b

10a

20b

Page 9: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Chamada da procedure xxx:Chamada da procedure xxx:

program ppp;program ppp;

var a, b: integer;var a, b: integer;

procedure xxx (x: integer; var y: integer);procedure xxx (x: integer; var y: integer);

beginbegin

x := x + 3; y := y + x;x := x + 3; y := y + x;

end;end;

beginbegin

a := 10; b := 20;a := 10; b := 20;

xxx (a, b);xxx (a, b);

write (“a = ”, a, “write (“a = ”, a, “; ; b = ”, b);b = ”, b);

end.end.

10a

20b

Page 10: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Alocação dos parâmetros e passagem de Alocação dos parâmetros e passagem de argumentos:argumentos:

program ppp;program ppp;

var a, b: integer;var a, b: integer;

procedure xxx (x: integer; var y: integer);procedure xxx (x: integer; var y: integer);

beginbegin

x := x + 3; y := y + x;x := x + 3; y := y + x;

end;end;

beginbegin

a := 10; b := 20;a := 10; b := 20;

xxx (a, b);xxx (a, b);

write (“a = ”, a, “write (“a = ”, a, “; ; b = ”, b);b = ”, b);

end.end.

10a

20b

x10x

y

O valor de a foi copiado em x

A variável y foi alocada coincidindo com b

Page 11: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

program ppp;program ppp;

var a, b: integer;var a, b: integer;

procedure xxx (x: integer; var y: integer);procedure xxx (x: integer; var y: integer);

beginbegin

x := x + 3;x := x + 3; y := y + x; y := y + x;

end;end;

beginbegin

a := 10; b := 20;a := 10; b := 20;

xxx (a, b);xxx (a, b);

write (“a = ”, a, “write (“a = ”, a, “; ; b = ”, b);b = ”, b);

end.end.

10a

20b

x10x

y

Page 12: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

program ppp;program ppp;

var a, b: integer;var a, b: integer;

procedure xxx (x: integer; var y: integer);procedure xxx (x: integer; var y: integer);

beginbegin

x := x + 3;x := x + 3; y := y + x; y := y + x;

end;end;

beginbegin

a := 10; b := 20;a := 10; b := 20;

xxx (a, b);xxx (a, b);

write (“a = ”, a, “write (“a = ”, a, “; ; b = ”, b);b = ”, b);

end.end.

10a

20b

x13x

y

Page 13: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

program ppp;program ppp;

var a, b: integer;var a, b: integer;

procedure xxx (x: integer; var y: integer);procedure xxx (x: integer; var y: integer);

beginbegin

x := x + 3; x := x + 3; y := y + x;y := y + x;

end;end;

beginbegin

a := 10; b := 20;a := 10; b := 20;

xxx (a, b);xxx (a, b);

write (“a = ”, a, “write (“a = ”, a, “; ; b = ”, b);b = ”, b);

end.end.

10a

20b

x13x

y

Page 14: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

program ppp;program ppp;

var a, b: integer;var a, b: integer;

procedure xxx (x: integer; var y: integer);procedure xxx (x: integer; var y: integer);

beginbegin

x := x + 3; x := x + 3; y := y + x;y := y + x;

end;end;

beginbegin

a := 10; b := 20;a := 10; b := 20;

xxx (a, b);xxx (a, b);

write (“a = ”, a, “write (“a = ”, a, “; ; b = ”, b);b = ”, b);

end.end.

10a

33b

x13x

y

Page 15: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Desalocação dos parâmetros: Desalocação dos parâmetros:

program ppp;program ppp;

var a, b: integer;var a, b: integer;

procedure xxx (x: integer; var y: integer);procedure xxx (x: integer; var y: integer);

beginbegin

x := x + 3; y := y + x;x := x + 3; y := y + x;

end;end;

beginbegin

a := 10; b := 20;a := 10; b := 20;

xxx (a, b);xxx (a, b);

write (“a = ”, a, “write (“a = ”, a, “; ; b = ”, b);b = ”, b);

end.end.

10a

33b

x13x

y

Page 16: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

program ppp;program ppp;

var a, b: integer;var a, b: integer;

procedure xxx (x: integer; var y: integer);procedure xxx (x: integer; var y: integer);

beginbegin

x := x + 3; y := y + x;x := x + 3; y := y + x;

end;end;

beginbegin

a := 10; b := 20;a := 10; b := 20;

xxx (a, b);xxx (a, b);

write (“a = ”, a, “; b = ”, b);write (“a = ”, a, “; b = ”, b);

end.end.

10a

33b

a = 10; b = 33No vídeo

a não foi alterada (por valor)

b foi alterada (por referência)

Page 17: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Quando se deseja que o argumento Quando se deseja que o argumento sofra alteraçõessofra alterações dentro do subprograma chamado: usar dentro do subprograma chamado: usar passagem passagem por referênciapor referência

Quando o subprograma Quando o subprograma mudar o valormudar o valor de um de um parâmetro, mas parâmetro, mas não se desejanão se deseja que isso que isso altere o altere o valorvalor do argumento de chamada: usar do argumento de chamada: usar passagem passagem por valorpor valor

Quando um subprograma Quando um subprograma não alteranão altera o valor de um o valor de um parâmetroparâmetro, pode-se usar os , pode-se usar os dois tipos de dois tipos de passagempassagem

Se o parâmetro for uma Se o parâmetro for uma variável estruturadavariável estruturada (matriz ou estrutura), pode-se (matriz ou estrutura), pode-se economizareconomizar memória memória usando usando passagem por referênciapassagem por referência

O O parâmetroparâmetro correspondente é alocado numa correspondente é alocado numa região já utilizadaregião já utilizada pelo programa pelo programa

Page 18: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

A A Linguagem CLinguagem C só trabalha com só trabalha com passagem passagem por valorpor valor

A passagem por referência é simulada por A passagem por referência é simulada por argumentos do tipo endereço e parâmetros argumentos do tipo endereço e parâmetros do tipo ponteirodo tipo ponteiro

Isso é visto logo a seguirIsso é visto logo a seguir

Page 19: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.3.3 – Passagem por valor em C8.3.3 – Passagem por valor em C

A A funçãofunção destinada ao cálculo de destinada ao cálculo de fatorialfatorial vista neste capítulo utiliza vista neste capítulo utiliza passagem por passagem por valorvalor

O O valor do argumentovalor do argumento é calculado e é calculado e depositado no depositado no parâmetroparâmetro

Depois da execuçãoDepois da execução, mesmo que função , mesmo que função mudasse o valor desse parâmetro, as mudasse o valor desse parâmetro, as variáveisvariáveis envolvidas no cálculo dos argumentos envolvidas no cálculo dos argumentos não não sofrem alteraçãosofrem alteração

Page 20: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Numa Numa chamada de funçãochamada de função aparece aparece primeiramente seu primeiramente seu nomenome e, a seguir, entre e, a seguir, entre parêntesisparêntesis, sua , sua lista de argumentoslista de argumentos

Essa Essa listalista deverá ser deverá ser vaziavazia se a função se a função não tiver não tiver parâmetrosparâmetros, mas o uso dos , mas o uso dos parêntesisparêntesis é é obrigatório obrigatório

Os Os argumentosargumentos devem ser em devem ser em mesmo númeromesmo número que os parâmetros e devem ser que os parâmetros e devem ser compatíveiscompatíveis com com os mesmosos mesmos

Caso um Caso um argumentoargumento seja o seja o nomenome de uma variável, de uma variável, apenas seu apenas seu valorvalor é transmitido ao parâmetro é transmitido ao parâmetro

DepoisDepois da execução, o da execução, o valorvalor dessa variável não dessa variável não terá sofrido terá sofrido nenhuma alteraçãonenhuma alteração

Page 21: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Exemplo: Exemplo: seja o programaseja o programa

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void ff (int a) {void ff (int a) {

a += 1;a += 1;

printf ("Durante ff, a = %d\n", a);printf ("Durante ff, a = %d\n", a);

}}

void main ( ) {void main ( ) {

int a = 5;int a = 5;

printf ("Antes de ff, a = %d\n", a);printf ("Antes de ff, a = %d\n", a);

ff (a);ff (a);

printf ("Depois de ff, a = %d\n", a);printf ("Depois de ff, a = %d\n", a);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

Antes de ff, a = 5Durante ff, a = 6Depois de ff, a = 5

Digite algo para encerrar:

Resultado

Page 22: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.3.4 – Passagem por referência em C8.3.4 – Passagem por referência em C

Às vezes, é desejável que a variável Às vezes, é desejável que a variável argumentoargumento seja seja alteradaalterada conforme a conforme a mudança sofrida pelo mudança sofrida pelo parâmetroparâmetro correspondentecorrespondente

Ao invés de passar o seu Ao invés de passar o seu valorvalor, passa-se o seu , passa-se o seu endereçoendereço

A seguir, um programa ilustrativo para A seguir, um programa ilustrativo para trocar trocar os valoresos valores de duas variáveis da função de duas variáveis da função mainmain

Page 23: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Exemplo: Exemplo: seja o programaseja o programa

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q){void trocar (int *p, int *q){

int aux;int aux;

aux = *p; *p = *q; *q = aux;aux = *p; *p = *q; *q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

Seja sua execução:

Page 24: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q){void trocar (int *p, int *q){

int aux;int aux;

aux = *p; *p = *q; *q = aux;aux = *p; *p = *q; *q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

3i

8j

Seja sua execução:

Page 25: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q){void trocar (int *p, int *q){

int aux;int aux;

aux = *p; *p = *q; *q = aux;aux = *p; *p = *q; *q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

3i

8j

Page 26: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q)void trocar (int *p, int *q){{

int aux;int aux;

aux = *p; *p = *q; *q = aux;aux = *p; *p = *q; *q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

3i

8j

Chamada de trocar e passagem de argumentos:

p qaux

p e q receberam &i e &j - são ponteiros

Page 27: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q){void trocar (int *p, int *q){

int aux;int aux;

aux = *p;aux = *p; *p = *q; *q = aux; *p = *q; *q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

3i

8j

p qaux

Page 28: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q){void trocar (int *p, int *q){

int aux;int aux;

aux = *p;aux = *p; *p = *q; *q = aux; *p = *q; *q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

3i

8j

p q3

aux

aux recebe conteúdo do local apontado por p (i.é, *p)

Page 29: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q){void trocar (int *p, int *q){

int aux;int aux;

aux = *p; aux = *p; *p = *q;*p = *q; *q = aux; *q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

3i

8j

p q3

aux

Page 30: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q){void trocar (int *p, int *q){

int aux;int aux;

aux = *p; aux = *p; *p = *q;*p = *q; *q = aux; *q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

8i

8j

p q3

aux

*p recebe conteúdo do local apontado por q (*q)

Page 31: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q){void trocar (int *p, int *q){

int aux;int aux;

aux = *p; *p = *q; aux = *p; *p = *q; *q = aux;*q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

8i

8j

p q3

aux

Page 32: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q){void trocar (int *p, int *q){

int aux;int aux;

aux = *p; *p = *q; aux = *p; *p = *q; *q = aux;*q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

8i

3j

p q3

aux

*q recebe conteúdo de aux

Page 33: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q){void trocar (int *p, int *q){

int aux;int aux;

aux = *p; *p = *q; *q = aux;aux = *p; *p = *q; *q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

8i

3j

p q3

aux

Desalocação das variáveis de Trocar:

Page 34: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

void trocar (int *p, int *q){void trocar (int *p, int *q){

int aux;int aux;

aux = *p; *p = *q; *q = aux;aux = *p; *p = *q; *q = aux;

}}

int main ( ) {int main ( ) {

int i = 3, j = 8;int i = 3, j = 8;

printf ("Antes de trocar, i = %d; j = %d\n", i, j);printf ("Antes de trocar, i = %d; j = %d\n", i, j);

trocar(&i, &j);trocar(&i, &j);

printf ("Depois de trocar, i = %d; j = %d\n", i, j);printf ("Depois de trocar, i = %d; j = %d\n", i, j);

printf("\n\Digite algo para encerrar: ");printf("\n\Digite algo para encerrar: ");

getch();getch();

}}

8i

3j

Antes de trocar, i = 3; j = 8Depois de trocar, i = 8; j = 3

Digite algo para encerrar:

Resultado

Page 35: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Exercícios 8.3:Exercícios 8.3:

1.1.Dado o programa ao Dado o programa ao lado contendo lado contendo variáveis globais, variáveis globais, locais e funções locais e funções com passagem de com passagem de argumentos por argumentos por valor e por valor e por referência, mostrar referência, mostrar o que será escrito o que será escrito no vídeo pela sua no vídeo pela sua execuçãoexecução

#include <stdio.h>int i = 58, j = 49;void gg (int i, int j, int k, int m) { printf ("%7d%7d%7d%7d\n\n", i, j, k, m);}void ff (int p, int q, int *r, int *s) { int k, m; gg (p, q, *r, *s); k = 100; m = 200; p = -1; q = -2; *r = -3; *s = -4; gg (i, j, k, m); gg (p, q, *r, *s);}main () { int i, j, k, m; i = 10; j = 20; k = 30; m = 40; gg (i, j, k, m); { int j, k; i = 1; j = 2; k = 3; m = 4; gg (i, j, k, m); ff (i, j, &k, &m); } gg (i, j, k, m);}

Page 36: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

2.2. A conjectura de Goldbach diz que todo número A conjectura de Goldbach diz que todo número inteiro, par, maior que 2, é a soma de dois inteiro, par, maior que 2, é a soma de dois números primos. Computadores têm sido muito números primos. Computadores têm sido muito usados para testar essa conjectura e nenhum usados para testar essa conjectura e nenhum contra-exemplo foi encontrado até agora.contra-exemplo foi encontrado até agora.

a)a) Escrever uma função que receba como Escrever uma função que receba como argumento por valor um número inteiro positivo argumento por valor um número inteiro positivo e que retorne e que retorne 11, se tal número for primo, ou , se tal número for primo, ou então então zerozero, em caso contrário. , em caso contrário.

b)b) Escrever um programa principal para comprovar Escrever um programa principal para comprovar que tal conjectura é verdadeira dentro de um que tal conjectura é verdadeira dentro de um intervalo lido, no campo dos inteiros maiores que intervalo lido, no campo dos inteiros maiores que 2, usando obrigatoriamente como subprograma a 2, usando obrigatoriamente como subprograma a função elaborada no item função elaborada no item a a deste exercício. Por deste exercício. Por exemplo, se o intervalo lido for [700, 1100], o exemplo, se o intervalo lido for [700, 1100], o programa pedido deve ser produzir no vídeo um programa pedido deve ser produzir no vídeo um resultado semelhante ao do próximo slideresultado semelhante ao do próximo slide

Page 37: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

No intervalo [ 700, 1100 ], todo número par é a soma de No intervalo [ 700, 1100 ], todo número par é a soma de dois primos, a saber:dois primos, a saber:

  

700 = 17 + 683700 = 17 + 683

702 = 11 + 691702 = 11 + 691

704 = 3 + 701704 = 3 + 701

. . . . . . .. . . . . . .

1098 = 5 + 10931098 = 5 + 1093

1100 = 3 + 10971100 = 3 + 1097

Page 38: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Capítulo VIII – Capítulo VIII – SubprogramaçãoSubprogramação

8.1 – Introdução8.1 – Introdução

8.2 – Escopo de validade de declarações8.2 – Escopo de validade de declarações

8.3 – Parâmetros e passagem de 8.3 – Parâmetros e passagem de argumentosargumentos

8.4 – Prototipação de subprogramas8.4 – Prototipação de subprogramas

8.5 – Classes de alocação8.5 – Classes de alocação

8.6 – Recursividade8.6 – Recursividade

Page 39: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.4 – Prototipação de 8.4 – Prototipação de SubprogramasSubprogramas

Nos programas em C, Nos programas em C, funçõesfunções devem ser devem ser declaradasdeclaradas antes de serem invocadasantes de serem invocadas

Há uma Há uma diferençadiferença entre entre declarardeclarar e e definirdefinir uma uma funçãofunção

Declarar:Declarar: dizer o dizer o nomenome da função, o da função, o tipotipo de seus de seus parâmetrosparâmetros e o e o tipotipo do valor por ela do valor por ela retornadoretornado

Definir:Definir: programar a função, ou seja, programar a função, ou seja, declarádeclará-la, -la, estabelecer suas estabelecer suas declaraçõesdeclarações locais e seus locais e seus comandoscomandos

Até agora: Até agora: declaraçãodeclaração das funções no das funções no ato de sua ato de sua definiçãodefinição

Page 40: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Há situações em que é Há situações em que é interessanteinteressante ou até ou até necessárionecessário que uma função seja que uma função seja invocada invocada antes de ser definidaantes de ser definida

É o caso de É o caso de programas recursivosprogramas recursivos, que são , que são assuntos do último tópico deste capítulo assuntos do último tópico deste capítulo

Exemplo: recursividade indireta:

- F2 invoca F1

- F1 invoca F2 antes da declaração de F2

- O compilador não aceitará

- Invertidas as funções, o problema continua

- - - - -int F1 (int a, float x) {

- - - - -chamada de F2()- - - - -

}int F2 (float y, char c ) {

- - - - -chamada de F1()- - - - -

}

Page 41: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Solução: Protótipos para funções

Protótipo de uma função: é a declaração da função feita separadamente de sua definição

No ponto em que F1 invoca F2, essa última já está declarada acima

Não é necessário colocar os nomes dos parâmetros, mas somente os tipos

Na definição, todos os tipos devem ser os mesmos do protótipo

- - - - -int F1 (int a, float x) {

- - - - -chamada de F2()- - - - -

}int F2 (float y, char c ) {

- - - - -chamada de F1()- - - - -

}

int F2 (float, char);- - - - -- - - - -- - - - -int F1 (int a, float x) {

- - - - -chamada de F2()- - - - -

}int F2 (float y, char c ) {

- - - - -chamada de F1()- - - - -

}

Forma geral de um protótipo:

Tipo Nome (lista dos tipos dos parâmetros);

Page 42: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

ProtótiposProtótipos para as funções usadas nos para as funções usadas nos programas programas deste capítulodeste capítulo: :

int fat (int);int fat (int); void sss (void); void sss (void); void ff (void);void ff (void); void ff (int);void ff (int); void trocar (int *, int *);void trocar (int *, int *);

Quando a função Quando a função não tem parâmetrosnão tem parâmetros, , coloca-se coloca-se void void entre parêntesisentre parêntesis

Quando o parâmetro é um Quando o parâmetro é um ponteiroponteiro, coloca-se , coloca-se o asterisco o asterisco ‘*’‘*’ depois do tipo depois do tipo

Page 43: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Pode-se adquirir o Pode-se adquirir o hábitohábito de fazer de fazer protótipos para protótipos para todas a funções todas a funções auxiliaresauxiliares dos programas dos programas

Eles podem ser Eles podem ser colocados colocados no iníciono início, juntamente com , juntamente com as as declarações globaisdeclarações globais

Então a Então a ordem das ordem das definições das funçõesdefinições das funções pode ser pode ser qualquerqualquer Programa

Diretivas de pré-

processamento

Declarações globais

Funções auxiliares

Funçãomain

Protótipos das funções

Page 44: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Pode-se Pode-se organizarorganizar o o programa de forma a colocar programa de forma a colocar primeiramenteprimeiramente a função a função mainmain

Depois vêm aquelas Depois vêm aquelas invocadas pela invocadas pela mainmain; depois, ; depois, aquelas invocadas por essas aquelas invocadas por essas últimasúltimas

E assim por dianteE assim por diante

Essa ordenação é Essa ordenação é interessante ao se utilizar a interessante ao se utilizar a metodologia metodologia top-downtop-down para para o desenvolvimento de o desenvolvimento de programasprogramas

Programa

Diretivas de pré-

processamento

Declarações globais

Função main

Funções auxiliares

Protótipos das funções

No capítulo sobre ponteiros serão vistos protótipos de funções com parâmetros do tipo variáveis indexadas, estruturas e funções

Page 45: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Capítulo VIII – Capítulo VIII – SubprogramaçãoSubprogramação

8.1 – Introdução8.1 – Introdução

8.2 – Escopo de validade de declarações8.2 – Escopo de validade de declarações

8.3 – Parâmetros e passagem de 8.3 – Parâmetros e passagem de argumentosargumentos

8.4 – Prototipação de subprogramas8.4 – Prototipação de subprogramas

8.5 – Classes de alocação8.5 – Classes de alocação

8.6 – Recursividade8.6 – Recursividade

Page 46: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.5 – Classes de Alocação8.5 – Classes de Alocação

8.5.1 - Generalidades8.5.1 - Generalidades

Toda variável e função em C tem, além do Toda variável e função em C tem, além do tipotipo, , outro outro atributoatributo, relacionado com a forma de , relacionado com a forma de ser ser alocadaalocada durante a execução do programa durante a execução do programa

Esse atributo é a Esse atributo é a classe de alocaçãoclasse de alocação

Page 47: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Há 4 Há 4 classes de alocaçãoclasses de alocação de variáveis e funções, de variáveis e funções, a saber: a saber:

variáveis automáticas, externas, estáticas e em variáveis automáticas, externas, estáticas e em registradoresregistradores

As palavras reservadas para elas são As palavras reservadas para elas são respectivamenterespectivamente

autoauto, , externextern, , staticstatic e e registerregister..

Essas palavras são colocadas Essas palavras são colocadas antes do tipoantes do tipo, numa , numa declaraçãodeclaração de variáveis e função de variáveis e função

Exemplos:Exemplos:

extern int i;extern int i; static float a; static float a; register register int j;int j;

Page 48: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Como já visto, as Como já visto, as variáveis automáticasvariáveis automáticas só só ocupam espaço na memória quando seu ocupam espaço na memória quando seu bloco bloco de declaração está no arde declaração está no ar

Todas as Todas as variáveis locaisvariáveis locais vistas até agora neste vistas até agora neste capítulo são capítulo são automáticasautomáticas

Quando Quando não se especificanão se especifica a classe de uma a classe de uma variável local, o compilador entende que ela é variável local, o compilador entende que ela é automáticaautomática

Então, como já foi visto: Então, como já foi visto:

int a, b; int a, b; equivale a equivale a auto int a, b; auto int a, b;

Por essa razão, a palavra reservada Por essa razão, a palavra reservada autoauto é é raramente usada nos programasraramente usada nos programas

Page 49: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.5.2 – Variáveis externas8.5.2 – Variáveis externas

Em C, toda variável declarada Em C, toda variável declarada fora do escopofora do escopo de qualquer função, ou seja, toda de qualquer função, ou seja, toda variável variável globalglobal, pertence à classe das , pertence à classe das variáveis variáveis externasexternas

Ela Ela ocupa espaçoocupa espaço de memória durante de memória durante toda a toda a execuçãoexecução do programa do programa

A palavra A palavra externextern pode ser usada em sua pode ser usada em sua declaração, mas na maioria dos casos é declaração, mas na maioria dos casos é dispensáveldispensável

Se Se int a = 1; int a = 1; for uma declaração global for uma declaração global então ela equivale aentão ela equivale a extern int extern int a = 1;a = 1;

Page 50: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

O principal uso da palavra O principal uso da palavra extern extern se dá em se dá em programas programas divididos em mais de um divididos em mais de um arquivoarquivo

Muitas vezes é desejável Muitas vezes é desejável compilarcompilar cada cada arquivo arquivo separadamenteseparadamente

Exemplo: seja o programa a seguir, dividido em Exemplo: seja o programa a seguir, dividido em dois arquivos dois arquivos arq1.c arq1.c e e arq2.carq2.c

#include <stdio.h>#include <conio.h>#include "arq2.c"int a = 1, b = 2, c = 3;void main ( ) { printf ("%3d\n", f( )); printf ("%3d%3d%3d\n", a, b, c); getch();}

int f () { extern int a; int b, c; a = b = c = 4; return (a + b + c);}

arq1.c

arq2.c

Page 51: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Na Na compilação separadacompilação separada do arquivo do arquivo arq2.carq2.c, , a declaração a declaração

extern intextern int a; a;

indica que a variável indica que a variável aa é é globalglobal e está e está declarada em declarada em outro arquivooutro arquivo

Para uma Para uma compilação conjuntacompilação conjunta, esta , esta declaração é declaração é dispensáveldispensável

#include <stdio.h>#include <conio.h>#include "arq2.c"int a = 1, b = 2, c = 3;void main ( ) { printf ("%3d\n", f()); printf ("%3d%3d%3d\n", a, b, c); getch();}

int f () { extern int a; int b, c; a = b = c = 4; return (a + b + c);}

arq1.c

arq2.c

12 4 2 3

Novídeo

Page 52: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

A habilidade em A habilidade em compilarcompilar arquivos arquivos separadamenteseparadamente é importante ao ser escrever é importante ao ser escrever grandes programasgrandes programas

O O código-fontecódigo-fonte desses programas costuma ser desses programas costuma ser organizado em organizado em diversos arquivosdiversos arquivos

Cada arquivo pode conter uma ou mais Cada arquivo pode conter uma ou mais funçõesfunções, , ou somente ou somente declarações globaisdeclarações globais, ou , ou protótiposprotótipos de funções, etc. de funções, etc.

Ocorrendo Ocorrendo erros de compilaçãoerros de compilação, só os , só os arquivos arquivos com erroscom erros precisam ser precisam ser re-compiladosre-compilados

Os Os arquivos corretosarquivos corretos são são dispensadosdispensados disso e, disso e, sendo numerosos, sendo numerosos, ganha-se tempoganha-se tempo com essa com essa dispensadispensa

Page 53: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.5.3 – Comunicação entre funções8.5.3 – Comunicação entre funções

FunçõesFunções se se comunicamcomunicam entre si através de entre si através de variáveis globaisvariáveis globais, parâmetros por , parâmetros por valorvalor, , parâmetros por parâmetros por referênciareferência e valores e valores retornadosretornados

int a;

void main () {int b, c, d;a = 10; b = 20; c =

30;d = ff (b, &c);printf (“- - -”, a, b,

c, d);}

int ff (int x, int *y) {int z;z = x + a + *y;a = 1; *y = 2;return z;

}

a

b c

d

x y z

Exemplo

Page 54: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Variáveis globais: Variáveis globais: comunicação nos comunicação nos 2 2 sentidossentidos

Parâmetros por valor: Parâmetros por valor: da da invocadorainvocadora para a para a invocadainvocada

Parâmetros por referência: Parâmetros por referência: comunicação nos comunicação nos 2 sentidos2 sentidos

Valores retornados: Valores retornados: da da invocadainvocada para a para a invocadorainvocadoraint a;

void main () {int b, c, d;a = 10; b = 20; c =

30;d = ff (b, &c);printf (“- - -”, a, b,

c, d);}

int ff (int x, int *y) {int z;z = x + a + *y;a = 1; *y = 2;return z;

}

a

b c

d

x y z

retorno

Page 55: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Variáveis globaisVariáveis globais dificultam a dificultam a modularidademodularidade e e portabilidadeportabilidade das funções das funções

ParâmetrosParâmetros e e valores retornadosvalores retornados são são decididamente decididamente preferíveispreferíveis quando isso é quando isso é desejadodesejado

Analogia: aparelho de som para automóveisAnalogia: aparelho de som para automóveis

Má portabilidade: Má portabilidade: com com muitos cabosmuitos cabos elétricos elétricos do carrodo carro a ele conectados, haverá a ele conectados, haverá dificuldade para dificuldade para retirá-loretirá-lo e colocá-lo em e colocá-lo em outro carrooutro carro

Boa portabilidade: Boa portabilidade: se se não houver cabosnão houver cabos a a ele conectados,ele conectados, essa dificuldade é essa dificuldade é nulanula

Page 56: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Uma função com Uma função com variáveis globaisvariáveis globais a ser a ser disponibilizada para a comunidade disponibilizada para a comunidade exigeexige de de quem vai utilizá-la: quem vai utilizá-la:

ConhecimentoConhecimento da existência dessas da existência dessas variáveisvariáveis

AdiçãoAdição das mesmas ao conjunto de das mesmas ao conjunto de variáveis globaisvariáveis globais de seu de seu programaprograma

Uma Uma função sem variáveis globaisfunção sem variáveis globais é muito é muito mais simples de ser mais simples de ser reutilizadareutilizada

Page 57: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Há Há casoscasos no entanto, em que o no entanto, em que o uso de variáveis uso de variáveis globais é providencialglobais é providencial

Um grande programa com Um grande programa com inúmeros inúmeros subprogramassubprogramas atuando numa mesma grande atuando numa mesma grande base de dadosbase de dados

As As variáveisvariáveis dessa base podem ser dessa base podem ser globaisglobais

Não haverá a necessidadeNão haverá a necessidade de, na maioria das de, na maioria das chamadas de subprogramas, fazer chamadas de subprogramas, fazer passagem de passagem de argumentosargumentos

Evita-se Evita-se transporte desnecessáriotransporte desnecessário de de informações entre os informações entre os subprogramassubprogramas, mesmo , mesmo que seja apenas de que seja apenas de ponteirosponteiros

Page 58: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Exemplo: um compilador

Analisador léxico

Analisador sintático

Analisador

semânticoGerador de

código intermediári

o

Otimizador de código

intermediário

Gerador de código objeto

while (i < nn) i = i + j;Programa-fonte (caracteres)

Sequência de átomos

Árvore sintática

while

i

<

nn i

=

i

+

j

i

nn

j

int

int

int

- - -- - -- - -Tabela

de símbolos

while ( i < nn )

i = i + j ;

R1: T1 = i < nn JF T1 R2 T2 = i + j i = T2 JUMP R1R2: - - - - -

Código intermediário

R1: T1 = i < nn JF T1 R2 i = i + j JUMP R1R2: - - - - -

load iR1: sub nn JZ R2 JP R2 load i add j st i J R1R2: - - - - -

Código objeto

Page 59: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Analisador léxico

Analisador sintático

Analisador

semânticoGerador de

código intermediári

o

Otimizador de código

intermediário

Gerador de código objeto

while (i < nn) i = i + j;Programa-fonte (caracteres)

load iR1: sub nn JZ R2 JZ R2 load i add j st i J R1R2: - - - - -

Código objeto

Seria incômodo e dispendioso o trânsito dos átomos, da árvore sintática, da tabela de símbolos e do código intermediário pelas funções do compilador

Fica a cargo do programador escolher o melhor modo de comunicação entre os módulos de seu programa

Page 60: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.5.4 – Variáveis em registradores8.5.4 – Variáveis em registradores

A Linguagem C permite que o programador A Linguagem C permite que o programador expresse sua expresse sua preferência por registradorespreferência por registradores, , na alocação de uma variávelna alocação de uma variável

RegistradoresRegistradores da CPU são de da CPU são de acesso muito acesso muito mais rápidomais rápido que o das palavras da que o das palavras da RAMRAM

Assim, os Assim, os programasprogramas poderão ficar mais poderão ficar mais rápidosrápidos

A declaração A declaração register int i;register int i;

indica que a variável inteira indica que a variável inteira ii deve, deve, se se possívelpossível, ser , ser alocada num alocada num registradorregistrador

Page 61: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Há Há limitaçãolimitação para o uso de para o uso de registradoresregistradores nos nos programas programas

Devido à sua Devido à sua sofisticada e carasofisticada e cara tecnologia, eles são em tecnologia, eles são em número muito menornúmero muito menor do que o das palavras da do que o das palavras da RAMRAM

Nem todas as variáveisNem todas as variáveis de um grande programa de um grande programa poderão caberpoderão caber no conjunto de no conjunto de registradoresregistradores de um de um computadorcomputador

Portanto o Portanto o programadorprogramador deve escolher as variáveis deve escolher as variáveis mais referenciadasmais referenciadas para serem alocadas em para serem alocadas em registradores registradores

Fortes Fortes candidatascandidatas para essa alocação são as variáveis para essa alocação são as variáveis usadas em usadas em controle de laçoscontrole de laços

Variáveis em Variáveis em registradoresregistradores, tais como as , tais como as automáticasautomáticas, só permanecem , só permanecem alocadasalocadas durante a durante a execução de seu execução de seu blocobloco

Page 62: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.5.5 – Variáveis estáticas8.5.5 – Variáveis estáticas

A declaração A declaração static int a;static int a;

diz que a variável inteira diz que a variável inteira ii é é estáticaestática

Variáveis estáticas podem ser Variáveis estáticas podem ser locaislocais ou ou externasexternas

Diferentes propriedades e utilidadesDiferentes propriedades e utilidades têm as têm as variáveis estáticas variáveis estáticas locaislocais e e externasexternas

Uma variável Uma variável estática localestática local tem seu valor tem seu valor conservadoconservado entre entre duas execuções consecutivasduas execuções consecutivas de seu bloco de declaraçãode seu bloco de declaração

Ao contrário, as Ao contrário, as variáveis automáticasvariáveis automáticas perdem perdem esse valoresse valor

Page 63: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Exemplo: Exemplo: seja o programa:seja o programa:

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

int i;int i;

void f () {void f () {

static int a = 0; static int a = 0; int b = 5;int b = 5;

printf ("a = %3d; b = %3d;", a, b);printf ("a = %3d; b = %3d;", a, b);

b = i + 10;b = i + 10;

printf (" b = %3d;\n", b);printf (" b = %3d;\n", b);

a += 3;a += 3;

}}

void main () {void main () {

for (i = 1; i <= 10; i++) for (i = 1; i <= 10; i++)

f ();f ();

getch();getch();

}}

Resultado

Variáveis estáticas locais são de uso privativo de seu bloco de declaração

Page 64: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Variáveis estáticas externasVariáveis estáticas externas oferecem um oferecem um importante serviço de importante serviço de privacidadeprivacidade, fundamental , fundamental para a para a modularizaçãomodularização de programas de programas

Seu Seu escopo de validadeescopo de validade começa no começa no ponto da ponto da declaraçãodeclaração e vai somente até o e vai somente até o final de seu final de seu arquivoarquivo

Se o programa tiver Se o programa tiver outros arquivosoutros arquivos, essa , essa variável variável não é visívelnão é visível em suas funções em suas funções

Então, pode-se escrever um Então, pode-se escrever um módulomódulo com um com um conjunto de funçõesconjunto de funções que tenham uso que tenham uso privativoprivativo de certas de certas variáveisvariáveis

Desse conjunto, uma função pode ser a Desse conjunto, uma função pode ser a líderlíder e as e as outras podem ser suas outras podem ser suas auxiliaresauxiliares

Page 65: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Capítulo VIII – Capítulo VIII – SubprogramaçãoSubprogramação

8.1 – Introdução8.1 – Introdução

8.2 – Escopo de validade de declarações8.2 – Escopo de validade de declarações

8.3 – Parâmetros e passagem de 8.3 – Parâmetros e passagem de argumentosargumentos

8.4 – Prototipação de subprogramas8.4 – Prototipação de subprogramas

8.5 – Classes de alocação8.5 – Classes de alocação

8.6 – Recursividade8.6 – Recursividade

Page 66: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.6 – Recursividade8.6 – Recursividade

8.6.1 – Definições matemáticas 8.6.1 – Definições matemáticas recursivasrecursivas

RecursividadeRecursividade é um expediente muito usado é um expediente muito usado para se estabelecer certas para se estabelecer certas definições definições matemáticasmatemáticas

Uma Uma entidadeentidade de uma certa de uma certa classe classe é definida é definida em função de em função de entidades menores da mesma entidades menores da mesma classeclasse

Page 67: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Exemplo 1: Exemplo 1: seja seja SSnn a soma dos a soma dos n n primeiros primeiros inteiros positivosinteiros positivos

SSnn = =

Para Para n = 5n = 5: :

1, para n = 1n + Sn-1, para n > 1

S5 = 5 + S4

= 5 + (4 + S3) = 5 + (4 + (3 + S2)) = 5 + (4 + (3 + (2 + S1))) = 5 + (4 + (3 + (2 + 1))) = 5 + (4 + (3 + 3)) = 5 + (4 + 6) = 5 + 10 = 15

Page 68: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Exemplo 2: Exemplo 2: cálculo de fatoriaiscálculo de fatoriais

n! =n! =

Para Para n = 5n = 5: :

-1, para n < 01, para 0 ≤ n ≤ 1n * (n-1)!, para n > 1

5! = 5 * 4! = 5 * (4 * 3!) = 5 * (4 * (3 * 2!)) = 5 * (4 * (3 * (2 * 1!))) = 5 * (4 * (3 * (2 * 1))) = 5 * (4 * (3 * 2)) = 5 * (4 * 6) = 5 * 24 = 120

Page 69: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Exemplo 3: Exemplo 3: cálculo do mdc de números não-cálculo do mdc de números não-negativosnegativos

mdc (m, n) =mdc (m, n) =

Para Para m = 48 e n = 64m = 48 e n = 64: :

∞, para m = 0 e n = 0m, para m > 0 e n = 0n, para m = 0 e n > 0mdc (n, m%n), para m e n > 0

mdc (48, 64) = mdc (64, 48) = mdc (48, 16) = mdc (16, 0) = 16

Page 70: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.6.2 – Subprogramas recursivos8.6.2 – Subprogramas recursivos

Subprograma recursivo: Subprograma recursivo: invoca a si próprio invoca a si próprio direta ou indiretamentedireta ou indiretamente

Recursividade direta: Recursividade direta: um subprograma um subprograma invoca a si próprio invoca a si próprio em seus próprios em seus próprios comandoscomandos

Recursividade indireta: Recursividade indireta: um primeiro um primeiro subprograma subprograma invoca outroinvoca outro, que invoca , que invoca outro, ... , que invoca outro, que outro, ... , que invoca outro, que invoca o invoca o primeiroprimeiro

Page 71: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

int fat (int n) {int fat (int n) {

int f;int f;

if (n < 0) f = -1;if (n < 0) f = -1;

else if (n <= 1) f = 1;else if (n <= 1) f = 1;

else f = n * else f = n * fat(n-1)fat(n-1);;

return f;return f;

}}

void main() {void main() {

char c; int n;char c; int n;

printf ("Calculo do fatorial de n");printf ("Calculo do fatorial de n");

printf ("\n\n\tDigite n: "); scanf ("%d", &n);printf ("\n\n\tDigite n: "); scanf ("%d", &n);

printf ("\n\tFat(%d) = %d", n, printf ("\n\tFat(%d) = %d", n, fat(n)fat(n)););

printf("\n\nDigite algo para encerrar: "); getch();printf("\n\nDigite algo para encerrar: "); getch();

}}

Exemplo 1: cálculo de fatoriais

-1, para n < 0n! = 1, para 0 ≤ n ≤ 1

n * (n-1)!, para n > 1

Page 72: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

int mdc (int m, int n) {int mdc (int m, int n) {

int r;int r;

m = abs(m); n = abs(n);m = abs(m); n = abs(n);

if (m==0 && n==0) r = -1;if (m==0 && n==0) r = -1;

else if (m == 0) r = n;else if (m == 0) r = n;

else if (n == 0) r = m;else if (n == 0) r = m;

else r = else r = mdc(n, m%n)mdc(n, m%n);;

return r;return r;

}}

void main() {void main() {

char c; int m, n;char c; int m, n;

printf ("Calculo do mdc de m e n");printf ("Calculo do mdc de m e n");

printf ("\n\n\tDigite m e n: "); scanf ("%d%d", &m, &n);printf ("\n\n\tDigite m e n: "); scanf ("%d%d", &m, &n);

printf ("\n\tmdc(%d, %d) = %d", m, n, printf ("\n\tmdc(%d, %d) = %d", m, n, mdc(m, n)mdc(m, n)););

printf("\n\nDigite algo para encerrar: "); getch();printf("\n\nDigite algo para encerrar: "); getch();

}}

Exemplo 2: cálculo de mdc’s

∞, p/ m = 0 e n = 0mdc (m, n) = m, p/ m > 0 e n = 0

n, p/ m = 0 e n > 0

mdc (n, m%n), p/ m e n >

0

Page 73: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

8.6.3 – Execução de subprogramas 8.6.3 – Execução de subprogramas recursivosrecursivos

Quando um Quando um subprogramasubprograma invoca a si mesmo, invoca a si mesmo, inicia-se uma nova execução (inicia-se uma nova execução (nova versãonova versão) desse ) desse subprogramasubprograma

Porém a Porém a versãoversão que faz a invocação continua que faz a invocação continua ativaativa

Em programas recursivos, pode haver Em programas recursivos, pode haver várias várias versões ativasversões ativas de um mesmo de um mesmo subprogramasubprograma recursivorecursivo

Cada qual com suas Cada qual com suas variáveis locaisvariáveis locais

As As variáveisvariáveis de versões diferentes têm o de versões diferentes têm o mesmo mesmo nomenome mas são entidades mas são entidades distintasdistintas

Page 74: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

int fat (int n) {int fat (int n) {

int f;int f;

if (n < 0) f = -1;if (n < 0) f = -1;

else if (n <= 1) f = 1;else if (n <= 1) f = 1;

else f = n * fat(n-1);else f = n * fat(n-1);

return f;return f;

}}

void main() {void main() {

char c; int n;char c; int n;

printf ("Calculo do fatorial de n");printf ("Calculo do fatorial de n");

printf ("\n\n\tDigite n: "); scanf ("%d", &n);printf ("\n\n\tDigite n: "); scanf ("%d", &n);

printf ("\n\tFat(%d) = %d", n, fat(n));printf ("\n\tFat(%d) = %d", n, fat(n));

printf("\n\nDigite algo para encerrar: ");printf("\n\nDigite algo para encerrar: ");

getch();getch();

}}

Exemplo: execução da função fat recursiva

Page 75: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

int fat (int n) {int fat (int n) {

int f;int f;

if (n < 0) f = -1;if (n < 0) f = -1;

else if (n <= 1) f = 1;else if (n <= 1) f = 1;

else f = n * fat(n-1);else f = n * fat(n-1);

return f;return f;

}}

void main() {void main() {

char c; int n;char c; int n;

printf ("Calculo do fatorial de n");printf ("Calculo do fatorial de n");

printf ("\n\n\tDigite n: "); printf ("\n\n\tDigite n: "); scanf ("%d", &n);scanf ("%d", &n);

printf ("\n\tFat(%d) = %d", n, fat(n));printf ("\n\tFat(%d) = %d", n, fat(n));

printf("\n\nDigite algo para encerrar: ");printf("\n\nDigite algo para encerrar: ");

getch();getch();

}}Valor digitado: 5

5n

Page 76: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

#include <stdio.h>#include <stdio.h>

#include <conio.h>#include <conio.h>

int fat (int n) {int fat (int n) {

int f;int f;

if (n < 0) f = -1;if (n < 0) f = -1;

else if (n <= 1) f = 1;else if (n <= 1) f = 1;

else f = n * fat(n-1);else f = n * fat(n-1);

return f;return f;

}}

void main() {void main() {

char c; int n;char c; int n;

printf ("Calculo do fatorial de n");printf ("Calculo do fatorial de n");

printf ("\n\n\tDigite n: "); scanf ("%d", &n);printf ("\n\n\tDigite n: "); scanf ("%d", &n);

printf ("\n\tFat(%d) = %d", n, printf ("\n\tFat(%d) = %d", n, fat(n)fat(n)););

printf("\n\nDigite algo para encerrar: ");printf("\n\nDigite algo para encerrar: ");

getch();getch();

}}Valor digitado: 5

5n

5n

f

fat – v1

f = 5*fat(4)

4n

f

fat – v2

f = 4*fat(3)

3n

f

fat – v3

f = 3*fat(2)

2n

f

fat – v4

f = 2*fat(1)

1n

f

fat – v5

f = 1

1 2

624

120

Page 77: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Observação:Observação: funções recursivas envolvendo funções recursivas envolvendo vetoresvetores, , matrizesmatrizes e e estruturasestruturas serão serão apresentadas no apresentadas no próximo capítulopróximo capítulo

Page 78: Capítulo VIII – Subprogramação 8.1 – Introdução 8.2 – Escopo de validade de declarações 8.3 – Parâmetros e passagem de argumentos 8.4 – Prototipação de.

Exercícios 8.6:Exercícios 8.6:

1.1.Uma importante função teórica conhecida como Uma importante função teórica conhecida como função de Ackermannfunção de Ackermann tem a seguinte tem a seguinte formulação recursiva:formulação recursiva:

Ackermann (m, n) = Ackermann (m, n) =

Escrever uma função inteira recursiva em C que Escrever uma função inteira recursiva em C que tenha como parâmetros duas variáveis inteiras tenha como parâmetros duas variáveis inteiras longas longas mm e e n n e que calcule e retorne o valor de e que calcule e retorne o valor de Ackermann (m, n)Ackermann (m, n), utilizando a definição acima. , utilizando a definição acima. Tal função deve retornar -1 (menos 1) se o valor Tal função deve retornar -1 (menos 1) se o valor de de m m ou deou de n n forem negativosforem negativos