E/S em C++ (2)
- Cuidado com o uso de cin, especialmente quando o valor de entrada é usado
diretamente, por exemplo, para controlar uma repetição:
#include <iostream>
using namespace std;
// Item 15.2 do C++ FAQ
int main()
{
cout << "Entre números separados por espaço ou
ENTER (digite -1 para terminar): ";
int valor = 0;
while (valor != -1)
{
cin >> valor; // PROBLEMA!
cout << "Você digitou: " << valor << endl;
}
}
Funciona perfeitamente, SE o usuário digitar sempre números
E/S em C++ (3)
- Se um caractere não-numérico for inserido, o stream de entrada cin entra em um estado denominado falho, e
passa a ignorar todas as entradas subseqüentes
- Solução:
#include <iostream>
#include <limits>
using namespace std;
int main() {
cout << "Entre números separados por espaço ou
ENTER (digite -1 para terminar): ";
int valor = 0;
while (valor != -1) {
if(cin >> valor)
cout << "Número: " << valor << endl;
else {
cout << "Inválido !!!" << endl;
cin.clear();
cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
}
}
}
E/S em C++ (4)
- C++ suporta também o uso de manipuladores que permitem alterar o formato
de saída padrão. Por exemplo, para aumentar a precisão de exibição de números float:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
...
float a = 1.525;
// fixed faz com que a precisão seja considerada apenas para as casas decimais
cout << "Valor: " << setprecision(10) << fixed << a << endl;
}
É importante observar que o novo formato fica valendo a partir do ponto
em que o manipulador é utilizado, e não apenas para essa linha
Outros manipuladores úteis incluem:
- setw(n) - ajusta tamanho do campo
- left,right - alinha campo à esquerda/direita
Uma lista completa dos manipuladores pode ser encontrada no
guia de referência C++
Passagem de parâmetros em C++ (1)
Em C++, é possível realizar a passagem de parâmetros de 3 maneiras diferentes
A primeira é denominada por valor:
- Argumento da chamada (parâmetro real) é avaliado, gerando um valor que é copiado para a variável declarada na função (parâmetro formal)
- Qualquer alteração da variável da função (parâmetro formal) não é "transmitida" para o a variável do argumento
- O argumento da chamada (parâmetro real) pode ser uma constante, uma variável ou uma expressão: 5, v1, v1+5-v2
Exemplo:
int fatorial (int x) {
int v;
for(v=1; x>1; --x)
v *= x;
return v;
}
...
y = fatorial (z);
Passagem de parâmetros em C++ (2)
A segunda é denominada por referência com ponteiros:
- O argumento é um endereço de uma variável
- O parâmetro formal é um ponteiro para a variável do argumento
- O efeito de alteração da variável argumento é feito por uso de "de-referência" do ponteiro na função
Exemplo:
void troca (int *x, int *y) {
int aux;
aux = *x;
*x = *y;
*y= aux;
}
...
troca (&v1, &v2);
Passagem de parâmetros em C++ (3)
A terceira é por referência C++:
- O argumento da chamada (parâmetro real) tem que ser uma variável: v1, v2
- A variável do argumento (parâmetro real) é associada com a variável declarada na função (parâmetro formal) durante a execução da função
- Qualquer alteração da variável da função (parâmetro formal) acontece também na variável do argumento
void troca (int & x, int & y) {
int aux;
aux = x;
x = y;
y= aux;
}
...
troca (v1, v2);
Pergunta: Porque o argumento não pode ser uma constante ou expressão ? Isso é um problema ?
Passagem de parâmetros em C++ (4)
Uso da palavra reservada const:
- Quando se passa um argumento que não vai ser alterado por referência,
pode-se declará-lo como const para garantir que não vai ser modificado
- Exemplo:
struct Ponto {
int x, y;
}
...
void imprime_ponto (const Ponto &p) { ... }
O modificador const informa ao compilador que a estrutura p não será modificada
dentro da função
Embora seu uso seja opcional, é extremamente recomendável
Nesse exemplo com struct, é importante o seu uso por uma questão de eficiência:
- Se a struct fosse passada por cópia, seu conteúdo seria copiado inteiramente para a função
- O modificador const permite ao compilador otimizar ao máximo a passagem da struct