04 - tabelas, qualificadores e lendo dados (w2)

51
Programação de Computadores Capítulo 4: Tabelas, qualificadores e lendo dados Teresa Martinez Gomes 2015-2016 1 / 51

Upload: bm82

Post on 07-Dec-2015

17 views

Category:

Documents


3 download

DESCRIPTION

04 - Tabelas, Qualificadores e Lendo Dados (w2)

TRANSCRIPT

Page 1: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Programação de ComputadoresCapítulo 4: Tabelas, qualificadores e lendo

dados

Teresa Martinez Gomes

2015-2016

1 / 51

Page 2: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Plano: Tabelas, qualificadores e lendo dadosLendo dadosTabelasStrings no Estilo C++Lendo stringsInicializando variáveisA função assert

Tabelas multi-dimensionaisStrings no estilo CQualificadoresA função sizeof

Strings no estilo C++ e no estilo CConstantes e referências

Constantes hexadecimais e octaisMais operadores de atribuição

2 / 51

Page 3: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo dados

O objecto cin utiliza o operador >> para ler dados. Exemplo,

#include <iostream>using namespace std;

int dia; // dia dado pelo utilizadorint mes; // mês dado pelo utilizador

int main(){cout << "\nDe-me dois inteiros (dia e mes):\n";cin >> dia >> mes;cout << "\ndia = " << dia << ", mes = " << mes << ’\n’;return(0);

}

Se o utilizador escrever 3 10 <return>:

De-me dois inteiros (dia e mes):3 10

dia = 3, mes = 10

3 / 51

Page 4: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

TabelasUni-dimensionais

I Ao declaramos uma variável obtemos espaço paraarmazenar um valor do tipo dessa variável.

I Assumindo que os inteiros ocupam 32 bits (4 octetos) eque a memória é endereçada octeto a octeto:int idadeA; // idade do sujeito AidadeA = 19;Resulta em (o valor escolhido para endereço é apenasexemplificativo):

idadeA 0x8049cc8

nome endereço valor

19

4 / 51

Page 5: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

TabelasUni-dimensionais

I Utilizamos tabelas quando pretendermos reservar um bloco dememória para guardar um conjunto de valores do mesmo tipo ():tipo nome[dimensão]; // comentárioE que [ ] é um operador de declaração posfix.

I Assumindo que os inteiros ocupam 32 bits (4 octetos) e que amemória é endereçada octeto a octeto:

int idade[5];idade[0] = 19;idade[1] = 25;idade[2] = 58;idade[3] = 47;idade[4] = 12;

nome endereço

19

25

58

47

12

0x8049d04

valor

idade

idadede

idade[0..4]de valor

(constante)(ponteiro)

I E o endereço de idade[1] será dado por 0x8049d08.

5 / 51

Page 6: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

TabelasTabelas uni-dimensionais – Exemplificando

#include <iostream>using namespace std;

int d[5]; // tabela com 5 idadesfloat idmedia; // media das idades

int main(){d[0] = 19; // as 5 idadesd[1] = 25;d[2] = 58;d[3] = 47;d[4] = 12;

idmedia = d[0] + d[1] + d[2] + d[3] + d[4];idmedia = idmedia / 5.0 ;cout << "\nA idade media vale: " << idmedia << "\n" ;return(0);

}

Produziria a saída:

A idade media vale: 32.2

6 / 51

Page 7: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

TabelasTabelas uni-dimensionais – Leitura/Escrita

I Apenas na inicialização,int primavera[4] = {3,4,5,6}; ,

é possível colocar numa tabela, toda a informação de umasó vez.

I Excepção: leitura/escrita de um bloco de dados, dado oendereço de início do bloco onde se pretende ler/escrever– só será explicado no final do semestre (quando for dadaa leitura/escrita em ficheiros).

I Assim (durante quase todo o semestre) os elementos deuma tabela devem escritos/lidos um de cada vez (como noexemplo do slide anterior).

7 / 51

Page 8: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo C++Definição; atribuição usando = e o operador []

I O tipo string não faz parte do núcleo da linguagem C++.

I É necessário fazer: #include <string>

I Em seguida podemos definir uma variável do tipo string:string meuNome;

e podemos atribuir-lhe um valor fazendo:meuNome = "Manuel";

I Os elementos existentes numa string inicializada podem seracedidos tal como os de uma tabela:char inicial;inicial = meuNome[0];colocaria na variável inicial a letra ’M’.

8 / 51

Page 9: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo C++Concatenação de strings no estilo C++: operador +, os métodos length e substr

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

string nome;string apelido;string nomeCompleto;

int main(){nome = "Manuel";apelido = "Costa";nomeCompleto = nome + " " + apelido;cout << "\nNome completo: " << nomeCompleto;cout << "\nSubstring desde " << nomeCompleto[7];cout << " ate " << nomeCompleto[7+2] << ": ";cout << nomeCompleto.substr(7,3);cout << "\nComprimento: " << nomeCompleto.length() << ’\n’;return(0);

}

produziria a saída:

Nome completo: Manuel CostaSubstring desde C ate s: CosComprimento: 12

9 / 51

Page 10: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo C++Acesso aos elementos: o método at

I A classe string tem um bom conjunto de funções demanipulação – manual de referência de C++.

I Ao aceder a um elemento de uma string como se fosse umatabela pode eventualmente fazer-se um acesso incorrecto!

I O comportamento do programa nesse caso é imprevisível. . .Pode continuar a executar, pode ser abortado pelo sistemaoperativo por acesso indevido à memória, ou no caso doWindows, se esse acesso indevido estiver associado a umaoperação de escrita, pode provocar o crash do sistema.

I Uma forma de prevenir estas situações é a utilização do método(função) at(), membro da classe string:string nome;nome = "Camilo Castelo Branco";char inicial;inicial = nome.at(7); // inicial <- ’C’Se 7 fosse maior ou igual ao comprimento de nome o programaseria terminado de forma ordeira.

10 / 51

Page 11: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsLendo uma palavra, cin, ou uma frase, getline

I Forma geral da instrução utilizando std::cin:std::cin >> nomeVariavel;

I A forma anterior funciona com as variáveis de tipo int, float,double, char (entre outras).

I Pode ser utilizada para ler uma string que seja formada poruma só palavra!Porquê? Porque o operador >> usa o espaço (ou tab) comoseparador.

I Se quisermos ler uma string que seja uma frase é necessárioutilizar a função global getline :std::getline(std::cin, string);oustd::getline(std::cin, string, char);Exemplo:std::string escritor; // nome de um escritorstd::getline(std::cin, escritor);

11 / 51

Page 12: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsExemplo: lendo uma palavra usando cin

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

string nome;

int main(){cout << "\nDe-me um nome (apenas uma palavra):\n";cin >> nome;cout << "Deu-me o nome:\n";cout << nome << endl;return(0);

}

De-me um nome (apenas uma palavra):JoaoDeu-me o nome:Joao

12 / 51

Page 13: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsExemplo: lendo uma palavra usando cin e o espaço como separador

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

string nome;

int main(){cout << "\nDe-me um nome (apenas uma palavra):\n";cin >> nome;cout << "Deu-me o nome:\n" << nome << endl;return(0);

}

E que acontece se o utilizador digitar “Joao Santos”?

De-me um nome (apenas uma palavra):Joao SantosDeu-me o nome:Joao

Justificação: O espaço funcionou como separador!

13 / 51

Page 14: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsExemplo: lendo uma frase usando a função getline

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

string nome;

int main(){cout << "\nDe-me um nome completo:\n";getline(cin, nome);cout << "Deu-me o nome:\n" << nome << endl;return(0);

}

E que acontece se o utilizador digitar “Joao Santos Matias”?

De-me um nome completo:Joao Santos MatiasDeu-me o nome:Joao Santos Matias

Justificação: A string foi lida pela função getline até surgir um \n (fim de linha)

14 / 51

Page 15: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsLeitura buffered, cin e getline

I A leitura do teclado usando cin e >> ou a função getlineusam uma zona de memória (“buffer”) onde fica armazenado oque escrevemos no teclado, incluindo o <enter>, que usámospara dar a escrita por terminada.

I No caso do cin e do operador >> uma vez extraído o últimovalor digitado antes do <enter>, o carácter ’\n’ permaneceno buffer de entrada.

I No caso caso da função getline, o carácter que finaliza aleitura da string (por omissão o ’\n’) é removido do bufferembora não seja armazenado na string.

Problema: A utilização de getline, logo após uma leiturarealizada pelo operador >> através do objecto cin eterminada com <enter>, resulta numa string vazia.

Solução: Esvaziar o buffer de entrada antes da utilização dafunção getline, se este tiver sido precedido de umaleitura usando cin e >>.

15 / 51

Page 16: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsO buffer cin, o carácter ’\n’ e a função getline – Problema

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

string nomeCompleto, nome, apelido;

int main() {cout << "\nDe-me o primeiro nome (apenas uma palavra):\n";cin >> nome;cout << "De-me o apelido (apenas uma palavra):\n";cin >> apelido;

nomeCompleto = nome + " " + apelido;cout << "Deu-me o nome:\n" << nomeCompleto << endl;

cout << "\nDe-me outro nome Completo:\n";getline(cin, nomeCompleto);cout << "Deu-me: |" << nomeCompleto << ’|’ <<endl;;

return(0);}

16 / 51

Page 17: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsO buffer cin, o carácter ’\n’ e a função getline – Problema

O algoritmo anterior termina sem dar oportunidade de introduzir o nome completo.Porquê?

De-me o primeiro nome (apenas uma palavra):ManuelDe-me o apelido (apenas uma palavra):CostaDeu-me o nome:Manuel Costa

De-me outro nome Completo:Deu-me: ||

Justificação: O ’\n’ que ficou no buffer de entrada associado ao teclado foientendido pela função getline como o terminador da cadeia de caracteresintroduzidos.O operador >> não remove do buffer o ’\n’ que termina a entrada.

17 / 51

Page 18: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsO buffer cin, o método ignore e a função getline – Solução

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

string nomeCompleto, nome, apelido;

int main() {cout << "\nDe-me o primeiro nome (apenas uma palavra):\n";cin >> nome;cout << "De-me o apelido (apenas uma palavra):\n";cin >> apelido;

nomeCompleto = nome + " " + apelido;cout << "Deu-me o nome:\n";cout << nomeCompleto << endl;

cout << "\nDe-me outro nome Completo:\n";cin.ignore(); // Remove do buffer o ’\n’ ou carácter seguinte do buffergetline(cin, nomeCompleto);

cout << "Deu-me o nome:\n";cout << nomeCompleto << endl;

return(0);}

18 / 51

Page 19: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsO buffer cin, o método ignore e a função getline – Solução

Agora já funciona! Porquê?

De-me o primeiro nome (apenas uma palavra):JoaoDe-me o apelido (apenas uma palavra):DiasDeu-me o nome:Joao Dias

De-me outro nome Completo:Carlos MoutinhoDeu-me o nome:Carlos Moutinho

19 / 51

Page 20: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsAinda o buffer cin, o carácter ’\n’ e a função getline – Problema

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

string nome;int i;

int main(){cout << "\nUm inteiro? ";cin >> i;cout << "Nome? ";getline(cin, nome); // Lê o nomecout << ’\n’ << i << ’|’ << nome << ’|’ << endl;

}

Se o utilizador digitar: 9<enter> o algoritmo termina! Porquê?

Um inteiro? 9<enter>Nome?9||

20 / 51

Page 21: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsAinda o buffer cin, o método ignore e a função getline – Solução

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

string nome;int i;

int main(){cout << "\nUm inteiro? ";cin >> i;//Ignora 1000 char ou ’\n’, o que occorrer 1o

cin.ignore(1000,’\n’); // preferível a cin.ignore() ?cout << "Nome? ";getline(cin, nome); // Lê o nomecout << ’\n’ << i << ’|’ << nome << ’|’ << endl;

}

Se o utilizador digitar: 9<enter>Manuel Silva<enter>

Um inteiro? 9<enter>Nome? Manuel Silva <enter>9|Manuel Silva|

21 / 51

Page 22: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsAinda o buffer cin, o carácter ’\n’ e a função getline

Por omissão, a função getline tem como terminador o ’\n’, e remove-o do buffer,por isso ao fazermos vários getline sucessivos, usando o ’\n’, como terminador, nãodevemos usar o método ignore.

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

string nomeA, nomeB;

int main() {cout << "De-me um nome Completo:\n";getline(cin, nomeA); // Le nomeA e remove do buffer o ’\n’

cout << "De-me outro nome Completo:\n";// Não deve usar cin.ignore(): removeria a 1a letra de nomeBgetline(cin, nomeB); // Le nomeB e remove do buffer o ’\n’

cout << "\nDeu-me o nomeA: " << nomeA << endl;cout << "Deu-me o nomeB: " << nomeB << endl;return(0);

}

22 / 51

Page 23: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Lendo stringsAinda o buffer cin, o carácter ’\n’ e a função getline

Se o utilizador digitarJoana Dias<enter>Daniel Costa<enter> o programa

anterior produziria o resultado

De-me um nome Completo:Joana DiasDe-me outro nome Completo:Daniel Costa

Deu-me o nomeA: Joana DiasDeu-me o nomeB: Daniel Costa

porque, por omissão, a função getline tem como terminador o’\n’, e remove-o do buffer.

23 / 51

Page 24: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Inicializando variáveisEstilo C++ e estilo C

O C++ permite que uma variável seja inicializada no momento dadeclaração.

I Exemplo de definição e inicialização a 0 de uma variável de tipointeiro no estilo C++ :int conta(0); // contou 0 elementos

I Exemplo de definição e inicialização a 0 de uma variável de tipointeiro no estilo C :int conta = 0; // contou 0 elementos

I Inicialização de tabelas:int redes[3] = {91, 96, 92};equivale a:redes[0] = 91; redes[1] = 96; redes[2] = 92;

I Exemplo de inicialização de uma string no estilo C:string nome ="Manuel Santos";

I Exemplo de inicialização de uma string no estilo C++:string nome("Manuel Santos");

24 / 51

Page 25: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

A função assert

I Tentar ler fora dos limites de uma tabela pode ter resultadosinesperados:int dados[4];...std::cout << dados[23]; // Mau!

I Tentar escrever fora dos limites de uma tabela pode terresultados desastrosos!int dados[4];...dados[23] = 15; // Péssimo!

I Em (Oualline 2003) descreve a utilização de assert() paraterminar de forma “ordeira” um programa, quando é detectadauma situação de erro:assert(expressão de verificação),como se pode ver no próximo slide.

I No entanto, em aplicações reais. . .

25 / 51

Page 26: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

A função assertExemplo

1 #include <iostream>2 #include <cassert>34 using namespace std;56 int verao[3] = {6,7,8};7 int main()8 {9 int i; // i deve pertencer a {0,1,2}

1011 cout << "\nDe-me um inteiro em {0,1,2}: ";12 cin >> i ;13 cout << "\nverao[" << i <<"] = " << flush;14 assert(i >= 0); // i deve ser positivo15 assert(i < 3); // i deve ser menor do que 316 cout << verao[i] << ’\n’;17 return(0);18 }

De-me um inteiro em {0,1,2}: 4verao[4] = usa_assert.exe: usa_assert.cc:15:int main(): Assertion ‘i < 3’ failed.Aborted (core dumped)

De-me um inteiro em {0,1,2}: 2verao[2] = 8

26 / 51

Page 27: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Tabelas multi-dimensionais

I As tabelas podem ter duas dimensões:tipo nomeVariavel[dim1][dim2]; // Comentário

I int matriz[2][3]; // matriz 2x3Atribuição de valores:matriz[0][0] = 2;matriz[0][1] = 4;...matriz[1][2] = 12;

I As tabelas podem ser multi-dimensionais:int matriz[2][3][5][10]; // 2x3x5x10desde que haja memória disponível.

I Inicialização:int matriz[2][3] =

{ {2, 4, 6}, {8, 10, 12} };Atribuição: matriz[0][1] = 8;

27 / 51

Page 28: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo CI Existe uma grande quantidade de programas escritos em C que utilizam strings

no estilo C.I Uma string em C não é mais do que uma tabela de caracteres, em que o fim da

sequência de caracteres é indicado por um carácter especial o ’\0’ (carácterNUL, de valor 0).

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

char nome[4]; // nome com 3 caracteres uteis

int main(){nome[0] = ’A’;nome[1] = ’n’;nome[2] = ’a’;nome[3] = ’\0’;cout << "\nNome = " << nome << ’\n’;return(0);

}

Nome = Ana

28 / 51

Page 29: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo CExemplo

I Um string em C não é mais do que uma tabela decaracteres, em que o fim da sequência de caracteres éindicado por um carácter especial o ’\0’ (carácter NUL,de valor 0):char linha[6] = "Marco";

nome endereço

0x8049d04

valor

linha linha[0]

linha[1]

linha[2]linha[2]

linha[3]

linha[5]

linha[4]

’M’

’a’

’r’

’c’

’o’

’\0’

Em C++ o fim de linha numa string é ’\0’.

29 / 51

Page 30: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo CInicialização e cópia de strings no estilo C - a função strcy

I Inicialização:// Reserva 6 caractereschar linha[] = "Marco";// Usa 13 = 12 + 1(NUL), das 50 posicoeschar longo[50] = "Manuel Costa";

I Há ainda outra forma de armazenar (por inicialização) umacadeia de caracteres, mas requer utilização explícita deponteiros pelo que só será abordada mais adiante.

I Em C++ não é possível copiar tabelas entre si.Logo é ilegal:linha = "Ana";longo = nome; // Erro!

I A função std::strcpy resolve esse problema:std::strcpy(nome, "Ana");

30 / 51

Page 31: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo CFunções para manipulação de strings no estilo C

Função Descriçãostd::strcpy(string1, string2) string1 <-- string2std::strncpy(string1, string2, comp) copia no máximo comp caracteres de

string2 para string1, a qual pode ficarsem NUL!

std::strcat(string1, string2) string1 <-- string1 + string2std::strncat(string1, string2, comp) string1 <-- string1 + no máximo comp

caracteres de string2 e termina a stringcom NUL

comp = std::strlen(string) comp fica com valor do comprimento destring

std::strcmp(string1, string2) 0 se string1 igual a string2;< 0 se string1 < string2;> 0 se string1 > string2

31 / 51

Page 32: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo CExemplo de utilização de funções para manipulação de strings no estilo C

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

char nome[51] = "The C++ Programming Language";char aux[] = "Bjarne Stroustrup";

int main(){cout << ’\n’ << nome;cout << "|tem comprimento " << strlen(nome);strcat( nome, " por ");cout << ’\n’ << nome;cout << "|tem comprimento " << strlen(nome);strcat(nome, aux);cout << ’\n’ << nome;cout << "|tem comprimento " << strlen(nome);strcpy(nome, aux);cout << ’\n’ << nome;cout << ", tem comprimento " << strlen(nome) << endl;

}

The C++ Programming Language|tem comprimento 28The C++ Programming Language por |tem comprimento 33The C++ Programming Language por Bjarne Stroustrup|tem comprimento 50Bjarne Stroustrup, tem comprimento 17

32 / 51

Page 33: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo CSegurança na manipulação de strings no estilo C

I A função strcpy não verifica se a string destino temespaço suficiente para guardar a string origem da cópia!Solução:

I usar strings C++!I verificar se o tamanho da string destino é suficiente:

assert(sizeof(nome) > strlen(aux));strcpy(nome, aux);

I O mesmo problema se passa com strcat:assert(sizeof(nome) > strlen(nome) + strlen(aux));

strcpy(nome, aux);

I De forma semelhante em strncat.I E no caso de strncpy a string pode ficar por terminar!

33 / 51

Page 34: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo CLendo strings no estilo C: o método getline

I A leitura de strings no estilo C:char nome[51];//...cin.getline(nome, sizeof(nome));oucin.getline(nome, sizeof(nome), ’.’);Desta forma o sistema garante que não lê mais caracteresque os que “cabem” em nome, ou lê até encontrar um ’.’Atenção: Gralha no livro (Oualline 2003), página 63,“Reading C-Style strings”: o exemplo dado não compila.

34 / 51

Page 35: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

QualificadoresTipos de inteiros: short long, unsigned, signed

I Em C++ é possível especificar vários tipos de inteiros.

I O tipo int indica que deve ser utilizado o tamanho maiseficiente para operações com inteiros na máquina em questão.Isso pode corresponder a 2 ou 4 octetos.

I Se desejarmos armazenar números inteiros de maior dimensão(perda de eficiência nos cálculos e maior consumo de memória):long int conta;

Para indicar que um valor inteiro constante é longo:long int conta = 12893L; // L em vez de l

I Da mesma forma se o valor a armazenar é pequeno e nãoprecisa de 32 bits:short int ano; // dois octetos chegam!

A dimensão de short int será em geral 2 octetos.

35 / 51

Page 36: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

QualificadoresTipos de inteiros: short long, unsigned, signed

I Qualquer compilador de C++ garante, relativamente ao númerode bits utilizados:long int >= int >= short int

I Os inteiros por omissão têm sinal (signed) – depende docompilador.

I Podemos definir:unsigned short conta; // 16 bits: 0..65535

I Se quisermos um inteiro verdadeiramente curto podemos usar otipo char:signed char curto = 97; // -128..127

mas se quisermos ver o valor numérico 97, precisamos de fazerum conversão de tipo (cast) explícita :cout << ’\n’ << curto << ’|’ << (int) curto << ’\n’;

produziria a saída:a|97

36 / 51

Page 37: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

QualificadoresTipos números em vírgula flutuante: float, double, long double

I O tipo float designa em geral números em vírgulaflutuante de precisão simples (4 octetos, 32 bits): 8.3f

I Para obter o dobro da gama e da precisão existe tambémo tipo double.Nalguns sistemas float e double são equivalentes!

I O tipo long double pretende oferecer precisãoadicional.Nalguns sistemas double e long double sãoequivalentes!

I Todos os números em vírgula flutuante têm sinal e,relativamente à precisão:long double >= double >= float

37 / 51

Page 38: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

QualificadoresExemplo

#include <iostream>

int main(){std::cout << "\nEm octetos (bytes)";std::cout << "\nbool ocupa " << sizeof(bool);std::cout << "\nchar ocupa " << sizeof(char);std::cout << "\nshort int ocupa " << sizeof(short int);std::cout << "\nint ocupa " << sizeof(int);std::cout << "\nlong int ocupa " << sizeof(long int);std::cout << "\nfloat ocupa " << sizeof(float);std::cout << "\ndouble ocupa " << sizeof(double);std::cout << "\nlong double ocupa " << sizeof(long double) << ’\n’;

}

Em octetos (bytes)bool ocupa 1char ocupa 1short int ocupa 2int ocupa 4long int ocupa 4float ocupa 4double ocupa 8long double ocupa 12

38 / 51

Page 39: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

QualificadoresComentado os tipos de inteiros disponíveis

I As declarações long int permitem (dependendo dosistema) definir inteiros mais longos, logo que permitemarmazenar inteiros com maior número de dígitos (maiorprecisão).

I Os short int permitem poupar memória, mas têm umagama de valores mais reduzida.

I Os inteiros mais compactos com que conseguimostrabalhar são os char – pois os caracteres sãorepresentados pelo seu valor numérico na tabela ASCII.

39 / 51

Page 40: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

QualificadoresMais alguns qualificadores

I No livro de referência Oualline 2003 é apresentada umalista de qualificadores que podem ser aplicados àdeclarações de variáveis.

I Até este momento cuja foram referidos todos excepto ospecial (que não iremos abordar) e a storage class (classede armazenamento) que irá ser abordada mais à frente.

40 / 51

Page 41: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

A função sizeofA função sizeof e tabelas (função strlen e método length)

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

int i;int tab[4] = {1,2,3,4} ;char nC[] = "Joana Dias"; // Ocupa 10 + 1(’\0’)string nCpp = "Vitor Hugo"; // Ocupa pelo menos 10 (...)

int main(){cout << "\n Um inteiro ocupa " << sizeof(int) << " octetos";cout << "\n tab ocupa " << sizeof(tab) << " octetos";cout << "\n\n nC ocupa " << sizeof(nC) << " octetos";cout << "\n Comprimento de nC " << strlen(nC) << " letras";cout << "\nComprimento de nCpp " << nCpp.length() << " letras";cout << endl;return (0);

}

Um inteiro ocupa 4 octetostab ocupa 16 octetos

nC ocupa 11 octetosComprimento de nC 10 letras

Comprimento de nCpp 10 letras

41 / 51

Page 42: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo C++ e no estilo CDiferenças entre strings no estilo C++ e C: na inicialização e na atribuição

I Na inicialização, usando =, não há grandes diferenças...I Na atribuição sim!

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

char nC[] = "Joana Dias"; // requer [] e Ocupa 10 + 1(’\0’)char auxC[11]; // requer [inteiro], reservar 11 (ou +)string nCpp = "Vitor Hugo"; // Utiliza 10 + ?? (depende da implementação)string auxCpp; // Nao e’ indicado o tamanho!

int main(){auxCpp = nCpp; // auxCpp <-- nCpp, str. no estilo C++strcpy(auxC, nC); // auxC <-- nC, str. no estilo C. ILEGAL auxC=nCcout << auxC << " e " << auxCpp << endl;nCpp = "Hugo, V."; // Em strings C++ a atribuicao com = funcionastrcpy(nC, "Dias, J."); // Em strings C é ILEGAL fazer nC = "Dias, J."cout << nCpp << " e " << nC << endl;return (0);

}

Joana Dias e Vitor HugoHugo, V. e Dias, J.

42 / 51

Page 43: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo C++ e no estilo CDiferenças entre strings no stilo C++ e C: a leitura a partir do teclado (1/2)

I A leitura de strings no estilo C :char nome[51];//...cin.getline(nome, sizeof(nome));oucin.getline(nome, sizeof(nome), ’.’);Desta forma o sistema garante que não lê mais caracteresque os que “cabem” em nome, ou lê até encontrar um ’.’

I Usando strings C++ pode fazer (como já foi visto):string qual; // nome de um escritorgetline(cin, qual);getline(cin, qual, ’.’);

43 / 51

Page 44: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Strings no estilo C++ e no estilo CDiferenças entre strings no estilo C++ e C: a leitura a partir do teclado (2/2)

I A leitura de strings no estilo C:Atenção! Se escrever:char outro[6];//...

cin >> outro;

Que acontece se introduzir abcdefgh <enter>?Observação: Quanta letras pode guardar outro e aindaterminar a string com o carácter NUL?E se escrever Ana Maria<enter>?

I A leitura de strings no estilo C++:Atenção! Se escrever:string nome;//...

cin >> nome; Que acontece se introduzirabcdefgh<enter>?E se escrever Ana Maria<enter>?

44 / 51

Page 45: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Constantes e referênciasDeclaração de constantes

I Um valor que deve ser invariante durante a execução deum programa, como por exemplo o número π (Ouaille2003):const float PI = 3.1415926 // o pi!

I Uma vez definido como constante, o valor de PI não podeser modificado, sendo ilegais atribuições a PI:PI = 3.14 // Erro na compilação!

I Podemos definir constantes inteiras para indicar adimensão de tabelas:const int MAX_ELEM = 100;float custo[MAX_ELEM];

45 / 51

Page 46: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Constantes e referênciasDeclaração de referências

I Uma referência é um nome alternativo para uma variável.#include <iostream>using namespace std;

int i; // A variavel iint & outroi = i ; // Outro nome para i

int main(){i = 3; // i <- 3cout << "\ni = "<< i;cout << "\toutroi = "<< outroi;

outroi = 7; // i <- 7cout << "\ni = "<< i;cout << "\toutroi = "<< outroi << endl;return (0);

}

i = 3 outroi = 3i = 7 outroi = 7

46 / 51

Page 47: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Constantes e referênciasDeclaração de referências

I A forma geral desta declaração é:tipo nomeVar; // comentáriotipo & nome = nomeVar; // comentárioem que & é um operador de declaração prefix.

I No exemplo:int i = 3; // i <- 3int & outroi = i; // nome alternativo para i

nome endereço

nome endereço valor

i 0xbf83bfdc

outroi 0xbf83bfdc

3

47 / 51

Page 48: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Constantes e referênciasConstantes hexadecimais e octais

I Os números inteiros são representados por sequências dedígitos, tais como 123, 2001, -15, que assumimos queestão na base 10 (sistema decimal).

I Os computadores trabalham em sistema binário (base 2 ).Já vimos que o sistema de representação octal ehexadecimal são uma forma simples (e compacta) derepresentar dígitos binários, em grupos de 3 e 4,respectivamente.

I A linguagem C++ possui convenções para arepresentação de valores em octal e decimal:

I Um zero no início de um número indica um número emoctal: 0101 equivale a 1018 em octal e vale 6510 emdecimal (letra ’A’, na tabela ASCII).

I Um “0x” indica um número na base 16. Assim 0x31equivale a 3116 e vale 4910 no sistema decimal (número ’1’na Tabela ASCII).

48 / 51

Page 49: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Mais operadores de atribuiçãoOperadores para escrita de código compacto

I Operador Notação curta Expressão equivalente+= x += 5; x = x + 5;-= x -= 5; x = x - 5;

*= x *= 5; x = x * 5;/= x /= 5; x = x / 5;%= x %= 5; x = x % 5;++ ++x; x = x + 1;-- --x; x = x - 1;

I Os operadores “++” e “--” podem usados antes ou depoisdo nome de uma variável:pré incremento/decremento ++k --j ou

pós incremento/decremento k++ j-- .

49 / 51

Page 50: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Mais operadores de atribuiçãoOperadores para escrita de código compacto: atenção à ordem! (1/2)

I Isoladamente: ++i; ou i++; ambas incrementam o valorda variável i. Mas,

I i = 5; // i <- 5k = i++; // k <- i e depois i <- i + 1ou seja o valor final de k é 5 e i passa a valer 6.

I i = 5; // i <- 5k = ++i; // i <- i + 1 e depois k <- i

ou seja o valor final de k é 6 (igual ao valor de i).

50 / 51

Page 51: 04 - Tabelas, Qualificadores e Lendo Dados (w2)

Mais operadores de atribuiçãoOperadores para escrita de código compacto: atenção à ordem! (2/2)

#include <iostream>using namespace std;

int i = 5, k;int main(){k = i++;cout << "i = " << i << "\tk = " << k << endl;k = ++i;cout << "i = " << i << "\tk = " << k << endl;return (0);

}

i = 6 k = 5i = 7 k = 7

Fim do capítulo 5 de Oualline 2003.Segue-se o capítulo 6 de Oualline 2003.

51 / 51