Apostila I - C/C++


1. Introdução
Esta apostila aborda os conceitos fundamentais da linguagem C e C++, tem o propósito de apresentar um conteúdo mínimo comuns as outras linguagens de programação, visa facilitar o aprendizado ao iniciante, porém é uma base para estudos mais avançados.

A linguagem C++ foi desenvolvida inicialmente por Bjarne Stroustrup na Bell Laboratories, em Murray Hill, New Jersey, de 1979 a 1983, à partir da linguagem C, tendo como idéia principal a de agregar o conceito de classes e  orientação à objetos, àquela linguagem. Razão porque iniciamente chamava-se de “C com classes”.  C++ deve ser vista como uma “outra linguagem”, por diversas razões. Em primeiro lugar, nem todo o programa escrito em C é compilado em C++ sem erros, e pode nem mesmo gerar o mesmo resultado, já que a sintaxe e a semântica de algumas construções diferem. Ao ligar-se partes de um programa em C++ com partes em C, estas devem ser bem especificadas, pois as convenções de funcionamento do código compilado também diferem. Além disso, C++ oferece um conjunto de mecanismos básicos que não estavam presentes em C, e estes devem ser usados para produzir software mais modular e confiável explorando-se as verificações disponíveis no compilador. Finalmente, os mecanismos de C++ devem inspirar a programação segundo o paradigma de orientação a objetos e, portanto, não se deve programar em C++ como se faz em C.

CPP é a forma utilizada para representar C++ em inglês pois, CPP são as letras iniciais de C Plus Plus, ou seja, C++.

A Standart Template Library (STL) é uma parte do padrão C++, e consiste em uma biblioteca de funções e estruturas de dados que todo compilador C++ deve oferecer, provê as implementações mais comuns em um programa, e pode-se utilizá-la com diferentes tipos de dados.

A maioria dos conceitos em C++ são aplicado a linguagem Java como objetos, herança, polimorfismo, etc. Portanto a compreenção da linguagem C++ será mais fácil para quem já assimilou os conceitos do Java que são mais abstratos.

É comum programadores iniciarem seus conhecimentos pelo Java, por ser mais comercialmente favorável, com a necessitade do desenvolvimento de novos recurso, os programadores então procuram novas linguagens a fim de resolver os problemas a eles apresentados.

1.1. Compilação e Interpretação
Um compilador é um programa de sistema que traduz um programa escrito em uma linguagem de alto nível para um programa equivalente em código de máquina para um processador. Em geral, um compilador não produz diretamente o código de máquina mas sim um programa em linguagem simbólica (assembly) semanticamente equivalente ao programa em linguagem de alto nível. O programa em linguagem simbólica é então traduzido para o programa em linguagem de máquina através de montadores.
Resumindo o compilador transforma a linguagem (humana) em linguagem de máquina.

Uma linguagem de programação pode ser convertida, ou traduzida, em código de máquina por compilação ou interpretação, que juntas podem ser chamadas de tradução.

tradução = compilação  ou interpretação

Se o método utilizado traduz todo o texto (código) do programa, para só depois executar o programa, então diz-se que o programa foi compilado e que o mecanismo utilizado para a tradução é um compilador (um programa). A versão compilada do programa tipicamente é armazenada, de forma que o programa pode ser executado um número indefinido de vezes sem que seja necessária nova compilação, essa é a forma de execução e processamento da linguagem C/C++.
Se o texto do programa é traduzido na medida em que vai sendo executado, como em Javascript, Python, Perl, PHP e Java, num processo de tradução de trechos seguidos de sua execução imediata, então diz-se que o programa foi interpretado e que o mecanismo utilizado para a tradução é um interpretador.

1.2. As Fases da Compilação

O primeiro passo consiste em escrever o código-fonte em linguagem C ou C++ (arquivos .c e .h para o C e .cpp e .hpp para o C++). Depois, executamos uma compilação, por exemplo, com o compilador gcc (em C) ou g++ (em C++). A compilação (no sentido lato do termo) é dividido em três fases principais.

1.2.1. A pré-compilação (pré-processador)
O compilador começa pela aplicação de cada instrução passada pelo pré-processador (todas as linhas que começam com um #, incluindo o #define). Estas instruções são, na realidade, muito simples, pois elas apenas recopiam ou excluem seções de código sem compilá-los. É a substituição de texto, nem mais nem menos.

É particularmente neste momento em que os "#define" encontrados em um arquivo fonte (.c ou .cpp) ou em um header (.h ou .hpp) são substituídos pelo código C/C++. Após esta etapa, então, não haverá mais instruções começando por um #, para o compilador.

1.2.2. A compilação
Em seguida, o compilador compila cada arquivo-fonte (.c e .cpp), ou seja, ele cria um arquivo binário (.o) pelo arquivo fonte, exceto para o arquivo que contém a função principal. Esta fase é a fase de compilação em si.

Estas duas primeiras etapas são realizadas pelo cc quando usamos o gcc/g++. Enfim, o compilador passa para o arquivo com a função principal.

1.2.3. A ligação (link)
Concluindo, o compilador agrega cada arquivo .o com eventuais arquivos binários das bibliotecas que são utilizadas (arquivos .a e .so no linux, arquivos .dll e .lib no Windows).
- Uma biblioteca dinâmica (.dll e .so) não é recopiada no executável final (o que significa que o programa é menor e receberá atualizações da dita biblioteca). Em troca, a biblioteca deve estar presente no sistema onde o programa é executado.
- Uma biblioteca estática (.a) é recopiada no executável final, o que faz com que este seja completamente independente das bibliotecas instaladas do sistema no qual ele foi recopiado. Em troca, o executável é maior, ela não receberá atualizações desta biblioteca, etc ...

O linker verifica, em particular, se cada função chamada no programa não é apenas declarada (isso é feito durante a compilação), mas também implementada (coisa que ele não tinha verificado nesta fase). Ele também verifica se uma função não foi implementada em vários arquivos .o.
Esta fase, também chamada de edição de link, constitue a fase final para obter um executável (notado .exe no windows, em geral sem extensão no linux).

Resumo:
Compilador: O código-fonte é traduzido para o assembly. É nessa fase que se verifica se o código-fonte possui erros de semântica ou de sintaxe.
Assembly: Ele traduz o código assembler criado pelo compilador para a linguagem de máquina(código-objeto).
Linker: Ele é o responsável por fazer a ligação entre os módulos do programa, para gerar um único executável. Também adiciona ao código-objeto bibliotecas e funções de outros programas alem de inserir código para lidar com o Sistema Operacinal. O linker resolve as pendecias de rótulos em partes do programa. É nessa etapa que o código-objeto é traduzido para a linguagem de máquina.
Loader: Carrega o programa executável na memória principal para ser executado.

2. Instalação dos Programas

Para criar programas em C/C++ necessita-se de um editor de texto simples afim de criar o código fonte da linguagem C/C++   e um compilador, há vários compiladores disponíveis na internet, serão em seguidas abordados alguns, é necessário testá-los, a instalação pode variar de acordo com a configuração de hardware e software do usuário.

2.1. Eclipse C/C++ e MinGW
O programa eclipse possui uma interface gráfica que pode trabalhar com o compilador MinGW, já que um completa o outro, estes programas não serão utilizados por esta apostila por gerar mais erro na configuração, mesmo assim serão citados.
O Eclipse IDE for C/C++ Developers possui várias características interessantes, no entanto a que mais se destaca é a possibilidade de criar, desenhar e desenvolver cada módulo de forma independente. Além disso, o programa conta com o seu próprio debugger (depurador), para ir analisando cada módulo criado em busca de erros.
O programador de Eclipse IDE for C/C++ Developers também pode criar suas próprias classes referenciadas e conta com editor de textos, corretor de sintaxe, compilador, etc
a) Baixando o Eclipse
- Site: eclipse.org
- Menu: downloads  Eclipse IDE for C/C++ Developers Eclipse IDE for C/C++ Developers, 140 MB
- Escolha: Juno Packages (última versão)
- Eclipse IDE for C/C++ Developers (includes Incubating components)
Escolha: Windows 32 bit
- Download eclipse-cpp-juno-SR2-incubation-win32.zip from:
Clique na seta

b) Instalação
É só descompactar o arquivo baixado no local desejado.

Obs: Versões
sem codinome lançado em 28 de Junho de 2004
sem codinome lançado em 28 de Junho de 2005
Callisto lançado em 30 de Junho de 2006
Europa lançado em 29 de Junho de 2007
Ganymede lançado em 25 de Junho de 2008
Galileo lançado em 24 de Junho de 2009
Helios lançado em 23 de Junho de 2010
Indigo lançado em 28 de Junho de 2011
Juno
lançado em 27 de Junho de 2012


c) Baixando o compilador MinGW
- http://sourceforge.net/projects/mingw/files/
- Download mingw-get-inst-20120426.exe (662.7 kB)
MinGW – Minimalist GNU for Windows
ou
- http://www.mingw.org/category/wiki/download

Convenções:
GCC (gcc) = GNU Compiler Colection é o Compilador da Linguagem C
g++ ou gpp = GCC C++ Compiler é o Compilador da Linguagem C++
GDB: GNU Debbuger. É o depurador do projeto Gnu. Pode ser utilizado tanto para C quanto pra C++, assim como outras linguagens (Pascal, etc.).

O  GNU Compiler Collection (chamado usualmente por GCC) é um conjunto de compiladores de linguagens de programação produzido pelo projeto GNU para construir um sistema operativo semelhante ao Unix livre.

O MinGW (Minimalista GNU para Windows) é um ambiente minimalista para aplicações MS Windows, ele oferece um conjunto de ferramentas Open Source para o desenvolvimento do aplicações no Windows sem depender de Runtime DLL, como o caso da plataforma de desenvolvimento dotNet (VB.NET, C#.NET) que usa o .Net Framework para criar e usar seus componentes, ou seja quando você for distribuir seu programa ou vender você terá que instalar o .Net Framework no seu cliente para que seu programa funcione. Com MinGW nós podemos instalar no MS Windows alguns programas de desenvolvimento nativo do GNU/Linux com o compilador de C o gcc e o compilador de C++ o g++, considerados por muitos programadores como um dos melhores compiladores para essas linguagens, para a instalação dele basta estar conectado na internet para começar a instalar.

d) Instalação
- Clique no arquivo e siga as instruções.

e) Configuração da variável de ambiente do Windows Vista
- Painel de Controle > Sistema e Manutenção > Sistema > Configuração Avançada do Sistema > Variável de ambiente
Em variáveis do sitema escolha path.
- editar a variável “Path” colocando nela o endereço da pasta do MinGW/bin, que deve ser C:\MinGW\bin, se você não modificou o caminho padrão na instalação. Observe que já existe conteúdo na variável de ambiente, separe o que há antes com um ponto-e-vírgula.

Caso você tenha instalado o Mingw em outro diretório, basta adicionar esse diretório ao "Valor da variável" ao invés de adicionar o padrão exibido aqui. Após isso, vá clicando  em Aplicar/Ok até fechar todas as janelas. Agora abra o prompt (iniciar > executar >  digite cmd.exe e clique em ok). Agora digite o comando "gcc" (sem as aspas) e aperte enter. Se aparecer "gcc: no input files" a instalação e configuração do Mingw foi  completada com sucesso! Caso não apareça, digite "c:\mingw\bin\gcc.exe" (sem aspas) se for exibida a mensagem "gcc: no input files", refaça o terceiro passo, se aparecer uma mensagem de comando não reconhecido, repita o processo desde o segundo passo.
Para compilar seu programa em C você deve abrir o prompt (iniciar > executar > digite  cmd.exe e clique em ok) e dirigir-se ao diretório aonde está o arquivo fonte do seu programa. Depois basta digitar o comando:
 
gcc -o nome_do_executavel_a_ser_gerado nome_do_arquivo_fonte.c -Wall

Exemplo: para compilar um arquivo fonte de nome teste.c que está no diretório "C:\programas" gerando um executável programa_teste.exe, digite: gcc -o programa_teste.exe teste.c -Wall

Caso não apareça nenhuma mensagem, significa que seu programa foi compilado com sucesso! Caso tenha algum erro no código do seu programa, o compilador exibirá Warnings ou Erros e você terá que resolvê-los. Para testar o  programa que você acabou de compilar, digite apenas o nome do executável.

Obs: a explicação acima deverá ser adaptada para a versão do MinGW que for baixada.

f) Eclipse C/C++
Na etapa anterior o compilador foi instalado sozinho, com a instalação do Eclipse C/C++ após a instalação do compilado MinGW é possível criar projetos com mais facilidades, a depuração, encontro de erros é feito pelo eclipse.

g) Visual C ++ 2010
Este programa da Microsoft é gratuito, há vários sites para download, o Eclipse C/C++ também pode trabalhar junto com ele da mesma forma que o MinGW.
Download:
http://www.superdownloads.com.br/download/72/microsoft-visual-c-2010-express/redir.html

2.2. Codeblocks
Outra opção é baixar o programa, codeblocks no site http://www.codeblocks.org/downloads, este já possui uma interface gráfica, portanto independe do eclipse, neste caso a variável de ambiente passa a ser c:\codeblocks\MinGW\bin.

2.3. Dev-Cpp
Esta é a opção mais fácil, para os objetivos apenas didáticos desta apostila, é o mais recomendado, as outras opções de programas geram mais erros de instalação, com o Dev-Cppa a instalação é mais simples, basta fazer o download e a instalação.

O Dev-C++ é um ambiente de programação (IDE - sigla em inglês que significa Ambiente Integrado de Desenvolvimento), ele torna a atividade de programar mais simples. Possui um ambiente de programação que torna a atividade do programador mais fácil para criar o seu programa. Ele é constituído de um editor de texto inteligente que reconhece elementos da linguagem de programação e, às vezes, contem auxílios para automatizar a escrita de códigos muito usados. Um compilador para compilar o arquivo com o código fonte e gerar um arquivo com o programa executável. No caso do Dev-C++, o compilador pode ser um pré-instalado ou o MinGW GCC. Um depurador de programas, em inglês, debugger, que serve para encontrar erros de lógica nos programas. No caso do Dev-C++ é usado o GDB. Todas estas ferramentas/programas são livres e podem ser obtidas na Internet sem custos.

http://sourceforge.net/projects/orwelldevcpp/files/Setup%20Releases/
Dev-Cpp 5.5.1 MinGW 4.7.2 Setup.exe

Configurando o Dev C/C++ para inserir código padrão.

Para quem faz programas de computadores com toda e qualquer IDE deve conhecer suas facilidades e recursos. É fundamental para que, se possa, produzir mais, e melhor. Pois bem! Seguindo esta tônica esta dica é para quem usa o Dev C/C++.

Dica:
Se você usa as mesmas bibliotecas, não tem que digitar todas as linhas das bibliotecas repetidas vezes. Você pode configurar o DEV C/C++ para inserir o código acima automaticamente. Para você configurar um código padrão você faz esta configuração em poucos cliques. Esta dica é para quem usa o DEV C/C++.

1) – Clique em TOOLS; depois clique em Editor Options.
2) – Na tela do Editor Options você vai clicar em CODE. E depois na parte de baixo clique em Default Source

Clique em OK. Todas as vezes que você for iniciar um novo arquivo, este bloco de código já aparece no novo arquivo, economizando tempo e digitação. Bem como evita erros, uma vez que você, terá este código inserido corretamente e automaticamente.

3. Comparação entre o  C e o C++
A internet tem um vasto material sobre as linguagens C/C++, porém algumas atualizações no código são necessário para que os exemplos sejam executados em compiladores modernos (atuais), os itens a seguir explanarão sobre o assunto.

3.1. Extensão

Para compilar com C++, o código fonte tem que ser salvo com a extensão .cpp, a extensão .c não é aceita mais nos compiladores modernos. Arquivos em C++ podem importar algumas bibliotecas do C puro, sendo referenciado na verdade por C/C++. Os exemplos deste tutorial foram feitos conforme as configurações de software anteriormente citadas (Dev C/C++), caso o compilador seja diferente, é necessáro testar os exemplos novamente.

Para compilar em C puro usa-se a extensão .c
As bibliotecas em C++ perderam a extensão h, exemplo: iostream.h não usa mais o .h, se colocado gerará erro, esta biblioteca é usada no lugar de stdio.h, porque a mesma tem mais recursos.
As bibliotecas do C usam a extensão .h.
Vale lembrar que as funções em C e C++ são diferentes.
Resumo:

Biblioteca
Códidgo Fonte
C++ sem o h arquivo.cpp
C/C++ com h arquivo.cpp
C com h arquivo.c

Exemplo 1:
- Abra o Dev C/C++
- File > New > Souce File ...
Next ...
- Recorte e cole o código abaixo:

Arquivo: transporte.cpp
#include <stdlib.h>
#include <iostream>
using namespace std;

#define taxa_transporte 4.2;  //constante
int main() {
    float distancia;
    printf("Deslocamento \n");  //erro: 'printf' was not declared in this scope
    printf("Qual a distâcia percorrida (em km)\n");
    scanf("%f", &distancia);  //erro: 'scanf' was not declared in this scope
    printf("\n");
    distancia = distancia * taxa_transporte;
    printf("Total da tarifa: R$ %.2f", distancia);
    getchar();  //erro: 'getchar' was not declared in this scope
}
Obs: as funções scanf( ), getchar( ) e printf( ) pertencem ao C puro e a biblioteca iostream pertence apenas ao C++ o que os tornam incompatíveis com a extensão .cpp.



Exemplo 2:

Arquivo: transporte.c
#include <stdlib.h>
#include <stdio.h>

#define taxa_transporte 4.2;  //constante
int main() {
    float distancia;
    printf("Deslocamento \n");
    printf("Qual a distâcia percorrida (em km)\n");
    scanf("%f", &distancia);
    printf("\n");
    distancia = distancia * taxa_transporte;
    printf("Total da tarifa: R$ %.2f", distancia);
    getchar();
}

Compile & Run:
Deslocamento
Qual a disÔcia percorrida (em km)
100 <enter>

Total da tarifa: R$ 420.00

Observação:
Para corrigir o erro de acentuação na palavra distância utiliza-se a função printf substituindo os caracteres acentuados das strings  pelos caracters %c seguidos no final das strings por vírgula e após a vírgula colocar os correspondentes números da tabela ASCII, conforme exemplo abaixo, onde o â corresponde a 131 na tabela ASCII.

Arquivo: transporte.c
#include <stdlib.h>
#include <stdio.h>

#define taxa_transporte 4.2;  //constante
int main() {
    float distancia;
    printf("Deslocamento \n");
    printf("Qual a dist%ccia percorrida (em km)\n", 131);
    scanf("%f", &distancia);
    printf("\n");
    distancia = distancia * taxa_transporte;
    printf("Total da tarifa: R$ %.2f", distancia);
    getchar();
}

Compile & Run:
Deslocamento
Qual a distâcia percorrida (em km)
100 <enter>

Total da tarifa: R$ 420.00

Observações:
1) Neste último exemplo as bibliotecas stdlib.h e stdio.h pertencem ao C puro e são utilizadas com as funções desta linguagem.
2) Note que a palavra distância apresenta os caracteres %c no lugar de â (dist%ccia), a codificação usada pelo prompt de comando é a CP850, para corrigir os acentos é necessário substituir o caractere acentuado por %c  e colocar o correspondente número ASCII logo após a vírgula dentro da função printf.
Por exemplo, a palavra "Aquário" é constituída por um acento agudo na quarta letra. Devido a isso, para imprimir "Aquário" corretamente é necessário realizar o seguinte procedimento:

printf("Aqu%crio",160);

Pois de acordo com a Tabela ASCII o número 160 corresponde a letra 'A' com acento agudo. Ou seja, "á" (sem aspas).

3) A codificação usada pelo prompt de comando é a CP850, pode-se fazer uma comparação com a do bloco de notas do windows que pode salvar em ( unicode utf-8 , ocidental iso8859-1 etc...), perceba que esta configuração não está relacionada com a configuração do Windows.

Quando você salva texto pelo Notepad ou qualquer outro editor que use a codificação padrão do sistema (o "ANSI" do Notepad) está criando arquivos com a codificação Windows-1252.

4) Observe que o prompt de comando usa o padrão CP850 e daí os caracteres especiais não coincidem com o do Windows.
Para mudar o console para Windows-1252:
4.1) Vá nas propriedades do prompt de comando e selecione uma fonte TrueType, tipo a Lucida Console ou outra monoespaçada de sua preferência.
4.2) Depois, mude a codificação numa janela do prompt de comando já aberta com o comando:

chcp 1252

4.3) Abra o programa executar e digite regedit
Localize o registro \HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\N ls\CodePage\OEMCP e alterar o valor de 850 para 1252.
Reiniciar o computador e pronto!
4.4) Com as alterações anteriorem ao compilar o programa, o mesmo está configurado para imprimir corretamente os caracteres no formato padrão do windows.


4. Regras gerais sobre Programação em C/C++

4.1. Todo comando em C/C++ termina com um ponto-e-vírgula (;)
4.2. O sinal de chave de abertura, {, deve ser alinhado na mesma coluna que o sinal de chave de fechamento, }. Todos os comandos entre { e } devem ser deslocados dois espaços para a direita.
4.3. Todo programa C/C++ inicia sua execução no programa principal, denominado main:

Exemplo de programa em C:
Código fonte: arquivo.c
#include <stdio.h>
int main() { /* a execução tem início aqui..., as chaves não estão alinhadas */
    return 0; // término da execução
}

Exemplo de programa em C++:
Código fonte: arquivo.cpp
#include <iostream>
using namespace std;
int main() { /* a execução tem início aqui... as chaves não estão alinhadas*/
    return 0; // término da execução
}

Obs: o alinhamento das chaves pelo eclipse assemelha-se com do Java.

4.4. Ao utilizar qualquer estrutura de seleção ou repetição, por exemplo, comandos de seleção (if, switch) ou de repetição (for, while, do-while), desloque dois espaços para a direita (indentation) os comandos contidos neles. Se há vários níveis de indentation, cada nível deve ser deslocado à direita por dois espaços.
4.5. O comando break usado nos comandos while, for, do/while, ou switch causa a saída imediata dessas estruturas para o próximo comando.
4.6. O comando continue usado nos comando while, for, do/while faz com que o controle do programa passe para o próximo passo da iteração. Nos comandos while e do/while as condições são imediatamente avaliadas após encontrar um continue; no comando for a expressão de incremento é executada e então a condição de término do comando for é avaliada.
4.7. Da mesma forma que no Java, nomes compostos devem possuir a primeira letra em maiúsculo: ImpostoCliente.
4.8. Deve ser evitado colocar mais de um comando em uma mesma linha.
4.9. As linguagens C/C++ são case-sensitive, ou seja, são sensíveis a letras maiúsculas e minúsculas.
4.10. Nunca utilize como identificadores (nomes de variáveis ou sub-programas) as seguintes palavras reservadas:
asm, auto, bool, break, case, catch, char, class, const, const_cast, continue, default, delete, do, double, dynamic_cast, else, enum, extern, false, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, operator, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof, static, struct, switch, template, this, throw, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_t while,  bitand, and, bitor, xor, compl, and_eq, or_eq, xor_eq, not e  not_eq.

5. Equivalência entre bibliotecas C e C++ (#include <biblioteca>)
C C++ Descrição Observação
stdio.h iostream Entrada/Saída using namespace std
iomanip
Formatação de entrada e saída
math.h cmath Funções Matemáticas
string.h cstring Manipulação de strings
stdlib.h cstdlib Funções de propósito geral

O Namespaces

Para usar os recursos de entrada e saída da biblioteca iostream em C++, é preciso incluir o comando using namespace std.
Este comando serve para definir um "espaço de nomes", ou namespace. Um namespace permite a definição de estruturas, classes, funções, constantes, etc, que estarão vinculadas a ele. Isso evita duplicidade como, por exemplo, outras implementações com nomes semelhantes. Por definição, a linguagem C++ utiliza o namespace std para definir todas as funções da biblioteca padrão.
Se não utilizarmos o comando using..., será necessário especificar explicitamente o namespace utilizado, como por exemplo:
#include <iostream>

int main()
{
    std::cout << "Exemplo de saída na tela" << std::endl;

    ...
}

6. Bibliotecas C++

6.1. #include <stdio.h>
Os compiladoresC++ modernos usam a bilioteca iostream no lugar da obsoleta stdio.h.
A biblioteca stdio.h é a responsável pela entrada e saída. Standard In/Out, ou seja, Entrada/Saída Padrão. Nela, encontramos funções para estes fins. Pode ser a leitura do teclado, escrita formatada ou não na tela e operações com arquivos.
Algumas funções dessas bibliotecas:
fprintf, printf, fscanf, scanf, getchar, putc, getc, fopen, fclose...

6.2. #include <ctype.h>
Esta biblioteca serve para testar caracteres. Alguns testes possíveis com caracteres são: testar se é maiúsculo, testar se é minúsculo, testar se é espaço, testar digito decimal. Além disso, essa biblioteca permite converter maiúscula em minúscula e vice-versa.
Algumas funções:
isupper, islower, isspace, isdigit, toupper, tolower...

6.3. #include <string.h>
A função string é responsável por disponibilizar funções para trabalhar com conjuntos de caracteres, isto é, strings. Este header possui dois grupos de comandos, os que começam com str e os que começam com mem. O primeiro grupo permite, por exemplo: copiar, concatenar, comparar e ver o tamanho de uma string.
As funções referentes a isso são:
strcpy, strcat, strcmp e strlen.
As funções do segundo grupo mencionado fazem coisas semelhantes como copiar, mover e comparar:
memcpy, memmove, memcmp.

6.4. #include <math.h>
Está biblioteca declara funções matemáticas que podem servir para: achar a raiz quadrada, achar o seno, co-seno, tangente, logaritmo na base 10.
As funções referentes a isso são:
sqrt, sin, cos, tan, log10.
Fora isso, um outro uso para declaração desta biblioteca é a possibilidade de arredondar um número! Para isso usamos a função que retorna o valor absoluto: fabs.

6.5. #include <stdlib.h>
Esta biblioteca é a responsável por conversões de números, alocação na memória e outras tarefas! Com ela podemos: converter um char em um double, converte um char para long, criar um número randômico, alocar na memoria, realocar na memória, desalocar da memória, execução de comandos do sistema operacional.
As funções citadas são:
atof, atol, rand, malloc, realloc, free e system...
Também não podia deixar de citar que ela retorna o valor absoluto de um número inteiro usando abs.

6.6. #include <time.h>
Esta biblioteca declara funções para manipularmos a data e hora. Podemos usar esta biblioteca para pegar o horário do processador, pegar o horário do sistema, fazermos a diferença entre dois horários.
As funções referentes são:
clock, time e difftime.

6.7. #define
A diretiva #define é semelhante às variáveis, mas contém uma principal diferença. A variável pode ser alterada durante a execução do programa. Já o #define, não.
É uma espécie de constante na qual após ser atribuído, não pode ser mudado. É uma diretiva útil para valores padrão que não podem ser alterados(Existe uma forma de alterar uma constante em tempo de execução).

Esquema:
#define nome valor_constante
#define PI = 3.14159265;

Exemplo:
Código fonte: arquivo.c

#include <stdio.h>
#include <stdlib.h>

#define taxa_transporte 4.2;  //constante
int main(){
float distancia;
                  printf("Deslocamento\n ");
                  printf("Qual a distâcia percorrida (em km)\n");
                  scanf("%f",&distancia);
                  printf("\n");
                  distancia = distancia*taxa_transporte;
                  printf("Total da tarifa: R$ %.2f",distancia);
                  getchar();
}

6.8. #undef
#undef remove um macro feito pela diretiva #define. Ele praticamente "exclui" a constante.
#undef <identificador>
#undef TARIFA;

Exemplo:
Código fonte: arquivo.c
#include <stdio.h>//importando a biblioteca stdio.h
#include <stdlib.h>//importando a biblioteca stdlib.h
#define COTACAO_DOLAR 1.20
     
main()
{
  printf("%f",COTACAO_DOLAR);//Imprime na tela o valor da Constante
  #undef COTACAO_DOLAR;//Exclui a constante
  //Daqui para baixo, o código acusa erro
  int real = real*COTACAO_DOLAR;
  printf("%f",COTACAO_DOLAR);
}

O código acima não vai compilar porque depois de executado o comando #undef, irá aparecer a seguinte mensagem:
"Undefined symbol ‘COTACAO_DOLAR’"
Ou seja, a constante COTACAO_DOLAR deixou de existir quando executei o comando #undef.

6.9. #ifdef
É a estrutura condicional do pré-processamento. É um "if" definido.

#ifdef <identificador>
É o mesmo que dizer #if <identificador> definido
Exemplo:
Códdigo fonte: arquivo.c
#include <stdio.h>
#include <stdlib.h>

#define constante1

    main(){
      #ifdef constante1   
      #define constante2 10
      #else
      #define constante2 20
      #endif
      printf("%i",constante2);
    }
Executar > Compilar & Executar
10


6.10. Função main()
Todo programa deve ter no mínimo uma função principal denominada main. A execução do programa começa na função main e termina quando esta função for encerrada.

Estrutura básica de um programa:
#include <arquivo de inclusão>
void main( )
{
    bloco de comandos;
}

O bloco de comandos de toda função C++ deve começar com uma chave de abertura ({) de bloco e terminar com uma chave de fechamento de bloco (}).
Em C++, existem comandos que são pré-processados os quais não se constituem propriamente em instruções da linguagem C++ e são chamados de diretivas de compilação ou simplesmente diretivas. O pré-processador é um programa que examina o programa-fonte e executa os comandos genericamente chamados de diretivas. Toda diretiva é iniciada pelo símbolo #.   A diretiva #include provê a inclusão de um arquivo da biblioteca de programas contendo definições e declarações que são incorporadas ao programa pelo pré-processador. Em outras palavras, o pré-processador C++ substitui a diretiva include pelo conteúdo do arquivo indicado antes de o programa ser compilado.
Por exemplo, os arquivos de cabeçalhos (header) iostream.h e conio.h permitem que se faça a utilização de diversos comandos de entrada e saída no programa, ou seja, tais arquivos servem para auxiliar no desenvolvimento do programa-fonte. O arquivo , iostream.h por exemplo, contém declarações necessárias ao uso do objeto cin e cout, entre outros.

Parâmetros da função main
Na verdade, o programa gerado por um compilador C / C++ deve ser entendido como o código fonte abaixo:

// inicializações do compilador
exit_code = main (argc, argv);
// finalizações do compilador

A função main é aquela que chama o próprio programa. Esta função admite ter parâmetros (argumentos) que são as palavras escritas na linha de comando que chamou o programa. O protótipo da função main é:

int main (int argc, char **argv[]);
int main();
Ambas as formas estão corretas, porém a última é utilizada em situações onde obter a linha de comando do programa não é importante. Isso é o que ocorre comumente.
O retorno da função main é o código de retorno ao sistema operacional, que só interessa para que um arquivo *.bat do DOS (em programas para Windows), ou um script em um programa em unix.
O primeiro argumento int argc é o número de parâmetros passados ao programa (incluindo o próprio nome dele).
O segundo char **argv é um array de strings (char*) cujos conteúdos são exatamente os parâmetros passados.
 
argc: é um valor inteiro que indica a quantidade de argumentos que foram passados ao chamar o programa, abreviatura para argument count.
argv: é um vetor de char que contém os argumentos, um para cada string passada na linha de comando, forma abreviada de argument vector.
argv[0] armazena o nome do programa que foi chamado no prompt, sendo assim, argc é pelo menos igual a 1, pois no mínimo existirá um argumento.

Vejamos o que são os argumentos da função:
Exemplo:
Codigo fonte: arquivo.cpp
#include <iostream>

using namespace std;
main (int argc, char *argv[])
{
for (int i=0;i< argc ; i++)
cout << "o argumento de chamada número " << i << " é " << argv[i] << endl;
}

1) Entrar com os parâmetro no compilador Div C++
Execute > Parameters... > 10 20
2) Compile & Run:
Resultado:
o argumento de chamada número 0 é C:\Users\Public\arquivo.exe
o argumento de chamada número 1 é 10
o argumento de chamada número 2 é 20

Observações:
1) Argumentos:
argv[0]: é o nome do executável
argv[1]: é o primeiro número digitado
argv[2]: é o segundo número digitado
2) A execução do programa depende do compilador, no caso do Div C++, os parâmetros são passados primeiros via menu.
Cada * aumenta um grau de "indirection". Por exemplo, char *p é um ponteiro para char, char **p é um ponteiro para ponteiro para char, e assim por diante.

(Em particular, na declaração do método main, não se recomenda usar char **argv e sim const char *argv[], que representa melhor a intenção de termos um array de ponteiros para const char *. )

Exemplo:
#include <iostream>
#include <stdio.h>
using namespace std;

int main (int argc, char * argv []) {

  cout << "argc =" << argc << endl;
   for (int i = 0; i <argc; i++)
      cout << "argv [" << i << "] =" << argv [i] << endl;
   return 0;
}
1) Entrar com os parâmetro no compilador Div C++
Execute > Parameters... > 10 20
2) Compile & Run:
argc =3
argv [0] =C:\testec\teste2.exe
argv [1] =10
argv [2] =20


Exemplo: Teste.cpp

#include <stdio.h>
#include <cstdlib>
#include <conio.h>

int main( int argc, char *argv[ ] )
{
  int Resultado, valorA=0, valorB=0;
    printf("\nMultiplicando valores passados na linha de comando\n");    
    //atoi converte de alfanumérico to (para) inteiro 
    valorA = atoi(argv[1]);   
    valorB = atoi(argv[2]);   
    Resultado = valorA * valorB;   
    printf("\n%d  X %d = %d\n",valorA,valorB,Resultado);
    getch();
    return 0;
}

1) Entrar com os parâmetro no compilador Div C++
Execute > Parameters... > 2 3
2) Compile & Run:

Multiplicando valores passados na linha de comando

2  X 3 = 6

Obs: as funções utilizadas no programa dependem dos arquivos de inclusão (#include).

7. Breve introdução aos ponteiros

São variáveis cujo conteúdo é um endereço de memória. O tamanho depende da arquitetura do processador/S.O. A s variáveis ficam armazenadas em determinados espaços na memória do computador. Ao trabalhar com uma variável, geralmente não precisamos nos preocupar com o endereço desta variável, pois o compilador cuida destes “detalhes” técnicos. Entretanto, pode ser bastante útil saber o endereço de uma variável.
Em C++, utilizamos o operador de endereço & para acessar o endereço de uma variável.

Declaração, em ANSI C:
int *ponteiro;

O tipo indica o tipo do conteúdo armazenado no endereços apontato pela variável ‘ponteiro’, o asterisco (*) indica que a variável é um ponteiro.
Um ponteiro é um endereço de um objeto de dado de um tipo particular. Em outras palavras, ponteiros  nada mais são do que variáveis cujos valores são endereços de memória.

Para guardar valores em variáveis ponteiro, deve-se utilizar o "operador de endereço" & à frente de uma  variável e para ler o conteúdo que um ponteiro indica deve-se utilizar o operador unário asterisco * à frente do ponteiro. Portanto ponteiro só tem sentido quando está associado  a uma outra variável ou um objeto.

Um ponteiro (apontador, pointer) é um tipo especial de variável que armazena endereços.  Um ponteiro pode ter o valor especial NULL que não é o endereço de lugar algum.  A constante NULL está definida no arquivo-interface stdlib e seu valor é 0 na maioria dos computadores.

Desreferenciando um Ponteiro
Desferenciar um ponteiro significa acessar o valor que está armazenado no endereço de memória armazenado pelo ponteiro. Como já foi dito, esta operação é feita pelo operador * (que chamamos formalmente de “asterisco de indireção”). Assim como utilizamos o operador de endereço & para acessar o endereço de uma variável, utilizamos o asterisco de indireção para obter o valor que está dentro da posição de memória guardada pela ponteiro.

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;
int main( )
{
int var = 42;
int * ponteiro;
cout << "Valor da variável original: ";
cout << var <<endl;
ponteiro = &var;
cout << "Endereço apontado pelo ponteiro: ";
cout << ponteiro <<endl;
cout << "Valor guardado por este endereço: ";
cout << *ponteiro <<endl;
cout << "Valor atualizado do ponteiro!"<<endl;
*ponteiro = 12458;
cout << "Novo valor guardado por este endereço: ";
cout << *ponteiro <<endl;
cout << "Novo valor guardado pela variável original: ";
cout << var <<endl;

system("PAUSE > null");
return 0;
}

Compilar & Executar
Valor da variável original: 42
Endereþo apontado pelo ponteiro: 0x22ff08
Valor guardado por este endereço: 42
Valor atualizado do ponteiro!
Novo valor guardado por este endereço: 12458
Novo valor guardado pela variável original: 12458

Esta operação é útil para acessar e modificar valores dentro de posições de memória. Um ponteiro com o asterisco de indireção se comporta como uma variável comum. Podemos utilizá-lo em comandos, expressões, atribuições e onde mais for necessário.

Exemplo:
int *p; // ou int* p;
int *p, *r, *s;
double *q; // ou double* q;

Neste caso, "p" é um ponteiro para um inteiro e "q" é um ponteiro para um double.

Exemplo:
#include <stdio.h>

int main() {
  int a=10, *b, **c;
  b=&a;
  c=&b;
  printf("\n**c: %d", **c);
  getchar();
  return 0;
}
Compile & Run:
**c: 10
 
Em resumo:
*ponteiro1;
**ponteiro2;
Significa: ponteiro1 e ponteiro2 são variáveis do tipo ponteiro.
ponteiro1 = &var1;
Significa que o ponteiro1 recebe como valor o endereço de memória da variável var1, a impressão de ponteiro1 corresponde ao número de memória da variável var1.
ponteiro2=&ponteiro1;
Significa que o ponteiro2 recebe como valor o endereço de memória do ponteiro1, a impressão de ponteiro2 corresponde ao número de memória do ponteiro1, e ponteiro2 aponta para o ponteiro1.
*ponteiro1 = valor;
Significa declaração de ponteiro.

* O asterisco pega o valor (conteúdo) do direcionamento do ponteiro.
& O e-comercial pega o endereço de memória de uma variável

Observe o esquema abaixo:


Obtendo o endereço de memóvia de um ponteiro e de uma variável
Para obtendo o endereço de memória do ponteiro e da variável, deve-se declarar uma variável como ponteiro para receber o endereço de memória da variável e deve-se declarar um ponteiro do ponteiro para receber o endereço de memória do primeiro ponteiro.

Código fonte: arquivo.cpp
#include <stdio.h>
#include <stdlib.h>

using namespace std;
int main(int argc, char **argv) {
     int a ; // declaração da variável a
     int *p;  // declaração de uma variável do tipo ponteiro (endereço de memória)
     int **p2; // declaração de uma variável do tipo ponteiro do ponteiro (endereço de memória)
     p2 = &p;
     p = &a;
     printf("Endereço de p:%d\n",p2);
     printf("Endereço de a:%d\n",p);
     return 0;
}

Compile & Run:
Endereþo de p:2293524
Endereþo de a:2293528

Ou seja, para um ponteiro:
*nome: corresponde ao valor para o qual o ponteiro aponta
nome: corresponde ao endereço de memória do ponteiro

Exemplo:
Código fonte: arquivo.cpp
#include <stdio.h>
#include <stdlib.h>

using namespace std;
int main(int argc, char **argv) {
     int a = 20; // declaração e inicialização da variável a
     printf("Valor de a: %d\n",a);
     int *p;  // declaração de uma variável do tipo ponteiro (endereço de memória)
     p = &a;  // a variável p recebe o endereço da variável a (como valor, cada variável tem endereço de memória diferentes)
     printf("Endereco de a: %d\n",p);
     int **p2; // declaração de uma variável do tipo ponteiro do ponteiro (endereço de memória)
     p2 = &p;  // a variável p2 recebe o endereço do ponteiro *p (como valor, cada variável tem endereço de memória diferentes)
     printf("Endereço de *p:%d\n",p2);
     *p = 50;
     printf("Valor de *p: %d\n",*p);
     printf("O novo valor de a: %d\n",a);
     a=100;
     printf("O novo valor de a: %d\n",a);
     printf("O novo valor de *p: %d\n",*p);
     return 0;
}

Compile & Run:


Valor de a: 20
Endereco de a: 2293528
Endereþo de *p:2293524
Valor de *p: 50
O novo valor de a: 50
O novo valor de a: 100
O novo valor de *p: 100

Obsever o quadro abaixo:
Memória
Valor da Variável
Variável
2293528 20 a=20 a
2293524 2293528 p = &a *p
50
*p = 50 *p 

O primeiro esquema abaixo mostra que o valor do ponteiro *p é o endereço de memória da variável a, assim o valor de *p é o mesmo da variável a.
O segundo esquema abaixo mostra que o valor do pondeiro *p é o endereço de memória da variável a, e que a alteração do valor do ponteiro *p altera também o valor da variável a.


Pelo exemplo acima pode-se concluir que:
Um ponteiro pode ter como valor o endereço de mémória de outra variável;
Quando o valor de um ponteiro é o endereço de memória de outra variável, esse valor apontará para o valor dessa variável;
Quando o valor de um ponteiro é o endereço de memória de outra variável e o pondeiro recebe um valor, este valor será também recebido por essa outra variável;
Conclusão:
Um ponteiro pode ter dois endereço de memória, um que é o seu próprio e o outro que é de outra variável (como valor), assim se for mudado o valor da variável, também muda o valor do ponteiro, e se for mudado o valor do ponteiro também muda o valor da variável.
Perceba que o ponteiro tem dois valor, um que é a memória da variável que aponta para um dado valor e o outro que é o seu próprio valor, sendo que a mudança do valor da variável muda o valor apontado pelo ponteiro e a mudança do valor do ponteiro muda o valor da variável.
p=&a este é o valor do ponteiro (uma memória).
a muda *p e *p muda a.


Matrizes
O operador de endereço, &,  é utilizável também em matrizes. Quando utilizamos este operador em uma matriz, temos o endereço inicial da matriz, que nada mais é do que o endereço do primeiro elemento da matriz. Também podemos utilizar o operador & para acessar os endereços de cada elemento de uma matriz.

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
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;
}

Compilar & Executar
0x22fef4 : 42
0x22fef8 : 37
0x22fefc : 28

Tipo
O tipo é essencial para a utilização de objetos de dados designados pelo endereço. O endereço  simplesmente dá a posição de memória inicial que contém o objeto de dado. O tipo determina o tamanho do objeto de dado, e as funções e operadores que podem ser aplicados a ele. Assim, não se tem apenas um único  tipo de ponteiro para todos os endereços. Tem-se um tipo de "ponteiro-para-int" para endereçar objetos de dados inteiros, um tipo "ponteiro-para-double" para endereçar objetos de dados double e assim por diante.

Operador
O operador unário "*" é chamado de "operador indireto", uma vez que ele permite que um objeto de dado
seja referenciado indiretamente, através de um identificador nomeando uma variável ponteiro, ao invés de
diretamente, através de um identificador nomeando o próprio objeto de dado. O termo ponteiro é aplicado tanto a variáveis ponteiro como aos endereços que elas contêm; o contexto no qual a palavra é usada determina quando  significa uma variável ponteiro ou um valor de ponteiro (endereço).

Pode-se usar ponteiros para dar às funções acesso a variáveis passadas como argumentos. Por
exemplo, suponha que queira-se escrever uma função que troque os valores de duas variáveis inteiras. Assim,  depois do comando swap (i, j);
ser executado, "i" terá o valor de "j", e "j" terá o valor anterior de "i". Em C e C++ argumentos são passados por valor somente se os valores atuais dos argumentos são apenas transmitidos para a função.
Por outro lado, ponteiros são valores e podem ser passados para funções. Se forem passados os  ponteiros para a função "swap", esta poderá usá-los para acessar as variáveis e trocar seus valores. Assim, declara-se "swap()" para ter dois "ponteiro-para-int" como argumentos:

void swap (int* p, int* q);
Quando chama-se a função, deve-se passar para ela ponteiros para as variáveis cujos valores deseja-se trocar.
Pode-se fazer isso com a ajuda do operador de endereço. O comando swap (&i, &j);
chama a função e passa os endereços de "i" e "j" como argumentos. A definição de "swap" é apresentada a seguir.

void swap (int* p, int* q) {
 int temp = *p; // salva o valor de p
 *p = *q; // atribui q para p
 *q = temp; // q recebe valor inicial de p }

Variáveis passadas para a função desta maneira são chamadas de variáveis passadas por referência,
porque referências para as variáveis (isto é, ponteiros para elas) são passadas ao invés de valores de variáveis.
 
Ponteiros também podem ser usados para "apontar" para estruturas. Por exemplo:
struct date {
 int day;
 int month;
 int year;
}
date dt; // variável dt
date* pdt = &dt; // ponteiro para dt
 
Neste caso, pode-se referir aos membros da variável "dt" diretamente, da seguinte maneira:
"dt.day"
"dt.month" e
"dt.year"
Também pode-se referir aos membros da variável indiretamente, através do ponteiro "pdt":
"(*pdt).day"
"(*pdt).month" e
"(*pdt).year".
Os parênteses são necessários porque o operador "." tem maior  precedência. Como estas expressões ocorrem freqüentemente, C++ fornece um operador de acesso indireto, "->", para simplificá-las. Assim, a expressão "pdt->day" é equivalente a "(*pdt).day".
 
Torna-se interessante comentar que o C++ acrescentou algumas características à sintaxe de ponteiros.
Basicamente, foi acrescentado o tipo void para ponteiros e ampliado o conceito const, associando-o aos
ponteiros. Para declarar um ponteiro void, a sintaxe é a mesma da declaração de qualquer tipo, ou seja, o tipo seguido do operador "*":

void * <nome_ponteiro>;

Exemplo:
void * ptr;
A diferença para os demais ponteiros está no fato de que o ponteiro void pode apontar para qualquer tipo de dados, inclusive o NULL. O C++ permite que se acesse o conteúdo apontado por um ponteiro genérico somente após ele ser formatado, isto é, eles não podem ser referenciados sem um casting explícito, porque o compilador não pode determinar o tamanho do objeto para o qual ele está apontando. No entanto, pode-se atribuir outros ponteiros a um ponteiro void ou atribuir o valor dele a um ponteiro comum. A motivação para a criação de ponteiros void está no fato de se poder especificar funções de propósito geral cujo parâmetro é um ponteiro a formatar em tempo de execução. Baseando-se em critérios internos da função (provavelmente um flag especificando o tipo), este ponteiro pode ser modelado, de modo a apontar para o tipo adequado. Exemplos:

Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;
int main (void) {
int *nullPointer;
nullPointer = NULL;
cout << nullPointer << endl;
system ("pause");
return EXIT_SUCCESS;
}

Compilar & Executar
0
Pressione qualquer tecla para continuar. . .

Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;

int main (void) {
void *ptr;
int *ptrVar1, var1 = 10;
float *ptrVar2, var2 = 50.123;
ptr = &var1; // ponteiro aponta para um inteiro
ptrVar1 = (int*) ptr; // typecasting: ponteiro genérico p/ inteiro
cout << *ptrVar1 << endl;
ptr = &var2; // o mesmo ponteiro aponta agora para um float
ptrVar2 = (float*) ptr; // typecasting: ponteiro genérico p/ float
cout << *ptrVar2 << endl;
system ("pause");
return EXIT_SUCCESS;
}
Compilar & Executar
10
50.123
Pressione qualquer tecla para continuar. . .

Em C++ pode-se definir ponteiros para constantes (apontadores cujo conteúdo é imutável), ponteiros constantes (apontadores que não mudam o endereço apontado) e ponteiros constantes para valores constantes.
O primeiro tipo é usado quando deseja-se que o conteúdo de um ponteiro fique inalterável durante o processamento de um programa. Neste caso utiliza-se a seguinte sintaxe:

const <tipo_a_apontar> * <nome_ponteiro>;

Exemplo:
const char *string = "Eu sou uma constante!";

Ponteiros constantes são usados quando há interesse em que um determinado endereço de memória  seja sempre localizado por um certo ponteiro, independente do valor nesse endereço. Nesses casos quem deve
ser constante é o ponteiro, e não seu conteúdo. A sintaxe para ponteiro constante é a seguinte:

<tipo_a_apontar> *const <nome_ponteiro>;

Exemplo:
char * const msg = "Meu pontero eh constante!";

Neste caso, a string "Meu ponteiro eh constante!" pode ser modificada, mas qualquer nova frase colocada sobre ela terá sempre o ponteiro "msg" a indicá-la. O compilador não permitirá que se aponte "msg" para outro local de memória, mesmo que lá esteja um char.
 
Também é possível desejar-se a total segurança de determinados dados declarando seu valor como  constante e ajustando um ponteiro constante para o endereço onde estará esse valor. Para tal, utiliza-se ponteiro constante para constante através da seguinte sintaxe:

const <tipo_a_apontar> *const <nome_ponteiro>;

Exemplo:
const char * const msg = "Todos somos constantes!";

Quando tanto o ponteiro quanto o valor apontado são constantes, o compilador "congela" ambos e não permite nem modificações no conteúdo do ponteiro, nem no local de memória para o qual ele aponta. No exemplo, a string "Todos somos constantes!" é inalterável e será sempre encontrada pelo igualmente imutável ponteiro "msg".
 
Uma referência consiste em um apelido (alias) de uma variável, ou seja, apesar de possuírem nomes  distintos, uma referência e sua variável de inicialização ocupam o mesmo endereço de memória. A modificação de uma afeta a outra. A principal utilidade de uma referência é melhorar a sintaxe de manipulação de parâmetros por referência.
A sintaxe de declaração de referência é a seguinte:

<tipo> &refer = var;

onde a referência "refer" constitui uma segunda forma de chamar a variável "var". Por exemplo, "int &" é um tipo "referência-para-int", "double &" é um tipo "referência-para-double", e assim por diante. Como regra geral, uma referência deve ser sempre inicializada na sua declaração, depois ela serve como outro nome para aquele objeto de dado.

Por exemplo, suponha a declaração de uma variável inteira "n":
int n = 10;
e a declaração da referência "r" através de
int& r = n;
Tanto "n" quanto "r" designam o mesmo objeto de dado, que pode ser referenciado pelos dois "nomes". Assim, a atribuição "n = 20;" altera o valor de "r" e "n" para 20, da mesma maneira que "r = 15;" altera o valor de "r" e "n" para 15.

É interessante observar que a inicialização e a atribuição são completamente diferentes para referências. A inicialização estabelece uma correspondência entre a referência e objeto de dados. A atribuição, que é igual para referência e outra variável/valor, somente atribui um novo valor para um determinado objeto de dado.
Também deve-se ter em mente que uma referência não é uma cópia nem um ponteiro para uma variável. trata-se da própria variável com nome diferente. A principal vantagem é mesmoa passagem de parâmetros por referência, dai, inclusive, o nome deste tipo de variável.

Ponteiros para Ponteiros
C/C++ nos permite criar, também, ponteiros com níveis de apontamento. O que isso quer dizer? Simples. É possível criar um ponteiro que aponte para outro ponteiro, criando assim níveis, pois um ponteiro poderá apontar para outro ponteiro, que, por sua vez, aponta para outro ponteiro, que aponta para um ponteiro diferente e assim por diante.

A sintaxe para se criar ponteiros para ponteiros é a mesma de ponteiros comuns, apenas a forma de acessar seus valores é diferente, pois para cada nível de apontamento usaremos um dereferenciador. Por exemplo, se um ponteiro aponta para um ponteiro que aponta para um valor inteiro, para acessarmos esse valor inteiro a partir do primeiro ponteiro usaríamos dois asteríscos (**), ao invés de apenas um (*).
Isso se dá ao fato que um ponteiro pode mudar o valor de outro ponteiro de acordo com seu nível.

O exemplo abaixo demonstra uma sintaxe simples.

#include <iostream> //biblioteca para o Cout e Cin como elementos de leitura e escrita de variáveis
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;
 
int main (void) {
int a=10, b=50;
int *ptr;      // ponteiro de inteiro
int **ptrPtr;  // ponteiro de um ponteiro inteiro
ptr = &a;
ptrPtr = &ptr;
cout << "O valor final de ptrPtr e " << **ptrPtr << endl;
system("pause");
return EXIT_SUCCESS;
}

Compile & Run:

O valor final de ptrPtr e 10
Pressione qualquer tecla para continuar. . .

O código acima contem duas variáveis inteiras (a e b) inicializados com os valores 10 e 50 respectivamente. Logo após, há uma variável de ponteiro (*ptr) e uma variável de ponteiro para ponteiro (**ptrPtr).

Então, atribuimos o endereço da variável inteira a em *ptr. Agora *prt aponta para a. Após isso, atribuimos o endereço do ponteiro *ptr ao ponteiro **ptrPtr. Neste momento **ptrPtr passa apontar para *ptr.


Entendendo os Níveis de Apontamento
Quando usamos ponteiros de ponteiros podemos usar os níveis de apontamento que são determinados pelo número de asteriscos que precedem o ponteiro.

Portanto, se um ponteiro aponta para um ponteiro que também aponta para um ponteiro que contem um endereço de uma variável char, usaríamos neste caso três asteríscos.

#include <iostream> //biblioteca para o Cout e Cin como elementos de leitura e escrita de variáveis
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;
 
int main (void) {
char letra='a';
char *ptrChar;
char **ptrPtrChar;
char ***ptrPtr;
ptrChar = &letra;
ptrPtrChar = &ptrChar;
ptrPtr = &ptrPtrChar;
cout << "O valor final de ptrPtr e " << ***ptrPtr << endl;
system("pause");
return EXIT_SUCCESS;
}

8. Equivalência entre comandos pseudo-código, C e C++

Pseudo-código
C
C++
Leia(A)
A inteiro:
A real:
A caracter:
A string:
 
scanf("%d",&A);
scanf(“%f”,&A);
scanf(“%c”,&A);
scanf(“%s”,&A);
cin >> A;
Leia(A,B,C,D) A inteiro, B real, C caracter e D string scanf("%d %f %c %s",&A,&B,&C,&D); cin >> A >> B >> C >> D;
ou
cin >> A >> B >> C;
getline(cin,D);
Escreva(A,B,C,D) A inteiro, B real, C caracter e D string


printf("%d %f %c %s",A,B,C,D);
printf("%d %f %c %s\n",A,B,C,D);
cout << A << " " << B << " "
<< C << " " << D; ou
cout << A << " " << B << " "
<< C << " " << D << endl;
printf("%4d",A);  cout << setw(4) << A;
printf("\n");  cout << endl;
printf("\n"); cout << "\n";
Obs: quando o programa é executado, ao encontrar o comando Leia (A) o mesmo para e fica esperando a entrada do valor da variável A.

Comandos de sequência (incluindo atribuição), seleção e repetição são idênticos entre C e C++. O mesmo se aplica à aritmética e prioridade de operadores (lógicos, relacionais e aritméticos).

Exemplo C

Arquivo: Teste.c

#include <stdio.h>
/* Algoritmo Conversão. Este algoritmo lê uma temperatura na escala Celsius (ºC) e imprime a equivalente em Fahrenheit (ºF).
*/

void main(void) {
    float C, F;
    /* um comentário até o final da linha */
    printf("Temperatura em graus Celsius?");
    scanf("%f",&C);
    F = 9.0 / 5.0 * C + 32;
printf("\nTemperatura em graus Fahrenheit=%f\n",F);
if(C > 25)
printf("Muito quente\n");
else
printf("Agradável\n");
}

Compile & Run:
Temperatura em graus Celsius?120 <enter>

Temperatura em graus Fahrenheit=248.000000
Muito quente


Arquivo: Teste.cpp

Exemplo em C++

#include <iostream>
using namespace std;
/* Algoritmo Conversão. Este algoritmo lê uma
 temperatura na escala Celsius (ºC) e imprime a
 equivalente em Fahrenheit (ºF).
 */
int main() {
    float C, F;
// impressão da frase
    cout << "Temperatura em grau Celsius? ";
    cin >> C;
    F = 9.0 / 5.0 * C + 32;
    cout << "\nTemperatura em graus Fahrenheit= " << F << endl;
    if(C > 25)
    cout << "Muito quente\ n";
    else
    cout << "Agradável" << endl;
    return 0;
}

Compile & Run:
Temperatura em grau Celsius? 100 <enter>

Temperatura em graus Fahrenheit= 212
Muito quente


9. Entrada/Saída com streams
9.1. Objeto cout
(c + out)
O objeto cout representa o stream de saída no C++. Este stream é uma espécie de seqüência (fluxo) de dados a serem impressos na tela.
Para realizar a impressão, usa-se o operador de inserção, <<, que "insere" dados dentro do stream.
 
<< Operador de Inserção
cout << "frase";

O operador << sobrecarregado executa a saída (imprime na tela) de streams em C++.  O objeto cout é usado em conjunto com ele para a impressão de dados.

Arquivo: teste.cpp
#include <iostream>
using namespace std;
int main()
{
  cout << "Imprimindo uma frase.\n";

  // imprimindo uma linha usando múltiplos comandos
  cout << "Teste com ";
  cout << "dois couts\n";

  // usando o manipulador endl
  // endl gera um caractere nova linha, e também descarrega o buffer de saída
  cout << "Escrevendo uma linha..." << endl;

  cout << "Mais uma vez...\n";
  cout << flush;    // agora apenas esvaziando o buffer de saída, sem gerar nova linha

  return 0;
}

Compile & Run:
Imprimindo uma frase.
Teste com dois couts
Escrevendo uma linha...
Mais uma vez...

<< sempre retorna uma referência ao objeto cout. Desta forma, é possível encadear vários cout, permitindo uma combinação de constantes e variáveis, como mostra o exemplo abaixo:

Arquivo: teste.cpp
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int b = 12;
// imprime uma string e o resultado da soma entre as variáveis a e b
cout << "Encadeando saídas: Somandos dois números " << a + b << endl;

  return 0;
}

Compilar & Executar
Encadeando saídas: Somandos dois números 22

A saída de caracteres também pode ser feita sem o uso do operador de inserção <<. Para isto, usa-se a função membro put, que retorna uma referência para o objeto cout.

cout.put('frase');

A função put não é igual a cout<<, que exibe um valor char como um caractere e um valor int como um número. Já a função cout.put() exibe ambos os dados como caracteres.

Exemplo:

Arquivo: Teste.cpp
#include <iostream>
#include <stdio.h>

using namespace std;

int main (int argc, char *argv[]) {
  char name[7] = "geeks";
  cout.put (name[0]);
  getchar();
  return 0;
}

Compile & Run:
g

Obs:

cout.put('caractere');    // fazendo a saída de um único caractere
cout.put('caractere').put('\n');    // fazendo a saída encadeada


Exemplos:

#include <iostream>
#include <stdio.h>
using namespace std;

int main (int argc, char * argv []) {
   cout << "argc =" << argc << endl;
   for (int i = 0; i <argc; i++)
      cout << "argv [" << i << "] =" << argv [i] << endl;
   return 0;
}

Compilar & Executar
argc =1
argv [0] =C:\testec\teste2.exe

9.2. Objeto scanf()
Este objeto é utilizado para entrada de dados para o C.
Suponho que queiramos pedir um inteiro ao usuário, primeiro temos que declarar um inteiro. Vamos supor um de nome 'numero'.
Para o usuário armazenar um número nessa variável 'numero', usamos a seguinte sintaxe:

scanf("%d", &numero);

Essa função nos diz "armazene na variável 'numero' um inteiro".

Por exemplo, vamos escrever um programa em C que pede um número ao usuário e o mostra na tela:

Arquivo: teste.c
#include <stdio.h>

int main()
{
    int numero;
    printf("Digite um numero: ");
    scanf("%d", &numero);

    printf("O numero digitado foi: %d", numero);
}

Compilar e Executar
Digite um numero: 12
O numero digitado foi: 12

Existe uma função que faz o mesmo papel da scanf e é voltada para o uso com caracteres, é a getchar().
Ela é mais simples, pois não precisar usar %c ou &, como fazemos na scanf(), e foi feito especialmente para ser usado com caracteres.

Para usar, fazemos:
seu_caractere = getchar();

Veja como é seu uso em um código que pede um caractere para o usuário, armazena no char 'letra', e em seguida exibe esse mesmo caractere.

Arquivo: teste.c

#include <stdio.h>

int main()
{
    char letra;

    printf("Insira um caractere: ");
    letra = getchar();
    printf("Você digitou: '%c'", letra);
}

Compilar & Executar
Insira um caractere: a
Você digitou: 'a'

9.2.1. O problema de usar scanf, getchar, getc e fgetc para receber caracteres em C


"Ora, é só declarar duas variáveis char e usar a scanf duas vezes, uma para cada variável", é que você deve ter pensado para criar o tal programa.

Vamos fazer isso então, e ver o resultado:

#include <stdio.h>

int main()
{
    char letra1, letra2;

    printf("Insira um caractere: ");
    scanf("%c",&letra1);

    printf("Insira outro caractere: ");
    scanf("%c",&letra2);

    printf("Você digitou: '%c' e '%c'", letra1, letra2);
}

Compile & Run:
Insira um caractere: M <enter>
Insira outro caractere: Você digitou: 'M' e '
'

Foi digitado 'M', foi dado enter, e antes de digitar a próxima letra o progarma terminou, exibindo a seguinte mensagem:
"Você digitou: 'M' e '
'"

Note que digitei 'M' e <enter>, porém <enter> também é uma tecla, e é representada por '\n'. Ou seja, o C entendeu que nossa segunda letra era o enter!

A solução para isso é bem simples.
Na função scanf, dê um espaço entre a aspa " e o símbolo %c.
Nosso código fica assim:

#include <stdio.h>

int main()
{
    char letra1, letra2;

    printf("Insira um caractere: ");
    scanf("%c",&letra1);

    printf("Insira outro caractere: ");
    scanf(" %c",&letra2);

    printf("Você digitou: '%c' e '%c'", letra1, letra2);
}

Compile & Run:
Insira um caractere: M <enter>
Insira outro caractere: N <enter>
Você digitou: 'M' e 'N'

 
9.3. Objeto cin (c + in)
O objeto cin representa o stream de entrada no C++. Ele realiza a leitura de um seqüência de dados, sem espaços e sem tabulações, vindas do teclado.
Para coletar estes dados armazenados, usa-se o "operador de extração" que "extrai" dados do stream.

>> Operador de Extração
cin >> "Frase";

O operador >> sobrecarregado executa a entrada com streams em C++, usando o comando cin para aquisição de dados. Variáveis podem ser usadas para o armazenamento das informações.

#include <iostream>
using namespace std;
int main()
{
  int Num1;
  int Num2;
  cout << "Lendo o primeiro número...: ";
  cin >> Num1;
  cout << endl;
  cout << "Lendo o segundo número....: ";
  cin >> Num2;
  cout << endl;

  return 0;
}

Compile & Run:
Lendo o primeiro número...: 10

Lendo o segundo número....: 11

Obs: A entrada de dados e sua saída automáticamente dentro do comando cout
cout << "....: ";
cin >> Num2;
...
cout << endl;

Encadeamento de vários cin
Da mesma forma que o operador de inserção, >> sempre retorna uma referência ao objeto cin, permitindo o encadeamento de vários cin. Exemplo:

float c;
float d;
cin >> c >> d;    // entra com um float, pressiona <ENTER>, entra com outro float, pressiona <ENTER>

Outras peculiaridades usando o operador de extração:

while(cin >> dado)    // repete enquanto o usuário não digitar fim de arquivo (Ctrl+Z ou Ctrl+D)

cin.eof();            // devolve 1 (verdadeiro) se chegou ao fim do arquivo

char c;
c = cin.get();
cin.get(vet, n, '\n');
char nome[100];
cin >> nome;            // lê até o 1º espaço em branco apenas
cin.get(nome, 100);     // lê até o 99º caractere ou <ENTER>
cin.get(nome, 100, 'x');
/* get sempre insere um NULL no final da seqüência lida.
   O delimitador não é retirado da entrada. Isto faz com que a próxima leitura devolva este caractere (no caso, uma linha será devolvida. */

cin.getline(nome, TAM);    // remove o delimitador do buffer automaticamente

cin.putback();        // recoloca o último caractere lido de volta no buffer
 
9.4. Entrada/Saída segura quanto ao tipo

Quando dados inesperados são processados pelos operadores << e >>, vários indicadores de erros podem ser ativados para indicar se houve sucesso ou falha em uma operação de E/S.
O exemplo abaixo apresenta alguns deles:

int dado;
cin.eof();         // retorna verdadeio ser o fim do arquivo foi encontrado
cin >> dado;       // lê um inteiro
if(cin.bad()) {    // houve uma falha na leitura
  // ...
}
if(cin.fail()) {   // dado digitado incompatível com o dado esperado
  // ...
}
if(cin.fail()) {   // estado da stream está OK
  // ...
}

ou usando

ios::eofbit
ios::badbit
ios::failbit
ios::goodbit
cin.clear();      // reseta o estado de stream, ativando "goodbit"
 
9.5. Manipuladores de streams

Executam tarefas de formatação, por meio de diferentes recursos. Alguns deles estão abaixo destacados:
Base do stream de inteiros

#include <iomanip>
#include <iostream>
using namespace std;
// ...
cin >> n;
cout << hex << n << endl            // apresenta n em hexadecimal
     << oct << n << endl            // apresenta n em octadecimal
     << setbase(10) << n << endl;   // apresenta n na base 10
// ...

Precisão em ponto flutuante:

double PI = 3.14159265;

cout.precision(5);    // define a precisão
cout << setiosflags (ios::fixed) << f << endl;
cout << PI;           // imprime PI com 5 casas decimais
ou
cout << setiosflags (ios::fixed) << setprecision(5) << PI;    // define e imprime PI com 5 casas decimais

Para retornar ao formato de impressão padrão:

  cout << setiosflags (ios::scientific);
  cout << f << endl;

Largura de campo:
Para definir a largura da impressão de uma variável usa-se o setw(n), onde n é o número de caracteres desejado para a impressão desta variável.
Note que o setw só afeta a próxima variável do cout.

int caixas = 45;
cout << "Número de caixas: " << setw(10) << caixas << endl;

Alinhamento da impressão
É possível alinhar os dados impressos tanto à esquerda quanto à direita, com os manipuladores left e right.

cout  << right <<  10;
cout  << left <<  10;

Exemplo:
#include <iostream>
#include <stdlib.h>


using namespace std;
using std::cout;
using std::endl;


int main(int argc, char *argv[])
{
    string s1, s2;
   
  int i,j;
  cout << "Ola'!" << endl;
  cin >> s1;
  cout << "String lida 1:" << s1 << "*" << endl;
  cin >> s2;
  cout << "String lida 2:" << s2 << "*" << endl;
 
  getline(cin, s1); // pega o enter que ficou no buffer
  getline(cin, s1); // permite a leitura de uma string com espaços em branco
 
  cout << "String lida 3:" << s1 << "*" << endl;
  system("PAUSE");   
  return 0;
}

/*
Ola'!
um teste <enter>
String lida 1:um*
String lida 2:teste*
outro teste  <enter>
String lida 3:outro teste*
Press any key to continue . . .
*/

Entrada de Strings

Em determinadas ocasiões, deseja-se coletar dados que contenham strings com tabulações, espaços em branco e/ou novas linhas. Frases são exemplos onde este tipo de situação ocorre. No entanto, o operador >> sobrecarregado ignora tais caracteres.

Para englobar essas situações, C++ oferece o uso da função-membro getline. Esta função remove o delimitador do stream (isto é, lê o caractere e o descarta) e armazena o mesmo em uma variável definida pelo usuário.

Abaixo, um exemplo de sua utilização.
 
#include <iostream>
using namespace std;
int main()
{
  const int TAM = 80;
  char guarda[TAM];
  cout << "Digite uma frase com espaços: " << endl;
  cin.getline(guarda, TAM);
  cout << "A frase digitada é: \n" << guarda << endl;
  return 0;
}

Compilar & Executar:
Digite uma frase com espaços:
Uma frase com espaços. <enter>
A frase digitada é:
Uma frase com espaços.


Exemplo:
Arquivo: Exemplo.cpp
#include <iostream>
#include <stdlib.h>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
using std::cout;
using std::endl;


int main(int argc, char *argv[])
{
    string s1, s2;
   
  int i,j;
  cout << "Ola'!" << endl;
  cin >> s1;
  cout << "String lida 1:" << s1 << "*" << endl;
  cin >> s2;
  cout << "String lida 2:" << s2 << "*" << endl;
 
  getline(cin, s1); // pega o enter que ficou no buffer
  getline(cin, s1); // permite a leitura de uma string com espaços em branco
 
  cout << "String lida 3:" << s1 << "*" << endl;
  system("PAUSE");   
  return 0;
}

Compilar & Executar:
Ola'!
Palavra1
String lida 1:Palavra1*
Palavra2
String lida 2:Palavra2*
Frase com muitas palavras.
String lida 3:Frase com muitas palavras.*

Observe que:
getline(cin, s1): pegou o enter que ficou no buffer
getline(cin, s1): permite a leitura de uma string com espaços em branco, ou seja, frase.

Exemplo:
Arquivo: Exemplo.cpp
#include <iostream>
#include <stdlib.h>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
using std::cout;
using std::endl;

int main(int argc, char *argv[])
{
  string s1;
  getline(cin, s1); // permite a leitura de uma string com espaços em branco
 
  cout << "Frase:" << s1 << endl;
  system("PAUSE");  
  return 0;
}

Compilar & Executar
Varias palavras em uma frase.
Frase:Varias palavras em uma frase.

Exemplo:
Arquivo: Exemplo.cpp
#include <iostream>
#include <stdlib.h>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
using std::cout;
using std::endl;

int main(int argc, char *argv[])
{
    string s1, s2;
   
  int i,j;
  cout << "Ola'!" << endl;
  getline(cin, s1);
  cout << "String lida 1:" << s1 << "*" << endl;
  getline(cin, s2);
  cout << "String lida 2:" << s2 << "*" << endl;

  getline(cin, s1, '&'); // para a leitura no '&'
  // note que o caracter '&' NÃO vai para 's1'
  cout << "String lida 1:" << s1 << "*" << endl; // deu erro, não saiu

  system("PAUSE");   
  return 0;
}

Compilar & Executar:
Olá!
Primeira entrada
String lida 1:Primeira entrada*
Segunda entrada
String lida 2:Segunda entrada*
Terceira entrada

10. Constantes Simbólicas em C/C++
Frequentemente, uma mesma constante é utilizada em várias partes de um programa. Para facilitar o entendimento, pode-se declarar uma constante simbólica, ou seja, uma constante com um nome associado. Em C++, a declaração de constantes simbólicas é efetuada por meio do modificador const. Por exemplo:
const int Max = 100;
const int N = 8;
É óbvio que não é permitido alterar o valor de uma constante. Considere o seguinte fragmento de código C++:

Sem uso de constante simbólica
int n,i,v[11],s[10];
cin >> n;
if (n > 10)
{ cout << "muito grande" << endl;
abort();
}

Com uso de constante simbólica
const int max = 10;
int n,i,v[max+1],s[max];
cin >> n;
if (n > max)
{ cout << "muito grande" << endl;
abort();
}

Observe que o uso de constantes simbólicas melhora o entendimento do código, além de facilitar qualquer alteração da dimensão dos vetores v e s: basta apenas alterar o valor definido pela constante simbólica max.
A linguagem C não tem constantes simbólicas; entretanto, isso normalmente é solucionado com diretivas do préprocessador (e não da linguagem C em si). O mesmo fragmento anterior poderia ser assim definido:

#define max 10
int n,i,v[max+1],s[max];
scanf(&n);
if (n > max)
{ printf("muito grande\n");
abort();
}

11. Passagem de parâmetros em C++
Em cada chamada de um procedimento ou função, uma correspondência é estabelecida entre os argumentos (ou parâmetros) da chamada particular e os parâmetros (ou argumentos) de definição do sub-algoritmo. Existem duas formas de executar essa correspondência:
Passagem de parâmetros por valor
Ao ser efetuada uma chamada de sub-algoritmo, os parâmetros passados por valor são calculados e seus valores são atribuídos aos parâmetros de definição; ou seja, os valores são copiados para os parâmetros de definição. Quaisquer alterações (nos valores das variáveis passadas por valor) efetuadas dentro do subalgoritmo não causam alterações nos parâmetros de chamada.

Passagem de parâmetros por variável (ou por referência ou por endereço)
Na passagem por variável, ao ser efetuada uma chamada de sub-algoritmo, os endereços dos parâmetros de chamada são passados aos parâmetros de definição, ou seja, a própria variável de chamada é passada. Quaisquer alterações (das variáveis passadas por referência) efetuadas dentro do sub-algoritmo causam a alterações nos parâmetros de chamada.

Em C++ a escolha de passagem por valor ou por variável é efetuada apenas na definição de cada parâmetro (nenhuma sintaxe adicional é necessária na chamada dos parâmetros).

Parâmetros passados por valor são declarados como variáveis comuns:
float f1(int a, float b, int c)
Os parâmetros a, b, c são passados por valor.

Parâmetros passados por referência devem ser precedidos pelo símbolo & antes do nome do parâmetro:
float f2(int &a, float b, double &c)
Os parâmetros a e c são passados por referência, parâmetro b é passado por valor

void p2(int &n, float a[])
O parâmetros n, a são passados por referência (a é do tipo vetor).

A linguagem C não abstrai o tipo de passagem de parâmetros por referência da mesma forma que a linguagem C++. Em C, os parâmetros passados por referência precisam ser declarados como ponteiros para o respectivo tipo de dados (usando *) e na chamada é necessário passar o endereço do parâmetro (usando &).

Passagem por Valor em C
Exemplo:
Arquivo: teste.c
#include <stdio.h>
void soma1(int X)
{ X = X + 5;
printf("%d\n",X);
}
int main()
{ int A;
A = 2;
soma1(A);
printf("%d\n",A); // observe que nesta linha o compilador Div-C entendeu que a variável A não mudou
return 0;
}
Compilar & Executar
7
2

Exemplo:
Pequena variação do exemplo anterior.
Arquivo: teste.c
#include <stdio.h>
int soma1(int X)
{
return X = X + 5;
}
int main()
{
int A,B;
A = 2;
B=soma1(A);
printf("%d\n",A); // observe que nesta linha o compilador Div-C entendeu que a variável A não mudou
printf("%d\n",B);
return 0;
}
Compilar & Executar
2
7


Passagem por Valor em C++

Exemplo:
Arquivo: teste.cpp
#include <iostream>
using namespace std;
void soma1(int X)
{ X = X + 5;
cout << X << endl;
}
int main()
{ int A;
A = 0;
soma1(A);
cout << A << endl; // observe que nesta linha o compilador Div-C entendeu que a variável A não mudou
return 0;
}
Compilar & Executar
5
0

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib>
using namespace std;
 
int somar (void){
int a, b, resultado;
cout <<"Digite um numero:\n";
cin >> a;
cin.ignore ();
cout <<"Digite mais um numero:\n";
cin >> b;
cin.ignore ();
resultado=a+b;
return resultado; //valor que será retornado
}
 
int main (void){
int resultadoDaFuncao;
resultadoDaFuncao= somar(); //gravando o resultado da função em uma variável
cout <<"\nO resultado da funcao e "<<resultadoDaFuncao<<"\n";
system ("pause");
return EXIT_SUCCESS;
}

Compilar & Executar
Digite um numero:
<enter>
Digite mais um numero:
<enter>

O resultado da funcao e 6


Passagem por Referência em C
Exemplo:

Arquivo: teste.c
#include <stdio.h>
void soma2(int *X)
{ *X = *X + 5;
}
int main()
{ int A;
A = 0;
soma2(&A);
printf("%d\n",A);
return 0;
}
Compilar & Executar
5

Passagem por Referência em C++
Exemplo:
Arquivo: teste.cpp
#include <iostream>
using namespace std;
void soma2(int &X)
{ X = X + 5;
}
int main()
{ int A;
A = 0;
soma2(A);
cout << A << endl;
return 0;
}
Compilar & Executar
5

Em C/C++ vetores e matrizes sempre são passados por variável e o símbolo & é omitido.
É desnecessário informar o tamanho dos vetores usados como parâmetros.
Para matrizes é necessário declarar o tamanho de todas as dimensões exceto a primeira.


12. Regras de Escopo de Identificadores
Um identificador consiste em um nome de variável, tipo de dado, sub-algoritmo ou constante simbólica. O escopo de um identificador é a região do programa na qual ele pode ser referenciado.
Parâmetros e variáveis locais de um sub-algoritmo só podem ser referenciados diretamente dentro do próprio sub-algoritmo; nenhum outro sub-algoritmo pode fazer referência a eles
Os parâmetros e as variáveis definidas em um sub-algoritmo são variáveis locais
Uma variável local é criada (alocada na memória) no momento em que o sub-algoritmo que a define é chamado.
Uma variável local é liberada da memória no momento em que o sub-algoritmo que a define termina.
O escopo de uma variável local é dentro do sub-algoritmo que a define.
Caso um mesmo identificador (nome de variável) seja declarado em sub-algoritmos distintos, esses identificadores são considerados distintos entre si (variáveis distintas).
O uso de variáveis locais minimiza a ocorrência de "efeitos colaterais" em programação: o programador pode definir e utilizar as variáveis que desejar em um sub-algoritmo sem interferir com outros subalgoritmos.
As variáveis definidas na "camada" mais externa de um programa são denominadas globais e têm sua existência durante toda a execução do programa.
O uso de variáveis globais deve ser evitado, pois elas podem ser alteradas por quaisquer sub-algoritmos.

13. Estrutura do código
Regras
a) Arquivos include, em C++, tem a extensão .hh (exceção: <iostream>).
b) Arquivos de implementação, em C++, sempre tem a extensão .cc ou .cpp.
c) Arquivos especificados em definição inline tem a extensão .icc

Recomendações:
a) Um arquivo include não deve conter mais que uma definiçào de classe.
b) Divida a definição de funções membro, ou de funções , em tantos arquivos quanto possível.
c) Ponha o código dependente-da-máquina em um arquivo especial, para que seja facilmente localizável quando portar o programa de uma máquina para outra.

O objetivo dessas convenções é permitir uma interpretação uniforme dos nomes de arquivos. Uma das razões para isso é permitir a criação de ferramentas que baseiam seu comportamento na extensão dos nomes de arquivos.

Há dois tipos de arquivos include em C++: aqueles que contem código aceito tanto pelos compiladores ANSI-C quanto pelos compiladores C++, e aqueles que contem código aceito apenas pelos compiladores C++. É apropriado distinguir esses dois tipos de arquivos para evitar erros de compilação por usar acidentalmente o arquivo include incompatível com o compilador.

Se um arquivo .cc contiver um número muito grande de definições, o arquivo objeto produzido pelo compilador será desnecessariamente grande. Para obter um arquivo executável do menor tamanho possível, é necessário ter um arquivo separado para cada definição de função. É especialmente importante lembrar que as funções virtuais são sempre linked. Por outro lado, não há qualquer problema em gerenciar um projeto C++ com um grande número de arquivos, já que existem no mercado de software ferramentas muito boas para auxiliá-lo nessa tarefa. Adicionalmente, lembre-se que os tempos de compilação serão menores para arquivos menores.

Algumas ferramentas de debug não conseguem analisar funções inline. Colocando tais funções em arquivos isolados, e inserindo esses arquivos no arquivo de implementação via include, tratando assim as funções inline como funções normais, é possível avaliá-las através das ferramentas de debug. Para essa tarefa deve-se usar algumas técnicas especial de pré-processamento. A definição do arquivo inline não deve ser inserida pelo arquivo include para a classe, e a palavra-chave inline deve ser removida. Quando não se dispõe de ferramentas adequadas para manejar os arquivos de código C++, essa tarefa será muito mais fácil se houver uma única definição de classe em cada arquivo, e se a definição de funções-membro de diferentes classes não estiverem misturadas no mesmo arquivo.

Exceções à regra:
a) Arquivos include que contem código aceito tanto por compiladores C quanto por compiladores C++ devem ter a extensão .h
b) Quando usando compiladores que não aceitam a extensão .cc, a extensão .C deve ser usada.
c) Sem exceções

14. Diretiva
Antes de um programa iniciar, ele precisa carregar suas bibliotecas para o funcionamento. Esses cabeçalhos são chamados de diretiva de pré-processamento.    
Na linguagem C/C++ , existem diversos tipos de diretivas para modificar a compilação. As principais diretivas são definidas pelo padrão ANSI:  #include, #define, #undef, #ifdef, #ifndef, #if, #else, #elif, #endif

14.1. #include
A diretiva #include informa ao pré-processador para tratar o conteúdo de um arquivo especificado, como se esse conteúdo tivesse aparecido no programa de origem no ponto em que a diretiva é exibida.
Serve para importar bibliotecas.Quando você quiser utilizar uma estrutura de entrada e saída de dados, basta importar a biblioteca.
A importação é feita através do comando include seguido da biblioteca entre os sinais <>

#include <nome da biblioteca.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>

Caso seja uma biblioteca criado pelo próprio programador, deverá ser utilizado aspas duplas("") ao invés dos sinais <>.

#include "bibliotecacriada.h"

OBS: A partir da linguagem C++, não utiliza-se mais o sufixo .h durante a importação de bibliotecas. Muitos compiladores aceitam formas híbridas na inclusão de bibliotecas, ou seja, colocar tanto sufixo ou não. Assim que você importa a biblioteca sem o sufixo, devemos utilizar a palavra USING para demonstrar que tipo de funções iremos utilizar.

Exemplo:
#include <conio.h> //include em C
#include <conio>   //include em C++
Using namespace std;//demonstrando o tipo da função

stdlib.h - Contém protótipos de funções variadas para: conversão de números em texto e texto em números, alocação de memória, números aleatórios; e outras funções com várias finalidades.

stdio.h
stdlib.h
time.h
math.h
ctype.h
conio.h
14.2. #define
A diretiva #define é semelhante às variáveis, mas contém uma principal diferença. A variável pode ser alterada durante a execução do programa. Já o #define, não.
É uma espécie de constante na qual após ser atribuído, não pode ser mudado. É uma diretiva útil para valores padrão que não podem ser alterados(Existe uma forma de alterar uma constante em tempo de execução e será explicado mais na frente).

Esquema:
#define nome valor_constante
#define PI = 3.14159265;

Exemplo:
Arquivo: teste.c

#include <stdio.h>
#include <stdlib.h>

#define taxa_transporte 4.2;  //constante
int main(){
float distancia;
     printf("Deslocamento\n ");
     printf("Qual a distâcia percorrida (em km)\n");
     scanf("%f",&distancia);
     printf("\n");
     distancia = distancia*taxa_transporte;
     printf("Total da tarifa: R$ %.2f",distancia);
     getchar();
}

Compilar & Executar
Deslocamento
 Qual a distÔcia percorrida (em km)
100

Total da tarifa: R$ 420.00

14.3. #undef
Remove um macro feito pela diretiva #define. Ele praticamente "exclui" a constante.
#undef <identificador>
#undef TARIFA;
           
Exemplo:
Arquivo: teste.c
#include <stdio.h>//importando a biblioteca stdio.h
#include <stdlib.h>//importando a biblioteca stdlib.h
#define COTACAO_DOLAR 1.20
     
main(){
   printf("%f",COTACAO_DOLAR);//Imprime na tela o valor da Constante
   #undef COTACAO_DOLAR;//Exclui a constante
   //Daqui para baixo, o código acusa erro
   int real = real*COTACAO_DOLAR;
   printf("%f",COTACAO_DOLAR);
}

O código acima não vai compilar porque depois de executado o comando #undef, irá aparecer a seguinte mensagem:

"Undefined symbol ‘COTACAO_DOLAR’"

Ou seja, a constante COTACAO_DOLAR deixou de existir quando executei o comando #undef.

14.4. #ifdef
É a estrutura condicional do pré-processamento. É um "if" definido.

#ifdef <identificador>

É o mesmo que dizer #if <identificador> definido

Exemplo:
Arquivo: teste.c
#include <stdio.h>
#include <stdlib.h>

#define COMPRIMENTO

main(){
#ifdef COMPRIMENTO
#define MAX_COMPRIMENTO 50
#else
#define MAX_COMPRIMENTO 70
#endif
printf("%i",MAX_COMPRIMENTO);
}

Compilar & Executar
50

15. Bibliotecas de funções da linguagem C

De uma forma geral, as funções possuem três partes básicas:
O tipo
que pode ser void, também chamada de função sem retorno ou de qualquer outro tipo suportado pela linguagem.
O nome da função que pode ser uma palavra reservada das bibliotecas do C, ou um nome dado pelo programador caso esta tenha sido estruturada durante a criação do programa.
A declaração dos parâmetros ou argumentos que são passados para a função, podem ser do tipo void (não receber nenhum argumento), ou receber qualquer outros tipos dentre os suportados pela linguagem.

15.1. A função main

#include <stdio.h>
void main(){
    printf("Estudando funcoes em C");
}

void main(){} é a função principal. toda aplicação em C deve ocorrer dentro de uma função main. Seu tipo é void e sua lista de parâmetro também é void. Tudo que esta dentro do campo entre chaves é o corpo da função, pode conter qualquer tipo de instrução inclusive outras funções, como no caso acima, onde o ocorre uma chamada a função printf, passando como parâmetro uma string.

Em C todas as ações ocorrem dentro de funções.
A função main é sempre a primeira a ser executada.
Com exceção da função principal main, uma função só pode ser usada dentro de outra função.
Com funções projetadas adequadamente, é possível, ignorar como uma ação é feita, saber o resultado é suficiente.
Funções são blocos de código que podem ser nomeados e chamados de dentro de um programa.

Forma geral.
tipo_retorno nome_função ( parâmetros )
{
declarações
comandos
}


15.2. Funções pré-definidas da linguagem C


São funções pré programadas da linguagem e guardadas em biblioteca de acordo com seu uso. São funções robustas onde o programador não tem o acesso ao corpo da função, apenas ao seus resultados. Seu uso é feito atráves de chamadas no programa principal main ou em outras funções. Para utilizar esses recursos o programador deve indicar seu uso atravéz da diretiva #include <nome_da_biblioteca> no inicio do código.

15.2.1. <stdio.h>
Contém protótipos de funções da biblioteca padrão de entrada/saída e as informações utilizadas por elas.
- printf(); Mostra dados formatados no dispositivo de saída padrão.
- scanf(); Lê dados formatados do dispositivo de entrada padrão.
- int getchar(void); Atalho para getc(stdin), lê um caracter individual do dispositivo de entrada padrão.
sintaxe: getchar();
Nota: para que nenhum "lixo" do buffer de teclado atrapalhe o uso da função getchar(), coloque fflush(stdin)(em Windows) ou __fpurge(stdin) (em Linux) antes da leitura do caracter.
- int putchar(int c);atalho para putc(ch, stdout), envia um único caracter, c, para o dispositivo de saída padrão.
sintaxe: putchar(c);

Exemplo:
Arquivo: teste.c
#include <stdio.h>
#include <stdlib.h>
int main(){
    char caracter;
    printf("Entre com um caracter :");
    caracter = getchar();
    printf("\nExibindo o caracter com putchar: ");
    putchar(caracter);
    return(0);
}

Compilar & Executar
Entre com um caracter :a

Exibindo o caracter com putchar: a

Obs.: Todos os comandos para vídeo e teclado são simplificações dos comandos para arquivos. Quando um programa inicia, o sistema operacional é responsável por abrir três arquivos: arquivo de entrada padrão (stdin), saida padrão (stdout) e erro padrão (stderr). stdout e sterr são direcionados para o vídeo e stdin é direcionado para o teclado.

15.2.2. <stdlib.h>
- Contém protótipos de funções variadas para: conversão de números em texto e texto em números, alocação de memória, números aleatórios; e outras funções.
- int abs(int x); Retorna o valor absoluto de x.
Sintaxe: abs(x);
- int rand (void); Devolve um número inteiro (pseudo)aleatório entre 0 e RAND_MAX inclusive, (#define RAND_MAX 32767), ou seja, um número inteiro no intervalo fechado [0,RAND_MAX]. Uso típico: i = rand ().
Sintaxe: rand(); A função rand() gera uma sequência de valores que se repete sempre que o programa é executado.
- void srand (unsigned int x); Define uma "semente" para a função rand. Ela deve ser chamada antes do primeiro uso de rand para que a seqüência de números devolvidos por rand não seja sempre a mesma.
Sintaxe: srand(x);
- int system(const char *command); command é uma string que contém o nome do comando.
Sintaxe: system("comando")
system() é uma chamada ao sistema.

Exemplo:
system("cls"); //limpa tela
system("pause"); //pausa na execução do programa

15.2.3. <time.h>
- Contém protótipos e tipos de funções para manipular horários e datas.
time_t time(time_t *tp ); Retorna a hora em segundos.
Uso típico: tempo = time(NULL)
- double difftime(time_t hora2, time_t hora1 ).
Retorna a diferença hora2-hora1 em segundos, onde hora2 e hora1 são variáveis do "tipo" tempo (time_t).
Sintaxe: difftime(hora2, hora1);

Se a intenção é gerar uma seqüência diferente de números aleatórios sempre que o programa é executado, e que não haja necessidade de mudar mecanicamente a semente, podemos usar a função time() da seguinte forma:
- srand(time(NULL));

Exemplo:
Arquivo: teste.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(){

    int i, vet[10], tempo, valor, a=0, p=0, logico;
    time_t tinicio, tfim; /* variaveis do "tipo" tempo */
    printf("Inicio do jogo\n");
    tinicio = time(NULL); /* marca o tempo inicial */

    do{
        /* Inicializa o gerador de numeros aleatorios */
        srand(time(NULL));
        /* Carregando o vetor com dez numeros aleatorios entre 1 e 10 */
        for(i=0; i<10; i++){
            vet[i] = rand()%10+1; /* gera numeros aleatórios entre 1 e 10 */
        }
        printf("\nEscolha um valor entre 1 e 10: ");
        scanf("%d",&valor);

        /* calcula quantas vezes o valor aparece na sequencia */
        for(i=0; i<10; i++){
            if(valor==vet[i]) a++;
        }

        if(a) printf("\nVoce marcou %d ponto(s)!", a); /* a é diferente de zero */
        else printf("\nVoce nao marcou pontos! Este valor nao esta na sequencia!");
        printf("\n\nSequencia: ");

        for(i=0; i<10; i++){
            printf("%d ",vet[i]);
        }

        p+=a; /* acumula os pontos */
        a=0; /* zera os pontos para uma nova jogada */
        printf("\n\nDigite 0 (zero) para terminar o jogo\nou qualquer outro
        valor para continuar jogando: ");
        scanf("%d", &logico);
    }while(logico);

    tfim = time(NULL); /* marca o tempo final */
    tempo= difftime(tfim, tinicio); /* marca a diferença tfim-tinicio */

    printf("\nFim do jogo\n");
    printf("Total de pontos: %d\n", p);
    printf("\n\nVoce jogou em %d segundo(s).\n", tempo);
    return 0;
    system("pause");
}

Compiar & Executar
Inicio do jogo

Escolha um valor entre 1 e 10: 3

Voce marcou 1 ponto(s)!

Sequencia: 2 5 2 9 4 5 3 5 2 6

Digite 0 (zero) para terminar o jogo
ou qualquer outro valor para continuar jogando:

15.2.4. <math.h>

- Contém protótipos de funções da biblioteca matemática.

double sin (double x); seno de x.
sintaxe: sin(x);

double cos (double x); co-seno de x.
sintaxe: cos(real);

double tan (double x); tangente de x.
sintaxe: tan(x);

double sqrt (double x); raiz quadrada de x (x>=0).
sintaxe: sqrt(x);

double exp (double x); ex (e é aproximadamente 2,718).
sintaxe: exp(x);

double log (double x); ln(x) (logaritmo natural- base e) (x>0).
sintaxe: log (x);

double log10 (double x); log10(x) (logaritmo base 10) (x>0).
sintaxe: log10 (x);

double pow (double x, double y); xy (erro de domínio se x=0 e y<=0, ou se x<0 e y não for inteiro).
sintaxe: pow (x, y);

double ceil (double x); menor inteiro não menor que x (teto x).
sintaxe: ceil (x);

double floor(double x); maior inteiro não maior que x (piso x).
sintaxe: floor(x);

double fabs(double x); valor absoluto de x, |x|.
sintaxe: fabs (x);

15.2.5. <ctype.h>

- Contém protótipos de funções e macros que permitem verificar se um determinado caracter é ASCII, se é numérico, se é maiúscula, minúscula, etc.

int isalnum(int c); verifica se o caracter é alfa-numérico. Devolve zero (falso) se não for caracter alfa-numerico e um valor não-zero se for.

int isalpha(int c); verifica se o caracter é uma letra (A-Z ou a-z) ou não. Devolve zero se não for uma letra e um valor não-zero se for.

int isdigit(int c); verifica se o caracter é uma algarismo (0-9) ou não. Devolve zero se não for um algarismo e um valor não-zero se for.

int islower(int c); verifica se o caracter é uma letra minúscula. Devolve zero se não for (0-verdadeiro) um valor não-zero se for(!0-verdadeiro).

int isupper(int c); verifica se o caracter é uma letra maiúscula. Devolve zero se não for (0-verdadeiro) um valor não-zero se for(!0-verdadeiro).

int tolower(int c); converte uma letra para o formato minúsculo.

int toupper(int c); converte uma letra para o formato maiúsculo.

15.2.6. <conio.h>

A biblioteca - con(console) para compiladores DOS ou Windows não é padrão. Geralmente as funções desta biblioteca não estão disponível em ambiente Unix (compiladores cc e gcc.). Algumas funções:

void clrscr (void); limpa a tela.
sintaxe: clrscr ();

int getche(void) lê um caracter do teclado imprimindo-o na tela.
sintaxe: getche()

int getch(void) apenas lê o caracter do teclado (sem imprimi-lo).
sintaxe: getch();

Exemplo:
Arquivo: teste.c

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main ( ){
    char car1, car2;
  
    printf ("Digite um caracter:");
    car1 = getche( );
    printf ("\nVoce digitou %c\n\n", car1);
    printf ("Digite um outro caracter:\n");
    car2 = getch( );
    printf ("Voce digitou %c\n\n", car2);
    system("pause");
    return (0);
}

Compilar & Executar
Digite um caracter:y
Voce digitou y

Digite um outro caracter:
Voce digitou k

Observe que não foi necessário digitar <enter> após a entrada do caractere.


15.3. Funções definidas pelo usuário
Sintaxe:
tipo nome_da_funcao (lista_de_parâmetros){
corpo da função
}

tipo:
define o tipo de valor que a função vai retornar à função que realiza a chamada.
nome_da_funcao: define o nome (o rótulo) da função. É através deste nome que a função é chamada.
lista_de_parâmetros: É uma lista, separada por vírgula, contendo a declaração das variáveis (parâmetros ou parâmetros formais) que recebem os argumentos (parâmetros reais - valores usados para chamar a função) quando a função é chamada.
Sintaxe:
tipo1 identificador1, tipo2 identificador2, ..., tipoN identificadorN)

Uma função pode não possuir parâmetros, ou seja, não receber argumentos. Neste caso utiliza-se a declaração do tipo void - (void).
Para retornar um valor (ao local onde a função foi chamada) utiliza-se o comando return. Este comando também indica o encerramento da execução da função. O valor retornado deve ser compatível com o tipo da função. Se o tipo não é definido é considerado o tipo int como retorno da função.

Se uma função não retornar nenhum valor ela deve ser definida com o tipo void e neste caso o comando return não é necessário.


Definição de função
Podemos definir uma funçãon no início de um programa, antes da função principal ou após a função principal.
Se a definição de uma função não é feita no início do programa, então é necessário fazer a declaração da função para que o compilador a reconheça quando esta for chamada dentro da função principal ou dentro de outra função. A declaração da função ou protótipo da função, consiste do cabeçalho da função seguido do ponto e vírgula.

Observação:
Toda função deve ser declarada antes de ser usada.
Quando uma função está definida no início do programa a declaração está implícita na definição.

Exemplos de funções:

1)Função "soma"

int soma(int a, int b) {
int s;
s=a+b;
return s;
}
Função do tipo int, com o identificador soma, recebe com parâmetro dois numeros inteiros, declara um terceiro inteiro que recebera a soma dos valores passados como argumento, em seguida utiliza a palavra reservada return retornando um valor inteiro.

2)Função "mensagem"

void mensagem(void) {
printf(" Entre com dois valores inteiros\n");
return; //nao e necessário
}

Função do tipo void e sem argumento, apenas imprime a mensagem definida em seu corpo. Observe que o uso de return é puramente estético, uma vez que a função foi declarada void não se faz necessário o uso de retorno.

3)Função "lendo_parcela"

int lendo_parcela(void) {
int a;
scanf("%d", &a);
return a;
}
Função que retorna um inteiro, mas não recebe parâmetro algum, solicita via declado a digitação de um inteiro e em seguida retorna para o programa este valor digitado.

4)Função "quad_soma"

void quad_soma(int a)
{
printf("quadrado da soma =%f\n\n", pow(a,2));
}

Função sem retorno, recebe um numero inteiro e internamente imprime seu quadrado. Observe que ápos a execução da função o valor passado como argumento não será alterado no programa principal.

NOTA.: Todas as variáveis criadas dentro uma função são locais à função que as utiliza, uma vez terminada sua execução estas variáveis não são reconhecidas pelo programa principal. Mesmo em função com retorno, pois o retorno é referência a um contéudo, sendo necessário a declaração de outra variável no programa principal do mesmo tipo do retorno da função para receber este valor.

15.4. Biblioteca de Execução (padrão do C++)
Muitas vezes, uma função criada para um determinado programa atende as necessidades de um segundo programa. A capacidade de reutilizar as funções em mais de um programa pode poupar um tempo considerável de programação e teste. Para isto é só copiar a função de um para outro programa.
A linguagem C++ possui uma biblioteca padrão com muitas funções úteis previamente implementadas para uso do programador, inclusive incluindo todas as funções da biblioteca padrão de C. A biblioteca padrão se divide em várias bibliotecas ou arquivos menores, divididos pelos tipos de função que cada um contém.
Por exemplo:
Biblioteca <cmath>: contém as funções matemáticas padrão da linguagem C.
A biblioteca <string>: contém funções da biblioteca padrão de C++ que tratam de strings. Para utilizar uma destas bibliotecas, é preciso “avisar” ao compilador através da diretiva#include <nome_da_biblioteca>

O comando “#include” copia o conteúdo da biblioteca para o programa que estamos compilando, para que as funções pertencentes à ela possam ser utilizadas.
Algumas das bibliotecas padrão de C++ e seus cabeçalhos são mostrados abaixo:
Funções matemáticas: #include <cmath>
Funções de string: #include <cstring>
Funções de string do C++: #include <string>
Funções de I/O: #include <cstdio>
Funções de tempo: #include <ctime>

15.5. Funções Recursivas
Em C++, as funções podem chamar a si próprias, com exceção da função principal main. Uma função é recursiva se um comando no corpo da função chama ela mesma.
Algumas vezes chamada de definição circular, a recursividade é o processo de definição de algo em termos de si mesmo.
Exemplos de recursividade existem em grande número. Uma maneira de definir um número inteiro sem sinal por meio de recursividade é utilizando-se os dígitos 0, 1, 2, 3, 4,5, 6, 7, 8, 9 mais ou menos outro número inteiro. Por exemplo:
O número 15 é o número 7 mais o número 8.
O número 21 é 9 mais 12.
O númerro 12 é 9 mais 3.
Para uma linguagem ser recursiva, uma função deve estar apta a chamar a si própria. O exemplo clássico de recursividade é mostrado na função fatorial_recursivo(), que calcula o fatorial de um número inteiro. O fatorial de um número N é o produto de todos os números inteiros entre 1 e N. Por exemplo, o fatorial de 3 é 1 x 2 x 3, cuja resultado é 6.

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdio>
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;
unsigned long fatorial_recursivo (int n){
unsigned long resposta;
if ((n == 1) || (n == 0))return(1);
resposta = n * fatorial_recursivo(n - 1);
return(resposta);
}
int main()
{
unsigned long f;
int n;
cout<<"Digite um número: \n";
cin >> n;
f = fatorial_recursivo(n);
cout<<"O fatorial de "<<n<<" e "<<f<<" \n";
system("PAUSE > null");
return 0;
}

Compilar & Executar
Digite um n·mero:
4
O fatorial de 4 e 24

Observação:
1) Recursividade:

A recursividade da função mostrada na figura acima funciona porque:
- o retorno (resposta) da função não tem sinal e a cada ciclo o parâmetro, n é subtraído 1, isto quer dizer que o ciclo se encerra quando n = 2 (2-1=1) ou n = 1 (1 - 1 = 0).
-
o retorno (resposta) chama a própria função.
- Quando uma função chama a si própria, as novas variáveis locais e os argumentos são alocados na pilha, e o código da função é executado com esses novos valores a partir do início. Uma chamada recursiva não faz uma nova cópia da função. Somente os argumentos e as variáveis são novos. Quando cada chamada recursiva retorna, as antigas variáveis locais e os parâmetros são removidos da pilha e a execução recomeça no ponto de chamada da função dentro da função.
Tendo em vista que o local para os argumentos de funções e para as variáveis locais é a pilha e que a cada nova chamada é criado uma cópia destas variáveis na pilha, é possível ocorrer overflow da pilha (stack overflow) e o programa terminar com um erro.


2)
Função system( )
A linha “system(“PAUSE > null”)” é uma chamada de função própria de C++. A função system( ) recebe argumentos como o PAUSE que na verdade são comandos para o sistema operacional. Neste caso, ela recebe o comando “PAUSE > null” para pausar a execução do programa até que o usuário aperte uma tecla qualquer. Utilizamos este recurso para que a tela do programa não seja terminadaautomaticamente pelo sistema, impedindo que vejamos os resultados do programa.

15.6. Sobrecarga da Função
Quando um programa usa uma função, a Linguagem C armazena o endereço de retorno, os parâmetros e as variáveis locais na pilha. Quando a função termina, a Linguagem C descarta o espaço da pilha que continha as variáveis locais e parâmetros, e,depois, usa o valor de retorno para retornar a execução do programa para a posição correta.
Embora o uso da pilha seja poderoso porque permite que o programa chame e passe as informações para as funções, também consome tempo de processamento. Os programadores chamam a quantidade de tempo que o computador requer para colocar e retirar informações da pilha de sobrecarga da função. Na maioria dos sistemas, os cálculos baseados em funções podem requerer quase o dobro do tempo de processamento.
Entretanto, C++ introduz um conceito que pode reduzir bastante a sobrecarga da função: são as funções inline.

15.7. Funções Inline
As funções inline são funções que são compiladas “na sequência” (“in line”) do código. Isso quer dizer que quando chamamos uma função inline em um programa, o compilador substitui a chamada de função pelo próprio código da função, adaptando automaticamente os parâmetros e retorno da função. Assim, elimina-se a necessidade do programa pular para outro ponto na memória do computador, executar a função e depois
retornar ao ponto onde parou.
Criamos funções inline do mesmo jeito que criamos funções normais: declarando seu protótipo e sua definição, com parâmetros e retorno. Só é preciso adicionar o prefixo inline antes do protótipo ou da definição da função, como é mostrado na função abaixo:

inline int quadrado (long x)
{
x = x * x;
return x;
}

Não podemos criar funções inline recursivas, pois logicamente uma função recursiva tem um tamanho variável de acordo com seu número de iterações, que muitas vezes muda durante a execução do programa.
Ganha-se velocidade com as funções inline, mas perde-se em memória utilizada. Se um programa chama uma função inline 10 vezes, criam-se 10 cópias da função dentro do código, aumentando seu tamanho durante a compilação. É preciso escolher com cuidado quando utilizar funções normais e funções inline, tendo em mente o compromisso rapidez de execução – memória utilizada.

15.8. Parâmetros Padrão
Outra novidade introduzida por C++ no manuseio de funções é a possibilidade de definir-se um valor padrão para parâmetros de uma função. Isto é, podemos definir um parâmetro para uma função e estabelecer um valor padrão para ele, da seguinte forma:

void mensagem (int x = 1);

Quando chamamos a função e enviamos um valor como parâmetro para ela, a função é executada normalmente, utilizando o valor de x que enviamos. Porém, caso não enviássemos um valor x como parâmetro para esta função, isto é, fizéssemos a seguinte declaração no programa:

mensagem( );

Automaticamente a função substituiria x por 1, como especificamos no protótipo da função. Caso não tivéssemos definido um valor padrão para o parâmetro x, o compilador nos retornaria um erro de parâmetros insuficientes para que a função seja executada.
Exemplo:
Arquivo: teste.cpp

#include <iostream>
#include <cstdio>
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;
void mensagem (int x = 1) {
if (x != 1) cout<<"Voce enviou um parametro para a função! O parametro X é igual a "<<x<<"\n";
if (x == 1) cout<<"Voce NAO enviou um parametro para função! O parametro X é igual a "<<x<<"\n";
}
int main()
{
int valor;
cout<<"Entre com um valor. Este valor será repassado para a função mensagem automaticamente!\n";
cin>>valor;
mensagem(valor);
cout<<"Agora chamaremos a função mensagem sem lhe dar um parametro. Veja o que acontece: \n";
mensagem();
system("PAUSE > null");
return 0;
}

Compilar & Executar
Entre com um valor. Este valor serrá repassado para a função mensagem automaticamente!
10
Voce enviou um parametro para a função! O parametro X é igual a 10
Agora chamaremos a função mensagem sem lhe dar um parametro. Veja o que acontece
:
Voce NÃO enviou um parametro para função! O parametro X é igual a 1

16. Escopo de Variáveis

As variáveis em C podem ser declaradas basicamente de 3 maneiras diferentes: dentro de uma função, fora de uma função, e como parâmetro de uma função. Essas 3 maneiras de declaração fazem com que as variáveis sejam chamadas de locais, globais ou parâmetros formais.
    
Variáveis Globais
As variáveis globais existem durante a execução de todo o programa e podem ser utilizadas por qualquer função. Elas devem ser declaradas fora de qualquer função, inclusive do main(), e no início de um programa.

Variáveis Locais
Uma variável local só pode ser utilizada pela função ou bloco que a declarou. Ela não é reconhecida por outras funções e só pode ser usada dentro do bloco de função onde está declarada. Uma variável local é criada quando a função começa a ser executada e destruída no final da execução dessa função. Além disso, no C ANSI, todas as variáveis locais precisam ser declaradas no início da função.

Parâmetros Formais
Os parâmetros formais são variáveis locais de uma função que são inicializadas no momento da chamada da função. Eles também só existem dentro da função onde foram declarados. Embora sejam utilizadas como inicialização da função, elas podem ser utilizadas normalmente como uma variável local dentro do bloco de função onde estão.
    
Exemplo:
int contador;    // variavel global;
int verifica(int);  // prototipo de funcao
  void main()
{
   int num, r;     // variaveis locais a main()
   contador = 100;
    scanf("%d",&num);
    r = verifica(num);   // chamada da funcao
    printf("Verificacao = %d",r);
    }

   int verifica(int valor)   // valor é parametro formal de verifica
   {
      int saida;   // variavel local a verifica()
      if(valor <= contador)
      saida=0;
      else saida=1;
      return(saida)
   }

Exemplo de funções definidas pelo usúario

#include<stdio.h>
#include<math.h>
#include<stdlib.h>

/* declaracao de funcoes */
void mensagem (void);
int lendo_parcela(void);
int soma (int a, int b);
void quad_soma (int x);

/* funcao principal main */
int main ( ){

    /* declaracao de variaveis locais */
    int a, b, total;

    /* chamadas de função */
    mensagem ();
    a= lendo_parcela();
    b= lendo_parcela();

    /* chamada por valor */
    total=soma(a,b);
    printf("soma=%d\n", total);
    /* chamada por valor */
    quad_soma(total);
    return 0;
    system("pause");
} // fim da main

/* definicao de funcoes */
void mensagem (void){
    printf(" Entre com dois valores inteiros\n");
}

int lendo_parcela (void){
    int p;
    scanf("%d", &p);
    return p;
}

int soma (int a, int b){
    int s;
    s=a+b;
    return s;
}

void quad_soma (int x){
    printf("quadrado da soma =%.1f\n\n", pow(x,2));
} // fim do programa

Compilar & Executar
Entre com dois valores inteiros
2 4
soma=6
quadrado da soma =36.0

Observe a estrutura do programa acima:


17. Arranjos e funções - Passagem de arranjos para funções.
17.1. Funções com arranjo unidimensional
Para passar um vetor como argumento de uma função, pode-se declarar a função de três modos equivalentes:

void fun (int vetor[10]);
void fun (int vetor[ ]);
void fun (int *vetor);

No terceiro caso temos um ponteiro do tipo inteiro chamado "vetor". Nesse ponteiro é armazenado o endereço do primeiro elemento do arranjo unidimensional que é passado por referência.

Exemplo de função que imprime um vetor:

void imprime_Vetor (int vetor[N]) {
    int i;
    for(i=0;i<N;i++)
    printf("%d\t", vetor[i]);
}

Exemplo:
Arquivo: teste.c
#include<stdio.h>
#define TAM 4
int Par(int x)
{
  if (x%2 == 0)
    return 1;
  return 0;
}
void main (void)
{
  int vet[TAM], i;
  for (i=0; i<TAM; i++)
    scanf("%d",&vet[i]);
  for (i=0; i<TAM; i++)
    if (Par( vet[i] ) == 1)
      printf("%d: numero par, ",vet[i]);
}

Compilar & Executar
2
4
8
1
2: numero par, 4: numero par, 8: numero par,

Exemplo:
Arquivo: teste.cpp
A função que recebe um número inteiro e positivo N como parâmetro e retorna a soma dos N números inteiros existentes entre o número 1 e esse número. O programa principal lê as entradas e imprimir os resultados.

#include <iostream>
#include <conio.h>
using namespace std;
int N; //variável global
//função: retorna valor da soma
int soma_1_ate_N(int& N)
{
int soma=0,i;
for (i=1; i<=N; i++)
soma=soma+i;
return (soma);
}
int main ()
{
cout << "Digite N\n";
cin >> N;
cout << "A soma de 1 ate N = "<<soma_1_ate_N(N);
getch();
}

Compilar & Executar
Digite N
4
A soma de 1 ate N = 10

Exemplo:
Arquivo: teste.cpp
A função calcula a média aritmética de um vetor inteiro passado como parâmetro. O programa principal lê as entradas e imprimir os resultados. Observe que é passado como parâmetro a quantidade de elementos a serem considerados.

#include <iostream>
#include <conio.h>
using namespace std;
//função para calcular média: recebe como parâmetros o vetor e sua dimensão
float media_vetor(int V[], int n)
{
  int i;
  float soma=0,media;
  for (i=0; i<n; i++)
    {
    soma = soma + V[i];
    }
  media=soma/n;
return (media);
}
int main()
{
int V[99999],i, n; // observe que o vetor foi declarado com um número muito grande de elementos
cout << "Escreva a quantidade de elementos do vetor\n";
cin >> n;
for (i=0; i<n; i++)
{
cout << "\nEscreva o elemento "<<(i+1)<<" do vetor\n";
cin >> V[i];
}
cout << "\nA media dos elementos do vetor = " << media_vetor(V, n);
getch();
}

Compilar & Executar
Escreva a quantidade de elementos do vetor
4

Escreva o elemento 1 do vetor
2

Escreva o elemento 2 do vetor
5

Escreva o elemento 3 do vetor
6

Escreva o elemento 4 do vetor
7

A media dos elementos do vetor = 5

Exemplo:
Função que retorna 1 se x pertence a um vetor e 0 caso contrário

int verifica_x (int vetor[N], int x) {
    int i, teste=0;
    for(i=0;i<N;i++){
        if(vetor[i]==x){
            teste=1;
        }
    }
    return teste;
}

Exemplo:
Função que retorna o maior elemento de um vetor

int Max(int vetor[ ], int n) {
    int i, temp;
    temp = vetor[0];
    for (i = 1; i<n; i++){
        if (temp < vetor[ i ])
            temp = vetor[ i ];
    }
    return temp;
}


17.2. Funções definidas pelo usuário

Exemplo:
Arquivo: teste.c

#include <stdio.h>
#include<stdlib.h>
#define N 4 // declaração de constante

// declaração das funções
void imprime_Vetor (int vetor[N]); // ou (int vetor[ ]) ou (int *vet)
int Max(int vetor[], int n);
int verifica_x (int vetor[N], int x);

int main(){ // função principal main
   
    int vet[N] = {10,20,30,40}, maior, valor, resultado;
    maior=Max(vet, N); // chamada de função
    printf("Entre com um inteiro menor que %d: ", maior+1);
    scanf("%d",&valor);  
    resultado=verifica_x(vet, valor); // chamada de função

    if(resultado)
        printf("O numero digitado pertence ao vetor!\n");
    else printf("O numero digitado não pertence ao vetor!\n");
        printf("Os elementos do vetor são:\n");

    imprime_Vetor (vet); // chamada de função
    printf("\n");
    system("pause");
    return(0);
}
/*Função que imprime um vetor */
void imprime_Vetor (int vetor[N]){
    int i;
    for(i=0;i<N;i++)
    printf("%d\t", vetor[i]);
}

/*Função que retorna 1 se x pertence ao vetor e 0 caso contrário */
int verifica_x (int vetor[N], int x){
    int i, teste=0;
    for(i=0;i<N;i++){
        if(vetor[i]==x)
            teste=1;
    }
    return teste;
}

/*Função que retorna o maior elemento de um vetor */
int Max(int vetor[ ], int n){
    int i, temp;
    temp = vetor[0] ;
    for (i = 1; i<n; i++){
        if (temp < vetor[ i ])
            temp = vetor[ i ] ;
    }
    return temp;
}

Compilar & Executar
Entre com um inteiro menor que 41: 20  <enter>
O numero digitado pertence ao vetor!
Os elementos do vetor sÒo:
10      20      30      40


17.3. Funções com arranjo bidimensional
Para passar uma matriz bidimensional como argumento de uma função, pode-se declarar a função de dois modos equivalentes:

void fun (int matriz[2][10]);
void fun (int matriz[ ][10]);

Nestes casos observe que pelo menos o comprimento de cada linha (segunda dimensão) precisa ser declarado para que a matriz possa ser indexada corretamente.

Exemplo 1: Função que imprime uma matriz

void imprime_matriz(int a[][N]) {
    int i, j;
    for (i=0;i<N;i++) {
        for (j=0;j<N;j++) {
            printf("%d\t", a[i][j]);
        }
        printf("\n");
    }
}

Exemplo 2: Função que carrega uma matriz com a soma de duas outras matrizes

void carrega_c (int a[][N], int b[][N], int c[][N]){
    int i, j;
    for (i = 0; i < N; i++){
        for (j = 0; j < N; j++){
            c[i][j]= a[i][j]+b[i][j];
        }
    }

Exemplo:
Arquivo: teste.c
O programa abaixo implementa as funções demostradas acima

#include <stdio.h>
#include<stdlib.h>
#define N 3 // declaração de constante

// declaração das funções
void imprime_matriz(int a[][N]);
void carrega_c (int a[][N], int b[][N], int c[][N]);

int main(){ // função principal main
    int i, j;
    int matriz_a[N][N], matriz_b[N][N], matriz_c[N][N];
    //Carrega as matrizes
    for (i=0;i<N;i++){
        for (j=0;j<N;j++){
            matriz_a[i][j]= i+1;
            matriz_b[i][j]= j+1;
        }
    }

    //Mostra as matrizes "matriz_a" e "matriz_b"
    printf("\nmatriz_a\n\n");
    imprime_matriz(matriz_a); // chamada de função
    printf("\nmatriz_b\n\n");
    imprime_matriz(matriz_b); // chamada de função
    //carrega matriz "matriz_c"
    carrega_c(matriz_a, matriz_b, matriz_c); // chamada de função
    //Mostra a "matriz_c"
    printf("\nmatriz_c\n\n");
    imprime_matriz(matriz_c); // chamada de função
    printf("\n");
    system("pause");

    return(0);
}

/*Função que imprime uma matriz */
void imprime_matriz(int a[][N]){
    int i, j;
    for (i=0;i<N;i++){
        for (j=0;j<N;j++){
            printf("%d\t", a[i][j]);
        }
        printf("\n");
    }
}

/*Função que carrega uma matriz com o resultado da soma de duas
outras matrizes */
void carrega_c (int a[][N], int b[][N], int c[][N]){
    int i, j;
    for (i = 0; i < N; i++) {
        for (j = 0; j < N; j++){
            c[i][j]= a[i][j]+b[i][j];
        }
    }
}

Compilar & Executar
matriz_a

1       1       1
2       2       2
3       3       3

matriz_b

1       2       3
1       2       3
1       2       3

matriz_c

2       3       4
3       4       5
4       5       6

18. Tipos e Dados
Quando um programa é escrito em qualquer linguagem de programação é necessário a definição de algumas variáveis. Variáveis são instâncias em que serão armazenados valores utilizados durante a execução de programas. Estas variáveis podem ser modificadas para suportar diferentes tipos de dados.
Os principais tipos de dados utilizados em C++ podem ser divididos em variáveis inteiras e reais.
Variáveis inteiras servem para armazenar números inteiros, sem partes fracionárias.
O principal tipo de variável inteira em C++ é o int. Além dele, existem os tipos char, short e long, cada um deles caracterizado por um tamanho em bits diferente. Estes tipos podem ser modificados pelo prefixo “unsigned”, que determina que a variável em questão só terá valores positivos, liberando o bit de sinal e aumentando a capacidade de armazenamento da variável (por default, todas as variáveis inteiras e reais declaradas em C++ são “signed”, ou seja, possuem um bit de sinal e podem ser tanto positivas como negativas). A tabela abaixo mostra os principais tipos de inteiros, seus tamanhos em bits e seu intervalo de armazenamento.
Tabela 3.1 – Tipos de variáveis inteiras em C++
Tipo
Tamanho (bits)
Intervalo
Char 8 -128 a 127
unsigned char 8 0 a 255
Int 16 -32768 a 32767
unsigned int 16 0 a 65535
Short 16 -32768 a 32767
unsigned short 16 0 a 65535
Long 32 -2147483648 a 2147483647
unsigned long 32 0 a 4294967295

Variáveis reais servem para armazenar números que possuem partes fracionárias.

Existem duas maneiras de representar números fracionários em C++. A primeira, a mais simples, é utilizar o ponto para separar as partes inteiras e fracionárias. Por exemplo:
0.00098
1.2145
3.1461
8.0
(Mesmo no caso de um número com parte fracionária igual a zero, a utilização do ponto assegura que este número seja considerado um número de ponto flutuante por C++).
A segunda maneira é utilizar a notação científica E.
Por exemplo :
3.45E7 significa
“3.45 multiplicado por 10 elevado à sétima potência (10.000.000)”. Essa notação é bastante útil para representar números realmente grandes ou realmente pequenos. A notação E assegura que o número 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 números reais em C++ podem ser representados por 3 tipos de variáveis com diferentes intervalos. São elas: float, double e long double.
Float é o tipo de variável real natural, aquela com a qual o sistema trabalha com maiornaturalidade.
Double e long double são úteis quando queremos trabalhar com intervalos de números reais realmente grandes. Utilizamos números reais geralmente para expressar precisão através do número de casas decimais, então podemos dizer que uma variável float é menos precisa que uma variável double, assim como uma variável double é menos precisa que long double.

A tabela abaixo mostra os tipos de variáveis reais, seu tamanho em bits e o intervalo de armazenagem.
Real
Tamanho (bits)
Intervalo
Float 32 3,4E-38 a 3,4E+38
Double 64 1,7E-308 a 1,7E+308
long double 80 3,4E-4932 a 1,1E+4932

19. Definição de Variáveis
As variáveis devem ser declaradas, ou seja, devem ser definidos nome, tipo e algumas vezes seu valor inicial. As variáveis são classificadas em variáveis locais e globais.
Variáveis globais são aquelas declaradas fora do escopo das funções.
Variáveis locais são aquelas declaradas no início de um bloco e seus escopos estão restritos aos blocos em que foram declaradas. A declaração de variáveis locais deve obrigatoriamente ser a primeira parte de um bloco, ou seja, deve vir logo após um caractere de “abre chaves”, '{'; e não deve ser intercalada com instruções ou comandos.

Para declarar uma variável somente é obrigatório declarar seu tipo e nome:
<tipo> <nome>;

Por exemplo:
in numero;

Além disso, caso seja necessário, podemos declarar um valor a esta variável no momento de sua declaração, e também adicionar um prefixo a ela, da seguinte forma:

<prefixo> <tipo> <nome> = <valor>;

Por exemplo:
unsigned int exemplo = 12;

20. Definição de Constantes
O conceito de constantes em linguagens de programação é atribuir um certo valor constante a um nome, e quando este nome for referenciado dentro do código do programa, será utilizado nas operações o valor atribuído a este nome. Ou seja, se for definida a constante PI com o valor “3,1415926536”, quando for encontrado no código o nome PI, será utilizado em seu lugar o valor “3,1415926536”.
Em C++ , utilizamos o prefixo const associado a um tipo, um nome e um valor para definir uma constante.

const <tipo> <nome> = <valor>;

Por exemplo:
const int coef = 256;

No exemplo acima, definimos uma constante inteira de nome “coef” que possui ovalor numérico 256. É importante notar que devemos declarar a constante e lhe atribuir um valor na mesma linha de comando. Não podemos criar uma constante e lhe atribuir um valor posteriormente, ou seja, as seguintes linhas de comando são inválidas:
const int coef;
coef = 256;

A partir da primeira linha, “coef” passa a ser uma constante e seu valor não pode ser mais mudado durante a execução do programa. Como seu valor não foi declarado, esta constante pode ter qualquer valor que esteja na memória do computador naquele momento da declaração da variável.

21. Números Hexadecimais e Octais
Em programação algumas vezes é comum usar um sistema de numeração baseado em 8 ou 16 em vez de 10.
O sistema numérico baseado em 8 é chamado octal e usa os dígitos de 0 a 7.
Em octal, o número 10 é o mesmo que 8 em decimal.

O sistema numérico de base 16 é chamado hexadecimal e usa os dígitos de 0 a 9 mais as letras de A até F, que equivalem a 10, 11, 12, 13, 14 e 15. Por exemplo, o número hexadecimal 10 é 16 em decimal. Por causa da freqüência com que estes dois sistemas numéricos são usados, a linguagem C++ permite que se especifique valores inteiros em hexadecimal ou octal parauma variável ou constante em vez de decimal.

Um valor hexadecimal deve começar com “0x” (um zero seguido de um x), seguido pelo valor em formato hexadecimal.
Um valor octal começa com um zero.
Exemplos:
hex = 0xFF; /* 255 em decimal */
oct = 011; /* 9 em decimal */

Outra base numérica muito utilizada na programação é a base binária. Apesar de C++ não possuir uma forma específica de se expressar valores de base binária, podemos utilizar a notação hexadecimal para esta função. A tabela abaixo mostra como pode ser feita a conversão de um valor binário para um valor hexadecimal.

Conversão de valor binário para hexadecimal
  
Dígito Hexadecimal Equivalente Binário Dígito Hexadecimal Equivalente Binário
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

22. Valores Strings
Outro tipo de valor suportado pela Linguagem C++ é o tipo string. Uma string é um conjunto de caracteres entre aspas. Por exemplo, “Uma string tem mais de uma letra” é uma string, composta pelas várias letras que formam a frase. Não confunda strings com caractere, que corresponde a apenas uma letra. Uma constante caractere simples fica entre dois apóstrofos, por exemplo ‘a’. Entretanto “a” é uma string que contém somente uma letra.

23. Códigos de Barra Invertida
A linguagem C++ fornece constantes caractere mais barra invertida especiais, úteis para caracteres que não são facilmente inseridos através do teclado ou de strings (como por exemplo, o retorno de carro). Estes códigos são mostrados na tabela a seguir:
Códigos de barra invertida em C++
Código Significado Código Significado
\b Retrocesso \f Alimentação de formulário
\n Nova linha \r Retorno de carro
\t Tabulação horizontal \” Aspas
\’ Apóstrofo \0 Nulo
\\ Barra invertida \v Tabulação vertical
\a Sinal sonoro \N Constante octal
\xN Constante hexadecimal


Usa-se um código de barra invertida exatamente da mesma maneira como usa qualquer outro caractere. Por exemplo:
ch = ‘\t’;
printf(“Este é um teste\n”);

Esse fragmento de código primeiro atribui uma tabulação a ch e, então, imprime“este é um teste” na tela, seguido de uma nova linha.

24. Operadores
Um operador é um símbolo que diz ao compilador para realizar manipulações matemáticas e lógicas específicas. A linguagem C++ possui três classes gerais de operadores: aritméticos, relacionais e lógicos além do bit-a-bit.

24.1. Operador de atribuição
O operador “=” atribui um valor ou resultado de uma expressão contida a sua direita para a variável especificada a sua esquerda. Exemplos:
a = 10;
b = c * valor + getval(x);
a = b = c = 1;
O último exemplo é interessante por mostrar que é possível associar vários peradores de atribuição em sequência, fazendo com que todas as variáveis envolvidas tenham o mesmo valor especificado.

24.2. Operadores Aritméticos
São aqueles que operam sobre números e expressões, resultando valores numéricos. São eles:
Operadores Aritméticos em C++
Operador Ação
+ Soma
- subtração
* multiplicação
/ divisão
% módulo da divisão
(resto da divisão inteira)
-
sinal negativo (operador unário)

24.3. Operadores Relacionais
Operam sobre expressões, resultando valores lógicos de TRUE (verdadeiro) ou FALSE (falso). são eles:
Operadores Relacionais em C++
Operador Ação
> Maior
>= maior ou igual
< Menor
<= menor ou igual
== Igual
!= não igual (diferente)

Observação:
Não existem os operadores relacionais: “=<“, “=>“ e “<>“.
Não confunda a atribuição (“=“) com a comparação (“==“).

24.4. Operadores Lógicos
Operam sobre expressões, resultando valores lógicos de TRUE (verdadeiro) ou FALSE (falso). Possuem a característica de “short circuit”, ou seja, sua execução é curta e só é executada até o ponto necessário. São eles:
Operadores Lógicos em C++
Operador Ação
&& operação AND
|| operação OR
! operador de negação NOT
(operadorunário)

Exemplos de “short circuit”:
(a == b) && (b == c) /* Se a != b não avalia o resto da expressão */
(a == b) || (b == c) /* Se a == b não avalia o resto da expressão */

24.5. Manipulação de bits
A manipulação é feita em todos os bits da variável. É importante notar que avariável manipulada não pode ser do tipo float ou double. Os operadores que manipulam bits estão relacionados abaixo:

Operadores para manipulação de bits em C++
Operador Ação
& bit and
| bit or
^ bit xor - exclusive or
<< Rotação a esquerda
>> Rotação a direita
~ bit not (complemento)
Observação: x << n irá rotacionar n vezes a variável x à esquerda.

24.6. Operadores de assinalamento
É expresso da seguinte forma: (operadores combinados)
var = var op expr -> var op = expr
Onde tempos op como um dos seguintes operadores:
Operadores de Assinalamento em C++
Operador Ação
+ Soma
- Subtração
*
Multiplicação
/
Divisão
%
módulo (resto da divisão)
>>
Rotação a direita
<<
Rotação a esquerda
&
And
^
xor - exclusive or
| Or

Exemplo de aplicação:
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;*/

24.7. Operadores de Pré e Pós-Incremento
Operadores de pré e pós-incremento são aqueles usados quando é necessário incrementar ou decrementar um determinado valor.

As operações abaixo podem ser representadas assim:
i = i + 1; i = ++i; ++i;
i = i – 1; i = --i; --i;
z = a; a = a + 1; z = a++;
z = a; a = a – 1; z = a--;
a = a + 1; z = a; z = ++a;
a = a - 1; z = a; z = --a;

24.8. Operadores de Endereço
São operadores usados com ponteiros, para acesso a endereços de memória.
Operadores de endereçamento em C++
Operador Significado
& endereço de uma variável
* conteúdo do endereço especificado

Exemplos:
int var, *x;
x = &var;
var = *x;

25. Expressões

Operadores, constantes e variáveis constituem expressões. Uma expressão em C++ é qualquer combinação válida dessas partes. Uma vez que muitas expressões tendem a seguir as regras gerais da álgebra, estas regras são freqüentemente consideradas.
Entretanto, existem alguns aspectos das expressões que estão especificamente relacionadas com a linguagem C e serão discutidas agora.
25.1.  Precedência e Associatividade de Operadores
C++ possui uma série de regras de precedência de operadores, para que o compilador saiba decidir corretamente qual operador será executado primeiro, em uma expressão com vários operadores. Essas regras seguem basicamente as regras algébricas.
Além disso, é possível o uso de parênteses para forçar o compilador a executar uma parte de uma expressão antes das outras.
Além das regras de precedência, existem também certas regras de associatividade para determinados operadores que possuem o mesmo nível de precedência, como por exemplo os operadores de divisão e multiplicação. Quando C++ encontra dois operadores com o mesmo nível de precedência em uma expressão, ele verifica se estes operadores possuem associatividade esquerda-para-direita ou direita-para-esquerda. Associatividade esquerda-para-direita significa que se estes dois operadores agirem sobre um mesmo operando, o operador da esquerda será aplicado primeiro. Da mesma forma, associatividade direita-para-esquerda significa que na mesma situação, o operador da direita será aplicado primeiro. Por exemplo, os operadores divisão e multiplicação possuem associatividade esquerda-para-direita.
A tabela abaixo mostra as regras de precedência e associativade para os operadoresde C++. O número na coluna de precedência indica qual o nível de precedência dos operadores em questão, sendo 1 o nível mais alto (operador a ser executado primeiro). Na coluna de precedência, é feito o uso dos termos unário (para operadores que usam um só operando) e binário (para operadores que necessitam de dois operandos) serve para diferenciar operadores que possuem símbolos iguais. Na coluna de associatividade, as siglas E-D e D-E indicam o tipo de associatividade dos operadores daquele nível de precedência: E-D significa associatividade esquerda-para-direita, e D-E significa associatividade direita-para-esquerda.

25.2. Precedência e Associatividade de operadores em C

Operador

Descrição

Associatividade

()
[]
.
->
++  --
Parênteses (chamada de funções) (veja Nota 1)
Colchetes (vetores)
Seleção de membro via nome
Seleção de membro via apontador
Incremento/decremento pós-fixado  (veja Nota 2)

esquerda para direita

++  --
+  -
!  ~
(type)
*
&
sizeof
 
 
Incremento/decremento pré-fixado
Mais/menos unário
Negação lógica e complemento bit-a-bit
Castig (mudança de tipo)
Dereferência
Endereço
Determina tamanho em bytes
direita para esquerda
*  /  % Multiplicação/divisão/módulo esquerda para direita
+  - Adição/subtração esquerda para direita
<<  >> Deslocamento bit-a-bit à esq. e à dir.
esquerda para direita
<  <=
>  >=
Operadores relacionais menor que, menor ou igual a, maior que, maior ou igual a esquerda para direita
==  != Operadores relacionais igual/não igual esquerda para direita
& AND bit-a-bit
esquerda para direita
^ OR exclusivo bit-a-bit esquerda para direita
| OR inclusivo bit-a-bit esquerda para direita
&& AND lógico
esquerda para direita
|| OR lógico
esquerda para direita
?: Condicional ternária
direita para esquerda
=
+=  -=
*=  /=
%=  &=
^=  |=
<<=  >>=
Atribuição
Atribuição com adição/subtração
Atribuição com multiplicação/divisão
Atribuição com módulo/AND bit-a-bit
Atribuição com OR exclusivo/inclusivo bit-a-bit
Atribuição com shift à esquerda bit-a-bit
Atribuição com shift à direita bit-a-bit
direita para esquerda

,

Vírgula (separa expressões) esquerda para direita

Note 1:
Parênteses também são utilizados para agrupar expressões e forçar uma ordem diferente de avaliação. Este tipo de expressões com parênteses pode ser agrupada e é avaliada de dentro para fora.
Note 2:
Incremento e decremento pós-fixado tem alta precedência, mas o incremento ou decremento do operando é retardado (para ser completado em algum momento antes de a expressão ser finalizada). Portanto, na expressão y = x * z++; o valor atual de z é utilizado para avaliar a expressão (i.e., z++ equivale a z) e z só é incrementado após todo o resto ter sido executado. Veja postinc.c para outro exemplo.

26. Conversões de Tipos
26.1. Conversões durante a atribuição
C++ permite que o programador atribua um valor de um certo tipo para uma variável designada para armazenar outro tipo de valor, mas quando isto é feito o valor é automaticamente convertido para o tipo da variável.
Quando atribuímos um certo valor para uma variável cujo tamanho é maior do que o valor atribuído, não há problemas. Porém, quando o tamanho da variável é menor do que o valor a ser atribuído à ela, haverá truncamento deste valor e consequente perda de informação e/ou precisão.
Outro caso complicado é a atribuição de valores reais em variáveis inteiras. Quando armazenamos valores reais em variáveis inteiras, a parte fracionária do valor é descartada, resultando em truncamento do valor. Pode ocorrer também incompatibilidades de tamanho, por exemplo, um valor de tamanho float (64 bits) tentando ser armazenado em uma variável int (16 bits), causando invariavelmente perda de informações.
Por isso, é preciso tomar cuidado com os tipos e tamanhos de variáveis envolvidos durante uma atribuição de valores, para termos certeza que o valor inserido pode ser armazenado por aquela variável.

26.2. Conversões durante expressões
Quando constantes e variáveis de tipos diferentes são misturadas em uma expressão, elas são convertidas para o mesmo tipo. O compilador C++ converterá todos os operandos para o tipo do operando maior. Isso é feito na base de operação a operação, como descrito nestas regras de conversão de tipos:
1. Se algum dos operandos for do tipo long double, o outro operando é convertido para long double também.
2. Senão, se algum dos operando for double, o outro operando sera convertido para double.
3. Senão, se algum dos operandos for float, o outro operando será convertido para float.
4. Senão, os operandos são inteiros e promoções inteiras serão feitas.
5. Nesse caso, se algum dos operandos for do tipo unsigned long, o outro operando será convertido para unsigned long.
6. Senão, caso um dos operandos seja long int e o outro seja um unsigned int, a conversão dependerá do tamanho relative entre os dois tipos. Se long conseguir expressar valores possíveis de unsigned int, a variável unsigne int será convertida para long.
7. Senão, ambos os operadores são convertidos para unsigned long.
8. Senão, se algum dos operadores for long, o outro será convertido para long.
9. Senão, se algum dos operadores for um unsigned int, o outro será convertido para unsigned int.
10. Caso o compilador chegue a este ponto na lista, ambos operadores serão int.

26.3. Modeladores de Tipos
É possível também forçar a conversão de uma variável ou expressão para um determinado tipo, usando o mecanismo dos modeladores de tipos, também chamado de “type cast”. É possível utilizar duas sintaxes diferentes para obter o mesmo resultado de modelamento. São elas:
(tipo) variável_ou_expressão;
Exemplo:
(int) modelos;
(int) 19.99;
e
tipo (variável_ou_expressão);
Exemplo:
int (modelos);
int (19.99);
Ambos os comandos produzem o mesmo resultado: forçar o valor presente na variável (ou expressão) à ser convertido no tipo desejado. Note que o valor da variável não é alterado; somente é feita uma conversão momentânea, cujo valor resultante deve ser armazenada em outra variável ou trabalhado imediatamente em uma expressão.

27. Formatação de exibição com cout
A função printf fornecia aos usuários de C múltiplas maneiras de formatar a exibição dos dados na tela do computador. A classe cout também fornece as mesmas facilidades para os usuários de C++. Nas subseções abaixo descreveremos como fazer vários tipos de formatação de dados utilizando cout e o operador de inserção.

27.1. Escolhendo a Base Numérica
Podemos escolher a base numérica que utilizaremos para representar números inteiros. Para isto, devemos utilizar os comandos:
cout << hex;
cout<< oct;
cout<< dec;
Após utilizar qualquer um destes comandos, sempre que pedirmos para cout exibir um número inteiro na tela, o comando automaticamente converterá o número para a base definida previamente.
Exemplo:
int numero = 10;
cout << hex;
cout << numero;
Dessa forma, cout exibirá na tela não o número 10 como estamos acostumados, mas a letra a, que representa 10 na base hexadecimal. Note que podemos utilizar o operador de inserção duas vezes para deixar o código mais compacto e obter o mesmo resultado:
int numero = 10;
cout << hex << numero;
Não se esqueça de retornar para a base decimal com “cout << dec;” após exibir valores na base hexadecimal ou octal!

27.2. Formatação de números reais
Podemos escolher também a notação utilizada para exibição de números reais. Com o comando:
cout << fixed;
Instruímos o programa a exibir valores reais usando a notação de ponto fixo ( por exemplo, 3.1214). Da mesma forma, com o comando:
cout << scientific;
Instruímos o programa a utilizar a notação científica (por exemplo, 3.21E-2).

27.3 – Espaçamento de Texto
O comando cout permite também escolher um número mínimo de caracteres para ser exibido na tela. Isto é feito utilizando o método:
cout.width ( x );
Onde substituímos x pelo número mínino de caracteres a ser exibido na tela. Após a utilização deste método, 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 três espaços em branco.

Observe que o valor especifica o número mínimo de caracteres que a saída consumirá. Se o valor a ser exibido requer mais caracteres do que o especificado, será usado o número de caracteres necessários para exibir o valor corretamente.
É importante observar também que o método cout.width só é válido para a próxima utilização de cout: após isto, o número mínimo de caracteres volta a ser zero.
Podemos também determinar o caractere a ser utilizado para preencher os espaços em branco de um campo de exibição. Isto é feito com o seguinte método:
cout.fill ( “caractere”);
Onde substituímos “caractere” pelo caractere que será exibido. É necessário utilizar aspas entre o caractere, para indicar para o compilador que não se trata de uma variável.
O exemplo abaixo mostra a utilização conjunta destes dois métodos:
int variavel = 10;
cout.width ( 8 );
cout.fill(“0”);
cout << variavel;
Este exemplo fará a seguinte exibição na tela, preenchendo os espaços em branco determinados por cout.width com o caractere 0, determinado por cout.fill:
00000010

27.4. Precisão de Variáveis Reais
O seguinte método é utilizado para fixar a precisão de variáveis reais, ou seja, o número mínimo de casas decimais à serem exibidas após a vírgula em um valor real:
cout.precision ( valor );
Por default, C++ utiliza 6 casas decimais após a vírgula. Quando alteramos o valor da precisão, este novo valor vale para todas as utilizações futuras de cout.

27.5. Alinhamento de Texto
A escolha da direção de alinhamento de texto é feita da seguinte forma utilizando cout:

Alinhamento à direita: cout << right << <valor a ser exibido>;
Alinhamento à esquerda: cout << left << <valor a ser exibido>;
Por default, todos os valores exibidos em um programa são automaticamente alinhados à direita. Quando mudamos o modo do alinhamento de texto, ele permanecerá dessa forma até que o alteremos novamente.

28. Utilização de cin
Utilizamos o comando cin para obter valores do usuário através do teclado. A sintaxe utilizada é a seguinte:

cin >> variavel_destino;
Assim como cout, cin utiliza um operador (nesse caso, o operador de extração >> ) para identificar o tipo de variável onde o valor será armazenado e encontrar o endereço de memória correto. Ao contrário da função scanf, utilizada na linguagem C, não é preciso especificar qual o tipo de valor será enviado pelo teclado pois o operador de extração faz as conversões necessárias. Podemos utilizar cin para ler valores inteiros, reais e strings de caracteres.
Na maioria dos casos, o comando cin cobre nossas necessidades de entrada de dados via teclado. Entretanto, quando precisamos ler strings com mais de uma palavra, como por exemplo frases ou nomes, cin apresenta certos “problemas”. Isto acontece por causa da maneira que C++ trata os espaços em branco em uma entrada via teclado.
Espaços em branco são considerados fim de entrada pelo comando cin; ao invés de descartar os caracteres que vierem após o espaço em branco, C++ os guarda em um buffer (uma espécie 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 estão nesse buffer. Assim, temos a impressão que a nova entrada de dados foi descartada pelo programa, mas na verdade ela foi jogada no buffer, esperando uma nova chamada de cin.
Para solucionar este problema, utilizamos o métdo de cin cin.getline.

28.1. Método de cin: cin.getline
O método cin.getline é muito útil para receber strings de caracteres com espaços, como frases. Este método lê uma linha inteira, marcando o fim da entrada de dados pelo uso da tecla <ENTER> indicando a entrada de uma nova linha. Abaixo temos a sintaxe do método:

cin.getline ( <matriz_destino>, <limite de caracteres>);
O primeiro argumento é a matriz de caracteres para onde serão enviados os dados recebidos. É necessário declarar uma matriz de caracteres previamente ao uso deste método. O segundo argumento é o número máximo de caracteres que será lido pelo método, menos o caractere \0 indicando o fim da string. Assim, se especificarmos um número máximo igual a 20, este comando lerá 19 caracteres e descartará os próximos
caracteres entrados pelo usuário, até que a tecla <ENTER> seja pressionada. Um espaço será sempre utilizado para marcar o fim da string através do caractere \0.
Exemplo:
char matriz[60];
cin.getline ( matriz, 50 );
cout >> matriz;
Nesse caso, o método cin.getline lerá os próximos 49 caracteres (lembre-se do espaço reservado para o caractere fim_de_string \0) que o usuário entrar através do teclado.
A leitura será feita até que ele aperte a tecla <ENTER> interrompendo o comando. Caso o usuário entre mais do que 50 caracteres , os próximos serão descartados pelo programa.

29. Estruturas de Controle de Fluxo
Estruturas de controle de fluxo são comandos utilizados em uma linguagem de programação para determinar qual a ordem e quais comandos devem ser executados pelo programa em uma dada condição. C++ oferece várias opções de estrutura de controle de fluxo, todas elas herdadas da linguagem C. Neste módulo iremos ver como funcionam cada uma destas estruturas em detalhe.
Geralmente, as estruturas de controle utilizam expressões condicionais. Caso a expressão retorne 0, dizemos que ela é falsa. Caso ela retorne qualquer outro valor, dizemos que ela é verdadeira. Nesse contexto, qualquer expressão pode ser utilizada desde que retorne um valor zero ou não zero. Podemos utilizar operadores aritméticos, relacionais, lógicos, desde que no final a expressão nos retorne um valor que possa ser testado. Também é possível testar várias condições ao mesmo tempo, unindo as expressões com o auxílio dos operadores AND e OR.

29.1. A declaração if
Utilizamos a declaração if quando desejamos que o programa teste uma ou mais condições e execute um ou outro comando de acordo com o resultado deste teste. A sintaxe de if é a seguinte:
if (condição)
{
comandos;
}
else
{
comandos;
}

A declaração if testará a condição expressa entre parênteses. Caso a condição seja verdadeira, os comandos declarados entre as chaves serão executados.
A declaração else é opcional: podemos utilizá-la para determinar um conjunto de comandos que serão executados caso a condição testada seja falsa. Note que somente um dos conjuntos de comandos será executado, nunca os dois: caso a condição seja verdadeira, o bloco pertencente a if será executado; caso a condição falhe, o bloco pertencente a else será executado.
O programa abaixo ilustra de maneira simples o uso da declaração if-else, obtendo um número do usuário e verificando se este valor é maior ou igual a 100.
Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;
int main()
{
int teste;
cout<<"Digite um numero qualquer:\n";
cin>> teste;
if (teste > 100)
{
cout<<"O numero que voce digitou é maior que 100";
}
else
{
cout<<"O numero que voce digitou é menor que 100";
}
system("PAUSE > null");
return 0;
}

Compilar & Executar
Digite um numero qualquer:
45
O numero que voce digitou é menor que 100


É possível também aninhar ifs, ou seja, fazer uma declaração if dentro de outra declaração if anterior. Este é um método muito útil em programação, mas é preciso tomar cuidado ao utilizá-lo para saber qual bloco else pertence à qual if. Em C++, o else é ligado ao if mais próximo dentro do mesmo bloco de código que já não tenha uma declaração 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 código abaixo:
if ( x > 10){
   if ( x == 17){
      cout<< “x é maior que 10 e igual a 17”;
   }
   else{
      cout<< “x é maior que 10 mas não é igual a 17”;
   }
}
else
{
   cout << “x é menor do que 10”;
}

Note que a segunda declaração if está totalmente contida pelas chaves da primeira declaração if. Utilizou-se chaves em todas os blocos de comando, para melhor separar as condições dos blocos de comandos. Além disso, note o uso da tabulação para separar visualmente os diferentes blocos e declarações: poderíamos escrever todo o código sem usar tabulação, alinhando todas as linhas à esquerda, mas isto dificultaria a identificação das diferentes declarações.

29.2. O Encadeamento If – Else if
Utilizamos a variação “If – Else If” quando desejamos que o programa teste várias condições em sequência, até encontrar uma que seja verdadeira. Sua sintaxe é muito parecida com a declaração if simples:
if (condição)
{
comandos;
}
else if (condição)
{
comandos;
}
else if (condição)
{
comandos;
}

Cada bloco “else if” deverá testar uma condição diferente. O programa testará todas as condições na sequência, de cima para baixo, até encontrar uma condição verdadeira.
Quando isto acontece, os comandos pertencentes ao bloco “verdadeiro” serão executados enquanto todos os outros blocos do encadeamento são ignorados. Caso nenhuma condição “else if” seja verdadeira, executa-se o bloco de comandos pertencente ao else final. Note
que o else é opcional: Se o else final não estiver presente e todas as outras condições forem falsas, então nenhuma ação será realizada.
Utilizando este encadeamento, ampliaremos o programa anterior para que ele teste várias condições sobre um número enviado pelo usuário, até encontrar uma condição verdadeira.
Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;

int main()
{
   int teste;
   cout<<"Digite um numero qualquer:\n";
   cin>> teste;
   if (teste <= 50)
   {
      cout<<"O número que você digitou é menor que 50\n";
   }
      else if (teste > 50 && teste <= 100)
      {
      cout<<"O número digitado é maior que 50 e menor ou igual a 100\n";
      }
      else if (teste > 100 && teste <= 200)
      {
      cout<<"O número 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;
}

Compilar & Executar
Digite um número qualquer:
40
O número que você digitou é menor que 50

29.3. A Declaração Switch
A declaração switch é uma maneira fácil e elegante de se fazer uma tomada de decisão com múltiplas escolhas. Na declaração switch, a variável é sucessivamente testada contra uma lista de inteiros ou constantes caractere. Quando uma associação é encontrada, o conjunto de comandos associado com a constante é executado.
Veja a sintaxe de switch abaixo:
switch ( variável )
{
case valor1:
comandos;
break;
case valor2:
comandos;
break;
...
case valorx;
comandos;
break;
default:
comandos;
}

A declaração switch testa o valor de uma única variável. Note que existem vários “case”, cada um associado a um determinado valor. A declaração comparará o valor da variável com o valor de cada um dos “case”: quando uma associação é encontrada, os comandos pertencentes ao “case” relacionado são executados. Se nenhuma associação for encontrada, a declaração switch executará os comandos pertencentes ao bloco default (note que o bloco default é opcional: caso ele não exista, caso nenhuma associação seja encontrada a declaração switch termina sem que nenhum comando seja executado).

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
int main()
{
int option;
cout<<"Digite a opção desejada:\n";
cout<<"1. Opção 1\n";
cout<<"2. Opção 2\n";
cout<<"3. Opção 3\n";
option = 0;
cin>> option;
switch(option)
{
case 1:
cout<<"Você escolheu a primeira opção\n";
break;
case 2:
cout<<"Você escolheu a segunda opção\n";
break;
case 3:
cout<<"Você escolheu a terceira opção\n";
break;
default:
cout<<"Você escolheu uma opção inválida!\n";
}
system("PAUSE > null");
return 0;
}

Compilar & Executar
Digite a opþÒo desejada:
1. Opção 1
2. Opção 2
3. Opção 3
1
Você escolheu a primeira opção

Após o fim de cada bloco de comandos “case”, é comum utilizar o comando “break;”. Este comando interrompe a execução do laço em que o programa se encontra, fazendo com que o programa prossiga para o próximo comando imediatamente após o laço. No caso de switch, o comando break assegura que a execução da declaração switch termine, forçando o programa à voltar para sua execução normal. Caso omitíssemos os comandos break; no fim de cada bloco, a declaração switch executaria os comandos presentes no “case” em que a associação foi encontrada, e continuaria a executar todos os comandos presentes em todos os “case” na sequência (incluindo o bloco default) até o término da declaração switch. Note que este comportamento pode ser útil em alguns programas, como por exemplo uma sequência de operações matemáticas onde utilizamos a declaração switch para escolher o ponto de partida da sequência.

29.4. A declaração for
Utiliza-se a declaração for para realizar tarefas repetitivas dentro de um programa, como somar todos os elementos de uma matriz ou exibir na tela uma sequência grande de valores. A declaração for tem o seguinte formato:
for ( valor_inicial; condição_testada; valor_incremento)
{
comandos;
}

A declaração for é o que chamamos de laço ou loop em programação: um conjunto de comandos que serão executados repetidamente até que uma determinada condição falhe e termine o laço. Em for, determinamos o número de repetições desejadas através de uma variável de controle que será modificada pelos argumentos da declaração for.
valor_inicial refere-se à atribuição de um valor inicial para a variável de controle, por exemplo: “controle = 0;”
condição_testada é uma expressão qualquer contendo a variável de controle, que será testada continuamente. Enquanto a condição for verdadeira, os comandos dentro do laço for serão executados. Quando a condição falhar, o laço termina e o programa continua seu fluxo normal.
Exemplo:
for(controle=0; controle<3;controle++)
{
y=y+controle;
}

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
int main()
{
int y=0;
int controle;
for ( controle = 0; controle <= 3; controle++)
{
y=y+1;
cout << "ciclo "<<y<<": " <<"controle = "<< controle <<"\n";
}
system("PAUSE > null");
return 0;
}

Compilar & Executar
ciclo 1: controle = 0
ciclo 2: controle = 1
ciclo 3: controle = 2
ciclo 4: controle = 3

Laços infinitos geralmente surgem por algum erro de programação. Quando o programa entra em um laço infinito, pode-se pressionar Ctrl+C no modo MS-DOS para finalizar o programa.
É importante saber que mesmo omitindo um argumento, é necessário incluir o ponto-e-vírgula correspondente. Podemos omitir também a inicialização da variável de controle, caso ela tenha sido declarada e inicializada anteriormente no programa.
Também podemos criar um laço for nulo, sem um bloco de comandos:
for (x = 0; x == 50; x++)
{
}
Nesse caso, o programa ainda é interrompido para a execução do laço for, e não faz nada durante este intervalo. Esta técnica pode ser utilizada para forçar uma pausa na execução de um programa, porém ela é pouco precisa e desperdiça recursos do microprocessador.

Podemos utilizar várias variáveis de controle para controlar um mesmo laço for. Para isto, utilizamos vírgulas para separar as expressões relacionadas a cada variável dentro de um mesmo argumento. O código abaixo abaixo ilustra como isto é feito:

for (i=0, j=100; i <= 100; i++, j++)
{
cout << i << j;
}

A utilização de várias variáveis dentro de um mesmo laço for é particularmente útil em programas que trabalham com matrizes e vetores.

29.5. A declaração while
Uma outra forma de laço é a declaração while. Seu funcionamento é muito parecido com a declaração for que estudamos anteriormente. Ao encontrar um laço while, o programa testa a condição especificada. Se a condição for verdadeira, efetuará os comandos contidos no laço. Quando a condição se torna falsa, o laço termina e o programa passa para o próximo comando. A sintaxe da declaração while é a seguinte:

while (condição)
{
comandos;
}

A declaração while é diferente da declaração for em alguns aspectos.
Em primeiro lugar, while não utiliza variáveis de controle automaticamente. O único argumento entre os parênteses é a condição a ser testada: caso a condição nunca mude e seja sempre verdadeira, estaremos criando um laço infinito. Assim, cabe ao programador inserir uma variável de controle no laço while para evitar que isso ocorra. Isso pode ser feito declarando-se e inicializando-se uma variável antes do laço while, testando esta variável de controle no laço while e finalmente modificando esta variável (incrementando-a
ou decrementando-a) após a execução dos comandos necessários.

Exemplo:
Arquivo:teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
int main()
{
int controle = 0;
int y=0;
while (controle <= 3)
{
y=y+1;
cout << "ciclo "<<y<<": " <<"controle = "<< controle <<"\n";
controle++;
}
system("PAUSE > null");
return 0;
}

Compilar & Executar
ciclo 1: controle = 0
ciclo 2: controle = 1
ciclo 3: controle = 2
ciclo 4: controle = 3

29.6. A Declaração Do While
A declaração do while é parecida com a declaração while, com uma única diferença fundamental: o teste condicional é feito após a execução dos comandos pertencentes ao laço.
Veja a sintaxe do laço do while:
do
{
comandos;
}
while ( condição);

Note a inversão da ordem: primeiro temos a declaração do seguida do corpo do laço, contendo os comandos à serem executados entre as chaves. Após o símbolo fechachaves, temos a declaração while e a expressão que será testada. Os comandos entre as chaves serão executados até que a condição torne-se falsa. Porém, lembre-se que a condição só será testada após a execução dos comandos dentro do laço, ao contrário dos
laços que vimos anteriormente que antes testavam uma condição para depois executar qualquer comando.
Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
int main()
{
int controle = 1;
do {
cout << "ciclo "<<controle<<": " <<"controle = "<< controle <<"\n";
controle++;
}
while (controle <= 3);
system("PAUSE > null");
return 0;
}

Compilar & Executar
ciclo 1: controle = 1
ciclo 2: controle = 2
ciclo 3: controle = 3

29.7. Laços Aninhados
Qualquer um dos laços estudados acima pode ser aninhados, ou seja, colocados um dentro do outro. Esta técnica pode ser muito útil para trabalhar com matrizes multidimensionais, programas que trabalhem com menus e várias outras situações.
Entretanto, é preciso atenção para não confundir quais blocos fazem parte de qual laço ou declaração. É fundamental a utilização de chaves para separar corretamente os blocos e laços, e também a utilização de tabulação na escrita do código para melhor visualização de cada uma das partes do programa. Também é interessante a utilização de comentários no código, para melhor identificação.
O programa exemplo abaixo demonstra a utilização de vários laços e declarações aninhadas, assim como a aplicação de tabulação e comentários para melhor entendimento do programa.

#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
int main()
{
int mult1, mult2;
   for (mult1 = 1; mult1 <= 10; mult1++)
   {
    cout<<"Tabuada do numero "<<mult1<<":\n";
       for (mult2 = 1; mult2 <= 10; mult2++)
       {
        cout.width(2);
        cout<<mult1<<" X ";
        cout.width(2);
        cout<<mult2<<" = ";
        cout.width(3);
        cout<<mult1*mult2<<"\n";
       }
   }
system("PAUSE > null");
return 0;
}

Compilar & Executar
Tabuada do numero 1:
 1 X  1 =   1
 1 X  2 =   2
 1 X  3 =   3
 1 X  4 =   4
 1 X  5 =   5
 1 X  6 =   6
 1 X  7 =   7
 1 X  8 =   8
 1 X  9 =   9
 1 X 10 =  10
Tabuada do numero 2:
 2 X  1 =   2
 2 X  2 =   4
 2 X  3 =   6
 2 X  4 =   8
 2 X  5 =  10
 2 X  6 =  12
 2 X  7 =  14
 2 X  8 =  16
 2 X  9 =  18
 2 X 10 =  20
Tabuada do numero 3:
 3 X  1 =   3
 3 X  2 =   6
 3 X  3 =   9
 3 X  4 =  12
 3 X  5 =  15
 3 X  6 =  18
 3 X  7 =  21
 3 X  8 =  24
 3 X  9 =  27
 3 X 10 =  30
Tabuada do numero 4:
 4 X  1 =   4
 4 X  2 =   8
 4 X  3 =  12
 4 X  4 =  16
 4 X  5 =  20
 4 X  6 =  24
 4 X  7 =  28
 4 X  8 =  32
 4 X  9 =  36
 4 X 10 =  40
Tabuada do numero 5:
 5 X  1 =   5
 5 X  2 =  10
 5 X  3 =  15
 5 X  4 =  20
 5 X  5 =  25
 5 X  6 =  30
 5 X  7 =  35
 5 X  8 =  40
 5 X  9 =  45
 5 X 10 =  50
Tabuada do numero 6:
 6 X  1 =   6
 6 X  2 =  12
 6 X  3 =  18
 6 X  4 =  24
 6 X  5 =  30
 6 X  6 =  36
 6 X  7 =  42
 6 X  8 =  48
 6 X  9 =  54
 6 X 10 =  60
Tabuada do numero 7:
 7 X  1 =   7
 7 X  2 =  14
 7 X  3 =  21
 7 X  4 =  28
 7 X  5 =  35
 7 X  6 =  42
 7 X  7 =  49
 7 X  8 =  56
 7 X  9 =  63
 7 X 10 =  70
Tabuada do numero 8:
 8 X  1 =   8
 8 X  2 =  16
 8 X  3 =  24
 8 X  4 =  32
 8 X  5 =  40
 8 X  6 =  48
 8 X  7 =  56
 8 X  8 =  64
 8 X  9 =  72
 8 X 10 =  80
Tabuada do numero 9:
 9 X  1 =   9
 9 X  2 =  18
 9 X  3 =  27
 9 X  4 =  36
 9 X  5 =  45
 9 X  6 =  54
 9 X  7 =  63
 9 X  8 =  72
 9 X  9 =  81
 9 X 10 =  90
Tabuada do numero 10:
10 X  1 =  10
10 X  2 =  20
10 X  3 =  30
10 X  4 =  40
10 X  5 =  50
10 X  6 =  60
10 X  7 =  70
10 X  8 =  80
10 X  9 =  90
10 X 10 = 100


29.8 Break e Continue
Utilizamos os comandos break e continue para pular partes de um código. Já vimos a utilização do comando break quando falamos sobre a declaração switch: ele é utilizado para interromper a execução de um laço, pulando imediatamente para o próximo comando após o fim do laço. O comando break “quebra” qualquer teste de condição que esteja sendo feito, forçando o laço a terminar abruptamente.
O comando continue é utilizado em um laço de repetição para pular todos os comandos que seriam executados na sequência do comando continue e forçar o laço a pular para a próxima repetição. O comando break força o laço a terminar; já o comando continue pula os próximos comandos que seriam feitos mas continua a executar o laço.

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;
int main()
{
int opcao;
while (opcao!= 5)
{
cout<<"Escolha um numero entre 1 e 4. Escolha 5 para sair do programa\n";
cin>>opcao;
if ((opcao> 5) || (opcao< 1))
{
cout<<"Voce escolheu um numero maior que 5 ou menor que 1\n";
continue; //opção invalida: volta ao inicio do loop
}
switch (opcao)
{ //início do switch
case 1:
cout<<"O numero 1 foi escolhida\n";
break;
case 2:
cout<<"O numero  2 foi escolhida\n";
break;
case 3:
cout<<"O numero 3 foi escolhida\n";
break;
case 4:
cout<<"O nmero 4 foi escolhida\n";
break;
case 5:
cout<<"Você saiu do programa\n";
break;
} //fim do switch
} //fim do laço while
system("PAUSE > null");
}

Compilar & Executar
Escolha um numero entre 1 e 4. Escolha 5 para sair do programa
<enter>
Voce escolheu um numero maior que 5 ou menor que 1
Escolha um numero entre 1 e 4. Escolha 5 para sair do programa
<enter>
O numero 1 foi escolhida
Escolha um numero entre 1 e 4. Escolha 5 para sair do programa
<enter>
O numero  2 foi escolhida
Escolha um numero entre 1 e 4. Escolha 5 para sair do programa
<enter>
O numero 3 foi escolhida
Escolha um numero entre 1 e 4. Escolha 5 para sair do programa
<enter>
O nmero 4 foi escolhida
Escolha um numero entre 1 e 4. Escolha 5 para sair do programa
<enter>
Você saiu do programa

Observação:
A primeira entrada foi o número 7, isso fez com que o comando continue fosse executado, depois foram digitados os números 1, 2, 3 e 4 que são opções de escolha do loop while, ao digitar 5 o programa é encerrado porque a condição do loop while é opcao!=5, ou seja, a variável de entrada dos dados ser diferente de 5.

30. Matrizes
Matrizes são variáveis que são capazer de armazenar vários valores do mesmo tipo, pondendo agrupá-los em linhas e colunas como a matriz que conhecemos na matemática, em programação as matrizes também são chamadas de vetores quando tem apenas uma dimensão. Uma das grandes vantagens da matriz na programação é de poder fazer cálculos matriciais normalmente como fazemos na matemática.
Podemos criar matrizes para armazenar qualquer um dos tipos básicos de variáveis, como int, float e char. Cada valor é armazenado separadamente em um elemento da matriz, e pode ser acessado e modificado a qualquer momento.

30.1. Declaração de uma matriz
<tipo> <nome> [<numero de elementos>];
Para criar uma matriz, precisamos declarar três atributos:
- O tipo de valor que vai ser armazenado na matriz
- O nome da matriz, para que possamos acessá-la
- O número de elementos da matriz
É necessário adicionar o número de elementos da matriz.

Podemos utilizar qualquer tipo de variáveis 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.
Não é possível criar uma matriz “genérica” que aceite um tipo qualquer, ou vários tipos.
Isso acontece porque ao declarar uma matriz, o compilador aloca memória suficiente para conter o número de valores especificado de acordo com o tipo da matriz.

Como uma variável normal, podemos atribuir valores para uma matriz no momento de sua declaração. Isto é feito utilizando o operador de atribuição “=” seguido dos valores contidos entre chaves e separados por vírgulas.
Por exemplo, considere a matriz de inteiros “mtz” abaixo:
int mtz[5] = { 1, 2, 3, 4 };
Também podemos atribuir apenas parte dos valores de uma matriz, por exemplo, podemos criar uma matriz que comporte 10 valores do tipo float e atribuir apenas 5 valores à ela, deixando para atribuir o restante dos valores no decorrer do programa.
float medidas[10] = { 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 inicio[10] = {0};

30.2. Acessando Valores de uma Matriz
O primeiro elemento de uma matriz tem índice 0 (zero), o segundo elemento tem índice 2 (dois) e assim sucessivamente, para uma matriz com quatro elementos, mtz[4], seu elementos são acessados através do seu índice:
1º elemento:
mtz[0]
2º elemento: mtz[1]
3º elemento: mtz[2]
4º elemento: mtz[3]

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;
int main() {
int mtz[4] = {10,20,30,40};
cout<<"o primeiro valor da matriz é: "<<mtz[0]<<endl;
cout<<"o segundo valor da matriz é: "<<mtz[1]<<endl;
cout<<"o terceiro valor da matriz é: "<<mtz[2]<<endl;
cout<<"o quarto valor da matriz é: "<<mtz[3]<<endl;
cout<<"Soma do primeiro e do último elemento da matriz temos: "<< mtz[0] + mtz[3]<<endl;
mtz[0]=5
cout<<"Mudando o valor do primeiro elemento da matriz é: "<<matriz[0]<<endl;
system(“PAUSE > null”);
return 0;
}

Compilar e Executar
o primeiro valor da matriz é: 10
o segundo valor da matriz é: 20
o terceiro valor da matriz é: 30
o quarto valor da matriz é: 40
Soma do primeiro e do último elemento da matriz é: 50
Mudando o valor do primeiro elemento da matriz para: 5

30.3. Utilizando Laços para Percorrer Matrizes
É só utilizar um loop para entrar com os elementos e outro loop para imprimí-los na tela.

Exemplo:
Arquivo: teste.cpp
#include <iostream>
using namespace std;
int main()
{
const int tamanho = 5;
int mtz[tamanho];
for (int i = 0; i < 5; i++) {
cout << "Entre com o elemento numero "<<(i+1)<<" da matriz: ";
cin >> mtz[i];
}
cout << "Os elementos entrados foram: ";
for (int i = 0; i < 5; i++) {
cout << mtz[i]<<", ";
}
system("PAUSE > null");
return 0;
}

Compilar & Executar
Entre com o elemento numero 1 da matriz: 2
Entre com o elemento numero 2 da matriz: 4
Entre com o elemento numero 3 da matriz: 6
Entre com o elemento numero 4 da matriz: 8
Entre com o elemento numero 5 da matriz: 10
Os elementos entrados foram: 2, 4, 6, 8, 10,

Observe que o tamanho da matriz foi definido por uma constante, isso facilita a alteração do código.

30.4. Matrizes Multidimensionais
Além das matrizes simples de uma única dimensão, C++ permite a criação de matrizes de múltiplas dimensões. As matrizes bidimensionais são sem dúvida as mais utilizadas e as mais úteis, pois comportam-se como tabelas com linhas e colunas. Ao declarar uma matriz multidimensional, adicionamos um conjunto de colchetes para cada dimensão extra. Entre os colchetes de cada dimensão, colocamos o número de elementos que aquela dimensão terá (ou uma variável que represente o número de elementos).

Exemplos:
int tabela [linha] [coluna]; //matriz bidimensional
int eixos [eixox] [eixoy] [eixoz]; //matriz de três dimensões
int tempo [seg] [min] [horas] [dias]; //matriz de quatro dimensões

É comum o uso de matrizes bidimensionais e tridimensionais na computação gráfica, facilita a manipulação de dados.
Uma matriz bidimensional nada mais é que uma matriz de uma dimensão cujos elementos são outras matrizes, da mesma forma para matrizes multidimensionais.

Dimensões
Uma Dimensão:
mtz[coluna]
Também chamada de vetor, observe que há apenas uma linha e o número de elementos é igual ao número de colunas. Uma dimensão significa uma linha.
O índice dos elementos começa com 0 (zero).
mtz={a0 0, a0 1, a0 2}

Duas dimensões: mtz[coluna][linha]
Também chamada tabela. A segunda dimensão significa a quantidades de agrupamentos de primeira dimensão, ou seja, o número de linhas.

int mtz[3][3] = {{a0 0, a0 1, a0 2},{a1 0,a1 1,a1 2},{a2 0,a2 1,a2 2}}

Agrupamento dos elementos na forma de uma matriz ou uma tabela:



array 0
0
1
2
0
a0 0 a0 1 a1 2
1
a1 0 a1 1 a1 2
2
a2 0 a2 1
a2 2

Obs: os índices dos elementos e o tamanho da matriz são trocados: mtz[coluna][linha] 
alinha coluna

Três Dimensões: mtz[coluna][linha][array]
A terceira dimensão é uma array cuja os elementos são os agrupamentos anteriores, ou seja, indica a quantidade de tabelas ou matrizes.

int mtz[3][3][3]=
= {{{a0 0, a0 1, a0 2},{a1 0,a1 1,a1 2},{a2 0,a2 1,a2 2}},
{{a0 0, a0 1, a0 2},{a1 0,a1 1,a1 2},{a2 0,a2 1,a2 2}},
{{a0 0, a0 1, a0 2},{a1 0,a1 1,a1 2},{a2 0,a2 1,a2 2}}}


Array 0
0
1
2
0
a0 0 a0 1 a1 2
1
a1 0 a1 1 a1 2
2
a2 0 a2 1
a2 2

Array 1
0
1
2
0
a0 0 a0 1 a1 2
1
a1 0 a1 1 a1 2
2
a2 0 a2 1
a2 2

Array 2
0
1
2
0
a0 0 a0 1 a1 2
1
a1 0 a1 1 a1 2
2
a2 0 a2 1
a2 2


Exemplo:
Por exemplo, veja a matriz bidimensional tabela:
int tabela [2] [3] = { {1,2}, {3,4}, {5,6}};
A mesma é constituida por duas colunas e três linhas, observe o esquema abaixo para facilitar o entendimento.
int mtz[2][3] = {{a
0 0, a0 1},{a1 0, a1 1},{a2 0, a2 1}}

Observe novamente que o indice dos elementos e o tamanho da matriz são trocados (linhas e colunas).

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
int main()
{
int duastabela [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 << duastabela[i][j][k]<<" ";
         }
      cout<<endl;
      }
   cout<<endl;
   }
system("PAUSE > null");
return 0;
}

Compilar & Executar
9 8
7 6

5 4
3 2

Observe a figura abaixo afim de entender melhor o exercício anterior. O primeiro cochete corresponde a matriz de uma dimensão com seu respectivo tamanho (quantidade de elemento), também chamada de vetor, o segundo cochete corresponde a uma matriz de duas dimensões
com seu respectivo tamanho (quantidade de elemento) e o terceiro cochete corresponde a matriz de três dimensões com seu respectivo tamanho (quantidade de elemento).



O esquema abaixo mostra melhor a distribuição dos elementos em uma matriz de uma , duas e três dimensões.




30.5. Matrizes em Funções
Podemos utilizar matrizes como parâmetros de funções com alguns cuidados simples. Ao declarar os parâmetros que serão utilizados na função, declaramos um parâmetro para a matriz e um parâmetro para seu tamanho separadamente. Fazemos isso para que possamos utilizar matrizes de qualquer tamanho utilizando a mesma função. Ao criar o parâmetro referente à matriz, usamos um conjunto de colchetes vazios para indicar
que se trata de uma matriz e não de uma variável simples. No entanto, quando utilizarmos esta função, passamos para ela somente o nome da matriz, sem os parênteses: o programa “já sabe” que uma matriz será enviada, pois já declaramos isso no protótipo da função. O programa abaixo mostra uma função que soma todos os elementos de uma matriz.

Exemplo:
Arquivo: teste.cpp
#include <iostream>
using namespace std;
int soma( int matriz[], int tamanho) {
int resultado = 0;
for (int i = 0; i < tamanho; i++){
resultado = resultado + matriz[i];
}
return resultado;
}
int main()
{
const int TAMANHO = 4;
int sequencia[TAMANHO];
int result = 0;
for (int i = 0; i < 4; i++) {
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;
}

Compilar & Executar
Entre com o elemento numero 1 da sequencia: 2

Entre com o elemento numero 2 da sequencia: 4

Entre com o elemento numero 3 da sequencia: 6

Entre com o elemento numero 4 da sequencia: 8

A soma de todos os elementos da matriz e igual a 20.


Também podemos utilizar funções que trabalhem com matrizes multidimensionais.
Entretanto, ao criar o parâmetro da matriz é preciso declarar o tamanho de todas as dimensões da matriz com exceção da primeira.
Exemplo:
int soma_tabela ( int matriz [ ] [3] [4], int elementos) { comandos; }

A primeira dimensão é deixada em branco, para ter seu tamanho definido pelo outro parâmetro “elementos”. Entretanto, as outras duas dimensões tem seu tamanho definido respectivamente em 3 e 4. Caso deixássemos estas outras duas dimensões sem um tamanho definido, o programa não seria compilado.
É muito importante notar que, ao trabalhar com matrizes dentro de funções, estamos trabalhando com a própria matriz, ou melhor, com o endereço dos dados desta matriz. Normalmente, quando trabalhamos com variáveis dentro de uma função, estamos trabalhando com cópias destes valores. Entretanto, isso não é verdade para matrizes, por razões que veremos no módulo sobre ponteiros. Por enquanto, basta saber que quando trabalhamos com matrizes dentro de funções, qualquer modificação feita na matriz é feita para valer. Se somarmos mais 10 a todos os valores de uma matriz em uma função, quando a função terminar a matriz estará modificada. Esta característica é muito útil para contornar o fato que não podemos utilizar uma matriz como retorno de uma função: não precisamos que a função retorne uma matriz, só precisamos fazer com que a função altere a matriz. Por exemplo, o programa abaixo usa uma função para ordenar os números dentro de uma matriz.
Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
int ordena( int matriz[], int tamanho) {
int temp = 0;
   for (int i = 0; i < tamanho; i++){
       cout <<"ciclo externo"<<i+1<<": i = "<<i<<"\n"; // para visualizar os ciclos
      for (int j = i; j < tamanho; j++){
          cout <<"ciclo interno"<<j+1<<": j = "<< j<<"\n"; // para visualizar os ciclos
         if (matriz[j] < matriz [i]) {
         temp = matriz[i];
         matriz[i] = matriz[j];
         matriz[j] = temp;
         }
      }
   }
}
int main()
{
const int TAMANHO = 4;
int sequencia[TAMANHO] = {100, 50, -5, 12};
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;
}

Compilar & Executar
Sequencia original: 100 50 -5 12
ciclo externo1: i = 0
ciclo interno1: j = 0
ciclo interno2: j = 1
ciclo interno3: j = 2
ciclo interno4: j = 3
ciclo externo2: i = 1
ciclo interno2: j = 1
ciclo interno3: j = 2
ciclo interno4: j = 3
ciclo externo3: i = 2
ciclo interno3: j = 2
ciclo interno4: j = 3
ciclo externo4: i = 3
ciclo interno4: j = 3
Sequencia ordenada: -5 12 50 100
 
Observe o loop for, como j = i no for interno, o ciclo interno inicia com 0, 1, 2 e 3, a comparação
matriz[j] < matriz [i] é realizada com cada elemento da matriz, o primeiro ciclo acha o menor elemento, o segundo ciclo acha o segundo menor elemento, e assim sucessivamente.

30.6. Criando Matrizes Dinamicamente
A linguagem C++ prima pela economia de memória durante a execução de seus programas. Quando declaramos uma matriz no início de um programa, o compilador separa um “pedaço” da memória do computador de tamanho equivalente ao tamanho máximo da matriz. Assim, se criarmos uma matriz de inteiros com 200 elementos, o compilador separa na memória do computador um espaço de 400 bytes (2 bytes x 200
elementos). Entretanto, quando trabalhamos com matrizes frequentemente não sabemos qual o tamanho exato de elementos que precisamos. Ao criar uma matriz, estipulamos um valor que seja maior do que o valor máximo de elementos que precisamos, mesmo que não utilizemos todos os espaços disponíveis na matriz. Isso causa desperdício de memória do computador e lentidão na execução de programas. Para evitar este problema, a linguagem C++ introduz dois novos operadores de controle de memória. Em primeiro lugar, temos o operador new, que é utilizado para alocar espaços na memória de computador durante a execução de um programa. Em segundo lugar, o operador delete, que libera a memória alocada com o operador new após
sua utilização. Este tipo de criação e destruição de variáveis é chamado de alocação dinâmica. Uma matriz criada dessa forma é chamada de matriz dinâmica.
A vantagem de se criar matrizes dinâmicas é que a memória utilizada pela matriz só é “tirada” do sistema após a execução do operador new, e pode ser liberada novamente após sua utilização com o operador delete. Quando criamos uma matriz do jeito “normal”, a memória utilizada por ela é guardada pelo programa durante toda sua execução, consumindo recursos desnecessários do computador.
A sintaxe para criar-se uma matriz utilizando o operador new é a seguinte:
<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 análoga ao de uma matriz criada do jeito “normal”: utilizamos o nome da matriz seguido do número do elemento acessado. Como já dito anteriormente, o primeiro elemento de uma matriz é sempre o elemento 0.
Note que não podemos inicializar automaticamente os valores de uma matriz criada dessa forma. Cada elemento da matriz deve ter seu valor atribuído 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 declaração normal não podem ser apagadas durante a execução do programa. Para utilizar o operador delete para apagar uma matriz, a sintaxe é a seguinte:
delete <nome>;
O programa abaixo pede ao usuário o número de elementos da matriz, cria uma matriz e depois volta a pedir ao usuário os valores de cada um dos elementos da matriz. No final do programa, a matriz é deletada.
Exemplo:
Arquivo: teste.cpp

#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
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++) { // preenchimento da matriz
      cout << "Entre com o elemento "<<(i+1)<<" da matriz: ";
      cin>>sequencia[i];
      cout<<endl;
   }
   cout<<"A matriz entrada é: ";
   for (int i = 0; i < tamanho; i++) {  // imprimindo a matriz na tela
      cout << sequencia[i]<<" ";
   }
   cout<<endl;
cout<<"Programa encerrado. A matriz criada será deletada, e a memória será devolvida para o processador.";
delete sequencia;
system("PAUSE > null");
return 0;
}

Compilar & Executar
Entre com o tamanho da matriz: 4

Entre com o elemento 1 da matriz: 10

Entre com o elemento 2 da matriz: 20

Entre com o elemento 3 da matriz: 30

Entre com o elemento 4 da matriz: 40

A matriz entrada é: 10 20 30 40
Programa encerrado. A matriz criada será deletada, e a memória será devolvida para o processador.

31. Strings
Não falamos até agora de matrizes de caracteres, apesar de já utilizá-las várias vezes. Uma matriz de caracteres é normalmente chamada de “string” em linguagem de programação. Em C++, existem duas maneiras de se criar e trabalhar com strings. Um deles é o método antigo, já utilizado pela linguagem C, de se declarar e trabalhar com uma matriz de caracteres do mesmo modo que trabalhamos com matrizes numéricas. O outro método é utilizar as facilidades da biblioteca padrão de C++, que define um tipo de variável específico para strings, com várias operações e funções próprias. 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.

31.1. Cabeçalho de um programa com strings
Todo programa escrito em C++ deve conter a seguinte linha de inclusão em seu cabeçalho:
#include <string>
Isso faz com que o compilador inclua no programa a biblioteca padrão de strings de C++, que contém todas as definições do tipo string, assim como as funções e facilidades relacionados à este tipo. Assim, o cabeçalho de um programa típico envolvendo strings fica assim:

#include <iostream>
#include <string>
using namespace std;

31.2  Declarando e Inicializando uma String
Declaramos strings da mesma maneira que declaramos variáveis: explicitando o tipo da variável (no caso, string) e seu nome. Veja a sintaxe e o exemplo abaixo:
string <nome da string>;
string nacionalidade;
string sobrenome;
Uma string declarada desta forma estará vazia até que um valor seja atribuído à ela, das maneiras já estudadas: através de uma atribuição, ou de uma entrada de dados do usuário, por exemplo.
C++ possui uma série de facilidades para a inicialização de strings. Cada um desses diferentes métodos é chamado de “inicializador” de uma string. A tabela abaixo reúne os quatro principais inicializadores de string:

string s1; Cria uma string vazia, chamada s1. Esta é a inicialização default de uma string: toda string criada dessa forma está vazia.
string s2 (s1); Cria a string s2 como uma cópia de outra string (nesse caso, s1).
string s2 (“Esta é uma string literal”);Cria a string s2 como uma cópia da string literal entre os parênteses.
string s2 (x, ‘c’); Cria a string s2, que contém x cópias do caractere entre aspas (no caso, c).

Exemplo:
Arquivo: teste.cpp

#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
#include <string>

using namespace std;
int main()
{
string str1;
cout <<"'str1' está sem valor:"<< endl;
str1="Primeiro valor da str1";
cout <<"Impressão da variável 'str1' com valor: "<<str1<< endl;
string copia_str1(str1);
string repete_a( 5, 'a');
cout <<"Impressão da cópia da 'str1':"<<copia_str1<< endl;
cout <<"Impressão do conteúdo da string 'repete_a': "<<repete_a<< endl;
system("PAUSE > null");
return 0;
}

Compilar & Executar
'str1' está sem valor:
Impressão da variável 'str1' com valor: Primeiro valor da str1
Impressão da cópia da 'str1': Primeiro valor da str1
Impressão do conteúdo da string 'repete_a': aaaaa

31.3. Leitura e Escrita de Strings na Tela
Utilizamos cin e cout para ler e escrever strings, assim como fazemos com variáveis simples. Basicamente, cin e cout tratam strings como se fossem variáveis simples, facilitando sua manipulação 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 através do teclado. A sintaxe é a seguinte: cin >> <nome da strin>;
Como já vimos, cin lerá os caracteres inseridos através do teclado até encontrar um espaço em branco (tecla barra de espaço) ou o fim da entrada (tecla Enter). Quando cin encontra um espaço em branco, todos os caracteres após este espaço são ignorados. O programa abaixo lê entradas do teclado para armazenar o nome e sobrenome do usuário dentro de strings.

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
#include <string>
using namespace std;
int main()
{
string p1;
string p2;
cout<<"Entre com uma palavra: ";
cin >> p1;
cout<<"Entre com outra palavra: ";
cin >> p2;
cout<<"As duas palavras são: ";
cout << p1<<" e "<<p2<<endl;
system("PAUSE > null");
return 0;
}

Compilar & Executar
Entre com uma palavra: palavra1
Entre com outra palavra: palavra2
As duas palavras são: palavra1 e palavra2

Observação:
Espaços em branco são considerados fim de entrada pelo comando cin; ao invés de descartar os caracteres que vierem após o espaço em branco, C++ os guarda em um buffer (uma espécie 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 estão nesse buffer. Assim, temos a impressão 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 não é o método recomendado para ler frases inteiras, com palavras separadas por espaços. Para este objetivo, utilizamos o método cin.getline.
O método cin.getline lê linhas inteiras de entrada através do teclado, sem se importar com os espaços em branco. Mas a sintaxe do método cin.getline é um pouco diferente, quando trabalhamos com strings:
getline ( cin, <nome da string>);
Assim, este método recebe todos os caracteres (incluindo os espaços em branco) entrados pelo usuário, até que ele aperte a tecla Enter.

Exemplo:
Arquivo:
teste.cpp

#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
#include <string>
using namespace std;
int main()
{
string frase;
cout<<"Entre com uma frase: ";
getline(cin, frase);
cout <<"A frase digitada é "<<frase<<endl;
system("PAUSE > null");
return 0;
}

Compilar e Executar
Entre com uma frase: Olá como vai!
A frase digitada é: Olá como vai!

31.4. Operações com Strings
C++ possui uma série de funções e operações próprias para strings. Seja str uma string qualquer:
str.empty( ) Função que retorna verdadeiro se a string está vazia (true ou 1), e falso (false ou 0)  caso contrário
str.size( ) Função que retorna o tamanho em caracteres da string
str [n] Acessa um elemento da string. Funciona exatamente com um elemento de uma matriz.
str1 + str2 Concatena duas strings
str1 = trs2 Atribui o conteúdo de str2 na string str1
str1 == str2 Testa a igualdade entre str1 e str2 (retorna verdadeiro se as duas strings forem iguais). Duas strings são consideradas iguais se elas tiverem o mesmo número de caracteres e seus caracteres forem iguais.

Como vemos acima, é possível acessar um elemento individual de uma string do mesmo modo que fazemos com matrizes. Esse tipo de acesso é útil quando precisamos manipular os vários caracteres de uma string, como por exemplo, identificar as letras maiúsculas de uma string e transformá-las em minúsculas. Para esse tipo de manipulação caractere à caractere, contamos com as diversas funções da biblioteca cctype.
A concatenação de strings é particularmente útil. Quando utilizamos o sinal de soma entre duas strings, estamos concatenando elas, ou seja, juntando o começo da segunda matriz com o final da primeira. Também é possível concatenar strings literais ( frases entre aspas) junto com as variáveis string dessa forma.


Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
#include <string>
using namespace std;
int main()
{
string frase1, frase2, strsoma;
cout<<"Entre com a primeira frase: ";
getline(cin, frase1);
cout<<"Entre com a segunda frase: ";
getline(cin, frase2);

strsoma= frase1 +" "+ frase2;
cout << "A concatenação  é : "<<strsoma;

system("PAUSE > null");
return 0;
}


Compilar & Executar
Entre com a primeira frase: Olá como vai!
Entre com a segunda frase: Por onde andas?
A concatenação  é : Olá como vai! Por onde andas?

32. Bibliotecas
32.1. Biblioteca cctype: operações com caracteres
A biblioteca cctype é uma versão da biblioteca ctype da linguagem C, convertida para C++. Ela contém diversas funções que permitem processar os caracteres de uma string, um por um. Por exemplo, podemos precisar saber se um determinado caracter é uma letra ou um número, se está acentuado ou não, se é minúsculo ou maiúsculo, e transformar este caractere. Para utilizar esta biblioteca, precisamos declará-la no cabeçalho do programa, assim como fizemos com a biblioteca de strings. Para declará-la, a sintaxe é a
seguinte:
#include <cctype>
Assim, o cabeçalho de um programa que utiliza strings e a biblioteca cctype ficaria assim:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;

Abaixo temos algumas das funções mais úteis desta biblioteca (x é um elemento de uma string, por exemplo, “str[6]”):
isalnum(x) Retorna verdadeiro (1) caso x for uma letra ou um número
isalpha(x) Retorna verdadeiro (1) caso x for uma letra
iscntrl(x) Retorna verdadeiro (1) caso x for um dígito de controle
isdigit(x) Retorna verdadeiro (1) caso x for um número
isgraph(x) Retorna verdadeiro (1) caso x não for um espaço
islower(x) Retorna verdadeiro (1) caso x for uma letra minúscula
isprint (x) Retorna verdadeiro (1) caso x for um caractere imprimível
ispunct(x) Retorna verdadeiro (1) caso x for um caractere acentuado
isspace(x) Retorna verdadeiro (1) caso x for um esaço em branco
isupper (x) Retorna verdadeiro (1) caso x for uma letra maiúscula
isxdigit (x) Retorna verdadeiro (1) caso x for um número hexadecimal
tolower (x) Transforma um caractere maiúsculo em minúsculo
toupper(x) Transforma um caractere minúsculo em maiúsculo

Com exceção das duas últimas funções 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 funções, através da leitura de uma string entrada pelo usuário. Note que também é feito o uso da função <string>.size para determinar o tamanho da string.

Exemplo:
Arquivo: teste.cpp

#include <iostream>
#include <string>
using namespace std;
int main()
{
string frase;
int letras = 0, upper = 0, lower = 0, digit= 0;
cout<<"Digite uma frase com letra maúsculas, minúsculas 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])) digit++;
if (islower(frase[i])) lower++;
if (isupper(frase[i])) upper++;
}
cout<<"Sua frase tem "<< digit<< " numeros."<<endl;
cout<<"Sua frase tem "<< lower<< " letras
minusculas."<<endl;
cout<<"Sua frase tem "<< upper<< " letras
maiusculas."<<endl;
system("PAUSE > null");
return 0;
}

Compilar & Executar
Digite uma frase com letra maúsculas, minúsculas e números:
São Paulo, 10 de janeiro de 1855.  <enter>
Sua frase tem 33 letras.
Sua frase tem 6 numeros.
Sua frase tem 16 letras minusculas.
Sua frase tem 2 letras maiusculas.

Observação:
A letra ã, os espaços em branco e o ponto final não foram contados como maiúsculas ou minúsculas;

32.2. Entrada e Saída de Dados
A maioria dos programas de computador trabalham com arquivos. Processadores de texto criam e editar arquivos de texto; navegadores de internet interpretam e exibem arquivos HTML; compiladores leêm arquivos-fonte e geram arquivos executáveis. Um arquivo nada mais é do que uma sequência de bytes armazenada em um dispositivo, seja esse dispositivo, por exemplo, um disco rígido, um CD ou um disquete. Tipicamente, o sistema operacional gerencia os arquivos presentes em um computador, mantendo registro
de onde estão armazenados, quais os seus tamanhos, quando foram criados, etc.
Quando trabalhamos com arquivos em programação, precisamos de meios para conectar um programa à um arquivo, de modo que o programa possa ler e escrever dados dentro deste arquivo, e também meios para criar novos arquivos e salvá-los em um dispositivo. A linguagem C++ possui um pacote de classes e funções que trabalham com arquivos de forma bastante semelhante às classes cout e cin já estudadas.

32.2.1.  <fstream>
O primeiro passo para manipular um arquivo em C++ é adicionar a biblioteca específica para a manipulação de dados em arquivos ao cabeçalho de nosso programa. Esta biblioteca é chamada de “fstream”, de “file stream” (fluxo de arquivos).
Exemplo:
#include <iostream>
#include <fstream>
using namespace std;

Note que os nomes das duas bibliotecas são parecidos: ambas contém classes que trabalham com entrada e saída de dados. No entanto, a biblioteca iostream trabalha apenas com o fluxo de dados via monitor/teclado/periféricos, enquanto que a biblioteca fstream trabalha com o fluxo de dados de arquivos. (Na verdade, atualmente a biblioteca fstream engloba todas as classes contidas em iostream, mas nem todos os compiladores já adotaram essa modificação).

32.2.2 – Os objetos de fstream
Uma vez adicionada a biblioteca, podemos criar objetos em nossos programas que servirão de intermediários entre o programa e os arquivos manipulados. A biblioteca fstream define três tipos de objeto para esta função, cada um com objetivo definido:
ofstream objetos que escrevem dados em um arquivo
ifstream objetos que leêm dados em um arquivo
fstream objetos que podem tanto ler como escrever em um arquivo

32.2.3  Escrita em arquivo
Podemos resumir assim as etapas necessárias para escrever em um arquivo através de um programa em C++:
- Cria-se um objeto do tipo ofstream.
- Associa-se este objeto com um arquivo em particular (seja criando ou abrindo um arquivo já existente).
- Usa-se o objeto para enviar dados para este arquivo, de forma bem parecida como usamos o comando cout. A diferença é que os dados vão para o arquivo, ao invés de serem exibidos na tela.

Criar um objeto
Utiliza-se
ofstream (object file) para criar um objeto, declaramos seu nome de maneira parecida com a declaração de uma variável:
ofstream <nome do objeto>
Por exemplo:
ofstream escreve;

A linha acima cria o objeto “escreve”, do tipo ofstream, capaz de escrever em arquivos.

Associar o objeto criado a um arquivo
Para isto, utilizamos a função: open( ), que abre o arquivo desejado ou cria um arquivo no disco rígido.
A sintaxe de open( ) é a seguinte:
<objeto>.open(“nome do arquivo”);
Por exemplo, vamos utilizar o objeto “escreve” para criar um arquivo chamado “strings.txt”. Para fazer isso, utilizamos a função open da seguinte maneira:
escreve.open(“strings.txt”);
Dessa forma, estamos associando o objeto escreve ao arquivo strings.txt.

Envio de dados para o arquivo
objeto<< "Strings a serem inseridas no arquivo\n";
Agora podemos enviar dados através do objeto “escreve”, e estes dados serão escritos no arquivo “strings.txt”. Para fazer isso, utilizamos o objeto que criamos da mesma forma que utilizamos o comando cout, ou seja, com o operador <<. Da mesma forma como escreveríamos na tela do computador com o comando cout utilizando variáveis, strings, strings literais, formatação, etc, podemos utilizar estes recursos todos também com os objeto do tipo ofstream, com a diferença que estas informações serão gravadas em um arquivo.

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <cstdlib> //biblioteca onde inclui o system("pause")
#include <fstream>
#include <string>
using namespace std;

int main(){
string frase;
cout<<"Escreva uma frase para ser escrita no arquivo str.txt:";
getline(cin, frase);
cout<<"Obrigado. Escrevendo dados no arquivo strings.txt...\n";
ofstream escreve;
escreve.open("str.txt");
escreve << "Utilizamos os objetos ofstream para escrever em arquivos\n";
escreve<< "Note que podemos utilizar os caracteres \\n pra quebrar a linha, como fazíamos em cout\n";
int numero = 100;
escreve<<"Podemos escrever o valor de variaveis numericas: " <<numero <<"\n";
int matriz[3] = {42, 19, 99};
escreve<<"Podemos também 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 execução do programa: "<<frase<<"\n";
escreve.close();
cout<<"Dados escritos no arquivo. Fim do Programa!";
system("PAUSE");
return 0;
}

Compilar & Executar
Escreva uma frase para ser escrita no arquivo str.txt:Frase de teste
Obrigado. Escrevendo dados no arquivo strings.txt...
Dados escritos no arquivo. Fim do Programa!

Procure o arquivo strings.txt em seu sistema, e abra ele (ele provavelmente está no mesmo diretório onde está o arquivo executável do programa que compilamos. Por definição, estes arquivos ficam no diretório onde está o compilador, a menos que tenhamos configurado o compilador para salvá-los em outro lugar.). Percebeu a semelhança entre a utilização do objeto ofstream com o comando cout? Todos os métodos que vimos com cout para exibir um dado na tela podem ser utilizado para gravar um dado em um arquivo.

32.2.4. Checando se o arquivo abriu sem problemas
Sempre existe a possibilidade de erros quando trabalhamos com arquivos. Talvez o arquivo que desejamos ler tenha sido apagado, ou renomeado, ou esteja sendo usado por outro programa. A biblioteca de C++ possui uma função que checa se um objeto ofstream/ifstream conseguiu abrir um determinado arquivo, e se continua conectado corretamente à este arquivo:
Função is_open( )
Esta função checa o estado do objeto, e retorna 0 para o programa caso tudo esteja certo. Caso um valor diferente de 0 seja enviado ao programa, isso indica que o arquivo não pode ser aberto pelo objeto.

O código 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 não pode ser aberto e a execução é terminada. Caso contrário, o programa continua sua execução normalmente.

if(!leitura.is_open( ))
{
cout<<”Não foi possível abrir arquivo! Programa será terminado!\n”;
leitura.clear( ); //reseta o objeto leitura, para limpar memória do sistema
return 0;
}


32.2.5. Fechando um Arquivo
Utilizamos a função close( ) no programa acima após escrever todos os dados desejados no arquivo. Como você deve ter adivinhado, a função close simplesmente fecha o arquivo a que o objeto estava associado, liberando o objeto e a memória do arquivo.
Após fecharmos o arquivo antigo, podemos associar o objeto à outro arquivo no mesmo programa. Dessa forma, um objeto ofstream (na verdade, qualquer um dos objetos derivados de fstream) pode trabalhar com múltiplos arquivos dentro de um mesmo programa, porém não simultaneamente (caso precisemos trabalhar com múltiplos arquivos simultaneamente, é preciso criar mais de um objeto fstream). A sintaxe da função close( ) é a seguinte:
<objeto>.close( );
Note que não é necessário especificar o arquivo à ser fechado, pois cada objeto só consegue estar conectado à um único arquivo por vez. No programa acima, por exemplo, utilizamos o seguinte comando para fechar o arquivo string.txt:
escreve.close( );

32.2.6. Lendo os dados de um arquivo
Para ler os dados de um arquivo em um programa, é preciso:
- Criar um objeto do tipo ifstream (input file), capaz de ser o intermediário entre o arquivo à ser lido e o programa. A criação do objeto ifstream é muito semelhante à criação de um objeto ofstream.
ifstream <nome do objeto>
- Conecta-se ele ao arquivo string.txt criado previamente.
objeto.open("arquivo.txt")
Exemplo:
ifstream leitura;
leitura.open(“string.txt”);

Após criarmos o objeto e conectarmos ele à um arquivo, podemos começar a ler através deste arquivo. A leitura de dados de um arquivo é parecida com a leitura de dados enviados através do teclado:
- criamos uma variável para armazenar os dados recebidos;
- utilizamos o objeto ifstream para ler e enviar os dados do arquivo para o programa (no caso da leitura via teclado, o objeto cin receberia os dados enviados pelo usuário e os repassaria para o programa). Assim, podemos utilizar qualquer um dos métodos de leitura que estudamos para cin, seja para ler caracteres, palavras ou frases inteiras.

Lendo caractere por caractere
Para lermos somente um caractere de um arquivo, por exemplo, nossa melhor opção é utilizar o método .get, que serve justamente para esta função. Criamos uma variável do tipo char para armazenar este caractere, e utilizamos o objeto ifstream da forma mostrada no exemplo abaixo:
char letra;  // variável de transporte
ifstream leitura;  // criação do objeto de leitura
leitura.open("strings.txt");
  // abertura do arquivo
leitura.get( letra);  // captura de um caractere
while (leitura.get(letra)) {cout << letra;}  // impressão na tela de todos os caracteres

O exemplo de código acima utiliza o objeto “leitura” e o método .get para ler um caractere de um arquivo, e armazena este caractere na variável “letra”. O laço de repetição para obtem todos os caracteres do arquivo, como vemos no exemplo abaixo. O laço while continuará a executar o método .get para ler o arquivo, até que seja encontrado o fim do arquivo. Quando o fim do arquivo é encontrado, o comando “leitura.get(letra) retorna “falso” para o laço while, terminando a repetição. Lembre-se que o arquivo strings.txt deve estar no mesmo diretório onde estamos executando o programa.

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(){
char letra;
ifstream leitura;
leitura.open("strings.txt");
if(!leitura.is_open( ))
{
cout<<"Não foi possível abrir arquivo! Programa será terminado!\n";
leitura.clear( ); //reseta o objeto leitura, para limpar memória do sistema}
}
while (leitura.get(letra)) {cout << letra;}
leitura.close();
system("PAUSE");
return 0;
}

Compilar & Executar
Primeira linha do arquivo strings.txt.
Segunda linha do arquivo strings.txt.
Terceira linha do arquivo strings.txt.

Obs: o arquivo strings.txt já existia conforme impressão acima.

Leitura de uma palavra
Para lermos uma palavra inteira de um arquivo, ao invés de utilizarmos uma simples variável 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 máximo especificado ou encontre um espaço em branco, uma quebra de linha ou o fim do arquivo.

char mtz[40];
leitura >> mtz;

Exemplo:
Arquivo: teste.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib> //biblioteca onde inclui o system("pause")
using namespace std;

int main(){
char palavra[40];

ifstream leitura;
leitura.open("strings.txt");
if(!leitura.is_open( ))
{
cout<<"Não foi possível abrir arquivo! Programa será terminado!\n";
leitura.clear( ); //reseta o objeto leitura, para limpar memória do sistema}
}
leitura >> palavra;
cout << palavra;

leitura.close();
system("PAUSE");
return 0;
}

Compilar
Olá!

Leitura de por linha
Para lermos uma linha inteira de um arquivo, utilizamos o método getline, que lê uma linha inteira de entrada, até que o tamanho máximo especificado seja atinjido ou até encontrar uma quebra de linha ou o fim de arquivo.
Sintaxe:
<nome do objeto>.getline ( <matriz_destino>, <limite de caracteres>);
Exemplo:
char mtz[80];
leitura.getline( mtz, 80);

O comando acima leria todos os caracteres de uma linha, até encontrar a quebra da linha. Como vimos com o método .get, podemos utilizar um laço de repetição para lermos todas as linhas de um arquivo utilizando o método getline. No exemplo abaixo, à cada repetição uma linha do arquivo será escrita na tela.

Exemplo:
Arquivo.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
int main(){
char linha[300];
ifstream leitura;
leitura.open("strings.txt");
if(!leitura.is_open( ))
{
cout<<"Não foi possível abrir arquivo! Programa será terminado!\n";
leitura.clear( ); //reseta o objeto leitura, para limpar memória do sistema}
}
while (leitura.getline(linha, 300)) {cout << linha <<"\n";}
leitura.getline(linha, 300); // para leitura de uma só linha
cout << linha <<"\n"; 
// para leitura de uma só linha
leitura.close();
system("PAUSE");
return 0;
}


Compilar & Executar
Olá! Como vai!
Hello! How are you!

Uma pequena diferença que vemos entre esses dois métodos de ler um arquivo inteiro, é que o método .get lê todos os caracteres até o fim de arquivo, incluindo quebras de linha. O método 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 à adicionar uma quebra de linha após exibir na tela cada uma das linhas lidas. (Entretanto, lembre-se que para arquivos grandes, o método getline é mais eficiente e mais rápido.
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, então temos milhares de caracteres, o que significa que o método get acessará muito mais vezes o mesmo arquivo do que o método getline).

32.3. Modos de Arquivo
Quando abrimos um arquivo, podemos querer fazer diferentes coisas com o conteúdo deste arquivo. Podemos querer continuar à escrever no fim do arquivo, dando continuidade aos dados já escritos nele. Podemos querer apagar todos os dados já escritos e começar do zero novamente. Os modos de arquivo servem justamente para isto: para definir como deve ser o comportamento de um arquivo quando acessado pelo programa.
Podemos definir que o arquivo será utilizado somente para leitura ou somente escrita, se será utilizado para anexar dados ou se será reescrito totalmente. Definimos o modo do arquivo quando abrimos ele com um objeto, adicionando um parâmetro novo ao método open.
Veja a sintaxe abaixo:
<objeto ofstream>.open(“nome do arquivo”, ofstream::<modo de arquivo>);
ou
<objeto ifstream>.open(“nome do arquivo”, ofstream::<modo de arquivo>);

Modos de arquivo disponíveis em C++.

::in Abre arquivo para leitura
::out Abre arquivo para escrita
::ate Procura o final do arquivo ao abrir ele
::app Anexa os dados à serem escritos ao final do arquivo
::trunc Trunca os dados existentes no arquivo
::binary Abre e trabalha com arquivos em modo binário

Note que um arquivo aberto por um objeto ofstream não necessita que definamos o modo de arquivo ofstream::out, pois este modo já é definido para este tipo de objeto por definição.
O mesmo ocorre com o modo ifstream::in e os objetos ifstream.

Por definição, um arquivo aberto por um objeto ofstream irá truncar os dados já existentes no arquivo, escrevendo os dados novos “por cima” dos antigos. Porém, o modo ofstream::app nos permite anexar dados ao final de um arquivo.

Exemplo:
Utiliza o modo ofstream::app para criar ou gravar dados em um arquivo de texto.
Arquivo: teste.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib> //biblioteca onde inclui o system("pause")

using namespace std;
int main(){
int n1,n2;
char frase[1000];
cout<<"Gravar dados em arquivo"<<"\n";
ofstream caderno;
caderno.open("arquivo1.txt", ofstream::app); // abre ou cria um novo arquivo
cout<<"Entre com uma frase: \n";
cin.getline(frase, 1000);
cout << "Entre com um número inteiro:\n";
cin >>n1;
cout << "Entre com mais um número inteiro:\n";
cin >>n2;
caderno << "A frase digitada é: "<<frase;
caderno << "O primeiro número digitado é: "<<n1<<"\n";
caderno << "O segundo número digitado é: "<<n2<<"\n";
caderno.close();
system("PAUSE");
return 0;
}

Compilar & Executar
Gravar dados em arquivo
Entre com uma frase:
Olá! Como vai?
Entre com um número inteiro:
5
Entre com mais um número inteiro:
7