17 - Funções e Procedimentos em C Programação Modular Unesp Campus de Guaratinguetá Curso de Programação Computadores Prof. Aníbal Tavares Profa. Cassilda Ribeiro Ministrado por: Prof. André Amarante
17 - Funções e Procedimentos - Definições Para a estruturação de programas, utiliza-se o conceito de MODULARIZAÇÃO. Modularizar um programa consiste em dividi-lo em partes que serão desenvolvidas em separado. Essas partes executam tarefas menores que depois serão acopladas para formar o programa. A cada uma dessas partes chamamos de subprograma. Os subprogramas permitem uma melhor legibilidade e manutenibilidade do programa Funções e Procedimentos em C 2
17 - Funções e Procedimentos - Definições A forma de modularizar um programa em C é através de Funções e Procedimentos. Pode-se então dizer que : Funções e Procedimentos são blocos de código c que podem ser nomeados e chamados de dentro de um programa. Programas grandes e complexos devem ser construídos bloco a bloco. Funções e Procedimentos em C 3
17 - Funções e Procedimentos - Definições Utilidade de funções: Um função pode ser empregada para evitar repetição de código e assim facilitar a manutenção do código contido no programa. Na linguagem C, de modo geral, as Funções e Procedimentos são chamadas dentro da Função Principal (main() ) ou ainda por outras funções. A declaração da função deve vir antes de seu uso. Funções e Procedimentos em C 4
17 - Funções e Procedimentos - Definições A declaração de uma Função em C é constituída de um cabeçalho e de um corpo. O cabeçalho identifica a Função através de um nome, e o corpo contém as declarações dos objetos locais, além de comandos e estruturas do procedimento. Uma função em C tem a seguinte forma geral: tipo_de_retorno nome_função ( parâmetros ) { declarações comandos Corpo da Função Funções e Procedimentos em C 5
O tipo-de-retorno é o tipo de valor que a função vai retornar. O default é o tipo int, ou seja, uma função para qual não declaramos o tipo de retorno é considerada como retornando um inteiro. A declaração de parâmetros é uma lista de variáveis com a seguinte forma geral: 17 - Funções e Procedimentos - Definições tipo nome1, tipo nome2,..., tipo nomen Repare que o tipo deve ser especificado para cada uma das N variáveis de entrada. É na declaração de parâmetros que informamos ao compilador quais serão as entradas da função (assim como informamos a saída no tipo-de-retorno). Funções e Procedimentos em C 6
17 - Funções e Procedimentos - Definições Uma função pode retornar qualquer valor válido em C, sejam de tipos pré-definidos ( int, char, float) ou de tipos definidos pelo usuário ( struct, typedef ) Um Procedimento é função que não retorna nada. Ela é definida colocando-se o tipo void como valor retornado. Pode-se colocar void entre parênteses se a função não recebe nenhum parâmetro O corpo da função é a sua alma. É nele que as entradas são processadas, saídas são geradas ou outras coisas são feitas. Funções e Procedimentos em C 7
17 - Funções e Procedimentos - Declara Funções Declaração de O cabeçalho de uma função NUNCA deve ser seguido de ponto e vírgula. Dentro do corpo de uma função pode-se escrever qualquer instrução ou conjunto de instruções da linguagem C. Em C não se pode definir funções dentro de funções. A comunicação entre a função e o programa principal (main) se faz através dos argumentos que são enviados a ela e dos parâmetros presentes na função. Funções e Procedimentos em C 8
17 - Funções e Procedimentos - Declaração de Funções É o programa principal que controla o fluxo de execução do programa como um todo. Quando o programa principal chama a função; através do seu nome; o controle do fluxo de execução do programa passa para a função. No momento que termina a execução da função o controle do fluxo de execução retorna para o programa principal. Funções e Procedimentos em C 9
17 - Funções e Procedimentos - Utilização de Funções Exemplo 171: Fazer um programa que imprima a seguinte saída na tela: +++ +++++ ======= +++++ +++ Para fazer este programa sem a utilização do conceito de modularidade, isto é, sem usar funções, é necessário fazer um laço para imprimir cada uma das linhas. Os dois programas mostrados a seguir resolvem este problema sem função e com função. Funções e Procedimentos em C 10
17.1 - Funções e Procedimentos: Utilização de Funções Exemplo 17.1 Sem usar Função #include <stdio.h> main() { int i; // Imprime linha com 3 +. for (i=0; i < 3; i++) printf( + ); printf( \n ); // Imprime linha com 5 +. for (i=0; i < 5; i++) printf( + ); printf ( \n ); // Imprime linha com 7 =. for (i=0; i < 7; i++) printf( = ); printf ( \n ); Continuação... // Imprime linha com 5 +. for (i=0; i < 5; i++) printf( + ); printf ( \n ); // Imprime linha com 3 +. for (i=0; i < 3; i++) printf( + ); printf( \n ); Observe que foi necessário repetir duas vezes o for para imprimir 3+ e duas vezes o for para imprimir 5+ Funções e Procedimentos em C 11
17.1 - Funções e Procedimentos: Utilização de Funções Exemplo 17.1 com Função #include <stdio.h> void imprime_linha_3 () { int i; for(i=0;i < 3; i++) printf( + ); printf ( \n ); void imprimelinha_5() { int i; for(i=0; i < 5; i++) printf( + ); printf ( \n ); void imprimelinha_7() { int i; for(i=0; i < 7; i++) printf( = ); printf ( \n ); main() {imprimelinha_3(); chamadas imprimelinha_5(); imprimelinha_7(); das funções imprimelinha_5(); no main. imprimelinha_3(); Observe que: 1. com o uso de funções, não é preciso repetir os comandos for. 2. O que se repete são as chamadas das funções. 3. As funções são chamadas dentro do main. 4. As funções utilizadas não têm parâmetros de entrada nem de saída (procedimentos). 5. O void serve para indicar que a função não tem parâmetro de saída. Funções e Procedimentos em C 12
17.1 - Funções e Procedimentos: Utilização de parâmetros. O programa do Exemplo 17.1 pode ser aperfeiçoado se forem utilizados parâmetros de entrada. Pode-se então fazer uma função mais genérica, por exemplo, a função imprimech. Nos parâmetros são passados: o caractere que será utilizado na função e o numero de linhas n, que serão impressas. Exemplo 17.2 Com parâmetros #include <stdio.h> void imprimech(char ch, int n) { int i; for(i=0;i < n; i++) printf( %c,ch); printf( \n ); main() { imprimech( +,3); imprimech( +,5); imprimech( =,7); imprimech( +,5); imprimech( +,3); chamada das funções com argumentos Funções e Procedimentos em C 13
17.1 - Funções e Procedimentos: Utilização de parâmetros. Relembrando: a comunicação entre a função e o programa principal (main) é feita através dos argumentos e dos parâmetros. Na declaração da função é necessário definir o tipo de cada parâmetro. Os argumentos da função têm que ser compatíveis com os tipos declarados nos parâmetros. Funções e Procedimentos em C 14
17.1 - Funções e Procedimentos: Utilização de parâmetros. No exemplo 17.2, os parâmetros passados no cabeçalho da função são: void imprimech(char ch, int n). Os argumentos são colocados na chamada da função imprimech( +,3); O primeiro parâmetro é a variável ch do tipo char, e ele é compatível com o primeiro argumento + segundo parâmetro é a variável n do tipo int e ele é compatível com o número 3. Relembrando: Uma função que não retorna nada (void ) é um procedimento. Logo o, exemplo 17.1 é um procedimento Funções e Procedimentos em C 15
17.1 - Funções e Procedimentos: Utilização de parâmetros. Exemplo 17.3: Fazer um programa para verificar se um dado número é par ou não. Para isso, utilize uma função com passagens de parâmetros. #include <stdlib.h> #include <stdio.h> int verifpar(int k) { if (k%2 == 0) return 1; else return 0; main() { int num, resultado; printf("digite um numero "); scanf("%d",&num); resultado = verifpar(num); if(resultado == 1) printf("\no numero que voce digitou eh par\n"); else printf("\no numero que voce digitou nao eh par\n"); system("pause"); A função verifpar retorna um número inteiro. É por esta razão que foi colocado o int antes do nome da função. O número é retornado através do comando return. O número retornado é armazenado na variável resultado Funções e Procedimentos em C 16
17.1 - Funções e Procedimentos: Utilização de parâmetros. Observações sobre o exemplo 17.3 É passado para a função int verifpar(int k) uma variável (k) do tipo inteiro. A função recebe esta variável, verifica se ela é par ou não e devolve ao programa principal o número 1 se k for par e o número zero se k for ímpar. A função utiliza o comando return para devolver o valor. O tipo do valor devolvido é que define o tipo da função. A função int verifpar(int k) é então uma função do tipo inteiro, porque o valor devolvido é inteiro. O programa principal armazena o valor recebido na variável resultado. Funções e Procedimentos em C 17
17.1 - Funções e Procedimentos: Conceitos Importantes Variáveis Locais : são variáveis declaradas dentro de um subprograma. Elas só podem ser manipuladas dentro do subprograma que as declarou. Logo, elas não são visíveis em nenhuma outra parte do programa. No Exemplo 17.4 mostrado a seguir, a variável a é uma variável local e qualquer alteração que se faça nela, dentro da função mudaa, não será visível dentro do programa principal, main( ). Funções e Procedimentos em C 18
17.2 - Funções e Procedimentos: Variável Local Exemplo 17.4 Variável Local #include <stdio.h> Função mudaa(). void mudaa() { int a; a = 4; printf( MudaA, a = %d \n,a); Função Principal. main() { int a; a = 2; printf( main, a = %d \n,a); mudaa(); printf( main, a = %d \n,a); Na tela main, a = 2 Na tela mudaa, a = 4 Na tela main, a = 2 Observe que o valor da variável a foi alterado em mudaa(), mas esta alteração não foi repassada para o main. Funções e Procedimentos em C 19
17.2 - Funções e Procedimentos: Variável Local Na realidade a variável a da função mudaa() NÃO é igual a variável a do main. O programa trabalha com as duas variáveis independentemente. Com a variável local, duas funções diferentes, por exemplo f1 e f2 podem ter o mesmo nome de variável, para armazenar dados diferentes, pois neste caso quando a função f1 está sendo executada o valor da variável fica oculto em f2 e vice-versa. Funções e Procedimentos em C 20
17.1 - Funções e Procedimentos: Variável Global Variáveis globais: são variáveis declaradas no início do programa principal (no corpo do main). As variáveis veis globais podem ser manipuladas durante toda a execução do programa, Assim qualquer alteração que se faça a numa variável vel global irá refletir em todas as funções do programa. Cuidado, pois ao se definir uma variável global, ela não poderá ser redeclarada em outra função do programa, porque isto acarreta um erro de compilação A seguir é mostrado um exemplo utilizando variável vel global Funções e Procedimentos em C 21
17.2 - Funções e Procedimentos: Variável Global Exemplo 17.5 Variável Global #include <stdio.h> int a; Função mudaa(). void mudaa() { a = 4; printf( MudaA, a = %d \n,a); Observe que a variável a foi declarada no corpo do programa principal e não dentro da função mudaa, como no exemplo anterior Função Principal. main() { a = 2; printf( main, a = %d \n,a); mudaa(); printf( main, a = %d \n,a); Quando uma variável é declarada no corpo do main, ela não pode ser declarada dentro da função. Funções e Procedimentos em C 22
17.2 - Funções e Procedimentos: Variável Global #include <stdio.h> int a; Função mudaa(). void mudaa() { a = 4; printf( MudaA, a = %d \n,a); Função Principal. main() { a = 2; printf( main, a = %d \n,a); mudaa(); printf( main, a = %d \n,a); Exemplo 17.5 Escopo Global Na tela main, a = 2 Na tela mudaa, a = 4 Na tela main, a = 4 O valor da variável a foi alterado em mudaa() e esta alteração foi passada para a variável a do main(). Mas,deve-se evitar o uso de variáveis globais Funções e Procedimentos em C 23
17.2 - Funções e Procedimentos: Escopo Local e Global Os conceitos de variáveis globais e locais determinam um termo denominado ESCOPO. Variáveis que possuem Escopo Global são acessadas por todos as subprogramas que estão contidos em um programa. Variáveis que possuem Escopo Local são acessadas somente por subprogramas que estão contidos no subprograma. Depois de terminada a execução de uma função (procedimento), todas as suas variáveis veis locais são destruídas. das. Funções e Procedimentos em C 24
17.2 - Funções e Procedimentos: Instrução Return Funções que retornam um valor Na linguagem C existem várias funções que já estão programadas, como por exemplo a função sqrt(x ) que calcula a raiz quadrada de x, a função sin(x) que calcula o seno(x), etc. Uma função pode ser responsável por fazer uma determinada tarefa e uma vez terminada esta tarefa, ela devolve, como resultado, apenas um valor. A devolução do resultado é feita através do comando return, seguido do valor a ser devolvido. Após o comando return pode ser colocado qualquer expressão válida em C. Funções e Procedimentos em C 25
17.2 - Funções e Procedimentos: Instrução Return Exemplo 17.6 Return #include <stdio.h> Função mudaa(). int mudaa(int b) { b = b*b; printf( MudaA, a = %d \n,b); return b; Função Principal. main() { int a; a = 2; printf( main, a = %d \n,a); a = mudaa(a); printf( main, a = %d \n,a); Tipo de retorno Tipo de Parâmetro Valor a retornar A variável vel a recebe o resultado da função mudaa(a) (a). Funções e Procedimentos em C 26
17.2 - Funções e Procedimentos: Instrução Return Exemplo 17.6 Return #include <stdio.h> Função mudaa(). int mudaa(int b) { b = b*b; printf( MudaA, a = %d \n,b); return b; Função Principal. main() { int a; a = 2; printf( main, a = %d \n,a); a = mudaa(a); printf( main, a = %d \n,a); Observe que aqui estamos utilizando variáveis locais, O valor de a foi alterado em mudaa(), e o novo valor de a foi repassado para main() através do return. Na tela main, a = 2 Na tela MudaA, a = 4 Na tela main, a = 4 Funções e Procedimentos em C 27
17.2 - Funções e Procedimentos: Instrução Return Uma função pode conter várias instruções return, mas apenas uma instrução return é executada. A devolução do resultado é feita através do comando return, seguido do valor a ser devolvido. Após o comando return pode ser colocado qualquer expressão válida em C. A instrução return termina a execução da função (procedimento), e o controle do programa é devolvido ao local onde a função (procedimento) foi invocada. Funções e Procedimentos em C 28
17.2 - Funções e Procedimentos: Instrução Return Exemplo 17.7 Fazer um programa que solicite ao usuário dois números e apresente na tela o resultado da sua soma e do dobro de cada um deles. Utilize uma função para calcular a soma e outra para o dobro. #include <stdlib.h> // Função que devolve a soma de dois inteiros int soma (int a, int b) { return a+b ; // Função que devolve o dobro de qualquer inteiro int dobro (int x) { return 2*x ; // Função principal chama as demais. main() { int n, i, total; printf( Introd. dois numeros ); scanf( %d%d,&n,&i); total=soma(n,i); printf( %d+%d=%d\n,n,i,total); printf( 2*%d=%d e 2*%d=%d\n,n,dobro(n), i, dobro(i)); Funções e Procedimentos em C 29
17.2 - Funções e Procedimentos: Instrução Return OBS: Uma vez que a função dobro devolve um inteiro o seu resultado pode ser usado dentro de um printf, sendo escrito com o formato de inteiro (%d) Ao executar este programa teremos na tela o seguinte: Introd dois numeros: 4 7 4+7=11 2*4=8 e 2*7=14 Uma função pode ser invocada dentro de uma outra função. O resultado é o mesmo que se obteria se, em vez da chamada a função aí estivesse o resultado devolvido a esta. Funções e Procedimentos em C 30
17.2 - Funções e Procedimentos: Instrução Return Exemplo 17.8 Qual seria a saída se acrescentássemos ao programa anterior a seguinte linha: printf( %d,dobro(soma(dobro(2), 3))); solução: dobro(2) 4 soma(dobro(2), 3)) soma(4, 3)) 7 dobro(soma(dobro(2), 3))) dobro(soma(4,3)) dobro(7) 14 Então o valor impresso na tela seria 14. Isto é equivalente a colocar no programa anterior as seguintes linhas: a= dobro(2); b= soma(a, 3)); c= dobro(b); printf( %d,c); Funções e Procedimentos em C 31
17.2 - Funções e Procedimentos: Escopo/Vetores Exemplo 17.9 Vetores. Fazer um programa, com duas funções sendo que a primeira deve gerar um vetor V com elementos aleatórios num dado intervalo [a,b] e a segunda deve imprimir os elementos do vetor. #include <stdlib.h> #include <stdio.h> #include <time.h> // Função que atribui elementos // aleatórios para v em [a,b]. void gerav(int v[], int n, int a, int b) { int i; srand(time(0)); for (i=0; i < n; i++) v[i] = (rand()%(b-a+1))+a; // Função que imprime um vetor. void imprimev(int v[], int n) {int i; for(i=0; i < n; i++) printf(" [%2d] ",v[i]); printf("\n"); // Função principal chama as demais. main() { int v[10]; // Gera vetor com valores em [a,b]. gerav(v,10,1,6); imprimev(v,10); Funções e Procedimentos em C 32
17.2 - Funções e Procedimentos: Escopo/Vetores OBSERVAÇÕES sobre o Exemplo 17.9 Vetores 1) Quando a função main chama o procedimento gerav, através da linha: gerav(v,10,1,6); é passado para o procedimento o valor de n=10 e o intervalo a= 1 e b= 6. 2) O procedimento gerav gera os elementos do vetor v e o devolve para o main. Isto é feito sem usar o comando return. O novo valor de v é utilizado em main(). 3) O valor de v retorna para a função main, pois no caso de vetores é passada a referência e não os valores (isto será melhor entendido com o estudo de ponteiros.) 4) Se a variável v não fosse um vetor ela não retornaria para a função main. Para que ela retornasse seria necessário usar o return e não teríamos um procedimento e sim uma função. Funções e Procedimentos em C 33
17.2 - Funções e Procedimentos: Escopo/Vetores Exemplo 17.10 Bubble Sort #include <stdio.h> #include <stdlib.h> // Usa o Bubble Sort Aperfeiçoado. void ordenavetor(float v[], int n ) { int i,j; float tmp; for (i=0; i < n-1; i++) for (j=0; j < n-i-1;j++) if (v[j] > v[j+1]) { tmp = v[j]; v[j] = v[j+1]; v[j+1] = tmp; // Função Principal. main() { float Vetor[60]; int n, i, j; printf( No. elementos de v: "); scanf("%d",&n); printf("digite elementos de v:"); for (i=0; i < n; i++) scanf("%f",&vetor[i]); ordenavetor(vetor, n); printf("vetor Ordenado\n"); for (i=0; i < n; i++) printf("%.1f\n",vetor[i]); system("pause"); Funções e Procedimentos em C 34
17.2 - Funções e Procedimentos: Escopo/Vetores OBSERVAÇÕES sobre Exemplo 17.10 Bubble Sort 1) Neste exemplo o vetor v é lido na função main e a seguir é passado para o procedimento ordenavetor através da linha: ordenavetor(vetor, n); 2) O procedimento ordenavetor, ordena os elementos do vetor e o devolve para o main. Isto é feito sem usar o comando return, pois trata-se de um vetor. 3) A seguir o main, imprime o vetor ordenado. 4) Observe também que dentro do procedimento o vetor tem o nome de v e dentro do main o nome é vetor. Funções e Procedimentos em C 35
17.2 - Funções e Procedimentos: Escopo/Matrizes Exemplo 17.11 Matrizes #include <stdio.h> #include <stdlib.h> #include <time.h> const int m = 5; const int n = 4; // Gera matriz com elementos em [a,b]. void geram(int A[][n], int a, int b) { int i, j; srand(time(0)); for (i=0; i < m; i++) for (j=0; j < n; j++) A[i][j] = (rand()%(b-a+1))+a; // Imprime matriz. void printm(int A[][n]) { int i, j; for (i=0; i < m; i++) { for (j=0; j < n; j++) printf("[%2d]",a[i][j]); printf("\n"); // Função Principal. main() { int i, j; int A[m][n]; geram(a,1,6); printm(a); Funções e Procedimentos em C 36
17.2 - Funções e Procedimentos: Escopo/Matrizes OBSERVAÇÕES sobre o Exemplo 17.11- Matrizes 1) Neste exemplo a matriz A é gerada aleatoriamente no procedimento geram. 2) O procedimento geram, devolve os elementos de A para o main. Isto é feito através das linhas: a) void geram(int A[][n], int a, int b) b) geram(a,1,6); Observe que: a linha (a) é o cabeçalho do procedimento geram e nele estão declaradas: a matriz A (int A[][n]), a variável inteira a (int a) e a variável inteira b (int b). No caso da declaração da matriz é necessário estipular somente o número de colunas, que neste caso é n. A linha (b) é a chamada do procedimento dentro do main e as variáveis que estão dentro do parêntese tem uma correspondência Funções e Procedimentos em C 37 direta com as variáveis do cabeçalho.
17.2 - Funções e Procedimentos: Escopo/Matrizes 3) A seguir o main, envia os elementos de A para o procedimento printm que o imprime. Isto é feito através das linhas: void printm(int A[][n]), printm(a); que são respectivamente, cabeçalho do procedimento e chamada do procedimento dentro do main. 4) Observe também que tudo isto é feito sem usar o comando return. 5) O return só pode ser usado quando se quer devolver um único valor. Funções e Procedimentos em C 38
Unesp-Campus de Guaratinguetá 17 - Funções e Procedimentos FIM Aula 17 Referências dos slides Curso de Programação de Computadores Prof. Aníbal Tavares Profa. Cassilda Ribeiro Prof. Décio Mourão Funções e Procedimentos em C Prof. Galeno Sena 39