• Nenhum resultado encontrado

Dica de Produtividade 2

Sintaxe 2.8: Chamada de função

function_name(expression1, expression2,..., expressionn)

Exemplo: sqrt(x) pow(z + y, n) Finalidade:

O resultado de chamar uma função e fornecer valores para os parâmetros da função.

Figura 7

Analisando uma expressão.

(–b +

sqrt

(b * b – 4 * a * c)) / (2 * a)

b2 b2 – 4ac 4ac 2a b2 – 4acb2 – 4ac –b+ √ 2a b2 – 4ac –b+ √

Aqui, entretanto, a / não indica divisão no sentido matemático. Ela indica divisão inteira, uma vez que s1 + s2 + s3e 3 são inteiros. Por exemplo, se as notas somarem 14, a média calcu- lada seria 4, o resultado da divisão inteira de 14 por 3. Este inteiro 4 é então movido para uma va- riável em ponto flutuante average. A solução é usar o numerador ou denominador como um nú- mero em ponto flutuante:

double total = s1 + s2 + s3; double average = total / 3;

ou double average = (s1 + s2 + s3) / 3.0;

Erro Freqüente

2.3

Parênteses Desbalanceados Considere a expressão 1.5 * ((-(b – sqrt(b * b – 4 * a * c)) / (2 * a))

O que há de errado com ela? Conte os parênteses. Existem cinco ( e quatro ). Os parênteses es- tão desbalanceados. Esse tipo de erro de digitação é bastante comum em expressões complicadas. Agora considere esta expressão.

Tabela 2

Outras funções matemáticas

Função Descrição

sin(x) seno de x ( x em radianos)

cos(x) cosseno de x

tan(x) tangente de x

asin(x) (arco seno) sen–1x∈ [–π/2, π/2], x ∈ [–1, 1] acos(x) (arco cosseno) arc–1 x∈ [0, π], x ∈ [–1, 1] atan(x) (arco tangente) tg–1x ∈ (–π/2, π/2) atan2(y, x) (arco tangente) tg–1(y/x) ∈ [–π/2, π/2], pode ser 0

exp(x) ex

log(x) (logaritmo natural) ln(x), x > 0 log10(x) (logaritmo decimal) ln(x), x > 0

sinh(x) seno hiperbólico de x

cosh(x) cosseno hiperbólico de x tanh(x) tangente hiperbólica de x

ceil(x) menor inteiro ≥ x

floor(x) maior inteiro ≤ x

1.5 * (sqrt(b * b – 4 * a * c))) – ((b / (2 * a))

Esta expressão possui cinco ( e cinco ) mas ainda não está correta. No meio da expressão, 1.5 * (sqrt(b * b – 4 * a * c))) – ((b / (2 * a))

existem somente dois ( mas 3 ), o que é um erro. No meio de uma expressão, o contador de ( deve ser maior ou igual ao contador de ) e ao final da expressão, os dois contadores devem ser iguais.

Aqui está um truque simples para tornar fácil a contagem sem usar lápis e papel. É difícil para o cé- rebro manter dois contadores simultaneamente. Mantenha somente um contador ao percorrer a expres- são. Inicie com 1 no primeiro parêntese que abre; adicione 1 sempre que você vê um parêntese que abre; e subtraia 1 sempre que você vê um parêntese que fecha. Diga em voz alta os números, à medi- da que você percorre a expressão. Se o contador se torna negativo, ou não é zero no final da expressão, os parênteses estão desbalanceados. Por exemplo, ao percorrer a expressão anterior, você murmuraria

1.5 * (sqrt(b * b – 4 * a * c) ) ) – ((b / (2 * a))

1 2 1 0 –1

e encontraria o erro.

Erro Freqüente

2.4

Esquecer Arquivo de Cabeçalho

Cada programa que você escreve necessita pelo menos um arquivo de cabeçalho, para incluir faci- lidades de entrada e saída; este arquivo normalmente é o iostream.

Se você usa funções matemáticas, tais como sqrt, precisa incluir cmath. Se você esquecer de incluir o arquivo de cabeçalho apropriado, o compilador não irá reconhecer símbolos tais como

sqrtou cout. Se o compilador reclamar sobre a indefinição de uma função ou símbolo, verifi- que seus arquivos de cabeçalho.

Às vezes você pode não saber qual o arquivo de cabeçalho a ser incluído. Suponha que você quer calcular o valor absoluto de um inteiro usando a funçãoabs. Acontece que absnão é defi-

nida em cmathmas em cstdlib. Como você pode encontrar o arquivo de cabeçalho correto? Você precisa localizar a documentação da funçãoabs, preferencialmente usando a ajuda online de seu editor (ver Dica de Produtividade 2.2). Muitos editores possuem uma tecla de atalho que ativa a ajuda conforme a palavra apontada pelo cursor. Você pode olhar o manual de referência da biblio- teca que acompanha o compilador, de forma impressa ou online. A documentação inclui uma pe- quena descrição da função e o nome do arquivo de cabeçalho que você deve incluir.

A documentação de alguns compiladores não está atualizada para refletir o padrão C++. Aqui está uma correspondência entre todos os arquivos de cabeçalho padrão e antigos que são usados neste livro.

Cabeçalho Padrão C++ Cabeçalho Antigo

iostream iostream.h

iomanip iomanip.h

fstream fstream.h

cmath math.h

cstdlib stdlib.h

string Sem equivalente

Tópico Avançado

2.6

Resto de Inteiros Negativos

Freqüentemente você calcula um resto (a % n) para obter um número no intervalo entre 0 e n – 1. Entretanto, se aé um número negativo, o resto a % nfornece um número negativo. Por exemplo, -7 % 4é −3. Este resultado é inconveniente, porque ele não se encontra no intervalo en- tre 0 e 3 e porque ele é diferente da definição matemática usual; em matemática, o resto é o núme- ro que você obtém iniciando com ae adicionando ou subtraindo até que você atinja um número en- tre 0 e n – 1. Por exemplo, o resto de 11 por 4 é 11 – 4 – 4 = 3. O resto de −7 por 4 é −7 + 4 + 4 = 1, que é diferente de -7 % 4. Para calcular o resto correto de números negativos, use a seguin- te fórmula:

int rem = n – 1 – (-a – 1) % n; /* se a é negativo */

Por exemplo, se a é −7 e n é 4, esta fórmula calcula 3 – (7 – 1) % 4 = 3 – 2 = 1.

Dica de Produtividade

2.2

Ajuda Online

Os atuais ambientes integrados de C++ contêm sofisticados sistemas de ajuda. Você pode empregar al- gum tempo aprendendo como usar a ajuda online em seu compilador. A ajuda é disponível em configu- rações do computador, em atalhos de teclado e, mais importante, em funções de biblioteca. Se você não está certo sobre como a função powfunciona, ou não pode lembrar se ela se chama powou power, a ajuda online pode dar a você a resposta rapidamente. A Figura 8 mostra uma típica tela de ajuda.

Figura 8 Ajuda online.

Dica de Qualidade

2.4

Espaço em Branco

O compilador não se importa se você escreve todo o seu programa em uma única linha ou coloca ca- da símbolo em uma linha separada. O leitor humano se importa bastante. Você deve usar linhas em branco para agrupar visualmente seu código em seções. Por exemplo, você pode marcar para o leitor que um prompt de saída e o comando de entrada correspondente estão relacionados, inserindo uma li- nha em branco antes e após o grupo. Você pode achar muitos exemplos nas listagens de códigos fonte neste livro. Espaços em branco dentro de expressões também são importantes. É mais fácil de ler

x1 = (-b + sqrt(b * b – 4 * a * c)) / (2 * a);

do que

x1=(-b+sqrt(b*b-4*a*c))/(2*a);

Simplesmente coloque espaços ao redor de todos os operadores + – * / % =. Entretanto, não coloque um espaço após um menos unário: um – usado para negar uma quantidade simples, tal como -b. Deste modo, ele pode ser facilmente distinguido de um menos binário, como em a – b. Não coloque espaços entre um nome de uma função e os parênteses, mas coloque um espa- ço após cada palavra chave C++. Isso torna mais fácil de ver que sqrtem sqrt(x)é o nome da função, enquanto que ifem if (x > 0)é a palavra-chave.

Dica de Qualidade

2.5

Coloque em Evidência Código Comum

Suponha que queremos encontrar ambas as soluções de uma equação do segundo grau ax2+ bx + c = 0. A fórmula de Báscara nos diz que as soluções são

Em C++, não existe nada análogo à operação ±, que indica como obter duas soluções simulta- neamente. Ambas as soluções devem ser calculadas separadamente.

x1 = (-b + sqrt(b * b – 4 * a * c)) / (2 * a); x2 = (-b – sqrt(b * b – 4 * a * c)) / (2 * a);

Esta abordagem possui dois problemas. A computação de sqrt(b * b – 4 * a * c) é

realizada duas vezes, o que é uma perda de tempo. Segundo, sempre que o mesmo código é replicado, aumenta a possibilidade de erros de digitação. A solução é colocar em evidência o código comum:

double root = sqrt(b * b – 4 * a * c); x1 = (-b + root) / (2 * a);

x2 = (-b – root) / (2 * a);

Podemos ir mais longe e colocar em evidência 2 * a, mas o ganho da fatoração deste cálcu- lo simples é pequeno e o código resultante pode ficar difícil de ler.

x b b ac a 1 2 2 4 2 , = − ± −

2.6

Strings

2.6.1 Variáveis Strings

Depois de números, strings são o tipo de dado mais importante que a maior parte dos programas usa. Um string é uma seqüência de caracteres, tal como "Hello". Em C++, strings são coloca- dos entre aspas, que não fazem parte do string.

Você pode declarar variáveis que armazenam strings. string name = "John";

O tipo stringfaz parte do padrão C++. Para usá-lo, simplesmente inclua o arquivo de cabe- çalho string:

#include <string>

Use atribuição para armazenar um string diferente na variável. name = "Carl";

Você também pode ler um string do teclado:

cout << "Por favor digite seu nome: "; cin >> name;

Quando um string é lido de um stream de entrada, somente uma palavra é colocada numa va- riável string (palavras são separadas por espaços). Por exemplo, se o usuário digita

Harry Hacker

como resposta ao prompt, então somente Harryé armazenado em name. Para ler o segundo string, outro comando de entrada deve ser usado. Esta restrição torna desafiador escrever um co- mando de entrada que lide adequadamente com respostas do usuário. Alguns usuários podem digi- tar apenas seus primeiro e último nomes, e outros podem fornecer também suas iniciais dos nomes do meio.

Para tratar tal situação, use o comando getline. O comando getline(cin, name);

lê todos os caracteres digitados até a tecla Enter, forma um string contendo todos eles, e o armaze- na numa variável name. No exemplo anterior de entrada, name é configurado como o string

"Harry Hacker". Esse é um string contendo 12 caracteres, um dos quais é um espaço. Você deve sempre usar a função getlinese não estiver certo de que a entrada do usuário con- siste de uma única palavra.

O número de caracteres em um string é denominado de tamanho do string. Por exemplo, o ta- manho de "Harry Hacker"é 12 e o tamanho de "Hello, World!\n"é 14 – o caractere de nova linha conta apenas como um caractere. Você pode calcular o tamanho de um string usan- do a função length. Diferentemente de sqrtou getline, a função lengthé invocada com a notação ponto. Você escreve primeiro o nome de uma variável string cujo tamanho você quer, de- pois o nome da função, seguido por parênteses:

int n = name.length();

Muitas funções C++ exigem esta notação ponto e você deve memorizar (ou procurar) quais usam e quais não usam. Estas funções são denominadas funções membro (ver Sintaxe 2.9).

Um string de tamanho zero, que não contém caracteres, é denominado de string vazio. Ele é escrito como "". Diferente de variáveis numéricas, variáveis string têm inicialização garantida; elas são inicializadas com o string vazio.

2.6.2 Substrings

Uma vez que você tem um string, o que pode fazer com ele? Você pode extrair substrings e colar strings pequenos para formar maiores. Para extrair um substring, use a operação substr:

s.substr(start, length)

retorna um string que é constituído pelos caracteres do string, iniciando no caractere starte contendo lengthcaracteres. Assim como length, substrusa a notação ponto. Dentro dos parênteses, você escreve os parâmetros que descrevem qual substring você quer. Aqui está um exemplo:

string greeting = "Hello, World!\n"; string sub = greeting.substr(0, 4); /* sub é "Hell" */

A operação substrforma um string que consiste de quatro caracteres obtidos do string

greeting. Assim, "Hell" é um string de tamanho 4 que ocorre dentro de greeting. O as- pecto curioso da operação substré a posição inicial. Iniciar na posição 0 significa “iniciar no co- meço do string”. Por razões técnicas que costumavam ser importantes mas não são mais relevan- tes os números de posição em strings iniciam com 0. O primeiro item em uma seqüência é nume- rado como 0, o segundo como 1 e assim por diante. Por exemplo, aqui estão os números de posi- ção do stringgreeting:

O número de posição do último caractere (13) é sempre um a menos que o tamanho do string. Vamos imaginar como extrair o substring"World". Conte os caracteres iniciando em 0, e não 1. Você vai ver que W, o oitavo caractere, está na posição número 7. O string que você quer possui comprimento 5. Portanto, o comando substring apropriado é

string w = greeting.substr(7, 5);

As funções string que você viu aqui estão resumidas na Tabela 3.

2.6.3 Concatenação

Agora que você sabe como separar strings, vamos ver como juntá-los novamente. Dados dois strings, tais como "Harry"e "Hacker", nós podemos concatená-los para formar um maior:

string fname = "Harry"; string lname = "Hacker"; string name = fname + lname;

H e l l o , W o r l d ! \n 0 1 2 3 4 5 6 7 8 9 10 11 12 13 5

{

H e l l o , W o r l d ! \n 0 1 2 3 4 5 6 7 8 9 10 11 12 13

Sintaxe 2.9: Chamada de Função Membro