Algoritmos e Programao MC 102 Prof Paulo Miranda

  • Slides: 38
Download presentation
Algoritmos e Programação MC 102 Prof. Paulo Miranda IC-UNICAMP Aula 15 Funções

Algoritmos e Programação MC 102 Prof. Paulo Miranda IC-UNICAMP Aula 15 Funções

Funções • Motivação: • Dividir tarefas grandes em tarefas menores: – Facilita manutenção do

Funções • Motivação: • Dividir tarefas grandes em tarefas menores: – Facilita manutenção do código. – As partes podem ser testadas separadamente. • Reaproveitar código existente: – Evitar a reescrita de um mesmo código repetidas vezes. – Integração com códigos de outros programadores. • Esconder detalhes: – Permite uma visão de mais alto nível. – Viabiliza programas mais complexos.

Funções • Exemplo: – Calcular o número de combinações de m elementos tomados p

Funções • Exemplo: – Calcular o número de combinações de m elementos tomados p a p (p<=m), não importando a ordem dos elementos.

Funções • Definição: – Uma função é uma unidade de código de programa autônoma

Funções • Definição: – Uma função é uma unidade de código de programa autônoma desenhada para cumprir uma tarefa particular (ex: printf, sqrt, strcmp). • Sintaxe: tipo nome_da_função(lista de argumentos){ Declarações de variáveis locais; Bloco de comandos; }

Funções • Exemplo: #include <stdio. h> int resto(int a, int b){ int q; q

Funções • Exemplo: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; }

Funções • Exemplo: #include <stdio. h> int resto(int a, int b){ int q; q

Funções • Exemplo: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; Corpo da função return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; }

Funções • Exemplo: #include <stdio. h> int resto(int a, int b){ int q; q

Funções • Exemplo: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } Lista de argumentos (parâmetros)

Funções • Exemplo: #include <stdio. h> int resto(int a, int b){ int q; q

Funções • Exemplo: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } Chamada da função

Chamando Funções comando 1; Corpo da Função comando. A; comando 2; comando. B; Chamada

Chamando Funções comando 1; Corpo da Função comando. A; comando 2; comando. B; Chamada da função; comando. C; comando 3; comando 4; comando. D;

Chamando Funções • Chamada a uma função: – Aloca espaço para todas variáveis locais

Chamando Funções • Chamada a uma função: – Aloca espaço para todas variáveis locais declaradas na função. – Inicializa os parâmetros com os valores passados para a função. – Desvia a execução do código para o corpo da função. • Após execução: – Desaloca memória das variávies locais. – Retorna para a próxima instrução após a chamada.

Variáveis locais • Variáveis declaradas dentro de uma função e argumentos são chamados de

Variáveis locais • Variáveis declaradas dentro de uma função e argumentos são chamados de variáveis locais. – Existem somente durante a execução da função. – Podem ser acessadas apenas no corpo da função onde foram declaradas. • OBS: Variáveis locais com mesmo nome declaradas em funções diferentes são variáveis distintas.

Variáveis locais • Variáveis declaradas dentro de uma função e argumentos são chamados de

Variáveis locais • Variáveis declaradas dentro de uma função e argumentos são chamados de variáveis locais. – Existem somente durante a execução da função. – Podem ser acessadas apenas no corpo da função onde foram declaradas. • OBS: Variáveis locais com mesmo nome declaradas em funções diferentes são variáveis distintas. #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } Possui 3 variáveis locais: int a, int b, int q

Valor de Retorno • Funções podem retornar um valor (ex: sqrt retorna a raiz

Valor de Retorno • Funções podem retornar um valor (ex: sqrt retorna a raiz quadrada de um número). • O valor retornado deve ser compatível com o tipo da função. • O valor é retornado através do comando return que causa a saída imediata da função. • Funções que não retornam nada são chamadas de procedimentos e em C são implementadas como sendo do tipo void.

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } • O programa inicia a execução na função principal (main).

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } • É alocado espaço para as variáveis locais da função principal (main). int r ?

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } • A função resto é chamada. int r ?

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } • É alocado espaço para as variáveis locais da função. int r ? int a int b ? ? int q ?

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } • Os parâmetros são inicializados com os valores passados para a função. int r ? int a int b 5 3 int q ?

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } • A variável q recebe o resultado da divisão inteira. int r ? int a int b 5 3 int q 1

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } • O resultado 2 da expressão (a-q*b)é calculado e retornado pela função. int r ? int a int b 5 3 int q 1

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } • A variável r recebe o valor de retorno da função e as variáveis locais da função são destruídas. int r 2 int a int b 5 3 int q 1

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } • O conteúdo da variável r é impresso na saída padrão. int r 2

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q

Exemplo de Execução: #include <stdio. h> int resto(int a, int b){ int q; q = a/b; return (a-q*b); } • A função principal retorna 0 e a execução do programa é encerrada. int r 2 int main(){ int r; r = resto(5, 3); printf("Resto: %dn", r); return 0; } • As variáveis locais da função principal são destruídas.

Passando variáveis como argumentos void teste(int x){ x = 3; } int main(){ int

Passando variáveis como argumentos void teste(int x){ x = 3; } int main(){ int x = 1; teste(x); printf("%d", x); return 0; } • Quando passamos variáveis a uma função, os seus conteúdos são copiados (atribuídos) para variáveis locais (parâmetros) da função. • Alterações nos parâmetros dentro da função não alteram os valores das variáveis que foram passados. Ex: A saída do programa acima será 1 e não 3.

Exemplo 2: • Problema: – Calcular o fatorial de um número. • Solução: double

Exemplo 2: • Problema: – Calcular o fatorial de um número. • Solução: double fatorial(int x){ double fat = 1. 0; while(x>1){ fat = fat*x; x--; } return fat; }

Problema: • Calcular o número de combinações de m elementos tomados p a p

Problema: • Calcular o número de combinações de m elementos tomados p a p (p<=m), não importando a ordem dos elementos. Podemos resolver facilmente usando a função do problema anterior: int binomial(int m, int p){ int b=0; if(m>=0 && p<=m) b = (int)(fatorial(m)/(fatorial(p)*fatorial(m-p))); return b; }

Exemplo com Estruturas: • Faça um programa que lê dois números complexos e testa

Exemplo com Estruturas: • Faça um programa que lê dois números complexos e testa se eles são iguais: #include <stdio. h> struct Complexo{ float real; float imag; }; struct Complexo Le. Complexo(){ struct Complexo A; printf("Digite a parte real: "); scanf("%f", &A. real); printf("Digite a parte imaginaria: "); scanf("%f", &A. imag); return A; } void Print. Complexo(struct Complexo A){ printf("%. 2 f + (%. 2 f)*in", A. real, A. imag); }

Exemplo com Estruturas: • Faça um programa que lê dois números complexos e testa

Exemplo com Estruturas: • Faça um programa que lê dois números complexos e testa se eles são iguais: (continuação) int Igualdade. Complexos(struct Complexo A, struct Complexo B){ return (A. real==B. real && A. imag==B. imag); } int main(){ struct Complexo A; struct Complexo B; A = Le. Complexo(); B = Le. Complexo(); if(Igualdade. Complexos(A, B)) printf("Números iguais. n"); else printf("Números distintos. n"); return 0; }

Vetores como argumentos de funções • Quando o nome de uma variável simples (ex:

Vetores como argumentos de funções • Quando o nome de uma variável simples (ex: int, estrutura) é passado na chamada da função, é gerada uma cópia do conteúdo da variável fornecida em uma variável local da função. Esse processo é conhecido como chamada por valor. – Ex: Todos exemplos até agora usaram chamadas por valor. • Vetores podem conter grandes quantidades de dados, logo copiar todos dados de um vetor em uma chamada por valor é ineficiente. Em C, vetores são passados por referência de modo que existe uma única cópia do vetor (a original). É passado apenas o endereço do vetor para a função.

Exemplo com Vetores: • Faça uma função que copia uma string em outra. #include

Exemplo com Vetores: • Faça uma função que copia uma string em outra. #include <stdio. h> #define LIM 300 void String. Copy(char dest[], char src[]){ int i=0; while(src[i]!=''){ dest[i] = src[i]; i++; } dest[i] = ''; } int main(){ char A[LIM]= "String 1"; char B[LIM]= "String 2"; String. Copy(B, A); printf("A: %sn", A); printf("B: %sn", B); return 0; }

Exemplo com Vetores: • Faça uma função que copia uma string em outra. #include

Exemplo com Vetores: • Faça uma função que copia uma string em outra. #include <stdio. h> #define LIM 300 void String. Copy(char dest[], char src[]){ int i=0; while(src[i]!=''){ dest[i] = src[i]; i++; } dest[i] = ''; } Os tamanhos dos vetores podem ser omitidos int main(){ char A[LIM]= "String 1"; char B[LIM]= "String 2"; String. Copy(B, A); printf("A: %sn", A); printf("B: %sn", B); return 0; }

Exemplo com Vetores: • Faça uma função que copia uma string em outra. #include

Exemplo com Vetores: • Faça uma função que copia uma string em outra. #include <stdio. h> #define LIM 300 void String. Copy(char dest[], char src[]){ int i=0; while(src[i]!=''){ dest[i] = src[i]; i++; } O nome de um vetor sem o dest[i] = ''; colchetes representa o } endereço do vetor que é passado para a função. int main(){ char A[LIM]= "String 1"; char B[LIM]= "String 2"; String. Copy(B, A); printf("A: %sn", A); printf("B: %sn", B); return 0; }

Exemplo com Vetores: • Faça uma função que copia uma string em outra. #include

Exemplo com Vetores: • Faça uma função que copia uma string em outra. #include <stdio. h> #define LIM 300 void String. Copy(char dest[], char src[]){ int i=0; Alterações nos elementos while(src[i]!=''){ dos vetores possuem efeito dest[i] = src[i]; externo a função, pois i++; atuam sobre o vetor original } (passagem por referência). dest[i] = ''; } int main(){ char A[LIM]= "String 1"; char B[LIM]= "String 2"; String. Copy(B, A); printf("A: %sn", A); printf("B: %sn", B); return 0; }

Exemplo com Matrizes: • Matrizes são vetores de vetores e logo também são passadas

Exemplo com Matrizes: • Matrizes são vetores de vetores e logo também são passadas por referência. • A função abaixo embaralha os dados de uma matriz: #include <stdio. h> #include <stdlib. h> #include <time. h> #define LIM 100 void Embaralha. Matriz(int M[][LIM], int m, int n){ int i, j, x, y, tmp; srand(time(NULL)); for(i=0; i<m; i++){ for(j=0; j<n; j++){ x = rand()%n; //valor de 0 a n-1. y = rand()%m; //valor de 0 a m-1. tmp = M[i][j]; M[i][j] = M[y][x]; M[y][x] = tmp; } } }

Exemplo com Matrizes: • Matrizes são vetores de vetores e logo também são passadas

Exemplo com Matrizes: • Matrizes são vetores de vetores e logo também são passadas por referência. • A função abaixo embaralha os dados de uma matriz: #include <stdio. h> #include <stdlib. h> #include <time. h> #define LIM 100 void Embaralha. Matriz(int M[][LIM], int i, j, x, y, tmp; srand(time(NULL)); for(i=0; i<m; i++){ for(j=0; j<n; j++){ x = rand()%n; //valor de 0 a y = rand()%m; //valor de 0 a tmp = M[i][j]; M[i][j] = M[y][x]; M[y][x] = tmp; } } } int m, int n){ Somente a primeira dimensão pode n-1. ser omitida. m-1.

Exemplo com Matrizes: • Matrizes são vetores de vetores e logo também são passadas

Exemplo com Matrizes: • Matrizes são vetores de vetores e logo também são passadas por referência. • A função abaixo embaralha os dados de uma matriz: #include <stdio. h> #include <stdlib. h> #include <time. h> #define LIM 100 void Embaralha. Matriz(int M[][LIM], int m, int n){ int i, j, x, y, tmp; srand(time(NULL)); for(i=0; i<m; i++){ for(j=0; j<n; j++){ de linhas e x = rand()%n; //valor de 0 a Número n-1. y = rand()%m; //valor de 0 a colunas m-1. efetivamente em uso. tmp = M[i][j]; M[i][j] = M[y][x]; M[y][x] = tmp; } } }

Exemplo com Matrizes: • Matrizes são vetores de vetores e logo também são passadas

Exemplo com Matrizes: • Matrizes são vetores de vetores e logo também são passadas por referência. • A função abaixo embaralha os dados de uma matriz: #include <stdio. h> #include <stdlib. h> #include <time. h> #define LIM 100 void Embaralha. Matriz(int M[][LIM], int i, j, x, y, tmp; srand(time(NULL)); for(i=0; i<m; i++){ for(j=0; j<n; j++){ x = rand()%n; //valor de 0 a y = rand()%m; //valor de 0 a tmp = M[i][j]; M[i][j] = M[y][x]; M[y][x] = tmp; } } } Troca elementos de cada posição i, j por elementos de posição y, x. int m, intaleatória n){ n-1. m-1.

Exemplo com Matrizes: • A função principal abaixo pode ser usada para testar a

Exemplo com Matrizes: • A função principal abaixo pode ser usada para testar a função que embaralha os dados de uma matriz: int main(){ int i, j; int A[LIM]={{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; Embaralha. Matriz(A, 3, 3); for(i=0; i<3; i++){ for(j=0; j<3; j++) printf(" %4 d", A[i][j]); printf("n"); } return 0; }