Professional Documents
Culture Documents
Sumrio
Mdulo 1 A Linguagem C++....................................................................... 4
1.1 Histria da Linguagem C/C++.............................................................................. 4 1.2 Caractersticas da Linguagem C++....................................................................... 4 1.3 Exemplos de Aplicaes Escritas em C++ ........................................................... 5 1.4 Comparao de C++ com outras linguagens ........................................................ 5 1.5 Paradigmas de Programao: Programao Estruturada e Orientada a Objetos .. 6
4.2 Declarando uma Funo ..................................................................................... 31 4.3 Main como uma Funo ..................................................................................... 33 4.4 Variveis dentro das Funes ............................................................................. 34 4.4.1 Variveis Locais .............................................................................................. 34 4.4.2 Variveis Globais.............................................................................................. 35 4.5.1 Chamada por Valor.......................................................................................... 36 4.5.2 - Chamada por Referncia .................................................................................. 37 4.6 Biblioteca de Execuo....................................................................................... 37 4.7 Funes Recursivas............................................................................................. 38 4.8 - Sobrecarga da Funo.......................................................................................... 39 4.9 Funes Inline..................................................................................................... 39 4.10 Parmetros Padro ............................................................................................ 40
Pgina 3
Em proposta geral, C++ deve ser to eficiente e portvel quanto C, sendo desenvolvida para ser uma linguagem com tipos de dados estticos. C++ desenvolvido para ser o quanto mais compatvel com C possvel, fornecendo transies simples para cdigo C. C++ desenvolvido para suportar mltiplos paradigmas de programao, principalmente a programao estruturada e a programao orientada a objetos, possibilitando mltiplas maneiras de resolver um mesmo problema. C++ desenvolvido para fornecer ao programador mltiplas escolhas, mesmo que seja possvel ao programador escolher a opo errada.
Pgina 4
Grande parte dos programas da Microsoft, incluindo Windows XP, Windows NT, Windows 9x, Pacote Office, Internet Explorer, Visual Studio e outros. Sistemas Operacionais como o j citado Windows, Apple OS X, BeOS, Solaris e Symbian (sistema operacional para celulares). Bancos de dados como SQL e MySQL. Aplicaes Web, como a mquina de busca Google e o sistema de comrcio virtual da Amazon. Aplicaes grficas como os programas da Adobe (Photoshop, Illustrator), Maya e AutoCAD. Jogos em geral, como o Doom III.
A lista enorme e poderia se estender por muitas e muitas pginas. Atualmente C++ , juntamente com Java, a linguagem de programao comercial mais difundida no mundo.
as consequncias de seu mau ou incorreto uso. O motivo para essa liberdade na programao permitir ao compilador criar cdigos muito rpidos e eficientes, deixando a responsabilidade da verificao de erros para o programador. O prprio criador de C++, Bjorne Stroustrup afirma que C faz com que dar um tiro no p seja fcil; C++ torna isso mais difcil, mas quando ns o fazemos arrebenta com a perna toda. A citao de Stroutrup trata com humor o fato de o C++, ao possibilitar a programao de alto nvel, ter facilitado a codificao de algoritmos e organizao de projetos em relao ao C, uma linguagem que requer constante ateno contra erros lgicos de programao devido sua alta flexibidade. Por outro lado, o C++ possui nuances da sintaxe e semntica da linguagem muito sutis, difceis de serem identificados, e que quando no percebidos podem levar a comportamentos indesejados no cdigo. As principais vantagens e desvantagens do C++ so listadas a seguir: Vantagens
Possibilidade em programao de alto e baixo nvel. Alta flexibilidade, portabilidade e consistncia. Compatilidade com C, resultando em vasta base de cdigos. Adequado para grandes projetos. Ampla disponibilidade e suporte, devido principalmente grande base de desenvolvedores. No est sob o domnio de uma empresa (em contraste do Java - Sun ou Visual Basic Microsoft). Padronizao pela ISO. Grandes possibilidades para a metaprogramao e programao genrica. Desvantagens
Compatilidade com o C herdou os problemas de entendimento de sintaxe do mesmo. Os compiladores atuais nem sempre produzem o cdigo mais otimizado, tanto em velocidade quando tamanho do cdigo. Grande perodo para o aprendizado. A biblioteca padro ainda no cobre reas importantes da programao, como threads, conexes TCP/IP e manipulao de sistemas de arquivos, o que implica na necessidade de criao de bibliotecas prprias para tal, que pecam em portabilidade. Devido grande flexibilidade no desenvolvimento, recomendado o uso de padres de programao mais amplamente que em outras linguagens.
programao orientada a objetos. Outras linguagens suportam vrios paradigmas, ou seja, o programador pode escolher qual paradigma se adapta melhor ao problema que ele precisa resolver e trabalhar com ele, e at mesmo alternar entre paradigmas (desde que ele saiba o que est fazendo). A linguagem C utiliza o paradigma da programao estruturada. A base da programao estruturada trabalhar a lgica do programa como uma estrutura composta de similares sub-estruturas, reduzindo a compreenso do programa compreenso de cada sub-estrutura individualmente. Na prtica, este mtodo envolve a criao de vrias funes dentro de um programa, pequenas e simples o suficiente para serem entendidas individualmente, sendo o programa a sequncia de todas estas funes trabalhando em conjunto. A programao estruturada se ope ao uso de comandos de pulo como GOTO, preferindo a criao de estruturas e condies lgicas que substituam ou mesmo eliminem a necessidade de um comando de pulo. Este paradigma o mais utilizado no ensino e aprendizado de linguagens de programao, por ser mais facilmente entendido por estudantes e por criar hbitos de programao saudveis e teis mesmo em outros paradigmas. A linguagem C++ uma das linguagens que suportam vrios paradigmas. Inicialmente, sendo uma evoluo de C, ela suporta inteiramente o paradigma da programao estruturada. Alm disso, ela suporta outros paradigmas como a programao procedural, a programao genrica, abstrao de dados e a programao orientada a objetos. Dentre estes paradigmas, o mais utilizado atualmente a Programao Orientada a Objetos, ou mais comumente chamado de OOP (Object-Oriented Programming). Apesar de ter sido criada nos anos 60, este paradigma s comeou a ganhar aceitao maior aps os anos 90,com a exploso das linguagens C++, Java e Visual Basic. A idia bsica por trs da OOP criar um conjunto de objetos (unidades de software) para modelar um sistema. Estes objetos so independentes entre si, possuindo responsabilidades e funes distintas no programa como um todo, mas que se comunicam entre si atravs do envio e recebimento de mensagens. A OOP especialmente til para grandes programas que se beneficiam mais com a modularidade oferecida por este paradigma: dividindo o programa em vrios mdulos independentes, aumenta-se a flexibilidade e a facilidade para manuteno do programa como um todo. Nesta apostila, enfocaremos os aspectos de linguagem de programao estruturada da linguagem C++, deixando os aspectos de linguagem orientada a objetos para os ltimos captulos a ttulo de introduo ao assunto. Isto se deve a maior dificuldade de aprendizado e entendimento do paradigma da programao orientada a objetos, principalmente tratando-se de estudantes com pouco contato com linguagens de programao. Por isso, prefervel estabelecer uma base para o estudante com os conceitos da programao estruturada, que so mais facilmente compreendidos e trabalhados, para que depois este estudante possa progredir para o paradigma da OOP com maior facilidade.
Pgina 7
Mdulo 2 Compiladores
2.1 O que um Compilador
Toda linguagem de programao possui um tradutor de cdigo. Este tradutor pode ser um compilador ou um interpretador, dependendo da linguagem. Interpretadores so programas que lem o cdigo-fonte e executam ele diretamente, sem a criao de um arquivo executvel. Chamamos de compilador o programa que traduz um arquivo escrito em cdigo de linguagem de programao (arquivo-fonte) para a linguagem do microprocessador, criando um arquivo capaz de executar as instrues pedidas (arquivo executvel). O primeiro passo de um compilador analisar o cdigo presente no arquivo-fonte, verificando se existem erros de sintaxe. Caso algum erro de sintaxe seja encontrado, a compilao interrompida para que o programador possa corrijir estes erros. Caso o cdigo no possua erros o prximo passo do compilador criar um arquivo de cdigoobjeto, que possui as instrues do programa j traduzidas para a linguagem da mquina e informaes sobre alocao de memria, smbolos do programa (variveis e funes) e informaes de debug. A partir deste arquivo de cdigo-objeto, o compilador finalmente cria um arquivo executvel com o programa compilado, que funciona independente do compilador e realiza as instrues criadas pelo programador.
2.3 DevC++
O Dev-C++ um compilador freeware das linguagens C, C++ e C#. uma opo muito interessante, pois de fcil utilizao e aprendizado para usurios novos e possui muitos recursos avanados para usurios experientes. Alm de, claro, seu download ser gratuito.
Pgina 8
2.3.1 - Instalao
A verso mais recente do DevC++ pode ser baixada atravs da pgina http://www.bloodshed.net/dev/devcpp.html, no link Download. Utilizou-se, na elaborao desta apostila, a verso do DevC++ beta 9.2, disponvel diretamente atravs do link http://prdownloads.sourceforge.net/dev-cpp/devcpp-4.9.9.2_setup.exe. O arquivo de instalao possui aproximadamente 9 megas. Aps o fim do download, preciso clicar duas vezes neste arquivo para comear a instalao. A instalao do DevC++ bem simples. Utilizaremos nesta apostila a instalao completa, escolhendo o item full durante a etapa da instalao mostrada na figura 2.1.
Figura 2.1 Escolha o tipo de instalao Full O prximo passo escolher o diretrio onde o programa ser instalado. Neste diretrio estaro todos os arquivos relacionados ao compilador, como bibliotecas, executveis, arquivos de ajuda e muitos outros. Alm disso, neste diretrio que o compilador salvar os cdigos e programas que fizermos. Normalmente os programas so instalados por definio em sua pasta prpria, geralmente c:/arquivos de programas/devcpp, mas podemos escolher outro diretrio qualquer que satisfaa nossas necessidades. Escolhemos para esta apostila instalar o compilador em C:/dev-cpp , como mostra a figura 1.b, por maior facilidade de acesso e referncia. So necessrios aproximadamente 60 megas de espao livre em disco.
Pgina 9
Figura 2.2 Escolha o local onde sero instalados os arquivos do compilador. Aps isto, a instalao ser concluda com sucesso. Para acessar o programa, basta encontrar o atalho ao programa no menu iniciar sob o nome Bloodsheed Dev-C++ e clicar para execut-lo.
2.3.2 - Interface
Importante: Na primeira vez que iniciamos o Dev-C++, todos os seus menus esto em ingls. Porm, o programa traduzido para vrias lnguas, inclusive portugus. Para mudar os menus do programa para a nossa lngua (ou qualquer outra lngua que desejar), basta acessar o menu Tools -> Enviroment Options. Uma janela se abrir, com vrias opes referentes ao funcionamento do ambiente de trabalho. Na aba Interface encontrase a opo Language com as vrias linguas em que o programa est disponvel. Basta procurar a opo portuguese (Brazil) e clicar OK, e o programa j estar traduzido para nossa lngua. A tela principal do programa mostrada na figura abaixo.
Pgina 10
Os menus principais do programa so muito parecidos com os programas windows padro. Temos os menus:
Arquivo: possui as funes bsicas de manuseio de arquivos (criar novo arquivo, abrir arquivo, fechar, imprimir, ver propriedades) Editar: aonde esto localizadas as funes de edio bsicas de edio (copiar, recortar, colar) e algumas funes teis para programao (como comentar e descomentar trechos do programa, e criar e acessar bookmarks, que so marcas de acesso rpido para partes do programa, especialmente teis para programas extensos) Localizar: possui os comandos de procurar e substituir partes do cdigo; o menu Exibir permite o controle de quais componentes da tela so exibidos Projeto: refere-se a projetos de programas que possuem vrios componentes e arquivos de cdigos separados e utilizado para adicionar e retirar componentes do projeto Executa: talvez o mais importante para ns, e nele esto localizadas as funes bsicas do compilador (como os comandos Compilar, Executar ) e algumas funes Pgina 11
teis como procurar por erros de sintaxe Debug: serve para controlar o debug de um programa, que a sua execuo passoa-passo para melhor anlise e busca por erros Ferramentas: refere-se a vrias opes do compilador, do ambiente de trabalho e de edio, alm de configuraes diversas CVS: uma funo extra do compilador, e no nos tem serventia Janela: possui comandos teis para os casos em que temos vrios arquivos ou projetos abertos ao mesmo tempo e precisamos alternar entre eles. Ajuda: d acesso ajuda do programa, que possui uma listagem dos principais comandos do compilador e um breve tutorial da linguagem C.
Logo abaixo dos menus, temos as barras de ferramenta com as principais funes e comandos do programa representados por cones para acesso rpido. Basta posicionar o mouse sobre qualquer um dos cones para saber sua funo. Abaixo das barras de ferramentas, esto as duas principais janelas do programa. A janela da esquerda chamada de Navegador de Classes e Projetos, e serve para acessar rapidamente os vrios arquivos de cdigo pertencentes um projeto ou ento acessar rapidamente as vrias classes existentes em um programa. A janela da direita nossa tela de trabalho, onde digitamos nossos cdigos. Note que caso exista mais de um arquivo sendo trabalhado ao mesmo tempo, podemos alternar entre eles atravs das pequenas abas que existem diretamente acima da tela de trabalho, cada uma identificada pelo nome de seu arquivo. Finalmente, a janela inferior do programa possui vrias informaes sobre o processo de compilao e debugagem de um programa. Ela particularmente til para encontrar erros de compilao, como veremos mais adiante.
2.3.3 - Utilizao
Para iniciarmos um novo arquivo de cdigo, preciso acessar o menu Arquivo -> Novo -> Arquivo Fonte (como mostra a figura 2.4) ou ento utilizar o atalho CTRL + N. O novo arquivo ser criado imediatamente e poderemos comear a trabalhar nele.
Figura 2.4 Utilize o comando Arquivo Fonte para criar um novo arquivo em branco. As funes bsicas do compilador podem ser encontradas no menu Executar, como mostra a figura 2.5. Os comandos que utilizaremos so: Compilar (atalho: CTRL + F9), Executar ( CTRL + F10) e Compilar & Executar ( atalho: F9). Utilizamos o comando Compilar para compilar o arquivo cdigo do programa em que estamos trabalhando e gerar UNESP Campus de Ilha Solteira 2007 Pgina 12
um arquivo executvel deste programa. Em seguida, utilizamos o comando Executar para automaticamente executar o arquivo criado pela compilao. O comando Compilar & Executar a unio dos dois comandos: compila e executa o programa logo em seguida. Como j indicado antes, estes trs comandos possuem cones de acesso rpido na barra de ferramentas (veja a figura 2.6).
Figura 2.5 O menu Executar possui todas os comandos necessrios para compilar e executar os programas que criaremos.
Figura 2.6 Localizao dos comandos bsicos na barra de tarefas. Coloque o mouse sobre qualquer um dos cones para saber qual sua funo.
2.3.4 Erros
Quando compilamos um arquivo de cdigo no Dev-C++, a janela indicadora do progresso da compilao automaticamente aberta. Caso o arquivo de cdigo no contenha nenhum erro, a compilao terminar e a janela de progresso permanecer aberta para indicar que tudo correu bem (verifique o quadrado da janela chamado status: ele dever indicar Done aps o fim da compilao). Desta maneira, aps o fim da compilao UNESP Campus de Ilha Solteira 2007 Pgina 13
Figura 2.7 Janela que indica o progresso da compilao do arquivo de cdigo. Caso nosso arquivo de cdigo contenha uma ou mais linhas de cdigos com erro, a compilao interrompida para que estes erros (ou advertncias) sejam verificados pelo programador. A janela de progresso da compilao fechada, e a janela inferior do programa maximizada mostrando todos os erros que foram encontrados durante a compilao do programa.
Figura 2.8 A janela que indica a posio e o tipo de erros encontrados durante a compilao do programa. A figura acima mostra que a janela possui trs colunas: linha, unidade e mensagem. A coluna linha indica a linha de cdigo onde o erro foi encontrado; a coluna unidade indica o arquivo onde foi encontrado o erro e a coluna mensagem relata o tipo de erro encontrado. Um duplo clique em qualquer uma das indicaes de erro nesta janela faz com que a linha de cdigo onde o erro foi encontrado seja sublinhada em vermelho na janela de edio de cdigo. Geralmente, os erros encontrados so erros de digitao do cdigo. Quando erramos o nome de uma varivel ou mesmo um comando, o Dev-C++ indica que o nome errado no foi declarado anteriormente (varivel_x undeclared(first use in this function)), pois ele age como se este nome desconhecido fosse uma varivel no declaradada e tenta continuar a compilao. Outro erro bastante comum a falta de ponto-e-vrgula no fim de uma linha de comando. Neste caso, a mensagem de erro geralmente ; expected before algum_comando, indicando que o compilador esperava o ponto-e-vrgula antes do prximo comando ou varivel. A mensagem de erro indica a prxima linha de cdigo, mas o ponto-e-vrgula ausente est na linha anterior. O compilador tambm indica quando utiliza-se o ponto-e-vrgula antes da hora, ou seja, quando o compilador espera por uma UNESP Campus de Ilha Solteira 2007 Pgina 14
expresso ou comando e encontra somente o ponto-e-vrgula. Por exemplo, uma declarao de varivel sem declarao de valor: varivel = ;. Neste caso, a mensagem de erro dada pelo programa expected primary-expression before ; token.
funo main. Cada programa ter seus prprios comandos, logicamente. Entretanto, o encerramento de um programa geralmente feito da mesma maneira para todos eles. As duas ltimas linhas antes do fecha-chaves so dois comandos normalmente utilizados ao fim de um programa. A linha system(PAUSE > null) uma chamada de funo prpria de C++. A funo system( ) recebe argumentos como o PAUSE que na verdade so comandos para o sistema operacional. Neste caso, ela recebe o comando PAUSE > null para pausar a execuo do programa at que o usurio aperte uma tecla qualquer. Utilizamos este recurso para que a tela do programa no seja terminada automaticamente pelo sistema, impedindo que vejamos os resultados do programa. Finalmente, o comando return 0 a resposta da funo main para o sistema. Quase toda funo retorna um valor para o sistema ou programa que a chamou, por exemplo, uma funo pode retornar o resultado de uma operao matemtica executada por ela. No caso da funo main, ela retorna um valor para o sistema operacional que executou o programa. Esse valor interpretado pelo sistema como uma mensagem indicando se o programa foi executado corretamente ou no. Um valor de retorno 0 indica que o programa foi executado sem problemas; qualquer outro valor de retorno indica problemas. Quando o programa executado at o fim, ele retorna 0 ao sistema operacional, indicando que ele foi executado e terminado corretamente. Quando o programa encontra algum erro ou terminado antes da hora, ele retorna um valor qualquer ao sistema, indicando erro durante a execuo.
Pgina 16
Pgina 17
importante notar que a linguagem C++ diferencia letras maisculas e minsculas, ou seja, char uma palavra reservada de C++ mas CHAR ou ChAr no (entretanto, normalmente desaconselha-se o uso dessa diferenciao por atrapalhar a legibilidade do cdigo). Reforando o que j foi mencionado, as palavras reservadas s iro executar os comandos que lhes foram designados.
Variveis reais servem para armazenar nmeros que possuem partes fracionrias. UNESP Campus de Ilha Solteira 2007 Pgina 18
Existem duas maneiras de representar nmeros fracionrios em C++. A primeira, a mais simples, utilizar o ponto para separar as partes inteiras e fracionrias. Por exemplo: 0.00098 1.2145 3.1461 8.0 (Mesmo no caso de um nmero com parte fracionria igual a zero, a utilizao do ponto assegura que este nmero seja considerado um nmero de ponto flutuante por C++). A segunda maneira utilizar a notao cientfica E. Por exemplo : 3.45E7 significa 3.45 multiplicado por 10 elevado stima potncia (10.000.000). Essa notao bastante til para representar nmeros realmente grandes ou realmente pequenos. A notao E assegura que o nmero seja armazenado em formato de ponto flutuante. Alguns exemplos: 2.52E8 = 2.52 x 100.000.000 = 252.000.000 -3.2E3 = -3.2 x 1000 = -3200 23E-4 = 23 x 0.0001 = 0.0023 Assim como os inteiros, os nmeros reais em C++ podem ser representados por 3 tipos de variveis com diferentes intervalos. So elas: float, double e long double. Float o tipo de varivel real natural, aquela com a qual o sistema trabalha com maior naturalidade. Double e long double so teis quando queremos trabalhar com intervalos de nmeros reais realmente grandes. Utilizamos nmeros reais geralmente para expressar preciso atravs do nmero de casas decimais, ento podemos dizer que uma varivel float menos precisa que uma varivel double, assim como uma varivel double menos precisa que long double. A tabela abaixo mostra os tipos de variveis reais, seu tamanho em bits e o intervalo de armazenagem. Tipo Float Double long double Tabela 3.2 Tipos de variveis reais em C++ Tamanho (em bits) Intervalo 32 3,4E-38 a 3,4E+38 64 1,7E-308 a 1,7E+308 80 3,4E-4932 a 1,1E+4932
Para declarar uma varivel somente obrigatrio declarar seu tipo e nome: <tipo> <nome>; Por exemplo: int exemplo; Alm disso, caso seja necessrio, podemos declarar um valor a esta varivel no momento de sua declarao, e tambm adicionar um prefixo a ela, da seguinte forma: <prefixo> <tipo> <nome> = <valor>; Por exemplo: unsigned int exemplo = 12;
0x (um zero seguido de um x), seguido pelo valor em formato hexadecimal. Um valor octal comea com um zero. Aqui esto alguns exemplos: hex = 0xFF; /* 255 em decimal */ oct = 011; /* 9 em decimal */ Outra base numrica muito utilizada na programao a base binria. Apesar de C++ no possuir uma forma especfica de se expressar valores de base binria, podemos utilizar a notao hexadecimal para esta funo. A tabela abaixo mostra como pode ser feita a converso de um valor binrio para um valor hexadecimal. Tabela 3.3 Converso de valor binrio para hexadecimal Dgito Hexadecimal Equivalente Binrio Dgito Hexadecimal Equivalente Binrio 0 0000 8 1000 1 0001 9 1001 2 0010 A 1010 3 0011 B 1011 4 0100 C 1100 5 0101 D 1101 6 0110 E 1110 7 0111 F 1111
Usa-se um cdigo de barra invertida exatamente da mesma maneira como usa qualquer outro caractere. Por exemplo: ch = \t; printf(Este um teste\n); Esse fragmento de cdigo primeiro atribui uma tabulao a ch e, ento, imprime este um teste na tela, seguido de uma nova linha.
3.9 Operadores
Um operador um smbolo que diz ao compilador para realizar manipulaes matemticas e lgicas especficas. A linguagem C++ possui trs classes gerais de operadores: aritmticos, relacionais e lgicos e bit-a-bit.
Pgina 22
Pgina 23
Tabela 3.8 Operadores para manipulao de bits em C++ Operador Ao & bit and | bit or ^ bit xor - exclusive or << Rotao a esquerda >> Rotao a direita ~ bit not (complemento) Observao: x << n ir rotacionar n vezes a varivel x esquerda.
Onde tempos op como um dos seguintes operadores: Tabela 3.9 Operadores de Assinalamento em C++ Operador Ao + Soma Subtrao * Multiplicao / Diviso % mdulo (resto da diviso) >> Rotao a direita << Rotao a esquerda & And ^ xor - exclusive or | Or Exemplo de aplicao: i+= 2; /* equivalente a: i = i + 2 */ j-= 3; /* equivalente a: j = j 3 */ k >>= 3; /* equivalente a: k = k >> 3;*/ z &= flag; /* equivalente a: z = z & flag;*/
As operaes abaixo podem ser representadas assim: i = i + 1; i = i 1; z = a; a = a + 1; z = a; a = a 1; i = ++i; i = --i; z = a++; z = a--; z = ++a; z = --a; ++i; --i;
a = a + 1; z = a; a = a - 1; z = a;
+ ! ~ & * sizeof ++ -* / /
resto da diviso soma subtrao shift right shift left maior que maior ou igual a menor que menor ou igual a igual a diferente de bitwise AND bitwise OR bitwise XOR logical AND logical OR assinalamento assinalamento
a = b % c; a = b + c; a = b c; a = b >> n; a = b << n; a>b a >= b a<b a <= b a == b a != b a = b & c; a = b | c; a = b ^ c; flag1 && flag2 flag1 || flag2 a = b; a OP= b;
3.11 Expresses
Operadores, constantes e variveis constituem expresses. Uma expresso em C++ qualquer combinao vlida dessas partes. Uma vez que muitas expresses tendem a seguir as regras gerais da lgebra, estas regras so freqentemente consideradas. Entretanto, existem alguns aspectos das expresses que esto especificamente relacionadas com a linguagem C e sero discutidas agora.
de C++. O nmero na coluna de precedncia indica qual o nvel de precedncia dos operadores em questo, sendo 1 o nvel mais alto (operador a ser executado primeiro). Na coluna de precedncia, feito o uso dos termos unrio (para operadores que usam um s operando) e binrio (para operadores que necessitam de dois operandos) serve para diferenciar operadores que possuem smbolos iguais. Na coluna de associatividade, as siglas E-D e D-E indicam o tipo de associatividade dos operadores daquele nvel de precedncia: E-D significa associatividade esquerda-para-direita, e D-E significa associatividade direita-para-esquerda. Tabela 3.10 Precedncia e Associatividade de operadores em C++ Precedncia Operador Associatividade Explicao (expresso) 1 Agrupamento () 2 E-D Chamada de funo ++ Operador de incremento, psfixado -Operador de decremento, psfixado 3 (todos unrios) ! D-E Negao lgica ~ Negao Bitwise + Mais unrio (sinal positivo) Menos unrio (sinal negativo) ++ Operador de incremento, pr-fixado -Operador de decremento, pr-fixado & Endereo * Contedo de endereo () Modelador de tipo (tipo) nome sizeof Tamanho em bytes new Dynamically allocate storage new [] Dynamically allocate array delete Dynamically free storage delete [] Dynamically free array 4 (todos binrios) * E-D Multiplicao / Diviso % Resto de diviso + 5 (todos binrios) E-D Adio Subtrao << 6 E-D Shift para esquerda >> Shift para direita < 7 E-D Menor que <= Menor que ou igual a >= Maior que ou igual a > Maior que == 8 E-D Igual a != No igual a & 9 (binrio) E-D Bitwise AND UNESP Campus de Ilha Solteira 2007 Pgina 27
10 11 12 13 14
15 16
:? ,
D-E E-D
Bitwise XOR (OR exclusivo) Bitwise OR AND Lgico OR Lgico Atribuio simples Multiplicao e atribuio Dividir e atribuio Achar resto da diviso e atribuio Adio e atribuio Subtrao e atribuio Bitwise AND e atribuio Bitwise XOR e atribuio Bitwise OR e atribuio Shift para esquerda e atribuio Shift para direita e atribuio Condicional Combine two expressions into one
Pgina 28
Pgina 29
Pgina 31
int compara_valores(int primeiro, int segundo) { if (primeiro == segundo) return (0); else if (primeiro > segundo) return (1); else if (primeiro < segundo) return (2); } A funo compara_valores examina dois valores listados na tabela abaixo: Resultado 0 1 2 Significado Os valores so iguais O primeiro valor maior que o segundo O segundo valor maior que o primeiro
Como regra, deve-se tentar limitar as funes a usar somente um comando return. medida que as funes se tornarem maiores e mais complexas, ter muitos comandos return normalmente tornar as funes mais difceis de compreender. Na maioria dos casos, pode-se reescrever a funo para que ela use somente um comando return
void valores_locais(void) { int a=1, b=2, c=3; cout<<"A vale "<< a <<". B vale "<< b <<". C vale "<< c <<".\n"; } int main (void) { valores_locais(); system("PAUSE > null"); return 0; }
Quando este programa compilado e executado, as funes variaveis_globais e main exibem os valores das variveis globais. Observe que as variveis globais so declaradas fora de todas as funes. Declarando variveis globais deste modo, todas as funes do programa podem usar e alterar os valores da varivel global simplesmente referenciando o nome dela. Embora as variveis globais possam parecer convenientes, o uso incorreto delas podem causar erros que so difceis de depurar. Se um programa usa variveis globais, algumas vezes o nome de uma varivel global o mesmo que aquele de uma varivel local que seu programa declara dentro de uma funo. Por isso, preciso estar atento com o uso de variveis globais e sua nomeao. Quando nomes de variveis globais e locais UNESP Campus de Ilha Solteira 2007 Pgina 35
Pgina 36
Funes de string do C++: #include <string> Funes de I/O: Funes de tempo: #include <cstdio> #include <ctime>
Uma descrio detalhada das funes presentes na biblioteca padro de C++ no cabe nesta apostila. Entretanto, muitos livros e websites contm listagens e explicaes das funes padres. Um bom exemplo o website http://www.cppreference.com/index.html , que contm uma vasta referncia sobre vrios aspectos da linguagem C++. No deixe de examinar as funes que seu compilador fornece. Muitos compiladores referenciam essas funes internas como biblioteca de execuo. A maioria dos compiladores fornece centenas de funes de biblioteca de execuo com propsito que vo de abertura e trabalho com arquivos para acessar informaes do disco ou de diretrio para determinar o tamanho de uma string de caracteres. As duas ou trs horas que sero gastas para ler a documentao da biblioteca de execuo pouparo muitas horas de programao.
} int main() { unsigned long f; int n; cout<<"Digite um nmero: \n"; cin >> n; f = fatorial_recursivo(n); cout<<"O fatorial de "<<n<<" e "<<f<<" \n"; system("PAUSE > null"); return 0; } Quando uma funo chama a si prpria, as novas variveis locais e os argumentos so alocados na pilha, e o cdigo da funo executado com esses novos valores a partir do incio. Uma chamada recursiva no faz uma nova cpia da funo. Somente os argumentos e as variveis so novos. Quando cada chamada recursiva retorna, as antigas variveis locais e os parmetros so removidos da pilha e a execuo recomea no ponto de chamada da funo dentro da funo. Tendo em vista que o local para os argumentos de funes e para as variveis locais a pilha e que a cada nova chamada criado uma cpia destas variveis na pilha, possvel ocorrer overflow da pilha (stack overflow) e o programa terminar com um erro.
programa pular para outro ponto na memria do computador, executar a funo e depois retornar ao ponto onde parou. Criamos funes inline do mesmo jeito que criamos funes normais: declarando seu prottipo e sua definio, com parmetros e retorno. S preciso adicionar o prefixo inline antes do prottipo ou da definio da funo, como mostrado na funo abaixo: inline int quadrado (long x) { x = x * x; return x;
}
No podemos criar funes inline recursivas, pois logicamente uma funo recursiva tem um tamanho varivel de acordo com seu nmero de iteraes, que muitas vezes muda durante a execuo do programa. Ganha-se velocidade com as funes inline, mas perde-se em memria utilizada. Se um programa chama uma funo inline 10 vezes, criam-se 10 cpias da funo dentro do cdigo, aumentando seu tamanho durante a compilao. preciso escolher com cuidado quando utilizar funes normais e funes inline, tendo em mente o compromisso rapidez de execuo memria utilizada.
if (x != 1) parametro X if (x == 1) O parametro }
cout<<"Voce enviou um parametro para a funo! O igual a "<<x<<"\n"; cout<<"Voce NAO enviou um parametro para funo! X igual a "<<x<<"\n";
int main() { int valor; cout<<"Entre com um valor. Este valor ser repassado para a funo mensagem automaticamente!\n"; cin>>valor; mensagem(valor); cout<<"Agora chamaremos a funo mensagem sem lhe dar um parametro. Veja o que acontece: \n"; mensagem(); system("PAUSE > null"); return 0; }
Pgina 41
unsigned char signed char char short unsigned short int unsigned int long unsigned long float Pgina 42
O operador de insero tambm fornece facilidades para a exibio de strings. Alm dos tipos bsicos mostrados acima, o operador de insero tambm reconhece os seguintes tipos de ponteiros:
Ponteiros sero explicados com maior propriedade no mdulo 8, mas precisamos saber que C e C++ representam strings utilizando ponteiros para o endereo de memria da string. Este ponteiro pode ser o nome de uma varivel matriz de tipo char, um ponteiro de tipo char ou ento uma frase entre aspas. O operador de insero reconhece cada um destes casos e exibe na tela a string de texto. Por exemplo: char nome[20] = Jose das Couves; char * nome2 = Jose das Galinhas; cout << Jose das Dores; cout << nome; cout << nome2; Estas 3 utilizaes de cout exibem as strings de texto na tela. Veremos mais adiante que toda string possui um caractere de trmino, \0, que indica para o compilador que a string terminou. Nestes trs casos, o operador de insero orienta-se por este \0 para terminar a exibio das strings. importante ressaltar que o operador de insero no reconhece automaticamente matrizes numricas e no as exibe automaticamente na tela. Para fazer isso, precisaremos utilizar os mtodos tradicionais envolvendo loops para mostrar cada membro da matriz de uma vez. Este assunto ser discutido no mdulo 7, dedicado para matrizes.
Pgina 43
O comando cout permite tambm escolher um nmero mnimo de caracteres para ser exibido na tela. Isto feito utilizando o mtodo: cout.width ( x );; Onde substitumos x pelo nmero mnino de caracteres a ser exibido na tela. Aps a utilizao deste mtodo, utilizamos o comando cout para exibir o valor desejado, como no exemplo abaixo: int variavel = 10; cout.width ( 5 ); cout << variavel; Neste exemplo, foi especificado cout.width (5); e o valor a ser exibido 10. Assim, cout predecer o valor 10 com trs espaos em branco. Observe que o valor especifica o nmero mnimo de caracteres que a sada consumir. Se o valor a ser exibido requer mais caracteres do que o especificado, ser usado o nmero de caracteres necessrios para exibir o valor corretamente. importante observar tambm que o mtodo cout.width s vlido para a prxima utilizao de cout: aps isto, o nmero mnimo de caracteres volta a ser zero. Podemos tambm determinar o caractere a ser utilizado para preencher os espaos em branco de um campo de exibio. Isto feito com o seguinte mtodo: cout.fill ( caractere); Onde substitumos caractere pelo caractere que ser exibido. necessrio utilizar aspas entre o caractere, para indicar para o compilador que no se trata de uma varivel. O exemplo abaixo mostra a utilizao conjunta destes dois mtodos: int variavel = 10; cout.width ( 8 ); cout.fill(0); cout << variavel; Este exemplo far a seguinte exibio na tela, preenchendo os espaos em branco determinados por cout.width com o caractere 0, determinado por cout.fill: 00000010
da preciso, este novo valor vale para todas as utilizaes futuras de cout.
Pgina 46
cin.getline ( <matriz_destino>, <limite de caracteres>); O primeiro argumento a matriz de caracteres para onde sero enviados os dados recebidos. necessrio declarar uma matriz de caracteres previamente ao uso deste mtodo. O segundo argumento o nmero mximo de caracteres que ser lido pelo mtodo, menos o caractere \0 indicando o fim da string. Assim, se especificarmos um nmero mximo igual a 20, este comando ler 19 caracteres e descartar os prximos caracteres entrados pelo usurio, at que a tecla <ENTER> seja pressionada. Um espao ser sempre utilizado para marcar o fim da string atravs do caractere \0. Um exemplo da utilizao de cin.getline: char matriz[60]; cin.getline ( matriz, 50 ); cout >> matriz; Nesse caso, o mtodo cin.getline ler os prximos 49 caracteres (lembre-se do espao reservado para o caractere fim_de_string \0) que o usurio entrar atravs do teclado. A leitura ser feita at que ele aperte a tecla <ENTER> interrompendo o comando. Caso o usurio entre mais do que 50 caracteres , os prximos sero descartados pelo programa.
Pgina 47
6.2 A declarao if
Utilizamos a declarao if quando desejamos que o programa teste uma ou mais condies e execute um ou outro comando de acordo com o resultado deste teste. A sintaxe de if a seguinte: if (condio) { comandos; } else { comandos; } A declarao if testar a condio expressa entre parnteses. Caso a condio seja verdadeira, os comandos declarados entre as chaves sero executados. A declarao else opcional: podemos utiliz-la para determinar um conjunto de comandos que sero executados caso a condio testada seja falsa. Note que somente um dos conjuntos de comandos ser executado, nunca os dois: caso a condio seja verdadeira, o bloco pertencente a if ser executado; caso a condio falhe, o bloco pertencente a else ser executado. O programa abaixo ilustra de maneira simples o uso da declarao if-else, obtendo um nmero do usurio e verificando se este valor maior ou igual a 50. #include <iostream> UNESP Campus de Ilha Solteira 2007 Pgina 48
using namespace std; int main() { int teste; cout<<"Digite um numero qualquer:\n"; cin>> teste; if (teste > 50) { cout<<"O numero que voce digitou maior que 50"; } else { cout<<"O numero que voce digitou menor que 50"; } system("PAUSE > null"); return 0; } possvel tambm aninhar ifs, ou seja, fazer uma declarao if dentro de outra declarao if anterior. Este um mtodo muito til em programao, mas preciso tomar cuidado ao utiliz-lo para saber qual bloco else pertence qual if. Em C++, o else ligado ao if mais prximo dentro do mesmo bloco de cdigo que j no tenha uma declarao else associada a ele. Para se certificar de que estamos aninhando os ifs e elses corretamente, utilizamos chaves para delimitar os diferentes blocos, como pode ser visto no cdigo abaixo: if ( x > 10) { if ( x == 17) { cout<< x maior que 10 e igual a 17; } else { cout<< x maior que 10 mas no igual a 17; } } else { cout << x menor do que 10; } Note que a segunda declarao if est totalmente contida pelas chaves da primeira declarao if. Utilizou-se chaves em todas os blocos de comando, para melhor separar as condies dos blocos de comandos. Alm disso, note o uso da tabulao para separar visualmente os diferentes blocos e declaraes: poderamos escrever todo o cdigo sem usar tabulao, alinhando todas as linhas esquerda, mas isto dificultaria a identificao das diferentes declaraes. UNESP Campus de Ilha Solteira 2007 Pgina 49
if (condio) { comandos; } else if (condio) { comandos; } else if (condio) { comandos; } else { comandos; } Cada bloco else if dever testar uma condio diferente. O programa testar todas as condies na sequncia, de cima para baixo, at encontrar uma condio verdadeira. Quando isto acontece, os comandos pertencentes ao bloco verdadeiro sero executados enquanto todos os outros blocos do encadeamento so ignorados. Caso nenhuma condio else if seja verdadeira, executa-se o bloco de comandos pertencente ao else final. Note que o else opcional: Se o else final no estiver presente e todas as outras condies forem falsas, ento nenhuma ao ser realizada. Utilizando este encadeamento, ampliaremos o programa anterior para que ele teste vrias condies sobre um nmero enviado pelo usurio, at encontrar uma condio verdadeira. #include <iostream> using namespace std; int main() { int teste; cout<<"Digite um numero qualquer:\n"; cin>> teste; if (teste <= 50) { UNESP Campus de Ilha Solteira 2007 Pgina 50
cout<<"O nmero que voc digitou menor que 50\n"; } else if (teste > 50 && teste <= 100) { cout<<"O nmero digitado maior que 50 e menor ou igual a 100\n"; } else if (teste > 100 && teste <= 200) { cout<<"O nmero digitado maior que 100 e menor ou igual a 200\n"; } else { cout<<"O numero digitado maior que 200\n"; } system("PAUSE > null"); return 0; }
case, cada um associado a um determinado valor. A declarao comparar o valor da varivel com o valor de cada um dos case: quando uma associao encontrada, os comandos pertencentes ao case relacionado so executados. Se nenhuma associao for encontrada, a declarao switch executar os comandos pertencentes ao bloco default (note que o bloco default opcional: caso ele no exista, caso nenhuma associao seja encontrada a declarao switch termina sem que nenhum comando seja executado). O exemplo abaixo demonstra uma utilizao da declarao switch. #include <iostream> using namespace std; int main() { int option; cout<<"Digite a opo desejada:\n"; cout<<"1. Opo 1\n"; cout<<"2. Opo 2\n"; cout<<"3. Opo 3\n"; option = 0; cin>> option; switch(option) { case 1: cout<<"Voc escolheu a primeira opo\n"; break; case 2: cout<<"Voc escolheu a segunda opo\n"; break; case 3: cout<<"Voc escolheu a terceira opo\n"; break; default: cout<<"Voc escolheu uma opo invlida!\n"; } system("PAUSE > null"); return 0; } Aps o fim de cada bloco de comandos case, comum utilizar o comando break;. Este comando interrompe a execuo do lao em que o programa se encontra, fazendo com que o programa prossiga para o prximo comando imediatamente aps o lao. No caso de switch, o comando break assegura que a execuo da declarao switch termine, forando o programa voltar para sua execuo normal. Caso omitssemos os comandos break; no fim de cada bloco, a declarao switch executaria os comandos presentes no case em que a associao foi encontrada, e continuaria a executar todos os comandos presentes em todos os case na sequncia (incluindo o bloco default) at o trmino da declarao switch. Note que este comportamento pode ser til em alguns programas, como por exemplo uma sequncia de operaes matemticas onde utilizamos a declarao switch para escolher o ponto de partida da sequncia.
Pgina 52
O exemplo de cdigo abaixo mostra uma declarao de lao for utilizando o exemplo dado anteriormente: #include <iostream> using namespace std; int main() { int controle; for ( controle = 0; controle <= 30; controle++) { cout << "Esta frase se repetir at que controle seja maior do que 30\n"; cout<< "controle = "<<controle<<"\n"; } system("PAUSE > null"); return 0; } UNESP Campus de Ilha Solteira 2007
varivel
Pgina 53
A varivel controle comea com valor 0. O lao for testa o valor da varivel continuamente, sempre determinando se ele menor do que 30. Sempre que o valor da varivel for menor que 30 (condio verdadeira), a varivel de controle incrementada de 1 e os comandos entre as chaves so executados. Quando a varivel controle for maior do que 30 (condio falsa), o lao termina e o programa volta a ser executado normalmente. O comando for extremamente flexvel. Podemos atribuir qualquer valor que quisermos varivel de controle, e tambm podemos increment-la (ou decrement-la da forma que desejarmos). No exemplo abaixo, utilizamos o lao for de forma inversa ao exemplo anterior: a varivel de controle comea em 60 e vai sendo decrementada de 2 a cada repetio. #include <iostream> using namespace std; int main() { int controle; for ( controle = 60; controle >= 0; controle = controle - 2) { cout << "Esta frase se repetir at que a varivel controle seja igual a 0\n"; cout<< "controle = "<<controle<<"\n"; } system("PAUSE > null"); return 0; } Os trs argumentos do lao for so opcionais: podemos omitir qualquer um dos argumentos, mas precisamos estar atentos s consequncias que isto traz ao programa. Por exemplo, o cdigo abaixo omite o argumento de incremento da varivel de controle. No entando, fazemos o incremento da varivel dentro do bloco de comandos do lao for: for (x = 0; x <= 50; ) { cout<<x; x++; } Caso no fizssemos o incremento dentro do bloco de comandos, a condio testada seria sempre verdadeira, e o lao for nunca terminaria. o chamado lao infinito: for (x = 0; x <= 50; ) { cout<<x; } Laos infinitos geralmente surgem por algum erro de programao. Quando o programa entra em um lao infinito, pode-se pressionar Ctrl+C no modo MS-DOS para UNESP Campus de Ilha Solteira 2007 Pgina 54
finalizar o programa. importante saber que mesmo omitindo um argumento, necessrio incluir o ponto-e-vrgula correspondente. Podemos omitir tambm a inicializao da varivel de controle, caso ela tenha sido declarada e inicializada anteriormente no programa. Tambm podemos criar um lao for nulo, sem um bloco de comandos: for (x = 0; x == 50; x++) { } Nesse caso, o programa ainda interrompido para a execuo do lao for, e no faz nada durante este intervalo. Esta tcnica pode ser utilizada para forar uma pausa na execuo de um programa, porm ela pouco precisa e desperdia recursos do microprocessador. Finalmente, podemos utilizar vrias variveis de controle para controlar um mesmo lao for. Para isto, utilizamos vrgulas para separar as expresses relacionadas a cada varivel dentro de um mesmo argumento. O cdigo abaixo abaixo ilustra como isto feito: for (i=0, j=100; i <= 100; i++, j++) { cout << i << j; } A utilizao de vrias variveis dentro de um mesmo lao for particularmente til em programas que trabalham com matrizes e vetores.
varivel de controle no lao while e finalmente modificando esta varivel (incrementandoa ou decrementando-a) aps a execuo dos comandos necessrios. O programa abaixo demonstra como inserir uma varivel de controle no lao while. #include <iostream> using namespace std; int main() { int controle = 0; while (controle < 20) { cout<<"A variavel de controle funcionar se esta frase se repetir somente 20 vezes: "; controle++; cout<<controle<<" \n"; } system("PAUSE > null"); return 0; }
cout<<"Esta frase foi escrita "<<controle<<" vezes!\n"; controle++; } while (controle <= 20); system("PAUSE > null"); return 0; }
Pgina 57
system("PAUSE > null"); } Em primeiro lugar, o lao while far com que o programa rode repetidamente at que a varivel opcao, cujo valor atribudo pelo usurio a cada repetio do programa, tenha valor igual a 5. A declarao if checa se o valor entrado pelo usurio maior que cinco ou menor que 1. Caso isto seja verdade, o comando continue interrompe a execuo de todos os comandos seguintes, fazendo o lao while ser repetido mais uma vez. Caso o usurio entre um valor entre 1 e 5, o comando continue no executado e o lao while continua para o prximo bloco de comandos, no caso, a declarao switch. A declarao switch utilizada para mostrar qual opo o usurio escolheu e, no caso do usurio ter escolhido o valor 5, indicar que o programa terminou. Quando o valor 5 escolhido, a condio do lao while torna-se falsa, terminando o programa.
Pgina 59
Mdulo 7 Matrizes
7.1 Matrizes
Matrizes so variveis que contm vrios valores de um mesmo tipo. Por exemplo, podemos criar a matriz notas para armazenar as notas obtidas por 100 alunos em um exame, ou ento utilizar uma matriz chamada gastos_mensais para anotar nossos gastos mensais ao longo do ano. Uma matriz armazena vrios valores de um mesmo tipo: podemos criar matrizes para armazenar qualquer um dos tipos bsicos de variveis, como int, float e char. Cada valor armazenado separadamente em um elemento da matriz, e pode ser acessado e modificado a qualquer momento.
A declarao de uma matriz muito parecida com a declarao de uma varivel, bastando adicionar o nmero de elementos que desejamos que ela tenha. A sintaxe a seguinte: <tipo> <nome> [<numero de elementos>]; Por exemplo, caso quisssemos criar uma matriz chamada catlogo para armazenar 156 inteiros, a declarao seria assim: int catalogo [156]; Podemos utilizar qualquer tipo de variveis j estudadas anteriormente para criar uma matriz, como float, int, char. Uma vez criada uma matriz de um determinado tipo, ela s pode receber valores deste tipo. Note que precisamos definir um tipo para uma matriz: no possvel criar uma matriz genrica que aceite um tipo qualquer, ou vrios tipos. Isso acontece porque ao declarar uma matriz, o compilador aloca memria suficiente para conter o nmero de valores especificado de acordo com o tipo da matriz. Por exemplo, uma matriz de 100 elementos do tipo int normalmente ir requerer 100*2 ou 200 bytes de memria. Por outro lado, uma matriz de 100 elementos do tipo float ir requerer 100*4 bytes ou 400 bytes. Assim como uma varivel normal, podemos atribuir valores para uma matriz no momento de sua declarao. Isto feito utilizando o operador de atribuio = seguido dos valores contidos entre chaves e separados por vrgulas. Por exemplo, considere a matriz de inteiros teste abaixo: int teste[5] = { 1, 2, 3, 4 , 5}; Tambm podemos atribuir apenas parte dos valores de uma matriz, por exemplo, UNESP Campus de Ilha Solteira 2007 Pgina 60
podemos criar uma matriz que comporte 50 valores do tipo float e atribuir apenas 5 valores ela, deixando para atribuir o restante dos valores no decorrer do programa. float notas[50] = { 7.65, 8.48, 4.27, 6.78, 9.10 }; A linguagem C++ faz com que toda matriz parcialmente inicializada tenha seus valores restantes automaticamente transformados em zero. Assim, caso precisemos de uma matriz que s contenha zeros, podemos atribuir o primeiro elemento da matriz como zero e deixar que o compilador transforme os elementos restantes em zero, como vemos abaixo: int zeros[75] = {0};
Pgina 61
#include <iostream> using namespace std; int main() { int sequencia[4]; for (int i = 0; i < 4; i++) { cout << "Entre com o elemento numero "<<(i+1)<<" da sequencia: "; cin >> sequencia[i]; cout << endl; } cout << "A sequencia entrada pelo usuario foi: "; for (int i = 0; i < 4; i++) { cout << sequencia[i]<<" "; } system("PAUSE > null"); return 0; } Importante: como vimos no exemplo anterior, podemos utilizar variveis para acessar os elementos de uma matriz. Da mesma forma, podemos definir constantes para indicar o nmero de elementos de uma matriz. Essa tcnica muito til, pois caso precisemos alterar o nmero de elementos da matriz ao invs de caarmos no cdigo todas as referncias este nmero, tudo que precisamos fazer alterar o valor da constante. Assim, veja o mesmo programa anterior reescrito utilizando uma definio de constante. #include <iostream> using namespace std; int main() { const int TAMANHO = 4; int sequencia[TAMANHO]; for (int i = 0; i < 4; i++) { cout << "Entre com o elemento numero "<<(i+1)<<" da sequencia: "; cin >> sequencia[i]; cout << endl; } cout << "A sequencia entrada pelo usuario foi: "; for (int i = 0; i < 4; i++) { cout << sequencia[i]<<" "; } system("PAUSE > null"); return 0; }
Pgina 62
Pgina 63
#include <iostream> using namespace std; int main() { int tritabela [2] [2] [2] = {{{ 9, 8}, {7,6}},{{5, 4},{3, 2}}}; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { cout << tritabela[i][j][k]<<" "; } cout<<endl; } cout<<endl; } system("PAUSE > null"); return 0; }
cout << "Entre com o elemento numero "<<(i+1)<<" da sequencia: "; cin >> sequencia[i]; cout << endl; } result = soma(sequencia, TAMANHO); cout << "A soma de todos os elementos da matriz e igual a "<<result<<"."<<endl; system("PAUSE > null"); return 0; } Tambm podemos utilizar funes que trabalhem com matrizes multidimensionais. Entretanto, ao criar o parmetro da matriz preciso declarar o tamanho de todas as dimenses da matriz com exceo da primeira. Por exemplo: int soma_tabela ( int matriz [ ] [3] [4], int elementos) { comandos; } A primeira dimenso deixada em branco, para ter seu tamanho definido pelo outro parmetro elementos. Entretanto, as outras duas dimenses tem seu tamanho definido respectivamente em 3 e 4. Caso deixssemos estas outras duas dimenses sem um tamanho definido, o programa no seria compilado. muito importante notar que, ao trabalhar com matrizes dentro de funes, estamos trabalhando com a prpria matriz, ou melhor, com o endereo dos dados desta matriz. Normalmente, quando trabalhamos com variveis dentro de uma funo, estamos trabalhando com cpias destes valores. Entretanto, isso no verdade para matrizes, por razes que veremos no mdulo sobre ponteiros. Por enquanto, basta saber que quando trabalhamos com matrizes dentro de funes, qualquer modificao feita na matriz feita para valer. Se somarmos mais 10 a todos os valores de uma matriz em uma funo, quando a funo terminar a matriz estar modificada. Esta caracterstica muito til para contornar o fato que no podemos utilizar uma matriz como retorno de uma funo: no precisamos que a funo retorne uma matriz, s precisamos fazer com que a funo altere a matriz. Por exemplo, o programa abaixo usa uma funo para ordenar os nmeros dentro de uma matriz. #include <iostream> using namespace std; int ordena( int matriz[], int tamanho) { int temp = 0; for (int i = 0; i < tamanho; i++){ for (int j = i; j < tamanho; j++){ if (matriz[j] < matriz [i]) { temp = matriz[i]; matriz[i] = matriz[j]; matriz[j] = temp; } } } } UNESP Campus de Ilha Solteira 2007 Pgina 65
int main() { const int TAMANHO = 4; int sequencia[TAMANHO] = {27, 12, 42, -8}; cout <<"Sequencia original: "; for (int i = 0; i < 4; i++) { cout << sequencia[i]<<" "; } cout<<endl; ordena(sequencia, TAMANHO); cout <<"Sequencia ordenada: "; for (int i = 0; i < 4; i++) { cout << sequencia[i]<<" "; } cout<<endl; system("PAUSE > null"); return 0; }
<tipo> * <nome> = new <tipo> [ <numero de elementos> ]; Por exemplo, para criar uma matriz do tipo float com 10 elementos: float * lista = new float [10]; O acesso aos elementos da nova matriz feito de forma anloga ao de uma matriz criada do jeito normal: utilizamos o nome da matriz seguido do nmero do elemento acessado. Como j dito anteriormente, o primeiro elemento de uma matriz sempre o elemento 0. Note que no podemos inicializar automaticamente os valores de uma matriz criada dessa forma. Cada elemento da matriz deve ter seu valor atribudo separadamente. A outra face do operador new o operador delete. S podemos utilizar este operador com matrizes criadas pelo operador new, ou seja, matrizes criadas por declarao normal no podem ser apagadas durante a execuo do programa. Para utilizar o operador delete para apagar uma matriz, a sintaxe a seguinte: delete <nome>; O programa abaixo pede ao usurio o nmero de elementos da matriz, cria uma matriz e depois volta a pedir ao usurio os valores de cada um dos elementos da matriz. No final do programa, a matriz deletada. #include <iostream> using namespace std; int main() { int tamanho = 0; cout<<"Entre com o tamanho da matriz: "; cin>>tamanho; cout<<endl; int *sequencia = new int[tamanho]; for (int i = 0; i < tamanho; i++) { cout << "Entre com o elemento "<<(i+1)<<" da matriz: "; cin>>sequencia[i]; cout<<endl; } cout<<"A matriz entrada e: "; for (int i = 0; i < tamanho; i++) { cout << sequencia[i]<<" "; } cout<<endl; cout<<"Programa encerrado. A matriz criada ser deletada, e a memria ser devolvida para o processador."; delete sequencia; system("PAUSE > null"); return 0; } UNESP Campus de Ilha Solteira 2007 Pgina 67
Mdulo 8 Strings
No falamos at agora de matrizes de caracteres, apesar de j utiliz-las vrias vezes. Uma matriz de caracteres normalmente chamada de string em linguagem de programao. Em C++, existem duas maneiras de se criar e trabalhar com strings. Um deles o mtodo antigo, j utilizado pela linguagem C, de se declarar e trabalhar com uma matriz de caracteres do mesmo modo que trabalhamos com matrizes numricas. O outro mtodo utilizar as facilidades da biblioteca padro de C++, que define um tipo de varivel especfico para strings, com vrias operaes e funes prprias. Nesta apostila trabalharemos com as strings do tipo C++, por serem elas mais simples e ao mesmo tempo apresentarem mais recursos do que as strings tipo C.
das maneiras j estudadas: atravs de uma atribuio, ou de uma entrada de dados do usurio, por exemplo. C++ possui uma srie de facilidades para a inicializao de strings. Cada um desses diferentes mtodos chamado de inicializador de uma string. A tabela abaixo rene os quatro principais inicializadores de string: string s1; Cria uma string vazia, chamada s1. Esta a inicializao default de uma string: toda string criada dessa forma est vazia. Cria a string s2 como uma cpia de outra string (nesse caso, s1). Cria a string s2 como uma cpia da string literal entre os parnteses. Cria a string s2, que contm x cpias do caractere entre aspas (no caso, c).
string s2 (s1); string s2 (Esta uma string literal); string s2 (x, c);
O programa abaixo exemplifica os mtodos descritos acima: #include <iostream> #include <string> using namespace std; int main() { string vazia; string ditado("Casa de ferreiro, espeto de pau"); string copia_ditado(ditado); string letra_z( 42, 'z'); cout <<"Mostrando o contedo da string 'vazia':"<< endl; cout << vazia; cout <<"Mostrando o contedo da string 'ditado':"<< endl; cout << ditado; cout <<"Mostrando o contedo da string 'copia_ditado':"<< endl; cout << copia_ditado; cout <<"Mostrando o contedo da string 'letra_z':"<< endl; cout << letra_z; system("PAUSE > null"); return 0; }
simples. Basicamente, cin e cout tratam strings como se fossem variveis simples, facilitando sua manipulao e seu uso em programas. J vimos no programa exemplo anterior que utilizamos cout para exibir strings inteiras na tela. cout exibe todos os caracteres da string, e detecta automaticamente o fim dela. Utiliza-se o comando cin para ler strings atravs do teclado. A sintaxe a seguinte: cin >> <nome da strin>; Como j vimos, cin ler os caracteres inseridos atravs do teclado at encontrar um espao em branco (tecla barra de espao) ou o fim da entrada (tecla Enter). Quando cin encontra um espao em branco, todos os caracteres aps este espao so ignorados. O programa abaixo l entradas do teclado para armazenar o nome e sobrenome do usurio dentro de strings. #include <iostream> #include <string> using namespace std; int main() { string nome; string sobrenome; cout<<"Digite seu nome: "; cin >> nome; cout<<"Digite seu sobrenome: "; cin >> sobrenome; cout << "Seu nome "<<nome<<" <<sobrenome<<"."<<endl; system("PAUSE > null"); return 0; } Esse programa apresenta alguns problemas quando o usurio possui mais de um nome ou sobrenome. Por exemplo, caso o nome Jos Ricardo seja inserido, a leitura do sobrenome ser ignorada e o programa exibir Jos como o nome e Ricardo como sobrenome. Da mesma forma, no caso da entrada de um sobrenome duplo, somente o primeiro sobrenome guardado na string sobrenome, sendo o segundo ignorado. Isto acontece por causa da maneira que C++ trata os espaos em branco em uma entrada via teclado. Espaos em branco so considerados fim de entrada pelo comando cin; ao invs de descartar os caracteres que vierem aps o espao em branco, C++ os guarda em um buffer (uma espcie de reserva ou pilha de dados). Quando cin for chamado novamente, antes de ler a nova entrada do teclado, o programa primeiro utiliza os dados que esto nesse UNESP Campus de Ilha Solteira 2007 Pgina 70
seu
sobrenome
buffer. Assim, temos a impresso que a nova entrada de dados foi descartada pelo programa, mas na verdade ela foi jogada no buffer, esperando uma nova chamada de cin. Dessa forma, cin no o mtodo recomendado para ler frases inteiras, com palavras separadas por espaos. Para este objetivo, utilizamos o mtodo cin.getline, que j estudamos no mdulo 5, com algumas alteraes. O mtodo cin.getline l linhas inteiras de entrada atravs do teclado, sem se importar com os espaos em branco. Mas a sintaxe do mtodo cin.getline um pouco diferente, quando trabalhamos com strings: getline ( cin, <nome da string>); Assim, este mtodo recebe todos os caracteres (incluindo os espaos em branco) entrados pelo usurio, at que ele aperte a tecla Enter. O programa abaixo uma verso melhorada do programa anterior, utilizando o mtodo cin.getline para receber os dados desejados. #include <iostream> #include <string> using namespace std; int main() { string nome; string sobrenome; cout<<"Digite seu nome: "; getline(cin, nome); cout<<"Digite seu sobrenome: "; getline(cin, sobrenome); cout <<"Seu nome "<<nome<<" "<<sobrenome<<"."<<endl; system("PAUSE > null"); return 0; }
seu
sobrenome
s1 + s2 s1 = s2 s1 == s2
Concatena duas strings. Atribui o contedo de s2 na string s1. Testa a igualdade entre s1 e s2 (retorna verdadeiro se as duas strings forem iguais). Duas strings so consideradas iguais se elas tiverem o mesmo nmero de caracteres e seus caracteres forem iguais.
A primeira funo, <string>.empty indica se uma string est vazia ou no. Esta funo retorna um valor booleano verdadeiro ( true ou 1 ) caso a string esteja vazia, caso contrrio ela retorna falso (false ou 0). A funo <string>.size bastante til para trabalhar com strings entradas pelo usurio. Como no podemos saber exatamente o nmero de caracteres entrados pelo usurio, til ter uma funo que nos retorne o tamanho de uma string. Como vemos acima, possvel acessar um elemento individual de uma string do mesmo modo que fazemos com matrizes. Esse tipo de acesso til quando precisamos manipular os vrios caracteres de uma string, como por exemplo, identificar as letras maisculas de uma string e transform-las em minsculas. Para esse tipo de manipulao caractere caractere, contamos com as diversas funes da biblioteca cctype, que veremos no item 8.5. A concatenao de strings particularmente til. Quando utilizamos o sinal de soma entre duas strings, estamos concatenando elas, ou seja, juntando o comeo da segunda matriz com o final da primeira. Tambm possvel concatenar strings literais ( frases entre aspas) junto com as variveis string dessa forma. O programa abaixo ilustra a concatenao de strings. #include <iostream> #include <string> using namespace std; int main() { string nome; string sobrenome; cout<<"Digite seu nome: "; getline(cin, nome); cout<<"Digite seu sobrenome: "; getline(cin, sobrenome); string concatena; concatena = nome + sobrenome; cout << "O seu nome completo : " + nome + " " + sobrenome << endl; system("PAUSE > null"); UNESP Campus de Ilha Solteira 2007 Pgina 72
return 0;
Pgina 73
Com exceo das duas ltimas funes que transformam caracteres, todas as outras testam os caracteres de uma string, retornando valores booleanos ( true ou false, 1 ou 0 ). O programa abaixo mostra o uso de algumas dessas funes, atravs da leitura de uma string entrada pelo usurio. Note que tambm feito o uso da funo <string>.size para determinar o tamanho da string. #include <iostream> #include <string> using namespace std; int main() { string frase; int letras = 0, maiusculas = 0, minusculas = 0, numeros = 0; cout<<"Entre com uma frase qualquer, composta de letras maiusculas, minusculas e numeros: "<< endl; getline(cin, frase); letras = frase.size(); cout<<"Sua frase tem "<< letras<< " letras."<<endl; for (int i = 0; i < letras; i++) { if (isdigit(frase[i])) numeros++; if (islower(frase[i])) minusculas++; if (isupper(frase[i])) maiusculas++; } cout<<"Sua frase tem "<< numeros<< " numeros."<<endl; cout<<"Sua frase tem "<< minusculas<< " letras minusculas."<<endl; cout<<"Sua frase tem "<< maiusculas<< " letras maiusculas."<<endl; system("PAUSE > null"); return 0; }
Pgina 74
Mdulo 9 Ponteiros
9.1 - Endereos de Memria
J dissemos vrias vezes que as variveis ficam armazenadas em determinados espaos na memria do computador. Ao trabalhar com uma varivel, geralmente no precisamos nos preocupar com o endereo desta varivel, pois o compilador cuida destes detalhes tcnicos. Entretanto, pode ser bastante til saber o endereo de uma varivel. Em C++, utilizamos o operador de endereo & para acessar o endereo de uma varivel. Sua sintaxe muito simples, bastando inserir o operador & na frente do nome de uma varivel: &<varivel> O programa abaixo cria uma varivel inteira e utiliza cout para exibir o valor da varivel e depois seu endereo, utilizando o operador &. #include <iostream> using namespace std; int main( ) { int valor = 124; cout << "A variavel armazena o seguinte valor: "; cout << valor <<endl; cout << "A variavel esta armazenada no seguinte endereo: "; cout << &valor <<endl; system(PAUSE > null); return 0; } O operador de endereo utilizvel tambm em matrizes. Quando utilizamos este operador em uma matriz, temos o endereo inicial da matriz, que nada mais do que o endereo do primeiro elemento da matriz. Tambm podemos utilizar o operador & para acessar os endereos de cada elemento de uma matriz, como vemos no exemplo abaixo: #include <iostream> using namespace std; int main( ) { int matriz[3] = { 42, 37, 28 }; cout << &matriz[0] << " : " << matriz[0] << endl; cout << &matriz[1] << " : " << matriz[1] << endl; cout << &matriz[2] << " : " << matriz[2] << endl; system(PAUSE > null); return 0; } UNESP Campus de Ilha Solteira 2007 Pgina 75
9.2 Ponteiros
Em linguagem de programao, chamamos de ponteiros as variveis especiais que armazenam endereos de memria. Como j vimos, as variveis possuem trs atributos bsicos: seu nome, o valor armazenado por ela e o endereo de memria onde ela est armazenada. Os ponteiros, ao invs de armazenar valores, armazenam endereos de memria. Ao utilizar um ponteiro, podemos acessar este endereo e manipular o valor que est armazenado l dentro. Ponteiros so utilizados constantemente em C++. Por exemplo, quando trabalhamos com matrizes sem saber estamos trabalhando com ponteiros: a linguagem C++ ( e a linguagem C tambm) utiliza ponteiros para acessar as diversas posies de uma matriz.
int main( ) { int valor = 124; int *referencia; cout << "A variavel armazena o seguinte valor: "; cout << valor <<endl; cout << "A variavel esta armazenada no seguinte endereo: "; referencia = &valor; cout << referencia <<endl; system(PAUSE > null); return 0; }
Esta operao til para acessar e modificar valores dentro de posies de memria. Um ponteiro com o asterisco de indireo se comporta como uma varivel comum. Podemos utiliz-lo em comandos, expresses, atribuies e onde mais for necessrio.
void potencia( int *variavel,int elevado) { int original = 2; if (elevado == 0) { *variavel = 1; return; } if (elevado == 1) return; for (int i = 2; i <= elevado; i++) { *variavel = *variavel*original; } Quando utilizamos uma funo deste tipo, preciso que o programa passe um ponteiro como parmetro desta funo. Isto pode ser feito de duas maneiras: indicando um ponteiro que contenha um endereo, ou indicando simplesmente o endereo de uma varivel. Como j vimos, utilizamos o operador & antes do nome de uma varivel para obter seu endereo. Assim, uma funo que utiliza ponteiros aceita em seu parmetro um ponteiro ou o endereo de uma varivel ( &varivel ). O programa abaixo mostra a utilizao de uma funo com chamada por referncia, tendo em mente os cuidados descritos anteriormente. #include <iostream> using namespace std; void potencia( int *variavel,int elevado) { int original = 2; if (elevado == 0) { *variavel = 1; return; } if (elevado == 1) return; for (int i = 2; i <= elevado; i++) { *variavel = *variavel*original; } } int main() { int dois = 2; int j = 5; potencia( &dois, j); cout << "dois elevado a "<< j <<" : "<< dois << endl; system("PAUSE > null"); return 0; } A utilizao da chamada por referncia parece no ter muita utilidade quando UNESP Campus de Ilha Solteira 2007 Pgina 79
trabalhamos com variveis simples. Porm, este cenrio muda quando trabalhamos com matrizes: a utilizao da chamada por referncia a melhor forma de se criar funes que trabalham com matrizes.
#include <iostream> using namespace std; int main() { int tabela[5] = { 20, 34, 58, 70, 125 }; int *ponteiro = tabela; cout << *ponteiro << endl; ponteiro++; cout << *ponteiro << endl; for (int i = 2; i < 5; i++){ ponteiro++; cout << *ponteiro << endl; } system("PAUSE > null"); return 0; } O programa abaixo ilustra a criao de duas funes que utilizam matrizes. As duas funes fazem a mesma coisa (organizar uma matriz em ordem crescente), mas a primeira funo trata a matriz como um ponteiro, enquanto que a segunda trabalha com a matriz do modo j conhecido. Os dois mtodos so vlidos e tem sua utilidade, mas de modo geral mais simples e recomendvel utilizar matrizes do modo j estudado. #include <iostream> using namespace std; int ordenamatriz( int matriz[], int tamanho) { int temp = 0; for (int i = 0; i < tamanho; i++){ for (int j = i; j < tamanho; j++){ if (matriz[j] < matriz [i]) { temp = matriz[i]; matriz[i] = matriz[j]; matriz[j] = temp; } } } } int ordenaponteiro (int *matriz, int tamanho) { int temp = 0; for (int i =0; i < tamanho; i++) { for (int j = i; j < tamanho; j++){ if ( *(matriz + j) < *(matriz + i ) ) { temp = *( matriz + i ); UNESP Campus de Ilha Solteira 2007 Pgina 81
int main() { const int TAMANHO = 4; int sequencia[TAMANHO] = {27, 12, 42, -8}; int sequencia2[TAMANHO] = {21, -27, 1024, 42}; cout<<endl; ordenamatriz(sequencia, TAMANHO); ordenaponteiro(sequencia2, TAMANHO); cout <<"Sequencia ordenada 1: "; for (int i = 0; i < 4; i++) { cout << sequencia[i]<<" "; } cout<<endl; cout <<"Sequencia ordenada 2: "; for (int i = 0; i < 4; i++) { cout << sequencia2[i]<<" "; } cout<<endl; system("PAUSE > null"); return 0; }
Encerrando os tpicos relacionados com ponteiros e funes, temos os ponteiros para funes. Um ponteiro para uma funo armazena o endereo de uma funo. Este tipo de ponteiro til para ser usado como parmetro de outra funo. Sua declarao parecida com a declarao de funes que retornam ponteiros, mas no deve ser confundida. Sua sintaxe a seguinte: <tipo do ponteiro/funo> (*<nome da funo>) ( ); Basicamente, coloca-se o asterisco antes do nome da funo, junto dos parnteses, Alguns exemplos: int (*seno) ( ); int (*integral) ( );
cout << "De forma direta (pela propria variavel): "<< inteiro << endl; cout << "De forma indireta (pelo ponteiro pontinteiro): "<< *pontinteiro << endl; para variavel
cout << "De forma duplamente indireta (pelo ponteiro para ponteiro pontponteiro): "<< **pontponteiro << endl; system("PAUSE > null"); return 0; } Na verdade, C++ nos permites criar infinitas indirees (ponteiros para ponteiros para ponteiros...e assim por diante). Mas na prtica, a utilizao de ponteiros para ponteiros geralmente evitada por causar grande confuso e dificultar a compreenso dos programas.
para o sistema. Apesar da vantagem da economia de memria apresentada pelos operadores new e delete, preciso saber aonde utiliz-los. Eles so especialmente teis para matrizes cujo tamanho exato no conhecemos, ocasionando grande economia de memria. Entretanto, para variveis que sero utilizadas o tempo todo pelo programa, a economia de memria obtida no to grande, e a alocao/liberao constante de memria pode deixar o programa at mais lento. Assim, recomenda-se a utilizao da declarao normal de variveis na maioria dos programas que criamos.
Pgina 85
int main(){ string frase; cout<<"Escreva uma frase para ser escrita no arquivo string.txt:"; getline(cin, frase); cout<<"Obrigado. Escrevendo dados no arquivo strings.txt...\n"; ofstream escreve; escreve.open("strings.txt"); escreve << "Utilizamos os objetos ofstream para escrever em arquivos\n"; escreve<< "Note que podemos utilizar os caracteres \\n pra quebrar a linha, como fazamos em cout\n"; int numero = 100; escreve<<"Podemos escrever o valor de variaveis numericas: " <<numero <<"\n"; int matriz[3] = {42, 19, 99}; escreve<<"Podemos tambm escrever matrizes!"; for (int i=0; i < 3; i++){ escreve.width(6); escreve<<matriz[i]<<" "; } escreve<<"\n"; escreve<<"Finalmente, podemos receber dados via cin e escrever estes dados no arquivo!\n"; escreve<<"A frase que voc digitou durante a execuo do programa: "<<frase<<"\n"; escreve.close(); cout<<"Dados escritos no arquivo. Fim do Programa!"; system("PAUSE"); return 0; } Procure o arquivo strings.txt em seu sistema, e abra ele (ele provavelmente est no mesmo diretrio onde est o arquivo executvel do programa que compilamos. Por definio, estes arquivos ficam no diretrio onde est o compilador, a menos que tenhamos configurado o compilador para salv-los em outro lugar.). Percebeu a semelhana entre a utilizao do objeto ofstream com o comando cout? Todos os mtodos que vimos com cout para exibir um dado na tela podem ser utilizado para gravar um dado em um arquivo.
O cdigo abaixo pode ser utilizado em qualquer programa que utilize leitura e escrita de arquivos (basta, logicamente, substituir os nomes do objeto e do arquivo) para checar o estado do objeto. Caso um erro seja encontrado, o programa indica que o arquivo no pode ser aberto e a execuo terminada. Caso contrrio, o programa continua sua execuo normalmente. if(!leitura.is_open( )) { cout<<No foi possvel abrir arquivo! Programa ser terminado!\n; leitura.clear( ); //reseta o objeto leitura, para limpar memria do sistema return 0; }
para o programa). Assim, podemos utilizar qualquer um dos mtodos de leitura que estudamos para cin, seja para ler caracteres, palavras ou frases inteiras. Para lermos somente um caractere de um arquivo, por exemplo, nossa melhor opo utilizar o mtodo .get, que serve justamente para esta funo. Criamos uma varivel do tipo char para armazenar este caractere, e utilizamos o objeto ifstream da forma mostrada no exemplo abaixo: char armazena; leitura.get( armazena); O exemplo de cdigo acima utiliza o objeto leitura e o mtodo .get para ler um caractere de um arquivo, e armazena este caractere na varivel armazena. Poderamos criar um lao de repetio para obter todos os caracteres do arquivo, como vemos no exemplo abaixo. O lao while continuar a executar o mtodo .get para ler o arquivo, at que seja encontrado o fim do arquivo. Quando o fim do arquivo encontrado, o comando leitura.get(armazena) retorna falso para o lao while, terminando a repetio. Lembrese que o arquivo strings.txt deve estar no mesmo diretrio onde estamos executando o programa, caso contrrio erros ocorrero! #include <iostream> #include <fstream> #include <string> using namespace std; int main(){ char letra; ifstream leitura; leitura.open("strings.txt"); if(!leitura.is_open( )) { cout<<"No foi possvel abrir arquivo! Programa ser terminado!\n"; leitura.clear( ); //reseta o objeto leitura, para limpar memria do sistema} } while (leitura.get(letra)) {cout << letra;} leitura.close(); system("PAUSE"); return 0; } Para lermos uma palavra inteira de um arquivo, ao invs de utilizarmos uma simples varivel de tipo char, utilizamos uma matriz do tipo char. Da mesma maneira que o comando cin, o objeto ler todos os caracteres em seu caminho, at que a matriz atinja seu tamanho mximo especificado OU encontre um espao em branco, uma quebra de linha ou o fim do arquivo. UNESP Campus de Ilha Solteira 2007 Pgina 90
char matriz_chars[80]; leitura >> matriz_chars; Finalmente, para lermos uma linha inteira de um arquivo, utilizamos o mtodo .getline, que j havamos estudado no mdulo 5. O mtodo getline l uma linha inteira de entrada, at que o tamanho mximo especificado seja atinjido ou at encontrar uma quebra de linha ou o fim de arquivo. Relembrando sua sintaxe: <nome do objeto>.getline ( <matriz_destino>, <limite de caracteres>); Por exemplo char matriz_chars[80]; leitura.getline( matriz_chars, 80); O comando acima leria todos os caracteres de uma linha, at encontrar a quebra da linha. Como vimos com o mtodo .get, podemos utilizar um lao de repetio para lermos todas as linhas de um arquivo utilizando o mtodo getline. No exemplo abaixo, cada repetio uma linha do arquivo ser escrita na tela. #include <iostream> #include <fstream> #include <string> using namespace std; int main(){ char depot[300]; ifstream leitura; leitura.open("strings.txt"); if(!leitura.is_open( )) { cout<<"No foi possvel abrir arquivo! Programa ser terminado!\n"; leitura.clear( ); //reseta o objeto leitura, para limpar memria do sistema} } while (leitura.getline(depot, 300)) {cout << depot <<"\n";} leitura.close(); system("PAUSE"); return 0; } Uma pequena diferena que vemos entre esses dois mtodos de ler um arquivo inteiro, que o mtodo .get l todos os caracteres at o fim de arquivo, incluindo quebras de linha. O mtodo getline utiliza as quebras de linha para determinar o fim de sua leitura, e descarta elas. Assim, no exemplo logo acima, tivemos que instruir o programa UNESP Campus de Ilha Solteira 2007 Pgina 91
adicionar uma quebra de linha aps exibir na tela cada uma das linhas lidas. (Entretanto, lembre-se que para arquivos grandes, o mtodo getline mais eficiente e mais rpido. Tenha em mente que cada acesso de um objeto fstream um arquivo demanda um certo processamento: em um arquivo grande, se temos centenas de linhas, ento temos milhares de caracteres, o que significa que o mtodo get acessar muito mais vezes o mesmo arquivo do que o mtodo getline).
Abre arquivo para leitura. Abre arquivo para escrita. Procura o final do arquivo ao abrir ele. Anexa os dados serem escritos ao final do arquivo. Trunca os dados existentes no arquivo. Abre e trabalha com arquivos em modo binrio.
Note que um arquivo aberto por um objeto ofstream no necessita que definamos o modo de arquivo ofstream::out, pois este modo j definido para este tipo de objeto por definio. O mesmo ocorre com o modo ifstream::in e os objetos ifstream. Alm disso, por definio, um arquivo aberto por um objeto ofstream ir truncar os dados j existentes no arquivo, escrevendo os dados novos por cima dos antigos. Porm, o modo ofstream::app nos permite anexar dados ao final de um arquivo. O exemplo abaixo utliza o modo ofstream::app para criar uma espcie de agenda simplificada em um arquivo de texto.
Pgina 92
#include <iostream> #include <fstream> #include <string> using namespace std; int main(){ int dia, mes; char letra[1000]; cout<<"PROGRAMA AGENDA Verso 0.00042\n"; ofstream agenda; agenda.open("agenda.txt", ofstream::app); cout<<"Digite o compromisso no espao abaixo (): \n"; cin.getline(letra, 1000); cout << "Digite o dia do compromisso:\n"; cin >> dia; cout << "Digite o ms do compromisso:\n"; cin >> mes; agenda << "Compromisso marcado para dia "<<dia<<" de "<<mes<<": "; agenda << letra; agenda<<"\n"; cout<<"Obrigado! Sua agenda foi atualizada com sucesso!"; agenda.close(); system("PAUSE"); return 0; }
Pgina 93
caractersticas diferentes. Por exemplo, criamos os objetos relgio de pulso e relgiocuco. Os dois so relgios, mas podemos ajust-los em horrios diferentes, com alarmes diferentes. Cada objeto possui todos os membros pblicos e privados que definimos na declarao da classe. Assim, utilizamos os membros pblicos para interajir com os objetos, enquanto que os membros privados so as engrenagens do objeto. Aqui temos um novo nome para os membros pblicos: chamamos eles de mtodos do objeto. Um mtodo nada mais do que uma funo que interaja com o objeto, ou seja, so prprios os membros pblicos que definimos na declarao da classe. Para termos um exemplo mais concreto, podemos pensar em um programa qualquer do ambiente Windows. Nas ferramentas de programao Windows, temos vrias classes que representam os vrios itens que vemos na tela: janelas, menus, cursores, cones. Quando um programador precisa criar uma janela, ele no precisa ter todo o trabalho para programar uma janela do zero: ele cria um novo objeto da classe Janela, e define suas caractersticas atravs das funes pblicas (ou mtodos) da classe. Ele no precisa saber como a janela desenhada na tela: basta saber quais mtodos definem as caractersticas que ele necessita para que seu objeto funcione da maneira desejada.
herdar todos os mtodos de A: a classe B pode ter caractersticas diferentes, ou seja, mtodos diferentes da classe-base. Dessa forma, o mesmo comando pode gerar resultados diferentes dependendo da subclasse qual o objeto pertence. A idia por trs dos conceitos de classes, objetos, herana e polimorfismo possibilitar a elaborao de cdigo mais simples para programas mais complexos, quebrando os diversos aspectos de um programa em blocos independentes entre si. Assim, no precisamos atacar todo o problema de uma vez, podemos divid-lo e trabalhar com cada uma dessas divises individualmente. Outro ponto importante por trs da programao orientada objetos a reutilizao de cdigo: porque reinventar a roda sempre que escrevemos um programa novo? Nesse aspecto, podemos pensar nas classes como grupos de funes: no precisamos saber como elas funcionam, apenas precisamos saber como utilizar seus mtodos para obter os resultados desejados. Atualmente existe um nmero muito grande de bibliotecas de classes para C++, tanto comercial como em cdigo aberto, com as aplicaes mais diversas, desde bibliotecas matemticas at bibliotecas grficas para a elaborao de jogos 3D.
Pgina 97
Referncias Bibliogrficas
[1] TORRES, Jair Gustavo M. Curso de Linguagem C Ilha Solteira: Faculdade de Engenharia de Ilha Solteira FEIS UNESP Departamento de Engenharia Eltrica, 2006. [2] PRATA, Stephen C++ Primer Plus, 4 edio Nova York: Sams Publishing. 2001. [3] STROUSTRUP , Bjarne - The C++ Programming Language, 3 edio New Jersey: Addison Wesley. 1997. [4] LIPPMAN, Stanley B.; LAJOIE, Jose Lajoie; MOO, Barbara E. C++ Primer, 4 edio New Jersey: Addison-Wesley. 2005.
Pgina 98