A maior rede de estudos do Brasil

Grátis
105 pág.
apostila de programacao em C - USP

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