(Parte 1 de 5)

INTRODUÇÃO AO C+03 é uma linguagem fácil de aprender, especialmente se você já conhece Pascal ou alguma outra linguagem procedural. Todo conceito em Pascal leva diretamente a um conceito em C: as idéias são exatamente as mesmas, mas você usa palavras diferentes para expressá-las. O C pode parecer difícil, às vezes, porque dá mais liberdade ao programador e, portanto, é mais fácil cometer erros ou criar bugs que são difíceis de descobrir. Este tutorial faz uma introdução ao C mostrando como fazer a conexão com o Pascal. Também introduz vários conceitos que não existem em Pascal. A maior parte desses conceitos trata dos ponteiros. Os leitores que possuem uma formação em

Fortran, Cobol, BASIC, etc., perceberão como o código do Pascal é fácil de ler. Eu acredito que a única maneira de aprender C (ou qualquer outra linguagem) é escrever e ler muito código. Uma boa maneira de conseguir experiência em C é pegar programas escritos em outras linguagens e convertê-los. Dessa forma, se o programa não funcionar em C, você sabe que é a tradução que está causando o problema e não o código original. Existe uma grande diferença entre o Pascal e o C que causa vários problemas: o C não permite procedures aninhadas, assim será necessário remover todas elas para converter qualquer programa em Pascal. O melhor é que você substitua estas procedures no código Pascal. Desta forma, você pode testar novamente o programa antes de traduzi-lo para C. Também repare que o C é case sensitive. Os compiladores entendem que X, x e Xxx são três nomes diferentes. Por convenção, as constantes em C são escritas em maiúscula, enquanto as variáveis em minúsculas ou combinadas. As palavras-chave em C são sempre em minúscula. Neste tutorial, todas as instruções de compilação e referências às páginas “man” assumem que você está trabalhando numa estação Unix normal. Se você não estiver, terá de usar os arquivos de ajuda do seu sistema para mapear as instruções para o seu ambiente.

Um simples programa Abaixo temos um programa simples em C que encontra o fator de 6. Abra seu editor favorito e digite-o. Salve o programa com algum nome como exemp.c. Se você esquecer do .c, terá um erro “Bad Magic Number” quando fizer a compilação. Assim, nunca se esqueça da extensão.

/* Programa para encontrar o fator de 6 */ #include <stdio.h>

#define VALUE 6 int i,j; void main() { j=1; for (i=1; i<=VALUE; i++) j=j*i; printf(“The factorial of %d is %d\n”,VALUE,j); }

Na maioria dos sistemas Unix, você encontrará um programa chamado C Beautifier, que irá formatar o código para você. Para compilar esse código, digite c exemp.c. Para dar o run, digite a.out. Se ele não compilar ou não o fizer corretamente, edite-o novamente e veja o que deu errado. Agora, vamos olhar o código Pascal equivalente:

{ Programa para encontrar o fator de 6 } program samp; const value=6; var i,j:integer; begin j:=1; for i:=1 to value do j:=j*i; writeln(‘The factorial of ‘,value,’ is ‘,j); end.

Você pode notar uma correspondência quase total. A única diferença real é que o código em C começa com #include <stdio.h>. Essa linha inclui a biblioteca Standard I/O no seu programa; assim você pode ler e escrever valores, trabalhar com arquivos texto e assim por diante. C tem um número grande de bibliotecas Standard como stdio, incluindo bibliotecas de texto, tempo e matemática. A linha #define cria uma constante. Duas variáveis globais são declaradas usando a linha int i,j;. Outros tipos de variáveis comuns são float (para números reais) e char (para caracteres), ambas podendo ser declaradas da mesma forma que int. A linha main() declara a função principal. Todo programa em C deve ter uma função chamada main em algum lugar do código. Em C, { e } substituem o begin e o end do Pascal. Da mesma forma, = substitui o operador de atribuição do Pascal :=. A estrutura de repetição for e a declaração printf são estranhas, mas elas fazem as mesmas funções que suas contrapartes no Pascal. Note que o C usa aspas duplas em vez de simples para strings. A declaração printf em C é mais fácil de usar do que a versão Pascal, uma vez que você se acostuma com ela. A porção em aspas é chamada de format string e descreve como o dado deve ser formatado quando impresso. A format string contém string literais como The factorial of e \n para retorno de linha e operadores como marcação para variáveis. Os dois operadores na format string indicam que os valores integer encontrados mais tarde na lista de parâmetros serão colocados na string exatamente nestes pontos. Outros operadores incluem floating point, para caracteres e strings. Você pode digitar man printf para ajuda em opções de formatação. Na declaração printf, é extremamente importante que o número de operadores na format string corresponda exatamente ao número e tipo das variáveis existentes. Por exemplo, se a format string contém três operadores, ela deve ser seguida exatamente por três parâmetros de mesmo tipo, na mesma ordem em que os especificados pelos operadores. Esse programa é bom, mas seria melhor se pudesse ler os valores em vez de usar uma constante. Edite o arquivo, remova a constante VALUE e declare uma variável como um integer global (mudando todas as referências em minúsculas porque o valor agora é uma variável). Coloque, então, as duas linhas seguintes no começo do programa:

printf(“Enter the value:”); scanf(“%d”,&value);

O código equivalente para isso em Pascal é:

write(‘Enter a value:’); readln(value);

Faça as mudanças, compile e rode o programa para ter certeza de que ele funciona. Note que scanf usa o mesmo tipo de format string que printf (digite man scanf para mais informações). Note também o sinal & na frente de value. Este é o address operator em C. Ele retorna o endereço da variável, mas isso não fará nenhum sentido até discutirmos ponteiros. Você precisa usar o operador & em scanf independente da variável ser tipo char, int ou float. Se você esquecer o operador &, você receberá um erro quando rodar o programa.

Erros a serem evitados: - Esquecer de usar o & no scanf.

- Muitos ou poucos parâmetros após as declarações printf ou scanf. - Esquecer o */ no final dos comentários.

Branching e estruturas de repetição (loops) As declarações e estruturas while em C baseiam-se nas idéias das expressões Booleanas, da mesma forma que em Pascal. Em C, entretanto, não existe o tipo Booleano: você usa integers no lugar. O integer value 0 em C é false, enquanto qualquer outro valor é true. Aqui temos uma tradução simples do Pascal para o C. Primeiro o código em Pascal:

if (x=y) and (j>k) then z:=1 else q:=10; A tradução para o C parece muito similar, mas há diferenças importantes, que nós vamos discutir em breve. if ((x==y) && (j>k)) z=1; else q=10;

Perceba que = em Pascal virou == em C. Esta é uma diferença importante, porque o C irá aceitar um = simples quando você compilar, mas irá se comportar de forma diferente quando você rodar o programa. O and em Pascal vira && em C. Perceba também que z=1; em C tem um ponto e vírgula, que C elimina o then, e que a expressão Booleana precisa ser completamente cercada por parênteses. O seguinte quadro mostra a tradução de operadores Booleanos do Pascal para o C:

O sinal == é um problema porque é comum esquecermos e digitarmos somente =. Como os integers substituem os Booleanos, a seguinte declaração é legal em C:

void main() { int a; printf(“Enter a number:”); scanf(“%d”, &a); if (a) { blah blah blah } se a for qualquer coisa diferente de 0, o código que blah blah blah representa será executado. Vejamos agora a seguinte declaração em Pascal:

if a=b then incorretamente traduzida para C como:

if (a=b) /* teria que ser “if (a==b)” */

Em C, esta declaração significa “Atribua b para a e depois teste o valor Booleano de a”. Então, se a for 0, a declaração if é falsa; senão, ela será verdadeira. O valor de a também muda. Este não é um comportamento previsto (apesar desta característica ser importante quando usada corretamente), então seja cuidadoso com as conversões entre = e ==. As declarações while são bem fáceis de traduzir. Por exemplo, vejamos o seguinte código em Pascal:

while a < b do begin blah blah blah end; em C vira:

while (a < b) { blah blah blah }

C também possui uma estrutura “dowhile” para substituir o “repeat-until” do Pascal como mostrada abaixo:

Pascal C

INTRODUÇÃO AO C+04 do { blah blah blah } while (a < b);

A estrutura de repetição for em C é bastante diferente da sua versão em Pascal, porque a versão em C é simplesmente um atalho para expressar uma declaração while. Por exemplo, vejamos o seguinte código em C:

x=1; while (x<10) { blah blah blah x++; /* x++ é a mesma coisa que escrever x=x+1. É uma adição. */ }

Você pode converter isso numa estrutura de repetição for da seguinte maneira:

for(x=1; x<10; x++) { blah blah blah }

Note que a estrutura while contém um passo de inicialização (x=1), um passo de teste (x<10) e um passo de incremento (x++). Com a estrutura for é possível colocar qualquer coisa nestas três partes. Por exemplo, vamos dar uma olhada nesta estrutura:

a=1; b=6; while (a < b) { a++; printf(“%d\n”,a); }

Você pode colocar isso numa declaração for também:

for (a=1,b=6; a < b; a++,printf(“%d\n”,a));

É confuso, mas possível. A vírgula permite que você separe diferentes declarações nas seções de inicialização e incremento da estrutura for (mas não nas seções de teste). Muitos programadores em C gostam de juntar muita informação numa única linha. Eu acho que isso dificulta a compreensão do código, portanto a ordem é quebrar o código em várias linhas.

Erros a serem evitados: - Colocando = quando o certo é == numa declaração if ou while. ? Acidentalmente coloque um ; no final de uma estrutura de repetição ou uma declaração if, de forma que essa declaração perca o efeito. Por exemplo:

for (x=1; x<10; x++); printf(“%d\n”,x); somente imprime um valor por causa do ponto e vírgula depois da declaração for.

Arrays Nesta seção, você irá criar um pequeno programa que gera dez números aleatórios e os embaralha. Inicie o editor e digite o seguinte código:

#include <stdio.h> #define MAX 10 int a[MAX]; int rand_seed=10; int rand() /* from K&R - returns random number between 0 and 32767.*/ { rand_seed = rand_seed * 1103515245 +12345; return (unsigned int)(rand_seed / 65536) % 32768; } void main() { int i,t,x,y; /* fill array */ for (i=0; i < MAX; i++) { a[i]=rand(); printf(“%d\n”,a[i]); } /* more stuff will go here in a minute */ }

Esse código contém vários conceitos novos, mas as linhas #include e #define são familiares para você. A linha int a[MAX]; mostra como declarar um array de integers em C. Como exemplo, a declaração int a[10]; é declarado desta forma em Pascal: a:array [0..9] of integer;

Todas arrays começam em zero e vão até n-1 em C. Pois int a[10]; contém 10 elementos e o maior índice válido é 9. Ao contrário do Pascal, C não oferece nenhuma forma de mudar os valores do índice. Notem também que por causa da posição do array a, esta situação é global para o programa inteiro. A linha int rand_seed=10 também declara uma variável global, desta vez chamada de rand_seed que é iniciada em 10 cada vez que o programa inicia. Este valor é a onda que inicia o código de números aleatórios que se segue. Num gerador de números aleatórios real, a onda deveria iniciar num valor aleatório. Aqui, a função rand produzirá os mesmos valores a cada vez que o programa for iniciado. A linha int rand() é uma declaração de função. A declaração de função equivalente aparece assim em Pascal: function rand:integer; A função rand não aceita nenhum parâmetro e retorna um valor integer. As quatro linhas que se seguem implementam a função rand. Nós iremos ignorá-las agora. A principal função é normal. Quatro integers locais são declaradas, e a array é preenchida com dez valores aleatórios usando uma estruturação de repetição for. Note que arrays são indexadas exatamente como em Pascal. Agora adicione o seguinte código no lugar do comentário que começa com more stuff:

/* bubble sort the array */ for (x=0; x < MAX-1; x++) for (y=0; y < MAX-x-1; y++) if (a[y] > a[y+1]) { t=a[y]; a[y]=a[y+1]; a[y+1]=t; } /* print sorted array */ printf(“——————————\n”); for (i=0; i < MAX; i++) printf(“%d\n”,a[i]);

Esse código mistura os valores aleatórios e os imprime misturadamente.

INTRODUÇÃO AO C+05

Exercícios: - No primeiro pedaço do código, tente mudar a estrutura de repetição for que preenche a array, para uma linha única de código. Faça com que o resultado seja o mesmo que o código original. ? Inicie a onda de números aleatórios em valores diferentes.

Erros a evitar: - C não tem checagem de série, portanto se você indexar depois do fim da array, você não será avisado. O programa pode eventualmente dar pau e retornará dados errados. ? Um chamado de função deve incluir (mesmo se nenhum parâmetro for passado. Por exemplo, C irá aceitar x=rand;, mas o chamado não irá funcionar. O endereço de memória da função rand será colocado em x. O correto seria x=rand();.

Operadores e precedência Os operadores em C são similares aos operadores em Pascal como mostrado abaixo:

O operador / faz uma divisão integer se ambos os operadores são integers e divide os pontos flutuantes. Por exemplo:

void main() { float a; a=10/3; printf(“%f\n”,a); }

Esse código imprime um valor de ponto flutuante a partir do momento em que a é declarado como um tipo flutuante, mas a será 3.0 porque o código fez uma divisão entre integers. A precedência do operador em C é também similar ao do Pascal. Como em Pascal, os parênteses controlam a precedência. Typecasting O C permite que você faça conversões de tipo facilmente. É possível fazer isso especialmente quando usando ponteiros. Typecasting também ocorre durante a operação de distribuição para certos tipos. Por exemplo, no código acima, o valor do integer foi automaticamente convertido para um ponto flutuante. Você faz typecasting em C ao colocar o nome do tipo entre parênteses e deixando-o em frente do valor que você quer mudar. Pois, no código acima, ao trocar a linha a=10/3; por a=(float)10/3; produza 3,3 em a porque 10 é convertido para um valor de ponto flutuante antes da divisão.

Tipos Você declara tipos definidos pelo usuário em C com a declaração typedef. O seguinte exemplo mostra um tipo que aparece freqüentemente no código C:

#define TRUE 1 #define FALSE 0 typedef int boolean; void main() { boolean b; b=FALSE; blah blah blah }

Esse código permite que você declare tipos Booleanos em programas C. Se você não gosta da palavra “flutuante” para números reais, você pode dizer:

typedef float real; and then later say: real r1,r2,r3;

Você pode colocar declarações typedef em qualquer lugar num programa C, mas eles devem estar antes de serem usados no código. Não é necessário agrupá-los nem dê nenhuma palavra especial para marcar o início do bloco como em Pascal.

Arrays Você declara arrays ao inserir um tamanho de array após uma declaração normal, como mostrado abaixo:

int a[10]; /* array of integers */ char s[100]; /* array of characters (a C string) */ float f[20]; /* array of reals */ struct rec r[50]; /* array of records */

(Parte 1 de 5)

Comentários