1. Única função obrigatória é a função main
2. Modularização
2.1. Chamamos essa técnica que decompõe um programa em partes menores de modularização.
2.2. Melhorar o entendimento do programa, depurar os erros com mais facilidade, simplificar a manutenção porque podemos trocar somente um determinado módulo, reutilizar o código no mesmo programa ou em outro programa, etc.
2.3. Esses módulos são “pequenos programas” com tarefas bem definidas. São conhecidos em algumas linguagens por procedimentos e, na linguagem C++, por funções.
2.3.1. Função Exemplo de programa sem Função e com Função. Sem Função alguns comandos são repetidos varias vezes no programa.
2.3.2. Imagem Exemplo
3. Protótipo de uma Função
3.1. O protótipo de uma função contém o tipo de retorno da função, o nome da função, seguido de um par de parênteses que podem ou não ter parâmetros. É finalizado, obrigatoriamente, com o ;(ponto-e-vírgula).
3.2. Em outras palavras, o protótipo de uma função é o cabeçalho da função com ;(ponto-e-vírgula) ao final.
4. Localização das Funções. As funções poderão ser colocadas antes, ou depois, da main.
4.1. Os protótipos das funções serão localizados antes da main e as definições, depois da main.
4.2. Antes
4.3. Exemplo
4.3.1. Atenção
4.4. Depois
5. Conceito inicial: Chamada da função e o seu retorno
5.1. Quando a função é chamada, o fluxo de controle é desviado para essa Função.
5.2. FUNÇÃO COM RETORNO: Apartir desse MOMENTO, os comandos da Função são executados e, ao finalizar, o FLUXO RETORNA ao comando que chamou com a resposta E PARA .
5.2.1. Imagem
5.3. FUNÇÃO SEM RETORNO: Apartir desse MOMENTO, os comandos da Função são executados e, ao finalizar, o FLUXO RETORNA ao comando SEGUINTE daquele onde ela foi ativada(VOID).
5.3.1. Imagem
6. Conceitos das Funções
6.1. Uma função é um conjunto de comandos limitado por um par de chaves e precedido por um cabeçalho.
6.2. Uma função é independente da outra e, por essa razão, jamais poderá ser criada dentro de outra função.
6.3. Imagem
7. Função SEM parâmetro VOID
7.1. EXEMPLO
7.1.1. A) Função SEM parâmetros (VOID)
7.1.1.1. Na linguagem C++ e Java não é obrigatório o uso de parâmetros em todas as funções.
7.1.1.1.1. Podemos ter a função VOID SEM PARAMETROS
7.1.1.1.2. Uma função que NÃO RETORNA NADA para a FUNÇÃO CHAMADORA é do tipo VOID.
7.1.1.2. Como é feita a chamada de uma função sem retorno?
7.1.1.2.1. Uma função do tipo void, TENDO ou NÃO PARÂMETROS, é chamada pelo nome, isto é, não precisará que um comando lhe anteceda. Se tiver parâmetros, eles estarão presentes entre os parênteses.
7.1.1.2.2. Imagem
7.1.1.2.3. Quando lemos o protótipo de algumas Funções sem retorno, não conseguimos visualizar todas as operações que serão realizadas.
7.1.2. B) Função COM PARÂMETROS (VOID)
8. Função COM parâmetros
8.1. Para que possamos trabalhar com funções com parâmetros, primeiro precisamos saber como a passagem para esses parâmetros é feita.
8.1.1. Passagem por Valor
8.1.1.1. Na passagem por valor, uma CÓPIA do valor, ou valores, É PASSADA PARA os parâmetros formais da FUNÇÃO CHAMADA ATRAVÉS dos parâmetros reais da FUNÇÃO CHAMADORA. Sendo que os parâmetros reais poderão estar representados por variáveis ou constantes. 1)No código ao lado temos o protótipo: int passagemPorvalor(int num1, int num2); Isso favorece na programação porque informa ao compilador que existe a função passagemPorValor e que esta função esta indicada para utilização. 2)Abaixo da main(), foi declarada as variáveis int valor1, valor2 que receberá valores digitados pelo usuário para armazenamento e manipulação. 3)Na linha cout << "\nA Soma: "<<passagemPorvalor(valor1, valor2); Esta a função chamadora, esta vai chamar a função chamada. 4) Observe que a função chamadora ver com as variáveis valor1 e valor2. Quando a função chamadora solicita a ação da função chamada ela passa uma cópia das valor1 e valor2, para a função chamada que esta declarada abaixo das {} do main, não pode criar funções dentro de funções, somente chamar. 5)A função chamada criada abaixo do {} main, tem o mesmo cabeçalho do protótipo, acima do int main(). Neste caso a função chamada foi DEFINIDA, porque tem o cabeçalho e o corpo(declaração das variáveis locais, comandos que forma o corpo e return <valor>. 6)Os valores das variáveis(valor1 e valor2) são passados por cópia, são manipulados pelo corpo do função e retorna SOMENTE com um valor numérico. 7)Esse retorno retorna como resposta para a função chamadora. E a função chamadora finaliza a ação. A função chamada poderá operar esses valores, mas não alterará os valores da função chamadora. Concordamos que para alguns poderá parecer confuso e, por essa razão vamos exemplificar com algo do cotidiano. Suponha um autor de livro e um leitor. Ao tentar entender a solução de um problema, o leitor percebe que tem um erro. Ele corrige o erro, mas não corrige o original que está na editora, visto que ele recebeu uma cópia do livro. As funções pré-definidas que você viu em Algoritmos eram todas com passagem por valor. Funções com passagem por valor podem, ou não ter retorno.
8.1.1.1.1. #include <cstdlib> #include <iostream> using namespace std; int passagemPorvalor(int num1, int num2); int main(int argc, char** argv) { int valor1, valor2; cout << "\nDigite o Numero 1 para passagem de valor: "; cin >> valor1; cout << "\nDigite o Numero 2 para passagem de valor: "; cin >> valor2; cout << "\nA Soma: "<<passagemPorvalor(valor1, valor2); cout <<"\n\n"; system("pause"); return 0; } int passagemPorvalor(int num1, int num2) { int soma; return soma = num1 + num2; }
8.1.1.2. Imagem
8.1.2. Passagem por Referência
8.1.2.1. Passagem por referência Na passagem por referência, o ENDEREÇO DA VARIÁVEL da FUNÇÃO CHAMADORA é PASSADO para a FUNÇÃO CHAMADA e dessa forma, o VALOR poderá ser ALTERADO. Na linguagem C, essa passagem tinha que ser feita através do uso da variável ponteiro e acarretava, quando não operado corretamente, em muitos problemas. Tendo em vista os problemas causados pela manipulação dos ponteiros, a linguagem C++ criou um tipo novo de dado, chamado referência que nada mais é do que uma forma de atribuir um nome alternativo(apelido ou alias) para um objeto. Esse conceito aplicado aos parâmetros formais, parâmetros da função chamada, possibilitará que a função chamada receba o endereço do valor da função chamadora, alterando-o. Esse tipo de passagem ficou mais simples do que o uso de ponteiros porque o compilador se responsabiliza por tudo. Como indicar uma referência? O operador & símbolo de endereço na linguagem C é usado com outra conotação na linguagem C++ como afirma Saade, Joel:” ... assume o papel de declarador de referências”(pág. 112).
8.1.2.1.1. Imagem
8.1.2.1.2. Imagem
9. Protótipos de funções Sem e COM Retorno
9.1. Imagem
9.2. Agora estaremos escrevendo as definições dos 4 protótipos.
9.2.1. /* * Construa uma função que receba valores que * correspondem ao caracter e à quantidade * de vezes que se deseja exibi-lo. */ #include <iostream> #include <stdlib.h> #include<cstdlib> using namespace std; void linha(char c, int n); int main() { cout << "\nEstacio\n"; linha('=', 7); cout << "\nEstruturas de Dados\n"; linha('*', 19); cout << "\nEnsino a Distancia\n"; linha('@', 18); cout << "\n\n"; system("pause"); } void linha(char c, int n) { for(int x = 1; x <= n; x++) cout << c; }
9.2.1.1. /* * Construa uma função que receba valores que correspondem ao ano atual e ao ano de nascimento de uma pessoa, retornando a idade que a pessoa terá até 31 de dezembro * */ #include <iostream> #include <stdlib.h> #include <cstdlib> using namespace std; int descobreIdade(int anoAtual, int anoNas); int main() { int anoA, anoN; cout << "\nDigite ano atual: "; cin >> anoA; cout << "\nDigite ano nascimento: "; cin >> anoN; cout << "\nVoce tera ate 31 de Dezembro de " << anoA << "\t" << descobreIdade(anoA, anoN) << " Anos"; cout << "\n\n"; system("pause"); return 0; } int descobreIdade(int anoAtual, int anoNas) { return anoAtual - anoNas; }
9.2.1.1.1. /* * Construa uma função que receba valores * que correspondem à base e à altura de um * retângulo e retorne a área. */ #include <cstdlib> #include <iostream> using namespace std; float areaRetangulo(float, float); int main(int argc, char** argv) { int base, altura; cout << "\nDigite a Base de um Retangulo: "; cin >> base; cout << "\nDigite a Altura de um Retangulo: "; cin >> altura; cout << "\nArea: " << areaRetangulo(base, altura); cout << "\n\n"; system("pause"); return 0; } float areaRetangulo(float pipoca, float milho) { return pipoca * milho; }
10. Como é feita a chamada de uma função que retorna valor? Muito Importante Isso!!!
10.1. Uma função que retorna valor deverá ser chamada através de um comando, não importando se ela tem, ou não, parâmetros. Uma Função que Retorna Valor(return), DEVERÁ SER CHAMADA ATRAVÉS DE UM COMANDO.
10.1.1. Imagem
10.1.2. Imagem
10.1.3. Imagem
11. Dúvidas?
11.1. Uma função, que não seja a main, chamando outra função poderá causar algum problema?
11.1.1. Qualquer função poderá chamar outra função desde que a função chamada já esteja declarada, ou definida.
11.1.2. Explicando: 1- A função main chamou a função juntando e como essa estava definida antes da main não teve problema. 2- A função juntando chamou a função fácil e como essa estava definida antes dela, não teve problema. 3- A função juntando também chamou a função legivel e como essa não estava definida antes dela, apareceu a mensagem na hora da compilação, informando que ela não estava declarada.
11.1.2.1. A primeira solução, para esse problema, seria colocar a função legivel() antes da função juntando().
11.1.3. Embora, a princípio, possa parecer mais simples, é sempre bom declarar as funções porque você não fica limitado à sequência das definições.
11.1.3.1. Imagem
12. Variáveis Locais & Variáveis Globais
12.1. Imagem
12.1.1. Variáveis declaradas DENTO das funções int notas(int num1, int num2) { int media; return media = (num1+num2)/2; } A esse tipo de declaração, onde as variáveis só são visualizadas nas funções onde foram declaradas, chamamos de variáveis locais.
12.2. Imagem
12.2.1. Variáveis declaradas fora do escopo de todas as funções são chamadas de variáveis globais. Esse tipo de variável poderá ser manipulado por qualquer função. int numero1, numero2, media; //Variável Global FORA de qualquer função { }. int main() { int idade; /*Variável Local -> Pois esta dentro da função main, e só pode ser manipulado dentro da main. */ return 0; }
12.2.1.1. Imagem
12.2.1.2. Usar variáveis globais poderá lhe trazer problemas na hora de debugar seu programa, pois fica complicado descobrir qual função que está alterando indevidamente.
13. Sintaxe da função main()
13.1. Imagem
13.2. O tipo int foi escolhido embora pudesse ser omitido. Mais tarde, aconteceu a remoção do int implícito. Sendo assim, o cabeçalho da main passou a ser:
13.2.1. int main()
13.2.1.1. Variação do main() pelas IDE
13.2.1.1.1. int main (int argc, char *argv[])
13.2.2. Se a main é do tipo int, então tem retorno. Porque funciona sem return?
13.2.2.1. A main é uma função chamada pelo sistema operacional e, ao finalizar, retorna, automaticamente, para o SO. Sendo pontual, o return da main poderia ser dispensável, visto que ele serve para informar que o programa foi executado com sucesso. Um bom hábito é escrever return 0; ou return EXIT_SUCCESS; em projetos maiores.
14. VETOR
14.1. Como passamos para uma função uma matriz unidimensional (vetor)
14.1.1. Falamos que só era armazenado o primeiro endereço do primeiro elemento do vetor.
14.1.2. Imagem
14.1.3. Imagem
14.1.3.1. Imagem
14.1.4. Considerações : 1- O endereço do 1o elemento do vetor é igual ao endereço do vetor. 2- Obtém-se o mesmo valor quando se pede para exibir o endereço do vetor e exibir o valor do vetor.
14.1.4.1. Imagem
15. Protótipos com PASSAGEM de VETORES para FUNÇÕES
15.1. Imagem
15.2. Construa uma função que receba o endereço um vetor que armazena notas dos alunos de uma turma e seu tamanho, retornando a média da turma. #include <iostream> #include <stdlib.h> using namespace std; double media(double [], int tam); int main() { double notas[5]; for(int x= 0; x < 5; x++) { cout << "\nNota "<<x+1<<": "; cin >> notas[x]; } cout <<"\nRelacao de notas originais\n"; for(int x = 0; x < 5; x++) { cout << notas[x]<<"\t"; } cout << "\n\nMedia da turma: "<<media(notas, 5); cout<<"\n\n"; system("pause"); return 0; } double media(double n[], int tam) { double soma = 0; for(int x = 0; x < tam; x++) { soma +=n[x]; } return soma/tam; }
15.2.1. Imagem
15.2.1.1. #include <iostream> #include <cmath> #include <stdlib.h> using namespace std; void arredonda(double a[], int tam); int main() { double notas[5]; for(int x = 0; x < 5; x++) { cout <<"\nNotas "<<x+1<<": "; cin >> notas[x]; } cout << "\nrelacao das notas originais\n"; for(int x = 0; x < 5; x++) { cout <<notas[x]<<"\t"; } arredonda(notas, 5); cout <<"\n\nrelaca das notas arrendondadas para cima\n"; for(int x = 0; x < 5; x++) { cout << notas[x]<<"\t"; } cout<<"\n\n"; system("pause"); return 0; } void arredonda(double a[], int tam) { for(int x = 0; x < tam; x++) { a[x] = ceil(a[x]); } }