Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas

apostila Cpp, Notas de estudo de Engenharia Elétrica

apostila com ensinamentos de algoritmos e instrução C++

Tipologia: Notas de estudo

2015

Compartilhado em 20/01/2015

maykon-tony-6
maykon-tony-6 🇧🇷

1 documento

1 / 103

Documentos relacionados


Pré-visualização parcial do texto

Baixe apostila Cpp e outras Notas de estudo em PDF para Engenharia Elétrica, somente na Docsity! Universidade Estadual Paulista "Júlio de Mesquita Filho" Faculdade de Engenharia de Ilha Solteira Departamento de Matemática Linguagem de Programação C++ Alan Rodrigo Panosso Fábio Roberto Chavarette 2014 Sumário Apostila C++ ..................................................................................................................................................... 1 1. Introdução ................................................................................................................................................. 1 1.1 Histórico da linguagem C++ ......................................................................................................... 1 1.2 Compilador – Tutorial de Instalação ............................................................................................ 2 1.3 Apresentando o Dev-C++ ............................................................................................................. 7 1.4 Compiladores .................................................................................................................................. 9 2. Estrutura de um programa ................................................................................................................... 12 2.1 Controle dos Fluxos de Entrada e de Saída ............................................................................ 13 2.2 Primeiro Programa ....................................................................................................................... 13 2.3 Segundo Programa ...................................................................................................................... 16 2.4 Terceiro Programa ....................................................................................................................... 18 3. Variáveis e Tipos de Dados ................................................................................................................. 19 3.1 Identificadores .............................................................................................................................. 19 3.2 Identificadores (nome das variáveis)......................................................................................... 19 3.3 Declaração de variáveis .............................................................................................................. 20 4. Constantes .............................................................................................................................................. 24 4.1 Definindo Constantes .................................................................................................................. 24 4.2 Classificação de Constantes e Variáveis ................................................................................. 25 5. Expressões ............................................................................................................................................. 26 5.1 Instruções ...................................................................................................................................... 26 5.2 Atribuição ....................................................................................................................................... 27 5.3 Expressões Aritméticas ............................................................................................................... 27 5.4 Expressões Lógicas ..................................................................................................................... 29 5.5 Tabela-verdade ............................................................................................................................ 29 5.6 Exemplo 1...................................................................................................................................... 30 5.7 Exemplo 2...................................................................................................................................... 31 5.8 Exemplo 3...................................................................................................................................... 31 6. Formatando as saídas dos programas ............................................................................................... 31 6.1 Exemplo 4...................................................................................................................................... 32 6.2 Exemplo 5...................................................................................................................................... 34 6.3 Precisão Numérica ....................................................................................................................... 35 6.4 Imprimindo Caracteres Gráficos ................................................................................................ 36 7. Controle de Fluxo de Execução - Estrutura Condicional SE ........................................................... 37 7.1 Estrutura if/else ............................................................................................................................. 37 7.2 Exemplo 6...................................................................................................................................... 42 7.3 Estrutura switch/ Escolha (caso selecione) .............................................................................. 44 7.4 Exemplo 7...................................................................................................................................... 45 7.5 Exemplo 8...................................................................................................................................... 46 7.6 Exemplo 9...................................................................................................................................... 46 7.7 Exemplo 10 ................................................................................................................................... 47 8. Laços ....................................................................................................................................................... 48 8.1 O laço for (para) ........................................................................................................................... 48 8.2 Exemplo 11 ................................................................................................................................... 52 8.3 O laço while (enquanto) .............................................................................................................. 53 8.4 O laço do-while (repetir) .............................................................................................................. 57 8.5 Exemplo 12 ................................................................................................................................... 59 8.6 Exemplo 13 ................................................................................................................................... 60 8.7 Exemplo 14 ................................................................................................................................... 60 9. Modularização ........................................................................................................................................ 61 9.1 Introdução e Histórico .................................................................................................................. 61 9.2 Modularização em pseudocódigo .............................................................................................. 62 9.3 Ferramentas .................................................................................................................................. 63 9.4 Transferência de Parâmetros ..................................................................................................... 65 9.5 Modularização em Sub-Rotinas ................................................................................................. 66 UNESP - FEIS Departamento de Matemática 2 comitê unificado ANSI e ISO em 1993 à convite de Andrew Koenig. Após uma proposta formal na reunião do ano seguinte, a biblioteca recebeu o aval do comitê. Pode-se dizer que C++ foi a única linguagem, entre tantas outras, que obteve sucesso como uma sucessora à linguagem C, inclusive servindo de inspiração para outras linguagens como Java, a IDL de CORBA e C#. 1.2 Compilador – Tutorial de Instalação Dentre os vários compiladores disponíveis, escolhemos para adotar na disciplina o Bloodshed Dev-C++, ou simplesmente Dev-C++ que é um ambiente de desenvolvimento integrado completo para as linguagens C e C++, que utiliza uma coleção de compiladores GNU. Este tutorial apresenta, de maneira simplificada, as principais etapas para a instalação do Dev-C++. Serão apresentadas a instalação no Sistema Operacional Windows 7. 1. Inicialmente Acesse o endereço http://www.bloodshed.net/devcpp.html e clique na opção "Go to Download Page", como apresentado na imagem abaixo. 2. Na próxima página localize o item Downloads. Faça o download da versão mais atual do programa, no nosso exemplo, é "Dev-C++ 5.0 beta 9.2 (4.9.9.2) (9.0 MB) with Mingw/GCC 3.4.2". Clique na opção SourceForge, e o download deverá iniciar automaticamente. UNESP - FEIS Departamento de Matemática 3 3. Após o download, localize o instalador do programa na pasta específica do seu computador e clique duas vezes para iniciar o processo de instalação. . 4. Siga os passos abaixo para a instalação do programa: a. Selecione a Linguagem "Português". b. Clique em "Aceito". UNESP - FEIS Departamento de Matemática 4 c. Clique em "Seguinte". d. Selecione "Instalar". e. Aguarde o assistente terminar a instalação do programa. UNESP - FEIS Departamento de Matemática 7 f. Ao final da aplicação, clique em "OK". g. Na janela de "Dica do Dia", marque a opção "Não exibir dicas na inicialização" e clique em fechar. 1.3 Apresentando o Dev-C++ Após a realização das etapas anteriores, será apresentado ao usuário a seguinte tela, onde podemos distinguir os seguinte elementos: Barra de Menu Barras de ferramentas Navegador de classes/projetos UNESP - FEIS Departamento de Matemática 8 Na barra de Ferramentas Menu, selecione a opção "Arquivo/Novo/Projeto...", como apresentado na imagem abaixo: Na janela "Novo Projeto", escolha o ícone "Console Application" e em "Opções de Projeto" digite no campo Nome, o nome do projeto (sem espaços ou caracteres especiais) e em seguida marque a opção "Projeto C++". Salve o projeto (.dev) em uma pasta pessoal destinada a armazenar seus projetos pessoais. UNESP - FEIS Departamento de Matemática 9 Em seguida será apresentado a Janela "Editor" com os comandos básicos para o início e desenvolvimento de um programa na linguagem C++. 1.4 Compiladores Um compilador é um programa de sistema que traduz um programa descrito em uma linguagem de alto nível para um programa equivalente em código de máquina (baixo nível) para um processador. Em geral, um compilador não produz diretamente o código de máquina, mas sim um programa em linguagem simbólica (assembly) semanticamente equivalente ao programa em linguagem de alto nível. O programa em linguagem simbólica é então traduzido para o programa em linguagem de máquina por meio de montadores. Para desempenhar suas tarefas, um compilador deve executar dois tipos de atividade. A primeira atividade Barra de Menu Barras de ferramentas Navegador de classes/projetos EDITOR UNESP - FEIS Departamento de Matemática 12 2. Estrutura de um programa Todo programa consiste em uma ou mais funções, tendo como particularidade desse fato a possibilidade de construir programas modulares e estruturados. Assim, a estrutura de um programa em C++ é: // Estrutura do C++ [<definições de pré-processamento – cabeçalhos>] [<declaração das variáveis globais>] [<tipo>] main([<parâmetros>]) { /* Este trecho é reservado para o corpo da função, com a declaração de suas variáveis locais, seus comandos e funções de trabalho*/ return[<valor>]; } [<tipo>] funçãonome([<parâmetros>]) {.... [<declaração de parâmetros>] [return; ou return(); ou return(valor);] } ] UNESP - FEIS Departamento de Matemática 13 2.1 Controle dos Fluxos de Entrada e de Saída É por meio dos fluxos de entrada e de saída que os operadores de acesso ao teclado e vídeo podem ser efetuados. Assim sendo será possível efetuar entrada (cin – console input) e saída de dados (cout – console output) para todas as operações realizadas por um programa. cin – trabalha com o teclado. cout – trabalha com o monitor. Para fazer uso básico dos fluxos cin (fluxo de entrada) e cout (fluxo de saída), é necessário inserir no início do programa a chamada ao arquivo de cabeçalho correspondente denominado iostream. Chamada do cabeçalho: #include <iostream> ou #include <iostream.h> 2.2 Primeiro Programa A melhor maneira de iniciarmos o aprendizado de uma nova linguagem de programação é escrevendo nossos próprios programas. Neste material, será adotada a seguinte estrutura, o primeiro painel mostra o código fonte para os nossos programas, e o segundo painel apresenta o resultado do programa uma vez compilado e executado. Janela Código Fonte Resultado (após compilação e execução) // Programa em C++ #include <iostream> using namespace std; int main(void) { cout << "Oi mundo" << endl; system ("Pause"); } Oi mundo Press any key to continue... O programa principal escrito em linguagem C++ é uma função, por natureza própria. UNESP - FEIS Departamento de Matemática 14 Vamos entender linha por linha do programa: // Programa em C++ Está é uma linha de comentário. Todas as linhas começando com duas barras (//) não tem qualquer efeito no comportamento de um programa. Recomendamos que, no processo de aprendizagem, várias linhas de comentários sejam adicionadas, para explicações ou observações a respeito do código. C++ apresenta duas maneiras de fazer comentários // Linha de comentário /* Bloco de comentário que pode abranger um grande número de linhas */ A primeira forma de comentário é conhecida como linha de comentário, descartando tudo a partir das duas barras (//) até o final da mesma linha. O segundo tipo é conhecido como bloco de comentário, descartando tudo entre a instrução /* e a primeira ocorrência da instrução */, com a possibilidade da inclusão mais de uma linha. #include <iostream> Linhas iniciando com o sinal (#) são diretrizes para o pré-processador, ou seja, instruções para o compilador. Neste caso, estamos dizendo ao pré-processador para incluir os arquivos padrões da biblioteca iostream. Estes arquivos específicos incluem as declarações da biblioteca básica de controle do fluxo de entrada (cin) e saída de dados (cout). UNESP - FEIS Departamento de Matemática 17 Declarando a variável como desejada, então o programa fica na espera por uma entrada do cin (teclado) para que possa armazena-la em um espaço reservado da memória. O comando cin só pode processar a entrada do teclado depois que a tecla ENTER for pressionada. No nosso exemplo, digitamos o número inteiro 5, e esse valor foi guardado dentro da variável a por meio da sentença: cin >> a; Sendo assim, mesmo que você peça um único caractere, o cin não irá processar a entrada até que o usuário pressione ENTER depois que o caractere tenha sido digitado. Deve-se atentar ao tipo da variável que estamos utilizando para guardar o valor extraído pelo cin. Se você pedir um inteiro, você receberá um inteiro, se você pedir um caractere, você receberá um caractere, e se você pedir uma string de caracteres, você receberá uma string de caracteres. cout << soma << '\n'; Observe o uso de execução do programa com o uso do caractere '\n' é semelhante ao uso do manipulador de saída endl. UNESP - FEIS Departamento de Matemática 18 2.4 Terceiro Programa Vamos estudar alguns novos comandos básicos. #include <iostream> using namespace std; int main(void) { char NOME[50], SOBRENOME[20]; cout << "Informe seu nome: "; cin.getline(NOME, sizeof(NOME)); cout << "Informe seu sobrenome: "; cin >> SOBRENOME; cout << "Ola, \n " << NOME; cout << " " << SOBRENOME << endl; system ("pause"); return 0; } Informe seu nome: Jose Informe seu sobrenome: Silva Olá Jose Silva Press any key to continue... char NOME[50], SOBRENOME[20]; Nesta instrução estamos declarando duas variáveis do tipo caractere, esses conceitos serão abordados posteriormente de maneira mais detalhada. Assim, as variáveis NOME e SOBRENOME apresentam, respectivamente, os tamanhos de 50 e 20, os quais representam o número de caracteres que poderão ser armazenados nas respectivas variáveis. Se tivéssemos declarado char NOME, essa variável seria capaz de armazenar apenas um caractere. cin.getline(NOME, sizeof(NOME)); Observe o uso da função getline() pertencente ao fluxo de entrada cin. Efetua a leitura de caracteres até que seja pressionado a tecla ENTER ou até atingir o valor máximo de caracteres permitidos. Já, a função sizeof() retorna o tamanho da variável NOME, que no caso é 50. UNESP - FEIS Departamento de Matemática 19 3. Variáveis e Tipos de Dados 3.1 Identificadores Variável é, no sentido de programação, uma região de memória de um computador, previamente identificada, que tem por finalidade armazenar as informações (dados) de um programa temporariamente. Uma variável armazena apenas um valor por vez, sendo considerado valor qualquer conteúdo armazenado em uma variável. Um valor está relacionado ao tipo de dado de uma variável, podendo ser numérico (inteiro ou real), lógico ou caractere. 3.2 Identificadores (nome das variáveis) Um identificador (nomes das variáveis, ou constantes) válido é uma sequencia de uma ou mais letras, dígitos ou underline (_). Nomes de variável podem ser atribuídos com um ou mais caracteres. Caracteres como espaços em branco, pontuações e símbolos especiais não podem ser utilizados para formar os identificadores. Identificadores de variáveis devem sempre ser inicializados por letras, ou mesmo por um underline (_). Os identificadores não devem ser iniciados por dígitos (números). Outra regra que devemos considerar é que os identificadores não podem coincidir com palavras-chaves da linguagem C++, ou palavras específicas do compilador, as quais são reservadas para o seu uso. As palavras-chaves reservadas são: asm, auto, bool, break, case, catch, char, class, const, const_cast, continue, default, delete, do, double, dynamic_cast, else, enum, explicit, export, extern, false, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, operator, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof, static, static_cast, struct, switch, template, this, throw, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_t, while, and, and_eq, bitand, bitor, compl, not, not_eq, or,or_eq, xor, xor_eq. Outro aspecto bastante importante é que a linguagem C++ é sensível ao case (case sensitive). Isso significa que um identificador escrito em letra maiúscula não é equivalente a outro identificador com o mesmo nome, mas escrito em letras minúsculas. Por exemplo, a variável RESULTADO, não é o mesmo que a variável resultado, ou Resultado. Eles são três diferentes identificadores de variáveis. Na execução de um programa, as variáveis são armazenadas na memória do computador, entretanto, o computador precisa saber que tipo de dado queremos armazenar nelas, uma vez que não se vai ocupar a mesma quantidade UNESP - FEIS Departamento de Matemática 22 double O tipo de dado double serve para armazenar números de ponto flutuante de dupla precisão, normalmente tem o dobro do tamanho e capacidade do float. #include <iostream> using namespace std; int main() { double a, b, d; a=5; b=3; d=a/b; cout << d << endl; system("Pause"); } 1.66667 Press any key to continue... Utilizando a variável double, teremos um número mais significativo de saída. O double é utilizado quando necessitamos de uma aproximação maior e mais exata do resultado. O double consome 64 bits de memória para o seu armazenamento. Esse consumo é explicado pela alta precisão de seu número (cerca de 15 decimais de precisão absoluta). O long double é usado para definir número de ponto flutuante (números fracionários com quinze dígitos decimais de precisão absoluta) de 80 bits. char O tipo char ocupa 1 byte, e serve para armazenar caracteres ou inteiros. Isso significa que o programa reserva um espaço de 8 bits na memória RAM ou em registradores do processador para armazenar um valor (char de tamanho maior que 8 bits é permitido pela linguagem, mas os casos são raros). #include <iostream> using namespace std; int main() { char nome[8]; cout << "Digite seu nome: ";cin >> nome; cout << "Seu nome e: " << nome << endl; system("Pause"); } Digite seu nome: Marcos Seu nome e: Marcos Press any key to continue... No nosso exemplo, pode-se guardar uma variável do tipo caractere com até 20 caracteres de comprimento, caso exceda o número máximo de caracteres, ocasionará erro no compilador. Caso fosse declarado apenas "char nome", a variável nome armazenaria apenas uma letra, por exemplo, se o usuário digitasse um nome com 7 letras, a variável apenas armazenaria a primeira letra digitada. A linguagem de programação C++ utiliza de duas formas: Utilizando apenas um caractere delimitado por apóstrofos 'e'; Ou uma sequência de caracteres delimitador por aspas "ee"; UNESP - FEIS Departamento de Matemática 23 string São variáveis tipo caracteres que podem armazenar valores maiores que um caractere simples. A biblioteca <string> fornece esse suporte. Não é tipo fundamental de variável, mas se comporta como um tipo fundamental. Para declararmos variáveis como string precisamos incluir uma linha adicional no cabeçalho do programa, o arquivo #include <string>. #include <iostream> #include <string> using namespace std; int main() { string nome; nome = "Marcos da Silva"; cout << nome << endl; nome = "Podemos mudar uma string"; cout << nome << endl; system("Pause"); } Marcos da Silva Podemos mudar uma string Press any key to continue... bool Os tipos de dados lógicos (tipo booleano) possuem apenas um de dois valores: true (verdadeiro = 1) e false (falso = 0) e são referenciados pela palavra- chave bool. Eles são utilizados para verificar o resultado de uma notificação ou expressão lógica. #include <iostream> using namespace std; int main() { bool t1, t2, t3; t1 = (4>=6);//falso t2 = true;//verdadeiro t3 = (true || 5==25/5;//verdadeiro cout << t1 << endl; cout << t2 << endl; cout << t3 << endl; system("Pause"); } 0 1 1 Press any key to continue... UNESP - FEIS Departamento de Matemática 24 4. Constantes Constante é tudo aquilo que é fixo ou estável. Em programação existirá vários momentos em que este conceito deverá estar em uso. Por exemplo, o valor 1.23 da fórmula seguinte é uma constante explícita: RESULTADO = ENTRADA * 1.23. É necessário para programar, ter conhecimento de constantes e seus respectivos significado, praticamente todos os programas fazem uso delas. São indispensáveis para a criação de programas de forma rápida e mais eficiente. Assim, as constantes são expressões com valor fixo. A linguagem C++ introduz um novo modificador chamado const, que tem comportamento variado dependendo do local onde está sendo declarado. Sua função, basicamente, é estabelecer um vínculo entre declaração e obrigatoriedade da coerência no uso do símbolo declarado. A princípio, quando declaramos uma constante com este modificador fazemos com que seja obrigatório o uso do símbolo de forma que o mesmo não possa ter seu valor alterado. Assim, se fizermos: const int x = 4; O inteiro x não poderá deixar de ter valor igual a 4. Qualquer tentativa de modificar o valor da constante ao longo do programa será reportada como erro pelo compilador. 4.1 Definindo Constantes Podemos definir os nomes de nossas constantes sem o consumo de memória, simplesmente utilizando o comando #define do pré-processador. #define identificador value #include <iostream> #define PI 3.14159 #define NL '\n' using namespace std; int main() { double raio=5, circulo; circulo=2*PI*raio; cout << circulo; cout << NL;cout << NL; system("Pause"); } 31.4159 Press any key to continue... UNESP - FEIS Departamento de Matemática 27 5.2 Atribuição Um comando de atribuição permite-nos fornecer um valor a uma variável, em que o tipo de dado deve ser compatível com o tipo da variável, isto é, somente podemos atribuir um valor lógico a uma variável capaz de comportá-lo. Em C++ o sinal de igual "=" é o símbolo de atribuição, por meio dele armazenamos valores ou resultados de expressões nas variáveis anteriormente declaradas com o mesmo tipo primário do dado que estamos atribuindo a ela. Exemplo: A = 5; Esta instrução atribuí o valor inteiro 5 à variável A. A parte a esquerda do sinal de igual (=) deve sempre ser uma variável, enquanto a parte à direita do sinal de atribuição pode ser uma constante, uma variável, um resultado de uma operação, ou qualquer combinação destes. A regra mais importante é que a atribuição é realizada da direita-para-a-esquerda, e nunca no outro sentido. 5 = A; Não faz sentido essa atribuição, então, o programa retorna um erro. 5.3 Expressões Aritméticas Expressões aritméticas são aquelas cujos operadores são aritméticos e cujos operandos são constantes, ou variáveis do tipo numérico (inteiro ou real). Chamamos de operadores aritméticos o conjunto de símbolos que representa as operações básicas da matemática, em C++ os principais operadores são: Operator Função Exemplos + Adição 2 + 3, X + Y - Subtração 4 – 2, N – M * Multiplicação 3 * 4, A * B / Divisão 10/2, X1/X2 ++ Incremento i++ equivale a i=i+1 -- Decremento i-- equivale a i=i-1 Demais operações estão disponíveis em C++, por exemplo, as operações de radiciação e potenciação, observe a tabela: Operator Função Exemplos pow(x,y) x elevado a y pow(2,3) sqrt(x) Raiz quadrada de x sqrt(9) UNESP - FEIS Departamento de Matemática 28 Tais função podem ser utilizadas desde que adicionado ao cabeçalho do programa a biblioteca <math.h>, a qual apresenta várias funções matemáticas e trigonométricas, dentre elas temos também: sin(): Retorna o valor do seno. Recebe como argumento o valor dos graus em double. cos(): Retorna o valor do co-seno. Recebe como argumento o valor dos graus em double. tan(): Retorna o valor da tangente. Recebe como argumento o valor dos graus em double. log(): Retorna o valor do logaritmo na base 2. Exige um argumento do tipo double. log10(): Retorna o valor do logaritmo na base 10. Exige um argumento do tipo double. Usaremos outras operações matemáticas não-convencionais, porém, muito úteis na construção de programas, que são o resto e o quociente de divisão inteira: Operator Função Exemplos % Resto da divisão 9 % 4 resulta em 1 27 % 5 resulta em 2 int(x/y) Quociente da divisão int(9/4) resulta em 2 int(27/5) resulta em 5 No caso do quociente da divisão, se as variáveis x e y forem reais (float ou double) será necessário utilizar a função int(x/y) para obtenção do quociente da divisão, caso contrário, se as variáveis forem inteiros (int ou long), o resultado da expressão x/y será o quociente da divisão. Na resolução das expressões aritméticas, as operações guardam uma hierarquia entre si: Prioridade Operadores 1ª Parênteses mais internos 2ª Potenciação, radiciação e funções trigonométricas 3ª * / int() % 4ª + - Em caso de empate (operadores de mesma prioridade), a resolução ocorre da esquerda para a direita, conforme a sequência existente na expressão trigonométrica. Para alterar a prioridade, utilizamos os parênteses mais internos. UNESP - FEIS Departamento de Matemática 29 5.4 Expressões Lógicas Denominamos expressão lógica aquela cujos operadores são lógicos ou relacionais e cujos operandos são relações ou variáveis do tipo lógico. Utilizamos os operadores relacionais para realizar comparações entre dois valores de mesmo tipo primitivo. Tais valores são representados por constantes, variáveis, ou expressões aritméticas. Os operadores relacionais são comuns para construirmos equações. Em C++ são eles: Operator Função Exemplos > Maior que 5 > 4, x > y >= Maior ou igual a 5 >= 3, X >= y < Menor que 3 < 6, x < y <= Menor ou igual a 3 <= 5, x <= y == Igual a 3==3, x == y != Não igual (diferente) 8 != 9, x != y O resultado obtido de uma relação sempre é um valor lógico. Por exemplo, analisando a relação numérica A + B == C, o resultado será verdade (1) ou falsidade (0) à medida que o valor da expressão aritmética A + B seja igual ou diferente do conteúdo da vaiável C, respectivamente. Utilizamos três operadores lógicos básicos para a formação de novas proposições lógicas compostas a partir de outras proposições lógicas simples. Os operadores lógicos são descrito na tabela abaixo. Operator Função Exemplos ! Não (negação) ! (3 > 5) && E (conjunção) 3 > 5 && 4 < 8 || Ou (disjunção) 3 > 5 || 4 < 8 5.5 Tabela-verdade Tabela-verdade é o conjunto de todas as possibilidades combinatórias entre os valores de diversas variáveis lógicas, as quais se encontram em apenas duas situações Verdadeiro (true equivale a 1) ou Falso (false equivale a 0), e um conjunto de operadores lógicos. Observe o programa abaixo: #include <iostream> using namespace std; int main() { cout << !(5 == 5) << endl; cout << !(6 <= 5) << endl; cout << !true << endl; cout << !false << endl; system("pause"); } 0 1 0 1 Press any key to continue... UNESP - FEIS Departamento de Matemática 32 6.1 Exemplo 4 Faça um programa que calcule o salário líquido de um profissional que trabalhe por hora. Para tanto, é necessário possuir alguns dados básicos, tais como valor da hora de trabalho, número de horas trabalhadas no mês e o percentual de desconto do INSS, para que seja possível apresentar os resultados do valor do salário bruto, valor de desconto e o valor do salário liquido. Após o programa escrito, Entre com : 10.33, 12.5 e 6.5 e a saída deve ser: 129.125, 8.39312 e 120.732. # include <iostream> using namespace std; int main(void) { float HT, VH, PD, TD, SB, SL; cout << "Entre com a quantidade de horas trabalhadas.: "; cin >> HT; cout << "Entre com o valor da hora de trabalho..............: "; cin >> VH; cout << "Entre com o valor do percentual de desconto..: "; cin >> PD; SB = HT * VH; TD = (PD / 100) * SB; SL = SB - TD; cout << "O Salario Bruto....: " << SB << endl; cout << "Desconto..............: " << TD << endl; cout << "O Salario Liquido.: " << SL << endl; system ("pause"); return 0; } Saída do programa: Apesar das saídas do programa estarem certas, elas estão sem nenhum formato. Para utilizar esses recursos, é necessário fazer a inclusão do arquivo de cabeçalho <iomanip>. Para definir a quantidade de casas decimais a ser apresentada em um fluxo de saída após o ponto decimal, deve-se utilizar o manipulador setprecision(), o qual possui como parâmetro o número de casas decimais a ser definido. Para fixar a apresentação do ponto decimal (valor decimal), mesmo quando o resultado for um valor de formato inteiro, deve-se fazer o uso do manipulador setiosflag(), o qual deve-se utilizar como parâmetro o sinalizador UNESP - FEIS Departamento de Matemática 33 de formato (flag) ios:fixed, que direciona a saída para apresentar o ponto decimal. Parâmetros do manipulador setiosflag(): setiosflags – acionar diversos recursos de sinalização de formatos. resetiosflags – desativar o recurso. Assim, os manipuladores de tamanho são: setw Seleciona o tamanho de próximo campo a ser impresso. setprecision Define o número de casas decimais a ser impressas para um número em ponto flutuante. setfill Seleciona o caractere que deverá preencher as colunas em branco iniciais de um campo. setiosflags Seleciona o modo de apresentação de um número (com ponto decimal, notação científica etc.). UNESP - FEIS Departamento de Matemática 34 6.2 Exemplo 5 Vamos reescrever o programa anterior definindo o formato da saído do programa para duas casas decimais. Entre com : 10.33, 12.5 e 6.5 e a saída deve ser: 129.13, 8.39 e 120.73. #include <iostream> #include <iomanip> using namespace std; int main(void) { float HT, VH, PD, TD, SB, SL; cout << setprecision(2); //Fixa em duas casas decimais cout << setiosflags(ios::right); //Tabulação a partir da direita cout << setiosflags(ios::fixed); //Estabelece a apresentação do ponto decimal cout << "Entre com a quantidade de horas trabalhadas.: "; cin >> HT; cout << "Entre com o valor da hora de trabalho..............: "; cin >> VH; cout << "Entre com o valor do percentual de desconto..: "; cin >> PD; SB = HT * VH; TD = (PD / 100) * SB; SL = SB - TD; cout << "O Salario Bruto....: " << setw(8) << SB << endl; cout << "Desconto..............: " << setw(8) << TD << endl; cout << "O Salario Liquido.: " << setw(8) << SL << endl; system ("pause"); return 0; } Saída do programa: Compare a saída atual com a saída do programa escrito no exemplo anterior. A definição da largura do campo é realizada pela função setw(8). Observe o programa abaixo que exemplifica a função setw(). #include <iostream> #include <iomanip> using namespace std; int main(void) { int lapis=45, borrachas=2354, cadernos=8; cout << "Lapis " << lapis << endl; cout << "Borrachas " << borrachas << endl; cout << "Cadernos " << cadernos << endl; system ("pause"); return 0; } Lapis 45 Borrachas 2354 Cadernos 8 Press any key to continue... UNESP - FEIS Departamento de Matemática 37 7. Controle de Fluxo de Execução - Estrutura Condicional SE Também conhecidos como comando de desvio, a estrutura condicional SE permite que o programa decida autonomamente entre dois caminhos possíveis, qual irá executar. Os métodos de tomada de decisão no C++, estão presentes para as tarefas mais corriqueiras que o programa deve executar. Além desta forma de controle de decisões, C++ provê certas funcionalidades relacionadas a objetos que modificam a forma como o código é estruturado e, por consequência, decidem como o programa deve se comportar em determinadas situações. Examinemos os métodos básicos e analisemos de forma simples as estruturas de decisão, para entender como isso poderá nos ajudar a tornar o código mais bem construído. Neste contexto, precisamos definir os chamados Blocos de Comandos, os comandos na nossa linguagem são escritos um por linhas, já um bloco de comandos é uma série de comandos, portanto, em um bloco ou todos os comandos são executados ou nenhum é executado. Em C++ os blocos de comandos são definidos entre chaves ({ }). Esse conceito é fundamental para o desenvolvimento de programas em C++, uma vez que o fluxo de execução de um programa muitas vezes se divide onde somente um dos blocos de comando é executado. 7.1 Estrutura if/else Uma ação muito importante que o processador de qualquer computador executa, e que o torna diferente de qualquer outra máquina, é a tomada de decisão definindo o que é verdadeiro e o que é falso. Se quisermos fazer um bom programa, esse programa deve ser capaz de definir caminhos diferentes de acordo com decisões que o próprio programa toma. Para isso, precisamos de uma estrutura seletiva da qual o único valor possível é o bit 1 ou 0, resumindo: retornar o valor VERDADEIRO (true) ou FALSO (false). UNESP - FEIS Departamento de Matemática 38 Forma Geral do comando SE em pseudocódigos pode ser definida como: Caso o bloco de comandos depois do senão seja vazio, esta parte pode ser omitida. A forma geral simplificada é, portanto: Em muitas linguagens de programação, quem faz isso é o "if", ou seja, se uma dada condição for verdadeira, faça tal ação. O "else" é o que chamamos de caso contrário, ou seja, se for falso execute o que está no ELSE. A Ideia é selecionaremos apenas uma ação ou um único conjunto de ações (bloco de comandos), não podendo realizar 2 condições diferentes. Assim, a estrutura de seleção permite a escolha de um grupo de ações (bloco) a ser executado quando determinadas condições, representadas por expressões lógicas UNESP - FEIS Departamento de Matemática 39 e/ou relacionais, são satisfeitas ou não. Os tipos de seleção são: Simples, Composta, Encadeada e Múltipla Escolha. Seleção Simples: Quando precisamos testar 01 condição antes de executar uma ação. Ocorre somente se a condição for VERDADEIRA. if (condição) { Declaração; } Neste caso o bloco de comandos é executado somente se a condição for verdadeira, caso contrário o algoritmo prossegue normalmente. Seleção Composta: Utilizadas em situações em que duas alternativas dependem de uma mesma condição, uma da condição VERDADEIRA, e outra da condição FALSA. if (condição) { declaração 1; } else { declaração 2; } Exemplo de Comando SE. UNESP - FEIS Departamento de Matemática 42 Como construir sem aninhamento Exemplo anterior Sem aninhamento 7.2 Exemplo 6 Uma empresa vai dar um abono aos empregados que tenham mais de 1 ano de casa:10% para os que tenham menos de 10 anos e 25% para os demais. Calcule o abono de um dado funcionário, dado o seu salário e o tempo de casa. O algoritmo acima em C++ será: #include <iostream> using namespace std; int main(void) { float tempo, salario; cout << "Entre com o salario: "; cin >> salario; cout << "Entre com o tempo de servico: "; cin >> tempo; if(tempo>1) if(tempo <10) salario=1.1*salario; else salario=1.25*salario; UNESP - FEIS Departamento de Matemática 43 cout << " Salario com abono = "<< salario << endl; system ("pause"); return 0; } Seleção Composta: É o agrupamento de várias seleções, ocorre quanto uma determinada ação, ou bloco deve ser executado se um grande conjunto de possibilidades ou combinações de situações for satisfeito. if(condição 1) { declaração1; } else if(condição 2) { declaração 2; } ... else if(condição (N-1)) { declaração (N-1) } else { declaração N; } Observe que podemos criar um programa com quantas condições desejarmos, restringindo a cada condição, uma ação ou um conjunto de ações. Um dos erros mais comuns é criar condições redundantes, como mostra o seguinte exemplo: Elabore um programa que diga qual ação, ou ações foram escolhidas: a) Ação 1: caso o número seja maior ou igual a 2. b) Ação 2: caso o número seja maior que 1. c) Ação 3: caso não seja satisfeita nenhuma condição. cin>>a; if (a>=2) { cout<<"Ação 1 escolhida"<<endl; } else if (a>1) { cout<<" Ação 2 escolhida"<<endl; } else { cout<<" Ação 3 escolhida"<<endl; } UNESP - FEIS Departamento de Matemática 44 Observe que o erro encontra-se no uso do "else if”, com ele, excluímos possibilidades possíveis de respostas. Por exemplo, se a variável a=3, o compilador nos dará como saída apenas a primeira condição ("Ação 1 escolhida”), onde na verdade temos duas respostas, pois satisfaz a ação 1 e 2 simultaneamente. Se substituirmos o if no lugar do else if, o compilador nos dará as 2 respostas possíveis ("Ação 1 escolhida” e "Ação 2 escolhida”), com isso, corrigiríamos o problema da redundância do nosso exemplo. Com o uso apenas do if e do else é possível que compilador execute várias condições que ocorram simultaneamente. 7.3 Estrutura switch/ Escolha (caso selecione) Textualmente conhecida como alternativa de múltiplas escolhas, é uma alternativa para os SES aninhados, deixando o algoritmo com uma estrutura melhor. Quando um conjunto de valores discretos precisa ser testado e ações diferentes são associadas a esses valores, pode-se utilizar a seleção de múltipla escolha (switch). O objetivo é testar vários valores constantes possíveis para uma expressão, semelhante à seleção composta. Ou seja, é quase que um if com várias possibilidades, mas com algumas diferenças importantes: Primeira diferença: Os cases não aceitam operadores lógicos. Portanto, não é possível fazer uma comparação. Isso limita o case a apenas valores definidos. UNESP - FEIS Departamento de Matemática 47 cout << "digite o numero: "; cin >> a; if (a==0) cout << "O número digitado e nulo" << endl; else if (a>0) cout << "O número digitado e positivo" << endl; else cout << "O número digitado e negativo" << endl; system("Pause"); } 7.7 Exemplo 10 Elabore um programa que identifique se um número inteiro digitado é par, impar ou nulo. #include <iostream> using namespace std; int main() { int n; cout << "digite o numero: "; cin >> n; if (n%2==0) { if(n==0) { cout << "nulo" << endl; } else { cout << "par" << endl; } } else { cout<<"impar"<<endl; } system("Pause"); } UNESP - FEIS Departamento de Matemática 48 8. Laços Laços são comandos usados sempre que uma ou mais instruções devam ser repetidas enquanto uma certa condição estiver sendo satisfeita. Em C++ existem três comandos de laços: for while do-while 8.1 O laço for (para) O laço for é em gral usando quando queremos repetir algo um número fixo de vezes. Isso significa que utilizamos um laço for quando sabemos de antemão o numero de vezes a repetir. O exemplo seguinte imprime uma linha com 20 asteriscos (*) utilizando um laço for na sua forma mais simples. #include <iostream> using namespace std; int main() { int i; for(i=0; i < 20; i++ ) cout << '*'; cout << endl; system ("PAUSE"); return 0; } ******************** Press any key to continue... A sintaxe consiste na palavra-chave for seguida de parênteses que contêm três expressões separadas por ponto-e-vírgula. Chamaremos a primeira dessas expressões de inicialização, a segunda de teste e a terceira de incremento. Qualquer uma das três pode conter qualquer instruções em C++. Em sua forma mais simples, a inicialização é uma instrução de atribuição (i = 0) e é sempre executada uma única vez, antes que o laço seja iniciado. O teste é uma condição avaliada como verdadeira ou falsa e controla o laço (i < 20). Essa expressão é avaliada toda vez que o laço é iniciado ou reiniciado. Se verdadeira (diferente de zero), a instrução do corpo do laço é executada (cout << '*'). Quando o teste torna-se falso (igual a zero), o laço é encerrado e o controle passa para a instrução seguinte ao laço. O incremento geralmente define a maneira pela qual a variável de controle será alterada cada vez que o laço for repetido (i++ o mesmo que i=i+1). Essa expressão é executada sempre, logo após a execução do corpo do laço. UNESP - FEIS Departamento de Matemática 49 for(i=0; i < 20; i++ ) { cout << '*'; } No nosso exemplo, o laço for é executado 20 vezes. Na primeira vez, a inicialização assegura que i vale zero. Na última vez, i vale 19; a informação é dada no teste (i<20). Em seguida, i passa a valer 20 e o laço termina. O corpo do laço não é executado quando i vale 20. O programa abaixo escreve os números e 1 a 5. #include <iostream> using namespace std; int main() { int i; for (i = 1; i <= 5; i++) cout << i; cout << endl; system ("PAUSE"); return 0; } 12345 Press any key to continue... O programa abaixo a mesma operação que o anterior, entretanto, observe o incremento. #include <iostream> using namespace std; int main() { int i; for (i = 1; i <= 5; i=i+1) cout << i; cout << endl; system ("PAUSE"); return 0; } 12345 Press any key to continue... Inicialização Ponto-e-vírgula Incremento Teste Não tem Ponto-e-vírgula aqui Corpo do laço UNESP - FEIS Departamento de Matemática 52 int main() // Início; { float soma=0.0; const int max=10; for(int i =0; i< max; i++) { cout << "\nDigite a nota " << (i+1) <<" : "; float nota; cin >> nota; soma+=nota;//soma=soma+nota; } cout << "\nMedia = " << (soma/max) << endl; system("Pause"); return(0); } Um aspecto importante dos blocos de código é o de que uma variável declarada dentro de um bloco não é visível fora dele. Ou seja, no programa anterior, declaramos a variável nota dentro do bloco do código do laço for. Essa variável só poderá se acessada pelas instruções desse mesmo bloco e que estão após a sua declaração. 8.2 Exemplo 11 Faça um programa que leia o número de termos, determine e mostre os valores de acordo com a série a seguir: Dica: #include <iostream> using namespace std; int main() { int i, num_termos=0, num1=2, num2=7, num3=3; cout << "Entre com o numero de termos da serie: "; cin >> num_termos; cout << num1 << endl << num2 << endl << num3 <<endl; for (i=4; i<=num_termos; i++) { num1 = num1*2; cout << num1 <<endl; i=i+1; if (i!=num_termos) { num2 = num2*3; UNESP - FEIS Departamento de Matemática 53 cout << num2 <<endl; i = i+1; if (i!=num_termos) { num3 = num3*4; cout << num3 <<endl; i = i+1; } } } system("PAUSE"); return EXIT_SUCCESS; } 8.3 O laço while (enquanto) O segundo comando de laço em C++ é o while (do inglês que significa enquanto). À primeira vista, o laço parece simples se comparado ao laço for, utiliza os mesmo elementos, mas eles são distribuídos de maneira diferentes no programa. Utilizamos o laço while quando o laço pode ser terminado inesperadamente, por condição desenvolvida dentro do corpo do laço. Trata-se de uma estrutura de repetição que pode ser utilizada quando o número de repetições necessárias não é fixo. Assim, os comandos serão repetidos até a condição assumir o valor falso. Nesse tipo de estrutura, o teste condicional ocorre no início. Isto significa que existe a possibilidade da repetição não ser executada quando a condição assumir valor falso logo na primeira verificação. O comando while consiste na palavra-chave while seguida de uma expressão de teste entre parênteses. Se a expressão de teste for verdadeira, o corpo do laço while é executado uma vez, e a expressão de teste é válida novamente. Esse ciclo de teste e execução é repetido até que a expressão de teste se torne falsa, então, o laço termina e o controle do programa passa para a linha seguinte ao laço. O corpo de um while pode ter uma única instrução terminada por um ponto-e-vírgula, várias instruções entre chaves ou ainda uma nenhuma instrução mantendo o ponto-e-vírgula. Em geral, um laço while pode substituir um laço for da seguinte maneira em um programa: Inicialização; while( Teste) { . . Incremento; . } UNESP - FEIS Departamento de Matemática 54 Em geral, um laço while pode substituir um laço for da seguinte maneira em um programa: #include <iostream> using namespace std; int main() { int i=0; //Incicialização while(i < 20) //Teste { cout << '*'; i++; //Incremento } cout << endl; system ("PAUSE"); return 0; } ******************** Press any key to continue... Em situação em que o número de iterações é conhecido o laço for é a escolha mais natural. Enquanto a condição for verdadeira, os comandos que estão dentro das chaves serão executados, observe o programa abaixo: #include <iostream> using namespace std; int main () { int X = 0; while (X != 5) { cout << "Valor de X = " << X << endl; X = X+1; } cout<<"X depois de sair do while = " << X; cout << endl; system("Pause"); return 0; } Valor de X = 0 Valor de X = 1 Valor de X = 2 Valor de X = 3 Valor de X = 4 X depois de sair do while = 5 Press any key to continue... Neste programa, os comandos cout << "Valor de X = " << X; e X = X+1; serão executados 5 vezes. O teste condicional avaliará X valendo 0,1, 2, 3, 4 e 5. UNESP - FEIS Departamento de Matemática 57 8.4 O laço do-while (repetir) Este é o terceiro e último comando de laço em C++. Este é bastante similar ao laço while e é utilizado em situações em que é necessário executar o corpo do laço uma primeira vez e depois avaliar a expressão de teste e criar um ciclo repetido. Trata-se de uma estrutura de repetição que pode ser utilizada quando o número de repetições necessárias não é fixo. Os comandos serão repetidos até a condição assumir o valor falso. A sintaxe do laço do-while é: Inicialização; do { . . Incremento; . }while(Teste); O comando do-while consiste na palavra-chave do seguida de um bloco de uma ou mais instruções entre chaves e termina pela palavra-chave while seguida de uma expressão de teste entre parênteses terminada por um ponto-e- vírgula. Primeiro, o bloco de código é executado; em seguida, a expressão de teste entre parênteses é avaliada; se verdadeira, o corpo do laço é mais uma vez executado e a expressão de teste é avaliada novamente. O ciclo de execução do bloco e teste é repetido até que a expressão se torne falsa (igual a zero), então o laço termina e o controle do programa passa para a linha seguinte ao laço. Observe o exemplo abaixo: #include <iostream> using namespace std; int main () { int X = 0; do { cout << "\nValor de X = " << X; X = X+1; }while (X != 5); cout << "\nX depois de sair do repetir" << X; cout << endl; system("Pause"); return 0; } Valor de X = 0 Valor de X = 1 Valor de X = 2 Valor de X = 3 Valor de X = 4 X depois de sair do repetir = 5 Press any key to continue... No trecho de programa acima, o comando cout << "Valor de X = " << X; e X=X+1; serão executados 5 vezes. O teste condicional avaliará X valendo 0,1, 2, 3, 4 e 5. UNESP - FEIS Departamento de Matemática 58 Observe o exemplo abaixo: #include <iostream> using namespace std; int main () { int X = 1, Y=10; do { cout << "\nValor de Y = " << Y; Y = Y-1; }while (Y > X); cout << "\nY depois que sair do repetir = " << Y; cout << endl; system("Pause"); return 0; } Valor de Y = 10 Valor de Y = 8 Valor de Y = 6 Valor de Y = 4 Valor de Y = 2 X depois de sair do while = 0 Press any key to continue... No trecho de programa acima, os comandos cout << “Valor de Y = “ << Y; e Y = Y-2; serão executados 5 vezes. O teste condicional avaliará Y valendo 10, 8, 6, 4, 2 e 0. Analise o exemplo: UNESP - FEIS Departamento de Matemática 59 #include <iostream> using namespace std; int main () { int X = 1, Y=1; do { cout << "Valor de X = " << X << endl; X = X+1; } while (X < Y); cout<<"Acabou o repetir"; cout << endl; system("Pause"); return 0; } Valor de X = 1 Acabou o repetir Press any key to continue... No trecho de programa acima, os comandos cout << "Valor de X = " << X; e X=X+1; serão executados 1 vez independente da condição ser falsa, pois os valores iniciais de X e Y serão verificados no final da estrutura. Agora, observe um exemplo de laço infinito: #include <iostream> using namespace std; int main () { int X = 1, Y=1; do { cout << "Valor de X = " << X << endl; } while (X <= Y); cout<<"Acabou o repetir"; cout << endl; system("Pause"); return 0; } Valor de X = 1 Valor de X = 1 Valor de X = 1 Valor de X = 1 Valor de X = 1 Valor de X = 1 Valor de X = 1 Valor de X = 1 Valor de X = 1 Valor de X = 1 Valor de X = 1 No trecho de programa acima, o comando cout << "Valor de X = " << X; e executados infinitamente, pois os valores de X ou Y não são modificados em nenhum momento do laço de repetição, não contrariando a condição do laço, tornando-o um laço infinito. 8.5 Exemplo 12 Elabore um programa que calcule o fatorial de um número dado. #include <iostream> using namespace std; int main() { int n; cout << "digite o numero: "; cin >> n; int fat=1; for(int i=1; i<=n; i++) fat=fat*i; UNESP - FEIS Departamento de Matemática 62 9.2 Modularização em pseudocódigo Seja um algoritmo para calcular o salário liquido de um empregado, com as seguintes etapas: início Leia os dados do empregado Determine o salário Escreva o salário fim. Onde "Determine o salário" pode ser refinado como:  Calcule as vantagens  Calcule as deduções SALARIOLIQ  VANTAGENS – DEDUCOES No refinamento sem modularização não houve preocupação de como o processo de cálculo das vantagens e deduções seria efetuado. Essas ações constituem funções bem definidas e que serão executadas por módulos específicos, neste caso, o algoritmo anterior ficaria: início Leia os dados do empregado Ative o módulo "Calculo das vantagens" Ative o módulo "Calculo das deduções" SALARIOLIQ ← VANTAGENS – DEDUCOES Escreva o salário fim. Exemplo da descrição estrutural da modularização: Módulo Principal Módulo Vantagens Módulo Deduções UNESP - FEIS Departamento de Matemática 63 A maneira mais intuitiva de proceder a modularização de problemas e feita definindo um módulo principal de controle e módulos específicos para as funções do algoritmo. Recomenda-se que os módulos de um programa tenham um tamanho limitado, pois módulos muito grandes são difíceis de ser compreendidos e, em geral, são multifuncionais. LEMA : "Dividir para conquistar" Nunca divida de menos e nunca divida de mais As linguagens de programação dispõem de recursos que facilitam a construção e manipulação de módulos, permitindo não só a modularização dos comandos do programa, como também dos dados utilizados. Cada módulo pode definir as próprias estruturas de dados, suficientes e necessárias apenas para atingir o objetivo final do módulo. Todo módulo e constituído por uma sequência de comandos que operam sobre um conjunto de objetos, que podem ser globais ou locais.  Objetos globais são entidades que podem ser usadas em módulos internos a outro modulo do algoritmo onde foram declaradas.  Objetos locais são entidades que só podem ser usadas no módulo do algoritmo onde foram declaradas. Estes objetos não possuem nenhum significado fora deste módulo.  São exemplos de objetos globais ou locais: variáveis, arquivos, outros módulos, etc.  A comunicação entre módulos devera ser feita através de vínculos, utilizando-se objetos globais ou transferência de parâmetros. Os benefícios da modularização são que a independência do módulo permite uma manutenção mais simples e evita efeitos colaterais no restante do algoritmo.  A elaboração do modulo pode ser feita independentemente e em épocas diferentes do restante do algoritmo;  Testes e correções dos módulos podem ser feitos separados;  Um módulo pode ser utilizado em outros algoritmos que requeiram o mesmo processamento por ele executado. 9.3 Ferramentas Sub-rotinas e funções são módulos que servem aos objetivos:  Evitar que em certa sequência de comandos necessária em vários locais de um algoritmo tenha que ser escrita repetidamente nesses locais;  Dividir e estruturar um algoritmo em partes fechadas e logicamente coerentes;  Aumentar a legibilidade de um algoritmo. UNESP - FEIS Departamento de Matemática 64 Sub-rotinas e funções são módulos hierarquicamente subordinados a um algoritmo, comumente chamado de módulo principal. Da mesma forma uma sub- rotina ou uma função pode conter outras sub-rotinas e funções aninhadas. A sub-rotina e a função são criadas através das suas declarações em um algoritmo e para serem executadas, necessitam de ativação por um comando de chamada. A declaração de uma sub-rotina ou função e constituída de um cabeçalho, que a identifica e contem seu nome e uma lista de parâmetros formais, e de um corpo que contem declarações locais e os comandos. Sub-rotinas Criação de sub-rotina: subrotina NOME (lista-de-parâmetros-formais) declarações dos objetos locais a sub-rotina comandos da sub-rotina fim subrotina; Chamada da sub-rotina: NOME (lista-de-parâmetros-atuais); Funções As funções têm a característica de retornar ao algoritmo que as chamou um valor associado ao nome da função. - Criação de função: função tipo NOME (lista-de-parâmetros-formais) declarações dos objetos locais a função comandos da função retorno valor fim função; - Chamada da função: NOME (lista-de-parâmetros-atuais); Como esta função ira retornar (retorno) um valor, este pode ser atribuído a alguma variável, contanto que esta seja de tipo compatível. A  NOME (lista-de-parâmetros-atuais); Ao terminar a execução dos comandos de uma sub-rotina ou função, o fluxo de controle retorna ao comando seguinte àquele que provocou a chamada. UNESP - FEIS Departamento de Matemática 67 carregado uma vez e pode ser executado quantas vezes forem necessárias. As principais vantagens da utilização se sub-Rotinas são que como o problema pode ser subdividido em pequenas tarefas, os programas tendem a ficar menores e mais organizados. Os programas em geral são executados linearmente, uma linha após a outra, até o fim. Entretanto, quando são utilizadas sub-rotinas, é possível a realização de desvios na execução dos programas. Sintaxe: função nome () entradas: nono, nonono[], nono, ... saídas: nono, nonono, nono[], ...) inicio { comandos } nome ← ... fim O exemplo abaixo mostra a utilização de uma sub-rotina que recebe um parâmetro (o valor atual do salário) e que, ao final, retorna um valor (aumento que será dado ao salário) para quem a chamou. Porém, as sub-rotinas podem não receber parâmetros nem retornar valor. 9.6 Modularização em C++ - Funções Um programa em C/C++ tem no mínimo uma função de chamada main, por onde a execução começa. Existem as funções pré-definidas pelo compilador, que são incluídas pela diretiva #include. ALGORITMO DECLARE sal NUMERICO LEIA sal aum ← calculo(sal) novosal ← sal + aum ESCREVA "Novo salário é", novosal FIM_ALGORITMO SUB-ROTINA calculo (sal NUMERICO) DECLARE perc, valor NUMERICO LEIA perc Valor ← sal * perc / 100 RETORNE valor FIM_SUB_ROTINA Variáveis Globais Variáveis Locais Programa Principal Sub-Rotina UNESP - FEIS Departamento de Matemática 68 Uma função é um conjunto de instruções desenhadas para cumprir determinado trabalho e agrupadas em uma unidade com um nome para referi-la. Vamos começar mostrando uma função que converte a temperatura de graus Fahrenheit para Celsius. #include <iostream> using namespace std; int celsius(int fahr); // protótipo int main() { int c, f; cout << "Digite a temperatura em graus Fahrenheit: "; cin >> f; c = celsius(f); // chamada à função cout << "Celsius = " << c << endl; system("PAUSE"); return 0; } int celsius(int fahr) // definição da função { int c; c=(fahr-32)*5/9; return c; } Como podemos identificar, a estrutura de uma função C++ é semelhante à da função main(). A diferença é que a main() possui um nome especial. Os componentes necessários para adicionar uma função a um programa são: o protótipo da função, a chamada da função e a sua definição. Uma função não pode ser chamada antes de ter sido declarada, sua declaração é dita protótipo da função, uma instrução colocada no início do programa (vide exemplo anterior), permitindo que o compilador verifique a sintaxe de sua chamada. Assim, a linha de código: int celsius(int fahr); // protótipo informa que a função de nome celsius() é do tipo int e recebe como argumento um valor int que será armazenado na variável fahr. Em C++ as funções poderão ser escritas antes de sua instrução de chamada, nesse caso, seu protótipo não será obrigatório assim, nosso exemplo anterior poderia ser escrito da seguinte maneira, sem a necessidade de definirmos o protótipo da função no início do programa: #include <iostream> using namespace std; UNESP - FEIS Departamento de Matemática 69 int celsius(int fahr) { int c; c=(fahr-32)*5/9; return c; } int main() { int c, f; cout << "Digite a temperatura em graus Fahrenheit: "; cin >> f; c = celsius(f); // chamada à função cout << "Celsius = " << c << endl; system("PAUSE"); return 0; } Entretanto, bons programadores escrevem os protótipos de todas as suas funções, pois no futuro elas poderão ser armazenadas em arquivos de bibliotecas e necessitarão dos protótipos. 10. Tipos de Funções As que iremos trabalhar são funções definidas pelo programador, do tipo: Sem passagem de parâmetro e sem retorno. Com passagem de parâmetro e sem retorno. Sem passagem de parâmetro e com retorno. Com passagem de parâmetro e com retorno. 10.1 Sem passagem de parâmetro e sem retorno É o tipo mais simples (não recebe e não repassa valor). #include <cstdlib> #include <iostream> using namespace std; void soma() { int a,b,s; cout<<"Digite o primeiro numero "; cin>>a; cout<<"\nDigite o segundo numero "; cin>>b; s=a+b; cout<<"\nA soma e "<< s <<"\n"; getchar(); } int main() { soma(); system("PAUSE"); UNESP - FEIS Departamento de Matemática 72 cout<<"\nO resultado e "<< resposta<<endl; system("PAUSE"); return EXIT_SUCCESS; } Obs.: no momento em que a função divisao foi chamada, duas variáveis foram colocadas entre parênteses, indicando que houve passagem de parâmetros. Os valores são copiados para as variáveis d1 e d2, descritas no cabeçalho da função. Chegando no final da função, o comando return é encontrado. Isto indica que a execução da função chegou ao fim e que o conteúdo da variável q será devolvido para quem a chamou. Retornando ao programa principal, o valor é armazenado na variável resposta. Por está razão, seu tipo é int, exatamente igual ao tipo de valor retornado. 10.5 Tipos de passagem de parâmetro Os tipos de passagem de parâmetros são por valor e por referência. Valor: São todos os exemplo vistos até aqui. A figura abaixo ilustra a passagem de parâmetro por Valor: Referência: Significa que os parâmetros são passados para uma função correspondente a endereços de memória ocupados por variáveis. Dessa maneira, toda vez que for necessário acessar determinado valor, isso será feito por meio de referência, ou seja, apontando o seu endereço. A figura abaixo ilustra a passagem de parâmetro por referência. UNESP - FEIS Departamento de Matemática 73 Quando argumentos são passados por valor, a função chamada cria variáveis e copia nelas o valor dos argumentos passados. Dessa forma, a função não tem acesso às variáveis originais da função que chamou, portanto, ela não poderá efetuar qualquer modificação nelas. Na passagem por referência, a função pode acessar as variáveis da função que as chamou. Esse mecanismo possibilita que uma função retorne mais de um valor para a função que chama. Os valores a serem retornados são colocados na referência de variáveis da função chamada. O Operador Unário de Referência &: Com esse operador podemos montar novos tipos de dados, chamados de referências. Referência é um outro nome para uma variável já existente. As instruções: Int n; Int& A = n; Informa que A é um outro nome para n. Toda a operação em qualquer um dos nomes tem o mesmo resultado. A referência não é uma cópia da variável que se refere, é a mesma variável sobre nomes diferentes. #include <iostream> using namespace std; int main () { int n; int& A =n; n=5; cout << "O valor de A e = " << A << endl; A = 8; cout << "O valor de n e = " << n << endl; system("Pause"); return 0; } O valor de A e = 5 O valor de n e = 8 Press any key to continue... UNESP - FEIS Departamento de Matemática 74 Obs.: Toda a referência deve ser obrigatoriamente inicializada int n; int& A; // Errado int& A =n; // Certo O próximo e exemplo mostra o uso simples de referência como argumento de uma função. #include <iostream> using namespace std; void reajusta20(float& p, float& r); int main () { float preco, val_reaj; do { cout << "Insira o preco atual "; cout << "ou 0 para terminar: "; cin >> preco; reajusta20(preco,val_reaj); cout << "Preco novo = " << preco; cout << endl; cout << "Aumento = " << val_reaj; cout << "\n\n"; }while(preco!=0.0); system("Pause"); return 0; } void reajusta20(float& p, float& r) { r=p*0.2; p=p*1.2; } Insira o preco atual ou 0 para terminar: 50 Preco novo = 60 Aumento = 10 Insira o preco atual ou 0 para terminar: 0 Preco novo = 0 Aumento = 0 Press any key to continue... No exemplo a seguir, criaremos uma função que troca o conteúdo de duas variáveis, por meio da função troca() para ordenar uma lista de 3 números fornecidos pelo usuário. Utilize os números 50, 13 e 28 respectivamente para as variáveis n1, n2 e n3. #include <iostream> using namespace std; void troca(float& n, float& m); int main () { float n1, n2, n3; cout << "Digite os tres numeros: "<<endl; cin >> n1 >> n2 >> n3; if (n1>n2) troca(n1,n2); if (n1>n3) troca(n1,n3); if (n2>n3) troca(n2,n3); cout << "n1= "<<n1<<endl; cout << "n2= "<<n2<<endl; cout << "n3= "<<n3<<endl; system("Pause"); Digite os tres numeros: 50 13 28 n1= 13 n2= 28 n3= 50 Press any key to continue... UNESP - FEIS Departamento de Matemática 77 cout << "\n"; system("pause"); return 0; } No exemplo acima definimos duas funções com o mesmo nome, opere() mas uma delas aceita dois argumentos do tipo int e a outra aceita os argumentos do tipo float. O compilador sabe qual deve chamar em cada caso pela inspeção do tipo de valor passado como argumento quanto a função é chamada. Se ela for chamada com dois inteiros como seus argumentos será utilizada a função que possui dois inteiros como argumentos no protótipo. O mesmo raciocínio segue para o caso dos argumentos utilizados forem floats. Observe que o sistema considera somente a lista de argumentos para escolher a função apropriada a cada chamada, e não o valor de retorno. 10.8 Recursividade de Funções Recursividade é a propriedade que uma função tem de ser chamada por ela mesma, ou seja, uma função é dita recursiva se definida em termos dela mesma. Isto é útil em muitas tarefas, como em ordenação ou cálculos de fatoriais de números. Por exemplo, para obtermos o fatorial de um número (n!) a fórmula matemática deve ser: n! = n * (n-1) * (n-2) * (n-3) ... * 1 assim, observe o exemplo do fatorial de 5: 5! = 5 * 4 * 3 * 2 * 1 = 120 e a função recursiva para calcular o fatorial em C++ poderia ser escrita como: #include <iostream> using namespace std; long fatorial(int a) { if(a>1) return (a*fatorial(a-1)); else return (1); } int main () { long n; cout << "Digite um numero: "; cin >> n; cout << n <<"! = "<< fatorial(n) << endl; system("Pause"); return 0; } Digite um numero: 5 5! = 120 Press any key to continue... Note que na função fatorial nós incluímos uma chamada a ela mesma, mas somente se o argumento passado for maior que 1, caso contrário a função UNESP - FEIS Departamento de Matemática 78 realizaria um loop recursivo infinito, pois, uma vez atingido o zero (0) a multiplicação continuaria por todos os números negativos o que provocaria um estouro de memória ou um erro no tempo de execução. O código gerado por uma função recursiva exige a utilização de mais memória, o que torna a execução mais lenta. Ao escrevermos uma função recursiva, três pontos devem ser lembrados: 1. Definir o problema em termos recursivos, ou seja, definir o problema em termos dele mesmo. 2. Encontrar uma condição básica de término para evitarmos problemas de estouro de memória e erro de tempos de execução. 3. Cada vez que uma função é chamada recursivamente, deve estar mais próxima de satisfazer a condição básica, isso garante que o programa não girará em uma sequência infindável de chamadas. UNESP - FEIS Departamento de Matemática 79 11. Estruturas Composta de Dados (Vetores) Geralmente, os algoritmos são elaborados para manipulação de dados. Quando estes dados estão organizados (dispostos) de forma coerente, caracterizam uma forma, uma estrutura de dados. A organização dos dados é chamada de estrutura composta de dados que se divide em duas formas fundamentais: • homogêneas (vetores e matrizes) • heterogêneas (registros). 11.1 Estrutura de Dados Composta Homogênea As estruturas de dados homogêneas possibilitam o armazenamento de grupos de valores em uma única variável que será armazenada na memória do computador. Essas estruturas são ditas "homogêneas" porque os valores que serão armazenados são de um mesmo tipo de dado. Estas estruturas homogêneas são divididas em unidimensionais e multidimensionais. Normalmente, as estruturas unidimensionais são chamadas de vetores e as multidimensionais são chamadas de matrizes. De fato, um vetor também é uma matriz, porém varia em somente uma dimensão. O algoritmo acima demostra a utilização de 5 variáveis para armazenar as alturas dos atletas, no caso de estruturas de dados homogêneas, todas as alturas seriam armazenadas em uma única variável. algoritmo "alturas de atletas" // Síntese // Objetivo: armazenar 5 alturas de atletas de basquete // Entrada: 5 alturas // Saída: - // Declarações var altura1,altura2,altura3,altura4,altura5 : real inicio escreva("Informe a altura do 1º atleta: "); leia (altura1) escreva("Informe a altura do 2º atleta: ") leia (altura2) escreva("Informe a altura do 3º atleta: ") leia (altura3) escreva("Informe a altura do 4º atleta: ") leia (altura4) escreva("Informe a altura do 5º atleta: ") leia (altura5) fimalgoritmo UNESP - FEIS Departamento de Matemática 82 11.3 Inicialização de Vetores Quando declaramos um vetor em um escopo local (dentro de uma função, por exemplo), se não especificado, seus elementos não serão inicializados como algum valor default, portanto, seu conteúdo será indeterminado até o momento em que armazenaremos algum valore nele. Os elementos de vetores globais ou estáticos, por outro lado, serão automaticamente inicializados com valores default, o que para todos os tipos de dados fundamentais, significa que serão preenchido com zero (0). Em ambos os casos, globais e locais, quando declaramos um vetor, devemos possibilitar a atribuição de valores iniciais para cada um dos seus elementos pela encerrando os valores em chaves ( { } ). int alturas [5] = {185, 201, 188, 195, 176}; Dessa maneira, nosso vetor altura apresentará, finalmente, a seguinte conformação. A quantidade de elementos entre chaves ( { } ) deve ser tão grande quanto o tamanho de elementos que declaramos entre colchetes ( [ ] ) . Por exemplo, quando declaramos o vetor: int alturas [5]; especificamos que ele tem 5 elementos e na lista de alturas: {185, 201, 188, 195, 176} temos 5 elementos. Em C++ podemos iniciar um vetor da seguinte forma: int alturas [ ] = {185, 201, 188, 195, 176}; Observe que deixamos vazio os colchetes ([ ]), nesse caso, o compilador assumirá que o tamanho para o vetor será o número de elementos incluídos entre chaves ( { } ). Após a declaração, portanto, o nosso vetor alturas terá o tamanho de 5 uma vez que fornecemos 5 elementos dentro das chaves. 11.4 Acessando os elementos dos vetores Em qualquer ponto de um programa, poderemos acessar individualmente qualquer um dos elementos de um vetor, como se este elemento fosse uma alturas 185 201 188 195 176 UNESP - FEIS Departamento de Matemática 83 variável normal, assim, somos capazes de ler e modificar esses valor. O formato para acessar um elemento é simples: nome [índice]; Seguindo o exemplo anterior, nosso vetor alturas apresenta 5 elementos, e cada um desses elementos são do tipo inteiro (int), os nomes que poderemos utilizar para nos referirmos a cada um dos seus elementos são: por exemplo, para armazenarmos o valor 190 no terceiro elemento do vetor alturas, nós poderemos escrever a seguinte declaração: alturas [2] = 190; e, se quisermos passar o valor do terceiro elemento do vetor alturas para a variável a, poderes utilizar a instrução: a = alturas [2]; Abaixo serão apresentadas mais algumas operações válidas para vetores: a = 1; alturas [0] = a; alturas [a] = 75; b = alturas[a+2]; //portanto b = 195 alturas[alturas [0]] = alturas[2] + 5; alturas 185 201 188 195 176 alturas[0] alturas[1] alturas[2] alturas[3] alturas[4] alturas 1 201 188 195 176 alturas[0] alturas[1] alturas[2] alturas[3] alturas[4] alturas 1 75 188 195 176 alturas[0] alturas[1] alturas[2] alturas[3] alturas[4] UNESP - FEIS Departamento de Matemática 84 Seguindo o exemplo anterior, nosso vetor alturas apresenta 5 elementos, e cada um desses elementos são do tipo inteiro (int), os nomes que poderemos utilizar para nos referirmos a cada um dos seus elementos são: O programa abaixo calcula a soma dos valores de alturas de jogadores de basquete presentes no vetor alturas. #include <iostream> using namespace std; int alturas [5] = {185, 201, 188, 195, 176}; int i, soma=0; int main () { for (i=0; i <=5; i++) soma += alturas[i]; // soma = soma + alturas[i] cout << "Soma das alturas = " << soma; cout << "\n\n"; system("Pause"); return 0; } Soma das alturas = 945 Press any key to continue... 11.5 Exemplo 15 Elabore um programa, utilizando modularização, que calcule a média ( x ), a variância (s2), o desvio padrão (s), o mínimo, o máximo e o coeficiente de variação (cv) das alturas dos atletas: x= ∑ i = 1 n x i n s2= ∑ i= 1 n x i 2− (∑ i = 1 n x i) 2 n n− 1 s=√s2=√∑i = 1n x i2− (∑i= 1 n x i) 2 n n− 1 cv= 100× s x Onde n é o número de elementos do vetor e x é o vetor de alturas. Para auxiliar, programe as funções para calcular: soma=∑ i= 1 n x i e soma ao quadrado=∑ i= 1 n x i 2 alturas 1 193 188 195 176 alturas[0] alturas[1] alturas[2] alturas[3] alturas[4] UNESP - FEIS Departamento de Matemática 87 Métodos de ordenação Sofisticados: Método Shell Sort Método Quick Sort Método Heap Sort Vamos colocar em ordem crescente os valores de alturas dos atletas. Para isso, inicialmente, nosso programa deve: Método Seleção • Selecionar o elemento do vetor (10 posições) que apresenta o menor valor; • Trocar esse elemento pelo primeiro; • Repetir essas operações, envolvendo agora somente os 9 elementos restantes (selecionando o de menor valor com a segunda posição, depois o 8 elementos (trocando o de menor valor com a terceira posição), depois os 7, os 6 e assim por diante, até restar um único elemento, o maior deles. #include <iostream> using namespace std; void imprime(float v[]); void organiza(float v[]); //vairáveis globais float dados[10] = {21.5, 25.5, 14.5, 15.8, 17.6, 8.9, 9.6, 18.6, 17, 12}; int n=10; //função principal int main() { cout<< "Vetor dados original: \n"; imprime(dados); cout<< "\n\nVetor dados organizado: \n"; organiza(dados); system("Pause"); return 0; } //função para imprimir vetor void imprime(float v[]) { cout<<"Indice\tElemento\n"; for(int i=0; i<= n-1; i++) cout << "["<<i<<"]\t"<<v[i] << endl; } //função para organiza e imprimir vetor void organiza(float v[]) { float aux; int i, j, k; for(i=0; i<=n-2;i++) { k=i; aux=v[i]; for(j=i+1; j<=n-1;j++) if (v[j]<aux) { UNESP - FEIS Departamento de Matemática 88 k=j; aux=v[k]; } v[k]=v[i]; v[i]=aux; } cout<<"Indice\tElemento\n"; for(int i=0; i<= n-1; i++) cout << "["<<i<<"]\t"<<v[i] << endl; } Método da Bolha Neste método de ordenação, o programa utiliza a seguinte estratégia para ordenar o vetor: • Comparar os pares de elementos adjacentes, permutando-os quando estiverem foram de ordem, até que todos estejam ordenados. O objetivo da função é colocar o menor item da lista nessa variável na primeira posição do vetor a ser ordenado v[0]. A função percorre um por um dos elementos seguintes a fim de encontrar o menor deles. Sempre que encontra um elemento menor, eles são trocados. Terminado essa operação, é tomado o próximo item, v[1]; ele deverá conter o próximo menor valor. Novamente, são realizadas as comparações e trocas. O processo continua até que a lista toda seja ordenada. #include <iostream> using namespace std; void imprime(float v[]); void organiza(float v[]); //vairáveis globais float dados[10] = {21.5, 25.5, 14.5, 15.8, 17.6, 8.9, 9.6, 18.6, 17, 12}; int n=10; int main() { cout<< "Vetor dados original: \n"; imprime(dados); cout<< "\n\nVetor dados organizado: \n"; organiza(dados); system("Pause"); return 0; } //função para imprimir vetor void imprime(float v[]) { cout<<"Indice\tElemento\n"; for(int i=0; i<= n-1; i++) cout << "["<<i<<"]\t"<<v[i] << endl; } //função para organiza e imprimir vetor void organiza(float v[]) { int i, j;float aux; for(i=0;i<=n-1;i++) UNESP - FEIS Departamento de Matemática 89 for(j=i+1;j<=n-1;j++) if(v[i] >v[j]) { aux=v[j]; v[j]=v[i]; v[i]=aux; } cout<<"Indice\tElemento\n"; for(int i=0; i<= n-1; i++) cout << "["<<i<<"]\t"<<v[i] << endl; } • O processo de ordenação é feito por meio de dois laços. O laço mais externo determina qual elemento do vetor será usado como base de comparação. O laço mais interno compara cada item seguinte com o de base e, quando encontra um elemento menor que o de base, faz a troca, realizada no corpo do if por meio de uma variável auxiliar (aux). 11.7 Exemplo 16 Elabore um programa, utilizando modularização, que calcule a mediana das alturas dos atletas. A mediana é o valor que ocupa a posição central do vetor ordenado dos dados, o valor é precedido e seguido pelo mesmo número de observações e nem sempre pertence ao conjunto de dados.        +=       +            + .parénse, 2 xx ;ímparénse,x Md 1 2 n 2 n 2 1n Onde x é o vetor de alturas e n o número de elementos do vetor. #include <iostream> using namespace std; float mediana(float v[]); //vairáveis globais float dados[10] = {21.5, 25.5, 14.5, 15.8, 17.6, 8.9, 9.6, 18.6, 17, 12}; int n=10; int main() { cout << "Mediana: " << mediana(dados) << endl; system("Pause"); return 0; } //função para cálculo da mediana float mediana(float v[]) { float mediana; int i, j; float aux; // ordenando o vetor for(i=1;i<=n-1;i++) UNESP - FEIS Departamento de Matemática 92 for(int j=0; j<i;j++) media+=alturas[j] ;// media=media+alturas[j] cout << "Medias das alturas: " <<(media/i)<<endl; system("Pause"); return 0; } O laço for foi substituído pelo laço do-while. Esse laço repete a solicitação da altura ao usuário, armazenando-a no vetor alturas[], até que seja fornecido um valor menor que zero. Quando o último elemento for digitado, a vaiável i terá alcançado um valor acima do total de elementos. Isso é verdadeiro, pois é contado o número negativo de finalização da entrada. Assim devemos subtrair 1 do valor contido em i para encontrar o número correto de elementos. Entretanto, a linguagem C++ não realiza verificação de limites em vetores, por isso, se o usuário decidir inserir mais de 100 valores de alturas, devemos expulsar os valores excedentes. Para providenciar a verificação do limite de uma matriz é de responsabilidade do programa. Portanto, não podemos permitir que o usuário digite dados acima do limite, assim, temos: do { if( i>= N) { cout << "BUFFER LOTADO" << endl; i++; break; // Saida do laço do-while } cout << "Digite o valor de altura " << i+1 << " : "; cin >> alturas[i]; } while(alturas[i++]>=0.0); Assim, quando i atingir 100, que é 1 acima do último índice do vetor, a mensagem " BUFFER LOTADO " será impressa e o comando break fará que o controle saia do laço do-while e passe para a segunda parte do programa, ou seja, o cálculo da média. Obs.: A linguagem C/C++ não permite que vetores e matriz sejam passados na íntegra como parâmetro para uma função. Para resolver esse problema, deve-se passar apenas o endereço da posição inicial do vetor ou da matriz. Esse endereço é obtido utilizando-se o nome do vetor (ou da matriz) sem o índice entre colchetes. #include <iostream> using namespace std; void soma_linhas(int m[ ][5], int v[ ]) { int i, j; for (i=0;i<3;i++) for (j=0;j<5;j++) v[i]=v[i]+m[i][j]; UNESP - FEIS Departamento de Matemática 93 } int main() { int i, j; int mat[3][5], vet[3]; for (i=0;i<3;i++) { vet[i]=0; system("cls"); for (j=0;j<5;j++) { cout<<"\nDigite o elemento Coluna: "<<i+1<<" e Linha: "<<j+1 <<" "; cin >> mat[i][j]; } } soma_linhas(mat, vet); for (i=0;i<3;i++) cout << "\nSoma da coluna " << i+1 << " = " << vet[i]; cout << "\n\n"; system("PAUSE"); return 0; } 11.10 Exemplo 18 Elabore um programa que dado um vetor de 10 valores inteiros, crie e imprima outro vetor, armazenando os elementos do primeiro a partir do centro para as bordas, de modo alternado (vetor inteiro com 10 posições também). Nesta primeira forma de resolução, utilizaremos a variável inteira j para receber os índices do vetor resposta (vr), inicializando-a com o valor do índice do elemento central, ou seja, a posição 4 (10/2-1). Observe que dentro do laço for utilizamos um if com a seguinte condição, se o resto da divisão de i (índice do vetor original) por 2 for igual a zero, j será incrementado em i+1 (lembre que o primeiro valor de i é zero), caso contrário j será decrementado em i+1. #include <iostream> using namespace std; int main() { int vetor[10]={11,22,33,44,55,66,77,88,99,1010}; int vr[10]={}; int j=10/2-1; //preenchimento de vr for(int i=0; i <=9;i++) { if(i%2==0) { vr[ j ]=vetor[i]; j=j+(i+1); } else { vr[ j ]=vetor[i]; UNESP - FEIS Departamento de Matemática 94 j=j-(i+1); } } //Impressão dos vetores cout<<"vetor\tvr"<<endl; for(int i=0;i<=9;i++) cout<<vetor[i]<<"\t"<<vr[i]<<endl; system("pause"); return 0; } Na segunda forma de resolução desse problema, vamos utilizar um segundo laço for, ao invés do if. Para isso vamos precisar de mais duas variáveis (l e k). O laço for realizará sucessivas multiplicações de k (iniciado com o valor de -1) l vezes, com l variando de 0 até o valor de i, fazendo k variar entre 1 e -1 a cada contagem do primeiro laço. Portanto, quando k=1, j será incrementado em i+1 e, quando k=-1 ,j será decrementado em i+1. #include <iostream> using namespace std; int main() { int vetor[10]={11,22,33,44,55,66,77,88,99,1010}; int vr[10]={}; int j=10/2-1; //preenchimento de vr for(int i=0; i <=9;i++) { vr[j]=vetor[i]; int k=-1; for(int l=0;l<=i;l++) k=k*(-1); j=j+(i+1)*k; } //Impressão dos vetores cout<<"vetor\tvr"<<endl; for(int i=0;i<=9;i++) cout<<vetor[i]<<"\t"<<vr[i]<<endl; system("pause"); return 0; } Na última forma de resolução, utilizaremos a função potência (pow()) da biblioteca math.h, para substituir o segundo for do programa anterior, implementando a expressão j= j +(− 1) i× (i +1) . #include <iostream> #include <math.h> using namespace std; int main() { int vetor[10]={11,22,33,44,55,66,77,88,99,1010}; int vr[10]={};
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved