Neste capítulo veremos os aspectos básicos dos programas em C, tais como a sua estrutura, a declaração de variáveis, os tipos de dados e os operadores. Assume-se o conhecimento de uma linguagem de programação de alto nível como o Pascal.
Definição de variáveis globais
Entrada e saída do valor de variáveis
A estrutura genérica de um programa em C é a que se apresenta a seguir, podendo alguns dos elementos não existir:
Comandos do pré-processador
Definições de tipos
Protótipos de funções - declaração dos tipos de retorno e dos tipos dos parâmetros das funções
Variáveis globais
Funções
Deverá existir sempre uma função main().
As funções têm a seguinte estrutura:
tipo nome_da_funcao(parâmetros)
{
variáveis locais
instruções em C
}
Assim, o programa:
void main(void)
{
printf("Eu gosto do C\n");
}
contém apenas uma função (a função main(), que é obrigatória), que não retorna nada (void) e que não tem parâmetros (outra vez void). Como instrução da função temos apenas a chamada a printf(), uma função da biblioteca standard que escreve no vídeo. Neste caso escreve uma cadeia de caracteres (string). A combinação \n no fim da string indica uma mudança de linha (o carácter new line ou line feed). Notar que no final de cada instrução existe sempre um terminador - ;
Se a chamada a printf() fosse: printf(".\n.1\n..2\n...3\n"); o que apareceria escrito no vídeo seria:
.
.1
..2
...3
O C tem pré-definidos os seguintes tipos de dados simples:
Tipo de dados |
Tamanho (bytes) |
Limite inferior |
Limite superior |
---|---|---|---|
char |
1 |
-128 |
127 |
unsigned char |
1 |
0 |
255 |
short int |
2 |
-32768 |
32767 |
unsigned short int |
2 |
0 |
65535 |
int |
4 |
-231 |
+231 - 1 |
long int |
4 |
-231 |
+231 - 1 |
float |
4 |
-3.2×10±38 |
+3.2×10±38 |
double |
8 |
-1.7×10±308 |
+1.7×10±308 |
Geralmente nos sistemas UNIX os tipos int
e long int são
equivalentes (inteiros de 32 bits). No entanto noutros sistemas é
possível que o tipo int
seja equivalente a um short int
(inteiro de 16 bits). É necessário consultar a
documentação do compilador para o sistema em questão.
O C não tem um tipo booleano pré-definido, no
entanto, poderá usar-se um char
(ou melhor um unsigned char) ou
um int para o efeito.
O
prefixo unsigned pode também
ser usado com os tipos int e
long int.
Para declarar variáveis em C, de um dado tipo, usa-se a seguinte regra:
tipo_das_variáveis lista_de_variáveis ;
Por exemplo:
int i, j, k;
float x, y, z;
char ch;
As variáveis globais, visíveis em todas as funções de um programa, declaram-se fora e antes de todas as funções (só são visíveis a partir do local da daclaração). Por exemplo:
short number, sum;
int bignumber, bigsum;
char letter;
void main(void)
{
}
É também possível inicializar as variáveis globais no momento da declaração. Usa-se para isso o operador de atribuição = (equivalente ao := do Pascal). Por exemplo:
float sum = 0.0;
int bigsum = 0;
char ch = 'A';
void main(void)
{
}
Poderíamos ter feito a mesma coisa de outra forma (mas mais ineficiente):
float sum;
int bigsum;
char ch;
void main(void)
{
sum = 0.0;
bigsum = 0;
ch = 'A';
}
O C também permite múltiplas atribuições (colocar o mesmo valor em várias variáveis ao mesmo tempo):
a = b = c = d = 3;
O C tem uma palavra chave que permite a definição de novos tipos - typedef. Esses novos tipos declaram-se utilizando a regra:
typedef tipo_já_definido novo_tipo;
Um exemplo muito sismples:
typedef float real;
typedef char letter;
real sum = 0.0; /* o mesmo que float */
letter ch = 'A'; /* o mesmo que char */
As funções da biblioteca standard printf() e scanf() permitem escrever no vídeo e ler do teclado, respectivamente, o valor de variáveis. Estas funções têm como primeiro parâmetro uma string especificando o formato e a ordem das variáveis a escrever ou a ler. Seguem-se como parâmetros as próprias variáveis pela ordem especificada. Na string de formatação indica-se o local e o tipo de um valor de variável através do carácter % seguido de uma letra indicadora do tipo. Alguns dos tipos suportados são:
%c - char
%d - int's
%f - float's
Um exemplo: printf("Os valores das três variáveis são: %c, %d, %f\n", ch, i, x);
A modificação de formatos, pode ocorrer para especificar largura e numero de casas decimais. Assim o modificador é colocado entre o sinal % e o código do formato. Se tivermos %10f informa que o campo terá 10 posições incluindo a parte inteira o ponto e a parte decimal. Se tivermos %12.3f informa que terá 12 posições no total com 3 casas decimais.
#include <stdio.h>
void main(void)
{
double
item;
item = 10.12304;
printf("%f\n",
item);
printf("%5.2f\n", item);
}
Produz o resultado:
10.123040
10.12
Notas: As strings em C definem-se entre aspas ". . .", os caracteres simples aparecem entre plicas '.'; o texto normal da string de formatação aparece tal e qual no vídeo, os valores das variáveis aparecem nos locais indicados pelo carácter %; seguem-se as próprias variáveis que deverão aparecer pela mesma ordem e com os tipos indicados na string de formatação.
Um possível resultado da chamada anterior seria: Os valores das três variáveis são: A, 41, 0.0
A função scanf() lê valores do teclado para variáveis. A sua estrutura é semelhante a printf(). Por exemplo: scanf("%c%d%f", &ch, &i, &x);
Notas: Na lista de variáveis é obrigatório
usar o operador & antes de
cada variável; veremos mais tarde porquê.
O C suporta as quatro operações aritméticas standard nas suas expressões que são representadas pelos símbolos habituais (+, -, *, /). Além destas operações aritméticas são suportadas outras.
A atribuição é representada no C pelo operador =. (No C a atribuição é considerada uma operação aritmética). Exemplos: i = 4; ch = 'y';
Outros operadores aritméticos são os operadores de incremento e decremento, representados respectivamente por ++ e --. Em geral geram código mais eficiente do que a soma ou subtracção de 1 unidade. Assim a atribuição x = x + 1; pode ser substituída simplesmente por x++; Os operadores ++ e -- podem ser pósfixos (colocam-se após a variável a incrementar ou decrementar) ou podem ser préfixos (colocando-se antes da variável a incrementar ou decrementar. Quando o operador é pósfixo a expressão x++ tem como valor o conteúdo de x antes deste ser incrementado, enquanto que com o operador préfixo a expressão ++x representa já o valor de x depois de incrementado (em ambos os casos x é incrementado, o que muda é o valor que a combinação x++ ou ++x representa como conjunto). Vejamos o exemplo:
int x, y, w;
void main(void)
{
x = ((++z) - (w--)) % 100;
}
Este programa seria equivalente a:
int x, y, w;
void main(void)
{
z = z + 1;
x = (z - w) % 100;
w = w - 1;
}
Um outro operador aritmético do C é o operador módulo - %. Este operador é equivalente ao operador mod do Pascal e tem como resultado o resto da divisão inteira. Só pode ser utilizado com valores inteiros. (Ver os exemplos anteriores).
O operador de divisão /, pode ser usado com inteiros e reais. No entando, se ambos os operandos forem inteiros o resultado é a divisão inteira. Assim a atribuição x = 3 / 2; coloca em x o valor 1, mesmo que x seja float ou double. Se quisermos colocar em x o resultado correcto da divisão real (se x for float ou double) deveremos escrever x = 3.0 / 2; ou x = 3 / 2.0; ou melhor ainda x = 3.0 / 2.0; (sem conversões de um inteiro para real).
O C suporta também alguns modos expeditos de escrever
atribuições. É comum termos de escrever nos
programas expressões como i
= i + 3; ou x
= x * (y + 2); Expressões deste tipo
podem ser abreviadas para qualquer coisa como variável
op=
expressão;
e que é equivalente a variável
= variável
op (expressão);
Assim podemos reescrever as duas expressões anteriores como
i += 3; e x
*= y + 2; Note-se que esta última
expressão vale sempre x
= x * (y + 2); e nunca x
= x * y + 2;
O operador de teste de igualdade no C é ==. Note-se que é muito fácil trocar o teste de igualdade pelo operador de atribuição (só um =), o que conduz invariavelmente a erros dificeis de detectar. A seguinte instrução condicional está sintacticamente correcta: if (i = j) ... ,no entanto o que faz é copiar o valor de j para i e tem como resultado o valor de j, que é interpretado como TRUE se for diferente de 0 e FALSE no caso contrário. O que se pretendia era comparar i com j com resultado TRUE se fossem iguais...
O operador de teste de desigualdade é em C !=.
Os outros quatro operadores de comparação são
iguais ao Pascal: <, <=,
> e >=.
Os operadores lógicos servem para combinar resultados de comparações e são geralmente utilizados nas instruções condicionais. Os três operadores lógicos do C são:
not - !
and - &&
or - ||
Existem também os operadores &
e |, com outro significado. Não
confundir.
Todos os operadores do C têm um nível de precedência. Os operadores de nível mais elevado são avaliados antes dos operadores de nível bais baixo. Por exemplo, a expressão a + b * c é avaliada como a + (b * c) porque o operador * tem maior precedência do que o operador +. Os operadores do mesmo nível de precedência são geralmente avaliados da esquerda para a direita (há excepções). Assim a - b - c é avaliado como (a - b) - c e não pela ordem inversa.
Na tabela seguinte podem ver-se todos os operadores do C pela
ordem decrescente do nível de prioridade, e também a
sua associatividade.
Operadores |
Associatividade |
---|---|
() [] -> . |
esquerda para a direita |
! - ++ -- * & (cast) sizeof |
direita para a esquerda |
* / % |
esquerda para a direita |
+ - |
esquerda para a direita |
<< >> |
esquerda para a direita |
< <= > >= |
esquerda para a direita |
== != |
esquerda para a direita |
& |
esquerda para a direita |
^ |
esquerda para a direita |
| |
esquerda para a direita |
&& |
esquerda para a direita |
|| |
esquerda para a direita |
?: |
direita para a esquerda |
= += -= *= /= %= &= ^= |= <<= >>= |
direita para a esquerda |
, |
esquerda para a direita |
Assim a expressão a
< 41 && 7 * b < c é
avaliada como (a < 41)
&& ((7 * b) < c).
Da mesma forma a
expressão a = b =
fahr / celsius + limit é
avaliada como a = (b = ((fahr /
celsius) + limit)).
[Rev. 8/2000]