Grátis
105 pág.

Denunciar
Pré-visualização | Página 9 de 24
dependem da avaliação de expressões condicionais para exe- cutarem seu trabalho. Para que essas expressões realmente façam sentido como condições, elas só podem assumir dois valores: verdadeiro ou falso (que indicam se o bloco correspon- dente será ou não executado). Variáveis que só indicam esses dois estados são chamadas booleanas ou lógicas. Em C, não há nenhum tipo primitivo especiĕcamente para lidar com variáveis boole- anas; por isso, convenciona-se que qualquer valor diferente de zero é interpretado como verdadeiro, e o zero é interpretado como falso. Ou seja, qualquer variável ou expressão, independente de seu tipo, pode ter um valor booleano que é ou ‘verdadeiro’ ou ‘falso’.⁵ Os operadores que devolvem um valor lógico usam os valores 0 e 1 (além de serem a escolha mais simples, esses dois valores são sempre representáveis em qualquer tipo numé- rico) para representar os resultados “falso” e “verdadeiro”, respectivamente; assim, quando fazemos alguma comparação do tipo a � �� ou [ y, o valor da expressão comparativa é 0 ou 1. No entanto, em geral não devemos nos preocupar com essa representação, pois essas expressões já têm um valor lógico bem deĕnido. A partir desse conhecimento, podemos analisar o que acontece em algumas das situa- ções capciosas quemencionamos anteriormente. Primeiro temos as comparações compos- tas do tipo a � b � F; quando escrevemos em C exatamente dessa maneira, o que ocorre é que a expressão é avaliada da esquerda para a direita, dois operandos por vez. Assim, pri- meiramente é avaliada a expressão a � b, cujo resultado poderá ser 0 ou 1— chamemo-no genericamente de R. Então é avaliada a expressão 5 � F, que nada tem a ver com a relação entre b e c. Olhemos agora para as comparações errôneas que usam o operador de atribuição em vez do operador de comparação de igualdade, como if �a b�. O valor de uma expressão como a b corresponde ao valor que foi atribuído, ou seja, b (ou a após a atribuição). Assim, o código if �a b� é equivalente a a b� if �b� No entanto, como a variável b está num contexto lógico, seu valor será interpretado como um valor booleano, ou seja, falso se b � e verdadeiro se b � �. Assim, ĕnalmente, a comparação if �a b� na verdade é equivalente a ⁵Nota para o futuro: na verdade, só podem ser interpretados como booleanos os tipos escalares, ou seja, os tipos numéricos (inteiro e ponto Ęutuante), além dos ponteiros, que só veremos no capítulo 5. Variáveis booleanas 35 a b� if �b � �� que, claramente, não tem nada a ver com a igualdade (prévia) entre a e b. R — 05/02/2011 3Funções 3.1 Introdução Em C, uma função é um pedaço de código, dentro de um programa maior, que realiza uma certa tarefa com uma certa independência do resto do programa. Funções podem ser executadas várias vezes, e uma grande vantagem disso é a reutilização de código: em vez de repetir várias vezes o código para executar certa tarefa, podemos simplesmente chamar várias vezes a função que executa essa tarefa. Além de economizar linhas de código, isso permite que você mude facilmente o código associado a essa tarefa — se não fosse pelas funções, você teria de buscar em seu programa por todos os locais em que você executou essa tarefa e alterar o código em cada um. Mais ainda, ao organizarmos o código em várias funções, podemos focar cada parte do código em uma só tarefa, deixando o programamais claro e limpo. Em C, uma função deve ter as seguintes características: • Um nome pela qual ela possa ser chamada. Os nomes possíveis seguem as mesmas restrições que os nomes de variáveis: devem começar com uma letra ou com um sublinhado (_), e podem conter qualquer combinação desses e dos algarismos 0–9. Lembre-se de que há distinção entre maiúsculas e minúsculas. • Valores de entrada ou parâmetros— são os valores sobre os quais a função deve ope- rar. Os parâmetros das funções (também chamados de argumentos) atuam de ma- neira análoga às variáveis das funções matemáticas. Também é possível criar funções sem argumentos — por exemplo, se você quiser criar uma função que calcula o valor (aproximado, é claro) do número pi, não precisa de nenhum parâmetro (a princípio; você poderia introduzir parâmetros se quisesse — por exemplo, a precisão desejada —, mas eles não são necessários se você quer executar a operação de uma maneira pré-determinada). • Um valor de saída, que corresponde ao resultado da função para o conjunto dos parâmetros de entrada fornecidos. Também é possível criar funções que não devol- vem nenhum valor de saída. Por exemplo, uma função que simplesmente exibe uma mensagem na tela não precisa devolver nenhum valor — embora a função tenha um resultado, ele é mostrado na tela, e não devolvido internamente para o programa. 37 38 Capítulo 3. Funções Burocraticamente, ao se deĕnir uma função, precisamos sempre especiĕcar todas essas características: o nome da função, a quantidade de parâmetros e o tipo de cada um, além do tipo do valor de saída (caso haja valor de saída). E, é claro, você deve deĕnir o que a função vai fazer. Para deĕnir uma função, usamos a seguinte estrutura: tipo_da_saída nome_da_funomo �parâmetros� ^ conteúdo da função� ` Essa deĕnição deve ser colocada no “nível superior” do arquivo, ou seja, não deve estar dentro de outra função como o main. Todas as funções dentro de um arquivo devem ĕcar no mesmo nível, cada uma após o ĕnal da anterior. Na verdade, enquanto eu não falar de uma outra coisa (ainda neste capítulo), as demais funções devem ĕcar antes da função main. O tipo do valor de saída pode ser qualquer um dos tipos usados para variáveis (por enquanto, você só conhece o int). No caso em que não há valor de saída, você deve usar no lugar do tipo a palavra void (vazio, em inglês). Ela não é um tipo de variável; ela apenas indica a ausência de um valor. (Muitos falam do “tipo void”, mas isso é apenas um abuso de linguagem.) A deĕnição dos parâmetros é semelhante à declaração de variáveis. Cada parâmetro deve ter um nome (seguindo, novamente, as mesmas restrições válidas para os nomes de variáveis) e um tipo. Para especiĕcar esses parâmetros, você deve usar o formato tipo_1 nome_1, tipo_2 nome_2, …, tipo_n nome_n Note que, nesse caso, não existe nenhum tipo de abreviação para vários parâmetros do mesmo tipo (como ocorria na declaração de variáveis). No caso de não haver parâmetros, você deve usar a palavra void sozinha dentro dos parênteses: tipo_da_saída nome_da_função (void) Atenção: segundo muitos textos, em caso de ausência de parâmetros bastaria deixar os pa- rênteses “vazios”, sem nada no meio. Segundo o padrão da linguagem, nesse caso o com- pilador apenas entenderia que não há informação sobre os parâmetros; mesmo assim, isso costuma ser aceito pela maioria dos compiladores. O conjunto dessas três deĕnições — do nome, do tipo de saída e da lista de parâmetros da função — é chamado de cabeçalho da função. Vamos construir alguns exemplos de cabeçalhos: • Uma função que calcula a soma dos divisores de um número inteiro n. Como en- trada, teremos obviamente o número n, que será uma variável do tipo int. Como saída, teremos outro valor do tipo int, que corresponderá á soma dos divisores de n. Com isso, o cabeçalho ĕca int soma_divisores�int n� Introdução 39 • Uma função que recebe dois números inteiros, a e b, e devolve o valor da potência ab. Novamente, todos os valores envolvidos são do tipo int, e nosso cabeçalho vem a ser int potenFia�int a� int b� • Você está criando uma função que recebe um mês e um ano e imprime na tela o calendário desse mês. Nesse caso, não há nenhum valor de saída (os dados são en- viados diretamente para a tela, com a função printf), o que indica que usaremos a palavra void no lugar do tipo da saída; mas há dois parâmetros do tipo int, então o cabeçalho ĕca assim: void imprime_FaOendario�int mes� int ano� • Suponha agora que você quer fazer uma função que lê um inteiro do teclado (usando a função scanf como intermediária). Para isso, você não precisa de nenhum