Página em branco
Walter J. Savitch
Tradução Claudia Martins
Revisão Técnica Oswaldo Ortiz Fernandes Jr. Professor concursado em Teoria da Computação e Compiladores no Centro Universitário Municipal de SC do Sul Bacharel e Licenciado em Física pela USP Pós-graduado em Física pela USP Mestrando em Engenharia Eletrônica e Computação pelo ITA
ASSOCIAÇÃO BRASILEIRA DE DIREITOS REPROGRÁFICOS
2004 by Pearson Education do Brasil Título original: Absolute C++ — first edition © 2002 by Pearson Education, Inc. ©
Publicação autorizada a partir da edição original em inglês publicada pela Pearson Education, Inc., sob o selo Addison Wesley Todos os direitos reservados. Nenhuma parte desta publicação poderá ser reproduzida ou transmitida de qualquer modo ou por qualquer outro meio, eletrônico ou mecânico, incluindo fotocópia, gravação ou qualquer outro tipo de sistema de armazenamento e transmissão de informação, sem prévia autorização, por escrito, da Pearson Education do Brasil.
Diretor Editorial: José Martins Braga Editor: Roger Trimer Editora de Texto: Adriane Gozzo Preparação: Sandra Garcia Revisão: Nilma Guimarães Designer de Capa: Marcelo Françozo , sobre o projeto original de Leslie Haimes, com foto de Renee Lynn/Stone by Getty Images Editoração Eletrônica: ERJ Composição Editorial e Artes Gráficas Ltda.
Dados Internacionais de Catalogação na Publicação (CIP) (Câmara Brasileira do Livro, SP, Brasil) Savitch, Walter J. C++ absoluto / Walter Savitch ; tradução Claudia Martins ; revisão técnica Oswaldo Ortiz Fernandes Jr. -- São Paulo : Addison Wesley, 2004.
ISBN: 85-88639-09-2
1. C++ (Linguagem de programação para computad ores) I. Título.
03 03-2860
CDD-005.133
Índices para catálogo sistemático 1. C++ C++ : Linguagem de programação programação : Computadores : Processamento de dados 005.133
2004 Direitos exclusivos para a língua portuguesa cedidos à Pearson Education do Brasil, uma empresa do grupo Pearson Education Av. Ermano Marchetti, Marchetti, 1435 CEP: 05038-001, Lapa – São Paulo – SP Tel: (11) 3613-1222 Fax: (11) 3611-0444 e-mail:
[email protected]
Prefácio C++ Absoluto
foi projetado como um manual e livro de referência para a programação na linguagem C++. Embora inclua técnicas de programação, foi organizado mais em função dos recursos da linguagem C++ do que de algum currículo específico de técnicas de programação. O público que eu tinha em mente ao escrevê-lo era o de estudantes universitários, especialmente de ciências da computação, ainda sem muita experiência em programação com a linguagem C++. Este livro foi projetado para ser útil a um grande número de usuários. Os capítulos iniciais foram escritos em um nível acessível a iniciantes, embora os quadros desses capítulos sirvam para apresentar rapidamente a sintaxe básica do C++ a programadores mais experientes. Os últimos capítulos também são acessíveis, mas foram escritos em um nível adequado a estudantes que já evoluíram para tópicos mais avançados. Este livro também inclui uma introdução aos padrões e à Linguagem Unificada de Modelagem (UML) e um capítulo inteiro sobre Recursão.
RECURSOS ESPECIAIS P ADRÕES ANSI/ISO C++ Este livro foi escrito de acordo com os novos padrões ANSI/ISO C++.
STANDARD TEMPLATE LIBRARY A Standard Template Library é uma extensa coleção de bibliotecas de classes de estrutura estrutura de dados pré-programapré-programadas e algoritmos importantes. A STL talvez seja um tópico tão extenso quanto o núcleo da linguagem C++. Este livro contém uma sólida introdução à STL. Há um capítulo inteiro sobre templates e outro sobre as particularidades da STL, além de outros assuntos relacionados com a STL em capítulos diversos.
PROGRAMAÇÃO ORIENTADA A OBJETOS Este livro trata da estrutura da linguagem C++. Dessa forma, os primeiros capítulos, que abordam aspectos do C++ comuns a quase todas as linguagens de programação de alto nível, não estão direcionados especificamente à programação orientada a objetos (OOP). Isso faz sentido em se tratando de um livro de referência e para ensino de uma segunda linguagem. Entretanto, considero C++ uma linguagem OOP. Se você estiver programando realmente em C++ e não em C, precisa tirar proveito dos recursos OOP do C++. Este livro fornece uma extensa abordagem sobre encapsulamento, herança e polimorfismo como entendidos na linguagem C++. O capítulo final sobre padrões e UML apresenta outros assuntos relacionados à OOP.
FLEXIBILIDADE NA ORDENAÇÃO DOS TÓPICOS C++ Absoluto permite
aos professores uma grande liberdade de reordenação do material. Isso é importante para uma obra de referência e combina com a minha filosofia de escrever livros que se adaptem ao estilo do professor em vez de amarrá-lo à preferência pessoal de ordenamento de tópicos do autor. Tendo isso em mente, a introdução de cada capítulo explica que material deve ser estudado antes que se execute cada seção do capítulo.
ACESSÍVEL AOS ESTUDANTES Não é suficiente que um livro apresente os tópicos certos na ordem certa. Nem é suficiente que seja claro e correto quando lido por um professor ou outro especialista. O material precisa ser apresentado em uma forma acessível a quem ainda não o conhece. Como meus outros manuais, que se revelaram bastante populares entre os estudantes, este livro foi redigido de maneira amigável e acessível.
Quadros Todos os pontos principais são resumidos em quadros, espalhados ao longo de cada capítulo, que servem como resumos do conteúdo, como fonte de referência rápida e como forma de aprender rapidamente a sintaxe do C++
VI
Prefácio
para recursos que o leitor já conhece de forma geral, mas para os quais necessita saber os detalhes do emprego da linguagem C++. Exercícios de Autoteste
Cada capítulo contém diversos Exercícios de Autoteste em pontos estratégicos. As respostas completas para todos os exercícios são dadas ao final de cada capítulo. Outros Recursos
Seções de "armadilhas", de técnicas de programação e exemplos de programas completos com amostras E/S são dadas ao longo de cada capítulo, que termina com uma seção de resumo e vários projetos de programação adequados para serem atribuídos aos estudantes. M ATERIAL
DE
A POIO POIO
Este livro foi planejado para uso com o Microsoft Visual C++. No site do livro em www.aw.com/savitch_br você encontra links para diversos sites relacionados, além dos seguintes recursos: ■ ■
Código-fonte do livro Transparências em PowerPoint
Os seguintes recursos estão disponíveis somente para os professores que adotam o livro. Por favor, entre em contato com o seu representante de vendas local ou envie um e-mail para
[email protected] para ter acesso ao: ■
Manual do professor (em inglês)
A GRADECIMENTOS GRADECIMENTOS
Diversas pessoas contribuíram de forma inestimável para tornar este livro uma realidade. Frank Ruggirello e minha editora Susan Hartman, da Addison-Wesley, foram os primeiros a imaginarem esta obra. Susan Hartman, Galia Shokry, Lisa Kalner e outras pessoas fantásticas da Addison-Wesley foram uma contínua fonte de apoio e encora jamento para a revisão técnica, revisão de provas e publicação. Cindy Kogut fez um incrível trabalho de edição de texto. Sally Boylan e outros da Argosy Publishing fizeram um ótimo trabalho, efetuado em um curto espaço de tempo, na digitalização das páginas. David Teague merece um agradecimento especial. Apreciei muito seu trabalho árduo, suas ótimas sugestões e a pesquisa cuidadosa para este livro. Agradeço a meu bom amigo Mario Lopez pelas muitas conversas proveitosas que tivemos sobre o C++. Os seguintes revisores forneceram correções e sugestões que contribuíram imensamente para o produto final. Agradeço a todos. Em ordem aleatória, eles são: Kenrick Mock, University of Alaska, Anchorage; Richard Albright, University of Delaware; H. E. Dunsmore, Purdue University; Christopher E. Cramer; Drue Coles, Boston University; Evan Golub, University of Maryland; Stephen Corbesero, Moravian College; Fredrick H. Colclough, Colorado Technical University; Joel Weinstein, Northeastern University; Stephen P. Leach, Florida State University; Alvin S. Lim, Auburn University; e Martin Dulberg, North Carolina State University. Mais uma vez, agradeço a David Teague, desta vez pelo seu excelente trabalho na preparação do manual do professor. Finalmente, agradeço a Christina por ter sido companheira quando eu ficava trabalhando até tarde no livro e por haver me encorajado em vez de reclamar. Walter Savitch http://www-cse.ucsd.edu/users/savitch/
[email protected]
Sumário Capí Capítu tulo lo 1 1.1 1.2 1.3 1.3 1.4 1.5 1.5 Capí Capítu tulo lo 2 2.1 2.1 2.2 2.2 2.3 Capí Capítu tulo lo 3 3.1 3.1 3.2 3.2 3.3 Capít Capítul ulo o4 4.1 4.2 4.2 4.3 4.3 Capítu ítulo 5 5.1 5.1 5.2 5.2 5.3 5.3 5.4 5.4 Capí Capítu tulo lo 6 6.1 6.2 Capít Capítul ulo o7 7.1 7.2 7.3
Fun Fundame dament ntos os do C++ C++
1
Int Introdução ção ao C++ 1 Variá Variáve veis is,, Expre Expressõ ssões es e Decla Declaraç rações ões de Atrib Atribuiç uição ão Entr Entrad ada/ a/Sa Saíd ídaa de Term Termin inaal 18 Estilo de Programa 23 Bib Bibliot liotec ecas as e Name Namesp spac aces es 24 Flux Fluxo o de Co Cont ntro role le
4
29
Exp Expressões ões Boole ooleaanas nas 29 Est Estrut ruturas uras de Co Cont ntro rolle 35 Loops 43 Fund Fundam amen ento toss das das Funç Funçõe õess
61
Funç Funçõe õess Pred redefin finidas 61 Funç Funçõe õess Defi Defini nida dass pelo pelo Prog Progra rama mado dorr Regr egras de Esc Escopo 79 Parâ Parâme metr tros os e Sobr Sobrec ecar arga ga
69
91
Parâmetros 91 Sobr Sobrec ecar arga ga e Argu Argume men ntostos-Pa Padr drão ão 103 103 Test Testan ando do e Depu Depura ran ndo Funç Funçõe õess 110 110 Vetores
117
Intr Introd oduç ução ão aos Vetor etores es 117 117 Vet Vetore ores em Funç Funçõe õess 123 Prog Progra rama mand ndoo com com Vet Vetores ores 132 132 Vet Vetores ores Multi ultidi dime mens nsio iona nais is 139 139 Estru strutu tura rass e Clas Classe sess
153 153
Estruturas 15 153 Classes 16 162 Const Construt rutor ores es e Outra Outrass Ferra Ferrame menta ntass
177
Construtores 17 177 Mais ais Ferra erram ment entas 191 Vecto Vectors rs — Intro Introduç dução ão à Standa Standard rd Temp Templat latee Librar Libraryy
200 200
VIII
Sumário
Capítulo Capítulo 8
Sobreca Sobrecarga rga de Operador Operador,, Amigos Amigos e Referên Referências cias
207
8.1 Fundam Fundamen ento toss da Sobr Sobreca ecarga rga de Opera Operador dor 207 207 8.2 Funções Funções Amigas Amigas e Conversão Conversão de Tipo Automáti Automática ca 218 8.3 Referênc Referências ias e Mais Mais Operador Operadores es Sobrecar Sobrecarregad regados os 223 Capí Capítu tulo lo 9
Stri String ngss
241 241
9.1 9.1 Tipo Tipo Veto Vetorr para para Stri Strings ngs 241 241 9.2 Ferramen Ferramentas tas de Manipula Manipulação ção de Caracter Caracteres es 249 9.3 Clas lasse-P se-Pad adrrão string 258 Capítu Capítulo lo 10
Pontei Ponteiros ros e Vet Vetor ores es Dinâm Dinâmico icoss
277 277
10.1 0.1 Ponte onteiiros 277 277 10.2 10.2 Veto Vetore ress Dinâ Dinâmi mico coss 288 288 10.3 10.3 Classe Classes, s, Ponte Ponteir iros os e Vetore Vetoress Dinâmi Dinâmicos cos 297 Capítulo Capítulo 11
Compil Compilação ação Separada Separada e Namespa Namespaces ces
313
11.1 11.1 Comp Compililaç ação ão Sepa Separa rada da 313 313 11.2 1.2 Na Nam mespa espace cess 324 324 Capítu Capítulo lo 12
12.1 12.1 12.2 12.2 12.3 12.4 12.4
E/S E/S de Arqui Arquivo vo e Strea Streams ms
343
Stre Stream amss de E/S E/S 344 344 Ferram Ferrament entas as para para E/S E/S de Strea Stream m 355 Hierarqu Hierarquias ias de Stream: Stream: Introduç Introdução ão à Herança Herança 363 Acesso Acesso Aleató Aleatório rio a Arqui Arquivos vos 369
Capítulo 13 Recursão
377
13.1 Funções void Recursivas 377 13.2 13.2 Funçõe Funçõess Recur Recursi siva vass que Retorn Retornam am um Valor Valor 386 13.3 13.3 Pens Pensand andoo Recu Recurs rsiv ivam amen ente te 390 390 Capí Capítu tulo lo 14
Heran erança ça
403 403
14.1 14.1 Fund Fundam amen ento toss da Hera Heranç nçaa 403 403 14.2 14.2 Prog Progra rama mand ndoo com com Hera Heranç nçaa 409 409 Capítu Capítulo lo 15
Poli Polimor morfi fismo smo e Fun Funçõ ções es Virtua Virtuais is
435 435
15.1 15.1 Princ Princíp ípios ios das das Funçõ Funções es Virtua Virtuais is 435 15.2 15.2 Pontei Ponteiros ros e Funçõe Funçõess Virtua Virtuais is 444 444 Capítu Capítulo lo 16
Temp Templat lates es (Gaba (Gabarit ritos) os)
455
16.1 16.1 Temp Templa late tess de Funç Função ão 455 455 16.2 16.2 Temp Templa late tess de Clas Classe se 464 464 16.3 16.3 Temp Templa late tess e Hera Heranç nçaa 472 472 Capítu Capítulo lo 17
17.1 17.1 17.2 17.2 17.3 7.3 17.4
Estr Estrutu utura rass de Dados Dados Ligada Ligadass
481
Nós Nós e List Listas as Liga Ligada dass 482 482 Aplica Aplicaçõe çõess de Lista Lista Ligada Ligada 498 498 Iter Iterad adoores res 508 508 Árv Árvores 515
Sumário
Capítu Capítulo lo 18 Trat Tratame ament ntoo de Exceç Exceções ões 529 18.1 18.1 18.2
Fundam Fundamen ento toss do Tratam Tratamen ento to de Exceç Exceções ões 530 Técnicas Técnicas de Programa Programação ção para o Tratamen Tratamento to de Exceções Exceções
Capítu Capítulo lo 19 Stand Standard ard Templ Templat atee Librar Libraryy 19.1 9.1 19.2 9.2 19.3 19.3
Iter Iterad adoores res 550 550 Cont Co ntaainers ners 559 Algo Algori ritm tmos os Gené Genéri rico coss
Capí Capítu tulo lo 20 Padr Padrõe õess e UML UML 20.1 20.2
Padrões 585 UML 593
Apêndice 1
599
Apêndice 2
600
Apêndice 3
602
Apêndice 4
603
Apêndice 5
608
Índice
609
585 585
569 569
549
543
IX
Fundamentos do C++ Capítulo 1C++ Básico Fundamentos do C++ A Máquina Analítica não tem nenhuma pretensão de criar nada. Pode fazer qual- quer coisa que saibamos como mandá-la fazer. Pode acompanhar a análise; mas não tem o poder de antecipar quaisquer relações analíticas ou verdades. Sua ocupação é nos assistir tornando disponível aquilo que já conhecemos. Ada Augusta, Condessa de Lovelace
INTRODUÇÃO Este capítulo apresenta a linguagem C++ e fornece detalhes suficientes para permitir que você lide com programas simples envolvendo expressões, atribuições e entrada e saída (E/S) de terminal. Os detalhes das atribuições e expressões são semelhantes aos da maioria de outras linguagens de alto nível. Cada linguagem possui sua sintaxe de E/S de terminal; portanto, se você você não está familiari familiarizado zado com C++, esse aspecto aspecto pode lhe parecer parecer novo e difere diferente nte..
1.1
Introdução ao C++ A linguagem é o único instrumento da ciência. Samuel Johnson
Esta seção fornece uma visão geral da linguagem de programação C++. ■ ORIGENS DA LINGUAGEM C++
Pode-se pensar nas linguagens de programação C++ como a linguagem de programação C com classes (e outros recursos modernos adicionados). A linguagem de programação C foi desenvolvida por Dennis Ritchie, dos AT&T Bell Laboratories, na década de 70. Foi usada, a princípio, para escrever e manter o sistema operacional UNIX. (Até aquela época, os programas de sistema UNIX eram escritos em linguagem assembly ou em uma linguagem chamada B, desenvolvida por Ken Thompson, o criador do UNIX.) C é uma linguagem de finalidade geral que pode ser usada para escrever qualquer tipo de programa, mas seu sucesso e popularidade estão intimamente ligados ao sistema operacional UNIX. Se você quisesse preservar seu sistema UNIX, precisava usar C. C e UNIX se deram tão bem que logo não só os programas de sistema mas quase todos os programas comerciais executados no UNIX eram escritos na linguagem C. C se tornou tão popular que versões da linguagem foram escritas para outros sistemas operacionais populares; assim, seu uso não se limitou aos computadores que utilizavam UNIX. Entretanto, apesar de sua popularidade, C não era uma linguagem isenta de problemas. A linguagem C é peculiar porque é uma linguagem de alto nível com muitos recursos de linguagem de baixo nível. C está entre os dois extremos, o de uma linguagem de nível muito alto e o de uma linguagem de baixo nível, e nisso residem tanto sua força quanto sua fraqueza. Como a linguagem (de baixo nível) assembly, os programas em linguagem
2
Fundamentos do C++
C podem manipular diretamente a memória do computador. Por outro lado, C possui recursos de uma linguagem de alto nível, o que a torna mais fácil de ler e escrever do que a linguagem assembly. Isso faz de C uma excelente escolha para escrever programas de sistema, mas para outros programas (e em certo sentido até para programas de sistema) C não é tão fácil de entender quanto outras linguagens; além disso, não possui tantas verificações automáticas quanto outras linguagens de alto nível. Para superar essas e outras desvantagens de C, Bjarne Stroustrup, dos AT&T Bell Laboratories, desenvolveu o C++ no início da década de 80. Stroustrup projetou o C++ como um C aperfeiçoado. A maior parte da linguagem C é um subconjunto da C++, e, assim, muitos programas em C também são programas em C++. (O inverso não é verdade; muitos programas em C++ não são, definitivamente, programas em C.) Ao contrário de C, C++ possui recursos para classes e, portanto, pode ser usada para a programação orientada a objetos. ■
C++ E PROGRAMAÇÃO ORIENTADA A OBJETOS
A programação orientada a objetos (Object-oriented (Object-oriented programming — OOP) é uma técnica de programação atual popular e poderosa. As principais características da OOP são encapsulamento, herança e polimorfismo. O encapsulamento é uma forma de ocultação de informação, ou abstração. A herança tem a ver com a escrita de código reutilizável. O polimorfismo se refere à forma pela qual um único nome pode ter múltiplos significados no contexto da herança. Tendo dado essas definições, precisamos admitir que elas possuem pouco significado para os leitores que nunca ouviram falar de OOP. Entretanto, descreveremos todos esses termos em detalhes no decorrer deste livro. C++ favorece a OOP fornecendo classes, um tipo de dado que combina dados e algoritmos. C++ não é o que algumas autoridades chamariam de uma "linguagem pura de OOP". C++ compatibiliza seus recursos OOP com preocupações em relação à eficiência e o que poderíamos chamar de "praticidade". Essa combinação tornou o C++ a linguagem de OOP mais amplamente utilizada, embora nem sempre seu uso siga estritamente a filosofia da OOP. ■
CARACTERÍSTICAS DO C++
C++ possui classes que permitem sua utilização como uma linguagem orientada a objetos. Admite a sobrecarga de funções e operadores. (Todos esses termos serão explicados ao longo do texto; não fique preocupado se não entender alguns deles.) A ligação do C++ com a linguagem C lhe fornece uma aparência mais tradicional do que a das linguagens orientadas a objetos mais recentes, e, no entanto, ele possui mais mecanismos poderosos de abstração do que muitas das linguagens populares atuais. C++ possui modelos que possibilitam a implementação total e direta da abstração do algoritmo. Os modelos de C++ permitem que se escreva código utilizando parâmetros para tipos. Os mais novos padrões de C++ e a maioria dos compiladores de C++ permitem namespaces múltiplos para possibilitar maior reutilização dos nomes de classes e funções. Os recursos de tratamento das exceções são semelhantes aos encontrados em outras linguagens de programação. O gerenciamento da memória em C++ é semelhante ao de C. O programador deve alocar sua própria memória e lidar com sua própria coleção de lixo. A maioria dos compiladores permitirá que você faça em C++ um gerenciamento de memória estilo C, já que o C é, em essência, um subconjunto de C++. Entretanto, o C++ também tem sua própria sintaxe para um gerenciamento de memória estilo C++, e seria aconselhável que você utilizasse o estilo C++ de gerenciamento de memória ao escrever código em C++. Este livro utiliza apenas o gerenciamento de memória estilo C++. ■
TERMINOLOGIA DO C++
Todas as entidades semelhantes a procedimentos são chamadas de funções funções em C++. Tudo o que é chamado de procedimento , método , função ou subprograma em em outras linguagens é chamado de função em em C++. Como veremos na próxima subseção, um programa em C++ é basicamente apenas uma função chamada main. As outras terminologias de C++ são praticamente as mesmas que as de outras linguagens de programação e serão explicadas quando da apresentação de cada conceito. ■
AMOSTRA DE PROGRAMA EM C++
O Painel 1.1 contém um programa simples em C++ e duas possíveis saídas de tela que podem ser geradas quando um usuário executa o programa. Um programa em C++ é, na realidade, uma definição de função para
Introdução ao C++
3
uma função chamada main. Quando o programa é executado, a função chamada main é invocada. O corpo da função main fica entre chaves, { }.Quando o programa é executado, as declarações entre as chaves são executadas. As duas linhas seguintes fazem com que as bibliotecas com entrada e saída de terminal estejam disponíveis disponíveis para o programa. Os detalhes concernentes a essas duas linhas e tópicos relativos são tratados na Seção 1.3 e nos Capítulos 9, 11 e 12. # include
using namespace std;
A linha seguinte diz que main é uma função sem parâmetros que ao terminar sua execução retornará um valor inteiro int: int main ( )
Alguns compiladores permitirão que você omita o int ou substitua-o por void, o que indica uma função que não retorna nenhum valor. Entretanto, a forma acima é a mais aceita universalmente para iniciar a função main em um programa C++. O programa termina quando o seguinte comando é executado: return 0;
Este comando termina a invocação da função main e fornece 0 como o valor da função. De acordo com o padrão ANSI/ISO C++, este comando não é obrigatório, mas muitos compiladores o exigem. O Capítulo 3 discutirá as funções de C++ em todos os detalhes. Painel 1.1
1 2 3 4 5
Amostra de programa em C++ parte (parte 1 de 2)
#inc #inclu lude de m> using namespace std; int main(
)
{ int numberOfLanguages;
6 7
cout cout << "Olá "Olá, , leit leitor or.\ .\n" n" << "Bem "Bem-v -vin indo do ao C++. C++.\n \n"; ";
8 9
cout cout << "Quant "Quantas as lingua linguagen gens s de program programação ação você você já usou? usou? "; cin cin >> num numberO berOfL fLan angu guag ages es; ;
10 11 12 13 14
if (numberOfLanguages
< 1) cout << "Leia o Prefácio. Prefácio. Talvez você prefira\n" prefira\n" << "um livro mais básico do mesmo autor.\n"; autor.\n";
else
cout cout << "Divir "Divirta-s ta-se!\n e!\n"; ";
15 16 }
return 0;
DIÁLOGO PROGRAMA-USUÁRIO I Olá, leitor. Bem-vindo ao C++. Quantas linguagens de programação você já usou? 0 Leia o Prefácio. Talvez você prefira um livro mais básico do mesmo autor.
O usuário digitou 0 no teclado.
4
Fundamentos do C++
Painel 1.1
Amostra de programa em C++ ( parte 2 de 2)
DIÁLOGO PROGRAMA-USUÁRIO 2 Olá, leitor. Bem-vindo ao C++. Quantas linguagens de programação você já usou? Divirta-se!
1
O usuário digitou 1 no teclado.
A declaração de variáveis em C++ é similar à de outras linguagens de programação. A linha seguinte do Painel 1.1 declara a variável numeroDeLinguagens: int numeroDeLinguagens;
O tipo int é um dos tipos de C++ para números inteiros (integers). Se você nunca programou em C++, o uso de cin e cout para a E/S de terminal deve ser novo para você. Este tópico será abordado mais adiante neste capítulo, mas a idéia geral pode ser observada neste programa-amostra. Por exemplo, considere as duas linhas seguintes do Painel 1.1: cout << "Quantas linguagens de programação você já usou? "; cin >> numeroDeLinguagens;
A primeira linha faz com que o texto entre aspas seja exibido na tela. A segunda linha lê um número que o usuário digita no teclado e estabelece o número digitado como o valor da variável numeroDeLinguagens, As linhas cout << "Leia o Prefácio. Talvez você prefira\n" << "um livro mais básico do mesmo autor. \n";
fazem com que duas strings sejam exibidas, em vez de uma. Os detalhes são explicados na Seção 1.3. O símbolo \n é o caractere de nova linha, que instrui o computador a começar uma nova linha de saída. Embora você possa não estar certo sobre os detalhes exatos de como escrever essas declarações, provavelmente será capaz de adivinhar o significado do comando if-else. Os detalhes serão explicados no próximo capítulo. (A propósito, se você ainda não teve experiência com nenhuma linguagem de programação, deveria ler o prefácio para ver se o livro mais básico de que falamos neste programa não lhe seria mais adequado. Você não precisa ter tido qualquer experiência com C++ para ler este livro, mas é necessária uma experiência mínima com programação.)
1.2
Variáveis, Expressões e Declarações de Atribuição Uma vez que uma pessoa tenha compreendido como as variáveis são usadas na programação, entendeu a quin- tessência da programação. E. W. Dijkstra, Notes on Structured Programming
As variáveis, expressões e atribuições em C++ são similares às da maioria das outras linguagens de finalidade geral. ■ IDENTIFICADORES
O nome de uma variável (ou outro item que possa ser definido em um programa) é chamado de identificador . Um identificador em C++ deve começar com uma letra ou um símbolo de sublinhado, e todos os outros caracteres de vem ser letras, dígitos ou o símbolo de sublinhado. Por exemplo, todos os identificadores seguintes são válidos: x x1 x_1_abc ABC123z7 soma TAXA contagem dado2 grandeBonus
Todos os nomes acima são corretos e deveriam ser aceitos pelo compilador, mas os primeiros cinco são escolhas ruins para identificadores, porque não descrevem o uso do identificador. Nenhum dos identificadores seguintes é correto, e todos seriam rejeitados pelo compilador: 12 3X %troco dado-1 meuprimeiro.c PROG.CPP
Variáveis, Expressões e Declarações de Atribuição
5
Os três primeiros não são permitidos porque não começam com uma letra nem com um caractere de sublinhado. Os três restantes não são identificadores porque contêm símbolos que não são letras, dígitos ou o caractere de sublinhado. Embora seja legal começar um identificador com um sublinhado, você deveria evitar fazer isso, porque os identificadores que começam com um sublinhado são reservados informalmente para identificadores do sistema e bibliotecas-padrão. C++ é uma linguagem que percebe a diferença entre maiúsculas e minúsculas nos identificadores. Assim, os três identificadores a seguir são diferentes e poderiam ser usados para nomear três variáveis diferentes. taxa TAXA Taxa
Entretanto, não é uma boa idéia usar duas variantes desse tipo no mesmo programa, já que isso poderia criar confusão. Embora não seja exigido pelo C++, as variáveis normalmente são escritas com a primeira letra em minúscula. Os identificadores predefinidos, como main, cin, cout e outros, devem ser escritos apenas com letras minúsculas. A convenção que agora está se tornando universal na programação orientada a objetos é escrever nomes de variáveis com uma mistura de letras maiúsculas e minúsculas (e dígitos), começando sempre o nome da variável com letra minúscula e indicando os limites das "palavras" com uma letra maiúscula, como ilustrado nos seguintes nomes de variáveis: velMax, taxaBanco1, taxaBanco2, horaDeChegada
Essa convenção não é tão comum em C++ quanto em algumas outras linguagens orientadas a objetos, mas está sendo usada mais amplamente e é uma boa convenção a seguir. Um identificador C++ pode ter qualquer comprimento, embora alguns compiladores ignorem todos os caracteres excedentes, caso a quantidade de caracteres seja maior que um número especificado. IDENTIFICADORES
Um identificador C++ deve começar com uma letra ou com um caractere de sublinhado, e os caracteres restantes devem ser apenas letras, dígitos, ou o caractere de sublinhado. Os identificadores C++ fazem diferença entre maiúsculas e minúsculas e não têm limite de comprimento.
Há uma classe especial de identificadores, chamados de palavras-chave ou palavras reservadas, que possuem um significado predefinido em C++ e não podem ser usados como nomes de variáveis ou qualquer outra coisa. Neste livro, as palavras-chave aparecem destacadas no texto. Uma lista completa das palavras-chave é fornecida no Apêndice 1. Algumas palavras predefinidas, como cin e cout, não são palavras-chave. Essas palavras predefinidas não fazem parte do núcleo da linguagem C++, e você não é autorizado a redefini-las. Embora essas palavras predefinidas não sejam palavras-chave, são definidas em bibliotecas exigidas pela linguagem C++ padrão. Não é preciso dizer que usar um identificador predefinido para algo diferente do padrão pode criar confusão e perigo; assim, isso deve ser evitado. A prática mais segura e fácil é tratar todos os identificadores predefinidos como se fossem palavras-chave.
■
VARIÁVEIS
Cada variável em um programa em C++ deve ser declarada antes de ser usada. Quando você declara uma variável, está dizendo ao compilador — e, em última análise, ao computador — que tipo de dados serão armazenados na variável. Por exemplo, aqui estão duas definições que podem ocorrer em um programa C++: int numeroDeFeijoes; double umPeso,
totalPeso;
A primeira define a variável numeroDeFeijoes de forma a conter um valor do tipo int, ou seja, um número inteiro. O nome int é uma abreviação de "integer" (inteiro). O tipo int é um dos tipos para números inteiros. A segunda definição declara umPeso e totalPeso como variáveis de tipo double, que é um dos tipos para números com um ponto decimal (conhecidos como números de ponto flutuante ). Como ilustrado aqui, quando há mais de uma variável em uma definição, as variáveis são separadas por vírgulas. Observe também que cada definição termina com um ponto-e-vírgula.
6
Fundamentos do C++
Cada variável deve ser declarada antes de ser usada; obedecida essa regra, podem-se declarar variáveis em qualquer lugar. É óbvio que elas devem sempre ser declaradas em um local que torne o programa mais fácil de ser lido. Normalmente, as variáveis são declaradas logo antes de serem usadas ou no início de um bloco (indicado por uma chave de abertura, { ). Qualquer identificador legal, exceto as palavras reservadas, pode ser usado para um nome de variável. * O C++ possui tipos básicos para caracteres, números inteiros e números de ponto de flutuação (números com um ponto decimal). O Painel 1.2 lista os tipos básicos de C++. O tipo comumente usado para intervalos é int. O tipo char é o tipo para caracteres únicos e pode ser tratado como um tipo inteiro, mas nós não o aconselhamos a fazer isso. O tipo comumente usado para números de ponto flutuante é double e, assim, você deve usar double para números de ponto flutuante, a não ser que tenha alguma razão específica para usar um dos outros tipos de ponto flutuante. O tipo bool (abreviação de booleano ) possui os valores true e false. Não é um tipo inteiro, mas, para se adaptar a códigos antigos, você pode converter bool em qualquer outro dos tipos inteiros e vice-versa. Além disso, a biblioteca-padrão chamada string fornece o tipo string, que é usado para strings de caracteres. O programador pode definir tipos para vetores, classes e apontadores, o que será discutido em capítulos posteriores deste livro. Painel 1.2
Tipos simples
NOME DO TIPO
MEMÓRIA UTILIZADA
INTERVALO
PRECISÃO
short (também chamado short int) int
2 bytes
–32.767 a 32.767
Não aplicável
4 bytes
Não aplicável
long (também chamado long int) float
4 bytes
–2.147.483.647 a 2.147.483.647 –2.147.483.647 a 2.147.483.647
Não aplicável
4 bytes
aproximadamente 7 dígitos 10–38 a 1038 8 bytes aproximadamente 15 dígitos double 10–308 a 10308 10 bytes aproximadamente 19 dígitos long double 10–4932 a 104932 1 byte Todos os caracteres ASCII (Também Não aplicável char pode ser usado como um tipo integer, embora não o recomendemos.) 1 byte Não aplicável bool true, false Os valores listados aqui são apenas valores experimentais para lhe dar uma idéia geral de como os tipos diferem. Os valores para cada um desses registros podem ser diferentes em seu sistema. Precisão refere-se ao número de dígitos significativos, incluindo dígitos na frente do ponto decimal. Os intervalos para os tipos float, double e long double são os intervalos para os números positivos. Os números negativos possuem um alcance similar, mas com um sinal negativo diante de cada número.
DECLARAÇÕES DE VARIÁVEIS Todas as variáveis devem ser declaradas antes de serem usadas. A sintaxe para declarações de variável é a seguinte:
SINTAXE Tipo_Nome Variavel_Nome_1, Variavel_Nome_2, . . . ;
EXEMPLO int count, numeroDeDragoes, numeroDeTrolls; double distancia;
*
O C++ faz uma distinção entre declarar e definir um identificador. Quando um identificador é declarado, o nome é introduzido. Quando é definido, aloca-se espaço para o item nomeado. Para o tipo de variáveis que discutimos neste capítulo e para várias outras partes do livro, o que estamos chamando de declaração de variável declara a variável e a define ao mesmo tempo, ou seja, aloca espaço para a variável. Muitos autores fazem distinção entre definição de variável e declaração de variável. A diferença entre declarar e definir um identificador é mais importante para outros tipos de identificadores, o que encontraremos em outros capítulos. (N. do R.T.)
Variáveis, Expressões e Declarações de Atribuição
7
Cada um dos tipos inteiros possui uma versão sem sinal que inclui apenas valores não-negativos. Esses tipos são unsigned short, unsigned int e unsigned long. Seus intervalos não correspondem exatamente aos intervalos dos valores positivos dos tipos short, int e long, mas tendem a ser maiores (já que usam o mesmo espaço de armazenamento que seus tipos correspondentes short, int ou long, mas não precisam se lembrar do sinal). Dificilmente você precisará desses tipos, mas pode encontrá-los em especificações para funções predefinidas em algumas das bibliotecas de C++, como discutiremos no Capítulo 3. ■
DECLARAÇÕES DE ATRIBUIÇÃO
A forma mais direta de se mudar o valor de uma variável é usar uma declaração de atribuição. Em C++, o sinal de igual é utilizado como um operador de atribuição. Uma declaração de atribuição sempre consiste em uma variável no lado esquerdo do sinal de igual e uma expressão no lado direito. Uma declaração de atribuição termina com um ponto-e-vírgula. A expressão no lado direito de um sinal de igual pode ser uma variável, números, operadores e invocações a funções. Uma declaração de atribuição instrui o computador a avaliar a (ou seja, a calcular o valor da) expressão do lado direito do sinal de igual e fixar o valor da variável do lado esquerdo como igual ao da expressão. Aqui estão alguns exemplos de declarações de atribuição em C++: totalPeso = umPeso * numeroDeFeijoes; temperatura = 98.6; contagem = contagem + 2;
A primeira declaração de atribuição fixa o valor de totalPeso como igual ao número na variável umPeso multiplicado pelo número em numeroDeFeijoes. (A multiplicação é expressa por meio do asterisco, *, em C++.) A segunda declaração de atribuição fixa o valor de temperatura como 98,6. A terceira declaração de atribuição aumenta o valor da variável contagem em 2. DECLARAÇÕES DE ATRIBUIÇÃO Em uma declaração de atribuição, primeiro a expressão do lado direito do sinal de igual é avaliada e depois a variável do lado esquerdo do sinal de igual é fixada como igual a esse valor.
SINTAXE Variavel = Expressao;
EXEMPLOS distancia = velocidade * tempo; contagem = contagem + 2;
Em C++, as declarações de atribuição podem ser usadas como expressões. Quando usadas como expressão, uma declaração de atribuição fornece o valor atribuído à variável. Por exemplo, considere n = (m = 2);
A subexpressão (m = 2) tanto altera o valor de m para 2 quanto fornece o valor 2. Assim, fixa tanto n quanto m como igual a 2. Como você verá quando discutirmos em detalhe a precedência de operadores, no Capítulo 2, podem-se omitir os parênteses; assim, a declaração de atribuição em questão pode ser escrita como n = m = 2;
Nós o aconselhamos a não utilizar uma declaração de atribuição como uma expressão, mas você deve conhecer esse comportamento, porque isso o ajudará a entender certos tipos de erro de código. Por exemplo, isso explicará por que você não receberá uma mensagem de erro quando escrever, erroneamente n = m = 2;
quando queria escrever n = m + 2;
(Este é um erro comum, já que os caracteres = e + ficam na mesma tecla.)
8
Fundamentos do C++ LVALUES E RVALUES Os autores se referem muitas vezes a lvalue e rvalue em livros sobre C++. Um lvalue é qualquer coisa que possa aparecer do lado esquerdo de um operador de atribuição (=), o que significa qualquer tipo de variável. Um rvalue é qualquer coisa que possa aparecer do lado direito de um operador de atribuição, o que significa qualquer expressão que calcule um valor.
Armadilha
VARIÁVEIS NÃO-INICIALIZADAS Uma variável não possui valor com significado até que um programa lhe atribua um. Por exemplo, se a variável numeroMinimo não recebeu um valor nem como lado esquerdo de uma declaração de atribuição nem de outra forma (como a de receber um valor de entrada através de um comando cin), então a linha seguinte está errada: numeroDesejado = numeroMinimo + 10;
Isto porque numeroMinimo não possui um valor com significado e, assim, toda a expressão do lado direito do sinal de igual não possui valor com significado. Uma variável como numeroMinimo, que não recebeu um valor, é chamada de não-inicializada. Essa situação é, na verdade, pior do que se numeroMinimo não tivesse nenhum valor. Uma variável não-inicializada, como numeroMinimo, simplesmente assumirá um valor qualquer. O valor de uma variável não-inicializada é determinado pelo padrão de zeros e uns deixado em sua porção na memória pelo último programa que utilizou aquela porção. Uma forma de evitar uma variável não-inicializada é inicializar as variáveis ao mesmo tempo em que são declaradas. Isso pode ser feito acrescentando-se um sinal de igual e um valor, desta forma: int
numeroMinimo = 3;
Esta linha tanto declara numeroMinimo como uma variável do tipo int como fixa o valor da variável numeroMinimo como igual a 3. Você pode usar uma expressão mais complicada envolvendo operações como adição ou multiplicação quando inicializa uma variável dentro da declaração assim. Os seguintes exemplos declaram três variáveis e inicializam duas delas: double
velocidade = 0.07, tempo, saldo = 0.00;
O C++ permite uma notação alternativa para inicializar variáveis quando estas são declaradas. Essa notação alternativa é ilustrada a seguir, como uma declaração equivalente à anterior: double velocidade(0.07),
tempo, saldo(0.00);
INICIALIZANDO VARIÁVEIS EM DECLARAÇÕES
Você pode inicializar uma variável (ou seja, atribuir-lhe um valor) no momento em que a declara.
SINTAXE Tipo_Nome Variavel_Nome_1 = Expressao_para_Valor_1, Variavel_Nome_2 = Expressao_para_Valor_2, ... ;
EXEMPLOS int
contagem = 0, limite = 10, fatorBobo = 2; double distancia = 999.99;
SINTAXE
Sintaxe alternativa para inicializar em declarações: Tipo_Nome Variavel_Nome_1 (Expressao_para_Valor_1), Variavel_Nome_2 (Expressao_para_Valor_2), ... ;
EXEMPLOS int
contagem(0), limite(10), fatorBobo(2); distancia (999.99);
double
Dica
Nomes de variáveis e outros nomes em um programa devem pelo menos aludir ao significado ou ao uso da coisa que estão nomeando. É muito mais fácil entender um programa se as variáveis possuem nomes com significado. Compare x = y
*
z;
Com os nomes mais descritivos
Variáveis, Expressões e Declarações de Atribuição
9
Dica distancia = velocidade * tempo;
As duas declarações efetuam a mesma coisa, mas a segunda é muito mais fácil de entender.
■
MAIS DECLARAÇÕES DE ATRIBUIÇÃO
Existe uma notação abreviada que combina o operador de atribuição (=) e o operador aritmético de forma que uma dada variável possa ter seu valor alterado por meio de adição ou subtração a um dado valor, multiplicação ou divisão por um dado valor. A forma geral é VariavelOperador = Expressao
que é equivalente a Variavel = VariavelOperador (Expressao)
A Expressao pode ser outra variável, uma constante ou uma expressão aritmética mais complicada. A lista seguinte fornece exemplos: EXEMPLO
EQUIVALENTE A
contagem += 2;
contagem = contagem + 2;
total –= desconto;
total = total – desconto;
bônus *= 2;
bônus = bônus * 2;
tempo /= fatorPressa;
tempo = tempo / fatorPressa;
troco %= 100;
troco = troco % 100;
quantia *= cnt1 + cnt2;
quantia = quantia * (cnt1 + cnt2);
Exercícios de Autoteste 1. Escreva a declaração para duas variáveis chamadas pés* e polegadas.** Ambas as variáveis são do tipo int e devem ser inicializadas com o valor zero na declaração. Forneça as alternativas de inicialização. 2. Escreva a declaração para duas variáveis chamadas contagem e distancia. contagem é do tipo int e inicializada com o valor zero. distancia é do tipo double e inicializada com o valor 1.5. Forneça as alternativas de inicialização. 3. Escreva um programa que contenha declarações que apresentem como saída os valores de cinco ou seis variáveis que tenham sido definidas, mas não inicializadas. Compile e execute o programa. Qual é a saída? Explique. *
■
**
COMPATIBILIDADE DE ATRIBUIÇÃO
Como regra geral, não se pode armazenar um valor de um tipo em uma variável de outro tipo. Por exemplo, a maioria dos compiladores não aceitará as seguintes linhas: int intVariavel;
intVariavel = 2.99;
O problema é uma má combinação de tipos. A constante 2.99 é do tipo double, e a variável intVariavel é do tipo int. Infelizmente, nem todos os compiladores reagirão da mesma forma à declaração de atribuição acima. Alguns emitirão uma mensagem de erro, outros, apenas uma mensagem de alerta, e alguns não apresentarão nenhuma forma de erro. Mesmo se o compilador permitir que você use a atribuição acima, ele dará a intVariavel o valor int 2, não o valor 3. Como você não pode contar com a aceitação do seu compilador à atribuição acima, não deve atribuir um valor double a uma variável de tipo int. * **
Um pé equivale a 30,5 cm no Sistema Internacional de Unidades. (N. do R.T.) Uma polegada equivale a 2,54 cm no Sistema Internacional de Unidades. (N. do R.T.)
10
Fundamentos do C++
Mesmo se o compilador permitir que você misture tipos em uma declaração de atribuição, na maioria dos casos isso não é aconselhável, pois torna seu programa menos portátil, além de causar confusões. Existem alguns casos especiais em que é permitido atribuir um valor de um tipo a uma variável de outro tipo. É aceitável atribuir um valor de um tipo inteiro, como int, a uma variável de tipo ponto flutuante, como o tipo double. Por exemplo, o seguinte estilo é ao mesmo tempo legal e aceitável: double doubleVariavel;
doubleVariavel = 2;
Isto fixará o valor de uma variável chamada doubleVariavel como igual a 2.0. Embora em geral essa seja uma má idéia, você pode armazenar um valor int, como 65, em uma variável de tipo char, e armazenar uma letra como ’Z’ em uma variável de tipo int. Para muitas finalidades, a linguagem C considera os caracteres como pequenos inteiros e, talvez infelizmente, o C++ herdou isso do C. A razão para permitir isso é que as variáveis de tipo char consomem menos memória do que as variáveis de tipo int. Assim, fazer operações aritméticas com variáveis do tipo char pode economizar um pouco de memória. Entretanto, é mais correto utilizar o tipo int quando se lida com inteiros e o tipo char quando se lida com caracteres. A regra geral é que não se pode colocar um valor de um tipo em uma variável de outro tipo — embora possa parecer que há mais exceções à regra do que casos que obedeçam a ela. Mesmo que o compilador não imponha essa regra com muito rigor, é uma boa prática segui-la. Colocar dados de um tipo em uma variável de outro tipo pode causar problemas porque o valor deve ser alterado para um valor do tipo apropriado e esse valor pode não ser aquele esperado. Valores de tipo bool podem ser atribuídos a variáveis de um tipo inteiro ( short, int, long), e inteiros podem ser atribuídos a variáveis do tipo bool. Entretanto, ao fazer isso você prejudica seu estilo. Para maior coerência e para conseguir ler o código de outras pessoas, é bom você saber: quando atribuído a uma variável de tipo bool, qualquer inteiro diferente de zero será armazenado como o valor true. O zero será armazenado como o valor false. Quando se atribui a um valor bool uma variável inteira, true será armazenado como 1, e false será armazenado como 0. ■ LITERAIS
Literal é um nome para um valor específico. Os literais muitas vezes são chamados de constantes, para se contra-
por às variáveis. Literais ou constantes não mudam de valor; variáveis podem mudar de valor. Constantes inteiras são escritas do modo como se costuma escrever números. Constantes de tipo int (ou qualquer outro tipo inteiro) não devem conter um ponto decimal. Constantes de tipo double podem ser escritas em qualquer das duas formas. A forma simples para constantes double é o jeito normal de escrever frações decimais. Quando escrita desta forma, uma constante double deve conter um ponto decimal. Nenhuma constante numérica (inteira ou de ponto flutuante) em C++ pode conter uma vírgula. Uma notação mais complicada para constantes do tipo double é chamada notação científica ou notação de ponto flutuante e é particularmente útil para escrever números muito extensos e frações reduzidas. Por exemplo, 3.67 x 1017que é o mesmo que 367000000000000000.00
é mais bem expresso em C++ pela constante 3.67e17. O número 5.89 x 10 -6, que é o mesmo que 0.00000589, é mais bem expresso em C++ pela constante 5.89e-6. E é o símbolo para expoente e significa "multiplicado por 10 na potência que se segue". O e pode ser escrito em letra maiúscula ou minúscula. Pense no número após o e como aquele que lhe diz a direção e o número de dígitos para mover o ponto decimal. Por exemplo, para mudar 3.49e4 para um número sem um e, mova o ponto decimal quatro casas para a direita para obter 34900.0, que é outra forma de se escrever o mesmo número. Se o número após o e é negativo, mova o ponto decimal pelo mesmo número indicado de casas para a esquerda, inserindo zeros extras se necessário. Assim, 3.49e-2 é o mesmo que 0.0349. O número antes do e pode conter um ponto decimal, embora isso não seja necessário. Entretanto, o expoente depois do e não deve, de modo algum, conter um ponto decimal.
Variáveis, Expressões e Declarações de Atribuição
11
O QUE É DOUBLE? Por que o tipo de números com uma parte fracional é chamado de double? Existe um tipo chamado "single" ("único") que possua a metade do tamanho do double ("duplo")? Não, mas há algo de verdade nisso. Muitas linguagens de programação utilizavam tradicionalmente dois tipos para números com uma parte fracional. Um tipo ocupava menos espaço e era bastante impreciso (ou seja, não permitia muitos dígitos significativos). O segundo tipo ocupava o dobro do espaço na memória e, assim, era bem mais preciso; também permitia números maiores (embora os programadores tendam a se preocupar mais com a precisão do que com o tamanho). Os tipos de números que utilizavam o dobro do espaço eram chamados de números de precisão dupla ; os que utilizavam menos espaço eram chamados de números de precisão simples. Seguindo essa tradição, o tipo que corresponde (mais ou menos) a esse tipo de precisão dupla foi denominado double em C++. O tipo que corresponde à precisão simples em C++ foi denominado float. C++ possui também um terceiro tipo para números com uma parte fracional, que é chamado de long double.
Constantes do tipo char symbol
char são
expressas colocando-se o caractere entre aspas simples, como ilustrado aqui:
= ’Z’;
Observe que a aspa da direita é o mesmo símbolo que a da esquerda. Constantes para strings de caracteres são dadas entre aspas duplas, como ilustrado pela seguinte linha, retirada do Painel 1.1: cout << "Quantas linguagens de programação você já usou? ";
Não se esqueça de que constantes string são colocadas entre aspas duplas, enquanto as de tipo char são colocadas entre aspas simples. Os dois tipos de aspas possuem significados diferentes. Em particular, ’A’ e "A" possuem significados diferentes. ’A’ é um valor de tipo char e pode ser armazenado em uma variável de tipo char. "A" é uma string de caracteres. O fato de que a string contenha apenas um caractere não transforma "A" em um valor de tipo char. Obser ve também que tanto nas strings quanto nos caracteres as aspas do lado esquerdo e direito são as mesmas. Strings entre aspas duplas, como "Oi", muitas vezes são chamadas strings C. No Capítulo 9 veremos que o C++ possui mais de um tipo de string, e esse tipo particular se chama strings C. O tipo bool possui duas constantes, true e false. Essas constantes podem ser atribuídas a uma variável de tipo bool ou usadas em qualquer outro lugar em que uma expressão de tipo bool é permitida. Devem ser escritas só com letras minúsculas. ■
SEQÜÊNCIAS DE ESCAPE
Uma contrabarra, \, precedendo um caractere diz ao compilador que a seqüência que se segue à contrabarra não tem o mesmo significado que o caractere sozinho. Tal seqüência é chamada de seqüência de escape. A seqüência é digitada como dois caracteres sem nenhum espaço entre os símbolos. Existem muitas seqüências de escape definidas em C++. Se você quiser colocar uma contrabarra, \, ou aspas, ", em uma constante string, precisa escapar à capacidade das " de terminar uma constante string utilizando \", ou a capacidade da \ de escapar utilizando \\. \\ diz ao computador que você quer uma barra "ao contrário" de verdade, \, e não uma seqüência de escape; o \" diz que você quer realmente aspas, não o final de uma constante string. Uma \ desgarrada, digamos \z, em uma constante string terá efeitos diferentes em compiladores diferentes. Um compilador pode simplesmente devolver um z; outro pode produzir um erro. O padrão ANSI/ISO afirma que seqüências de escape não-especificadas possuem comportamento indefinido. Isso significa que um compilador pode fazer qualquer coisa que seu autor achar conveniente. A conseqüência é que o código que usa seqüências de escape não-definidas não é portátil. Você não deve utilizar seqüências de escape além daquelas fornecidas pelo padrão C++. Esses caracteres de controle estão listados no Painel 1.3. ■
DANDO NOMES A CONSTANTES
Números em um computador criam dois problemas. O primeiro é que eles não carregam nenhum valor mnemônico. Por exemplo, quando o número 10 é encontrado em um programa, ele não fornece nenhuma pista do seu significado. Se o programa é um programa bancário, pode ser o número de filiais ou o número de caixas na central. Para entender o programa, você precisa conhecer o significado de cada constante. O segundo problema é que, quando é preciso alterar alguns números em um programa, a alteração tende a produzir erros. Suponha que 10
12
Fundamentos do C++
ocorra doze vezes em um programa bancário — quatro vezes ele representa o número de filiais e oito vezes ele representa o número de caixas na central. Quando o banco abrir uma nova filial e o programa precisar ser atualizado, há uma boa possibilidade de que alguns dos 10 que deveriam ser alterados para 11 não sejam, ou que alguns que não deveriam ser alterados sejam. A maneira de evitar esses problemas é dar nome a cada número e utilizar o nome em vez do número dentro do seu programa. Por exemplo, um programa bancário poderia ter duas constantes com os nomes CONTAGEM_DE_FILIAIS e CONTAGEM_DE_CAIXAS. Ambos os números poderiam ter o valor 10, mas, quando o banco abrir uma nova filial, tudo o que você precisa fazer para atualizar o programa é mudar a definição de CONTAGEM_DE_FILIAIS. Painel 1.3
Algumas seqüências de escape
SEQÜÊNCIA
SIGNIFICADO
\n
Nova linha
\r
Sinal de retorno (Posiciona o cursor no início da linha atual. Provavelmente você não o utilizará muito.)
\t
(Horizontal) Tabulação (A vança o cursor até a próxima tabulação.)
\a
Alerta (Soa o sinal de alerta, em geral uma campainha.)
\\
Contrabarra (Permite que você coloque uma contrabarra em uma expressão citada.)
\’
Aspas simples (Em geral usada para colocar aspas simples dentro de uma citação de um caractere.)
\”
spas duplas (Em geral usada para colocar aspas duplas dentro de uma citação em string.)
As seqüências seguintes não costumam ser usadas, mas nós as incluímos para fornecer um quadro completo. \v
Tabulação vertical
\b
Retrocesso
\f
Suprimento de folha (comando que faz a impressora retirar a folha atual)
\?
Interrogação
Como se dá nome a um número em um programa C++? Uma das formas é inicializar uma variável com o valor daquele número, como no seguinte exemplo: int CONTAGEM_DE_FILIAIS int CONTAGEM_DE_CAIXAS
= 10; = 10;
Existe, porém, um problema com esse método de nomear constantes-número: você poderia, inadvertidamente, trocar o valor de uma dessas variáveis. O C++ fornece uma forma de marcar uma variável inicializada de modo que esta não possa ser alterada. Se o seu programa tentar mudar uma dessas variáveis, um erro será produzido. Para marcar uma declaração de variável de modo que o valor da variável não possa ser alterado, coloque antes da declaração a palavra const (que é uma abreviação de constante ). Por exemplo, const int CONTAGEM_DE_FILIAIS const int CONTAGEM_DE_CAIXAS
= 10; = 10;
Se as variáveis são do mesmo tipo, é possível combinar as linhas acima em uma declaração, como se segue: const int CONTAGEM_DE_FILIAIS
= 10, CONTAGEM_DE_CAIXAS = 10;
Entretanto, a maioria dos programadores pensa que colocar cada definição de nome em uma linha separada torna o programa mais claro. A palavra const geralmente é chamada de modificador , porque modifica (restringe) as variáveis declaradas. Uma variável declarada utilizando o modificador const é, em geral, chamada de constante declarada . Escrever constantes declaradas com todas as letras em maiúscula não é uma exigência da linguagem C++, mas é uma prática comum entre os programadores de C++. Uma vez que um número tenha sido nomeado dessa forma, o nome pode então ser usado em qualquer lugar em que o número seja permitido, e terá exatamente o mesmo significado que o número que nomeia. Para alterar uma constante nomeada, você precisa apenas mudar o valor de inicialização na declaração da variável const. O significado de todas as ocorrências de CONTAGEM_DE_FILIAIS, por exemplo, pode ser mudado de 10 para 11 simplesmente alterando-se o valor de inicialização 10 na declaração de CONTAGEM_DE_FILIAIS. O Painel 1.4 contém um programa simples que ilustra o uso do modificador de declaração const.
Variáveis, Expressões e Declarações de Atribuição
13
OPERADORES ARITMÉTICOS E EXPRESSÕES Como a maioria das outras linguagens, o C++ permite que você forme expressões utilizando variáveis, constantes e os operadores aritméticos: + (adição), – (subtração), * (multiplicação), / (divisão) e % (módulo, resto). Essas expressões podem ser usadas em qualquer lugar em que seja legal utilizar um valor do tipo produzido pela expressão. Todos os operadores aritméticos podem ser usados com números de tipo int, números de tipo double e até mesmo com um número de cada tipo. Entretanto, o tipo do valor produzido e o valor exato do resultado dependem dos tipos de números que estão sendo combinados. Se ambos os operandos (ou seja, ambos os números) são de tipo int, então o resultado de combiná-los com um operador aritmético é do tipo int. Se um ou ambos os operandos for do tipo double, então o resultado é do tipo double. Por exemplo, se as variáveis quantiaBase e juros são do tipo int, o número produzido pela expressão seguinte é do tipo int: ■
quantiaBase + juros
Painel 1.4 1 2 3 4 5 6 7
Constante nomeada
#include using namespace std; int main(
)
{ const double TAXA
= 6.9;
double deposito;
8 9
cout << "Digite o total do seu depósito $"; cin >> deposito;
10 11 12 13
double novoBalanco;
14 15 }
return 0;
novoBalanco = deposito + deposito* (TAXA /100); cout << "Em um ano, esse depósito aumentará para\n" << "$" << novoBalanco << "uma quantia pela qual vale a pena esperar.\n";
DIÁLOGO PROGRAMA-USUÁRIO Digite o total do seu depósito R$ 100 Em um ano, esse depósito aumentará para R$ 106.9, uma quantia pela qual vale a pena esperar.
Entretanto, se uma ou ambas as variáveis são do tipo double, então o resultado é do tipo double. Isso também é verdade se você substituir o operador + por qualquer dos outros operadores, –, *, ou /. De modo mais geral, você pode combinar quaisquer tipos aritméticos em expressões. Se todos os tipos forem tipos inteiros, o resultado será de tipo inteiro. Se pelo menos uma das subexpressões for de tipo ponto flutuante, o resultado será de tipo ponto flutuante. O C++ faz o possível para tornar o tipo de uma expressão int ou double, mas, se o valor produzido pela expressão não for um desses tipos devido ao tamanho do valor, um inteiro ou tipo ponto flutuante diferente adequado será produzido. Você pode especificar a ordem das operações em uma expressão aritmética inserindo parênteses. Se você omitir os parênteses, o computador seguirá as chamadas regras de precedência , que determinam a ordem em que as operações, como a adição e a multiplicação, são executadas. Essas regras de precedência são similares às regras utilizadas na álgebra e em outras classes matemáticas. Por exemplo, x + y * z
é calculada fazendo-se primeiro a multiplicação e depois a adição. Exceto em alguns casos-padrão, como na adição de strings ou na multiplicação simples inserida dentro de uma adição, normalmente é melhor incluir os parênteses, mesmo que a ordem pretendida de operações seja aquela ditada pelas regras de precedência. Os parênteses tor-