230 likes | 386 Views
Funções em C. Universidade do Estado de Santa Catarina Centro de Ciências Tecnológicas Departamento de Ciências da Computação. Profa. Rebeca Schroeder Email: rebeca@joinville.udesc.br. Introdução. Funções constituem estruturas que permitem ao programador separar seus programas em blocos
E N D
Funções em C Universidade do Estado de Santa Catarina Centro de Ciências Tecnológicas Departamento de Ciências da Computação Profa. Rebeca Schroeder Email: rebeca@joinville.udesc.br
Introdução • Funções constituem estruturas que permitem ao programador separar seus programas em blocos • Em geral, utilizamos funções para definir um conjunto de operações para a resolução de um problema específico • Função é o tipo mais primitivo de encapsulamento: através de um único nome (nome da função) é possível acionar uma série de operações ou dados
Introdução • No C, e em linguagens procedurais, as funções são as estruturas primárias de estruturação dos programas • Tudo no C é executado a partir de funções • Inicialmente a função Main • Separar a resolução de problemas em unidades funcionais (funções) é vantajoso: • Promove o reuso de código • Torna o programa mais limpo e organizado
Forma Geral de Funções tipo_de_retorno nome_da_função(lista_de_argumentos) { código_da_função }
Forma Geral de Funções - Exemplo float calculaMedia(float notas[10]) { float soma = 0; for(int i=0; i<10; i++) soma+=notas[i]; return soma/10; }
O Comando return • O comando return tem a seguinte forma geral: • return valor_de_retorno; ou return; • Durante a execução de uma função, quando se chega a um comando return a função é encerrada imediatamente e, se o valor de retorno é informado, a função retorna este valor • É importante lembrar que o valor de retorno fornecido deve ser compatível com o tipo de retorno declarado para a função • Uma função pode possuir mais de uma chamada ao comando return
O Comando return - Exemplo int ePar (int num) { if (num % 2 == 0) return 1; return 0; } main () { int a; cout<<"Entre com numero: "; cin>>a; if (ePar(a) == 1) cout<<"\n\nO numero e par."; else cout<<"\n\nO numero e impar."; } • Observer que o retorno das funções pode ser aproveitado em atribuições ou em comparações • Mesmo que a função retorne um valor, você não é obrigado a “aproveitar” este valor.
Protótipo de Funções • As funções devem ser declaradas antes de serem utilizadas • No exemplo anterior definimos a função antes do bloco main. Porém se tivéssemos definido abaixo do bloco main teríamos que informar o protótipo da função antes do ser efetivo uso • Em geral, adicionamos o protótipo das funções abaixo das diretivas de include • O protótipo de uma função nada mais é do que seu tipo de retorno, nome, e lista de parâmetros + ponto-e-vírgula (;) • Um protótipo tem o seguinte formato: • tipo_de_retorno nome_da_função (declaração_de_parâmetros);
Protótipo de Funções - Exemplo #include<iostream.h> int ePar(int num); main () { int a; cout<<"Entre com numero: "; cin>>a; if (ePar(a) == 1) cout<<"\n\nO numero e par."; else cout<<"\n\nO numero e impar."; } int ePar (int num) { if (num % 2 == 0) return 1; return 0; }
Passagem de Parâmetros • Por valor: os valores dos argumentos são copiados para os parâmetros das funções • Consequência: alterações realizadas dentro da função não alteram o valor dos argumentos passados a função • Por referência: o endereço dos argumentos é copiado para os parâmentros das funções • Consequência: alterações realizadas dentro da função alteram o valor dos argumentos passados a função
Passagem de Parâmetros por Valor • Quando chamamos uma função os parâmetros copiam os valores que são passados para ela • Isso significa que os valores que os parâmetros têm fora da função não são alterados • Esse tipo de chamada de função é denominado chamada por valor.
Passagem de Parâmetros por Valor - Exemplo #include <iostream.h> float sqr (float num); void main (void) { float num,sq; cout<<"Entre com um numero: "; cin>>num; sq=sqr(num); cout<<"\n\nO numero original e: “<<num; cout<<"O seu quadrado vale: “<<sq; } float sqr (float num) { num=num*num; return num; }
Passagem de Parâmetros por Referência • Passagem de parâmetros por referências ocorre quando as alterações realizadas dentro da função alteram os valores dos parâmetros que foram passados para a função • Neste tipo de chamada, não se passa para a função os valores das variáveis, mas sim suas referências (a função usa as referências para alterar os valores das variáveis fora da função). • Quando queremos alterar as variáveis que são passadas para uma função, nós podemos declarar seus parâmetros como sendo ponteiros. Os ponteiros são a "referência" que precisamos para poder alterar a variável fora da função • Na chamada desse tipo de função, temos que colocar um & na frente das variáveis que estamos passando para a função.
Passagem de Parâmetros por Referência – Exemplo (1) #include <iostream.h> float sqr (float num); void main (void) { float num,sq; cout<<"Entre com um numero: "; cin>>num; sq=sqr(&num); cout<<"\n\nO numero original e: “<<num; cout<<"O seu quadrado vale: “<<sq; } float sqr (float *num) { *num=(*num)*(*num); return *num; }
Passagem de Parâmetros por Referência – Exemplo (2) #include <iostream.h> void Swap (int *a,int *b); void main (void) { int num1,num2; num1=100; num2=200; Swap (&num1,&num2); cout<<“\n\nEles agora valem “<<num1<<“ e ”<<num2; } void Swap (int *a,int *b) { int temp; temp=*a; *a=*b; *b=temp; }
Vetores como argumentos de Funções • Quando vamos passar um vetor como argumento de uma função, podemos declarar a função de três maneiras equivalentes. Digamos que temos o seguinte vetor: int v[50]; • e que queiramos passá-la como argumento de uma função func(). Podemos declarar func() das três maneiras seguintes: void func (int v[50]); void func (int v[]); void func (int *v); • Ao passarmos um vetor para uma função, na realidade estamos passando um ponteiro. Neste ponteiro é armazenado o endereço do primeiro elemento do vetor. Isto significa que não é feita uma cópia, elemento a elemento do vetor. Isto faz com que possamos alterar o valor deste vetor dentro da função (Passagem por Referência!). • PARA VETORES SÓ EXISTE PASSAGEM POR REFERÊNCIA!
Parâmetros da Função Main • A função main() pode possuir parâmetros. Mas o programador não pode escolher quais serão eles • A declaração mais completa que se pode ter para a função main() é: int main (int argc,char *argv[]); • Os parâmetros argc e argv dão ao programador acesso à linha de comando com a qual o programa foi chamado • O argc (argument count) é um inteiro e possui o número de argumentos com os quais a função main() foi chamada na linha de comando. Ele é, no mínimo 1, pois o nome do programa é contado como sendo o primeiro argumento. • O argv (argument values) é um ponteiro para uma matriz de strings. Cada string desta matriz é um dos parâmetros da linha de comando. O argv[0] sempre aponta para o nome do programa (que é considerado o primeiro argumento).
Parâmetros da Função Main #include <iostream.h> #include <stdlib.h> void main (int argc, char *argv[]) { int mes; char *nomemes [] = {"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"}; if(argc == 4) { // Testa se o numero de parametros fornecidos está correto o 1o parametro é o nome do programa, o //2o o dia e o 3o o mes e o 4o os dois ultimos algarismos do ano mes = atoi(argv[2]); /* argv contem strings. A string referente ao mes deve ser transformada em um numero inteiro. A funcao atoi esta sendo usada para isto: recebe a string e transforma no inteiro equivalente */ if (mes<1 || mes>12) /* Testa se o mes é valido */ cout<<"Erro!\nUso: data dia mes ano, todos inteiros"; else cout<<"\n<<argv[1]<<“ de “<< nomemes[mes-1]<<“ de 20”<<argv[3]; } else cout<<“Erro!\nUso: data dia mes ano, todos inteiros”; }
Recursividade • A função recursiva é uma função que faz chamada a si própria • Um ponto fundamental para se trabalhar com funções recursivas é estabelecer um critério de parada, que corresponde a uma condição para que a função pare de chamar a si própria • Evitar que a função chame a si própria infinitamente
Recursividade - Exemplo #include <iostream.h> int fat(int n) { if (n>0) return n*fat(n-1) else return 1; } void main() { int n; cout<<"\n\nDigite um valor para n: "; cin>>n; cout<<"\nO fatorial de “<<n<<“ é “<<fat(n); }
Recursividade - Exemplo 1- fat recebe valor 4. 2- Passo 1: 4*fatorial(3); 3- Fatorial é chamada de dentro com o valor 3. 4- Passo 2: 3*fatorial(2); 5- Passo 3: 2*fatorial(1); 6- Se valor for 1, retorna 1. Fim de loop, mas não de contas. 7- Voltamos aos passos, ao contrário. 8- Passo 3: fatorial := 2*1; 9- Passo 2: fatorial := 3*2; 10- Passo 1: fatorial := 4*6; 11- A primeira retorna o valor 24. #include <iostream.h> int fat(int n) { if (n>0) return n*fat(n-1) else return 1; } void main() { int n; cout<<"Digite um valor: "; cin>>n; cout<<"\nO fatorial de “<<n<<“ é “<<fat(n); }