C
Esta é a pagina dedicada à linguagem de programação C. A estrutura da página segue de muito perto a estrutura da página anterior que explica a linguagem Fortran. Assim os que desejarem compará-las poderão fazê-lo com maior facilidade.
Olá Mundo
Já é um divertida tradição que o primeiro programa de um iniciante a uma linguagem de programação é um programa que ao ser acionado responde escrevendo a expressão "Hello World" ou em português "Olá Mundo". Você pode até achar na Wikipedia uma página com este programa escrito em mais de 30 linguagens conhecidas.
Para o C este código é
#include <stdio.h> void main(void) { printf("Ola mundo! \n"); }
O código acima mostra pelo menos dois elementos essenciais da gramática de C. Primeiro a existência de instruções para incluir funções. Diferente de alguns compiladores, como o Fortran, o compilador C necessita de instruções explícitas dizendo quais funções estarão presentes no programa, mesmo que estas funções sejam as mais óbvias. No caso do código acima a diretiva de compilação "#include" indicou a inclusão de um grupo de funções de entrada e saída, contidas no arquivo "stdio.h". Se tal instrução não fosse passada ao compilador ele não reconheceria a função "printf", que permite ao programa escrever "Ola Mundo!".
Um segundo elemento da linguagem C é o programa principal. Todo o código C deve ter um programa principal indicado pela expressão "main" e contido entre chaves "{" "}". A ordem temporal das intruções realizadas pelo programa são lidas dentro deste programa principal. Vocês vão observar que um código em C pode ser até bem desordenado fora do programa principal, mas funcionará se estiver em ordem dentro dele. Assim para entendermos um programa em C o primeiro passo é olhar dentro do "main".
A função "printf" permite a impressão formatada da saída do programa. Veremos mais adiante todas as possibilidades desta função. Por hora observe que o formato é escrito entre aspas e que a instrução "\n" representa a mudança de linha. Ou seja, o programa escreve "Ola Mundo!" e o cursor muda de linha.
Editar
Estas linhas devem estar dentro de um arquivo (ex: ola.c), isto pode ser feito com cat linha por linha ou com um editor de texto (jed,emacs ou view)
Compilar
ola.c deve ser compilado, isto é traduzido da linguagem C (código fonte) para Assembler (código objeto ou de maquina) com a seguinte instrução:
> gcc ola.c -o ola
gcc invoca o compilador que faz a dita conversão
-o nome é uma opção para nomear o código objeto (o programa executável) que no exemplo terá o nome ola
sem essa opção o executável criado terá o nome a.out
Rodar
ola.c não é executável, o computador não sabe o que fazer com ele, para isso o compilador traduz para uma série de instruções que o computador sim sabe executar.
Para rodar fazemos:
> ./ola
./ na frente é necessário para o interprete de comandos (shell) saber que o programa está no diretório de trabalho (veremos depois como configurar a sessão para não ter que digitar esses caracteres)
> Ola Mundo!
será a saída na tela
Desta forma completamos o processo de ter criado nosso primeiro código C, compilado e executado o mesmo.
Tipos de Variáveis
Por diversas razões entre as quais o bom gerenciamento da memória, ou a correta interpretação de um caractere, a linguagem C exige que o tipo de cada variável seja definido no programa. Não existem "defaults", toda a variável deve ser definida caso contrário o compilador acusa erro. As mais comuns são
char - Caracter. O valor armazenado é um caracter usualmente em código ASCII. int - Número inteiro. float - Numero de ponto flutuante de precisão simples. double - Número de ponto flutuante de precisão dupla. void - Tipo indefinido, cuja utilidade veremos mais adiante.
Operadores matemáticos
. ponto decimal (vírgula *NÃO*) + - * / soma subtração multiplicação e divisão (igual que uma calculadora)
Diferente do Fortran o C não tem um operador básico associado a potenciação. A potenciação
é feita por uma função matemática.
Funções Matemáticas
Estas são as funções fazem parte da biblioteca de funções do compilador C, contidas em math.h. Ou seja o compilador C as reconhece se a instrução
#include <math.h>
estiver presente nas primeiras linhas no código.
A sintaxe de uso é o nome da função (geralmente três letras) e o argumento entre parêntesis:
sqrt(x) - raiz quadrada: pow(x,y) - x elevado na potencia y sin(x), cos(x), tan(x) - funções trigonométricas exp(x) - exponencial log(x) - logarítmo natural
Ciclos (loop)
O grande lance dos programas (e do computador claro) é poder repetir operações. Ou seja, utilizando a lógica para repetir tarefas que podem ter variações especificadas pelo programador dentro de um ciclo. Vejamos um exemplo usando a instrução for:
int i; float x,y; ... for(i=1;i<=100;i++) { x = i*0.1; y = pow(x,2); printf("%f %f\n",x,y); } ...
a interpretação do for é a seguinte:
* comece com i=1 * faça o que esta entre chaves. * incremente i em 1 ( i++ ) e veja se ultrapassou o valor máximo de i (no exemplo 100) * se a resposta é não faça de novo com o novo valor de i * o ciclo se repete até o valor máximo de i (= 100 no exemplo) * quando i ultrapassa esse valor o laço é interrompido e o programa prossegue
Observe que assim como no comando main todas as instruções dentro do comando if devem estar entre chaves. A presença das chaves só é facultativa se houver uma única instrução dentro do ciclo. As chaves são essenciais para organizar a estrutura de encadeamentos dentro de um código C. Quando o código é muito grande é usual que o programador use certas regras de identação ou alinhamento das chaves para melhor visualizá-lo ( Por exemplo, no exemplo acima a chave fecha diretamente abaixo de onde ela abriu). Editores tradicionais como o emacs ou o gvim ajudam o programador a verificar se o fechamento das chaves está correto.
Pergunta:
Qual será no exemplo acima o valor da variável i finalizado o laço?
Notas em sintaxe - Maísculas, Abrevições e printf
Mauísculas
No C como no shell maiúsculas são diferentes de minúsculas. Por exemplo em C , não existe o commando "Printf" e sim "printf". Isto também vale para variáveis definidas dentro do programa, por exemplo a variável a é diferente da variável A.
Abreviações
O C é uma linguagem que possui muitas notações abreviadas para melhorar a dinâmica de escrita. Por exemplo "i++" é uma abreviação de "i = i+1" ou seja o incremento de 1 de uma variável. A notação para um incremento genérico é "x += a" onde "a" é um valor qualquer. Isto também serve para multiplicações e divisões, por exemplo. "x *= a" é equivalente a "x = x*a" e assim por diante.
printf - Impressão formatada
Neste exemplo vemos que para imprimir dois números do tipo float a expressão %f deve estar no argumento de printf. O que indica o comando acima é que os dois números de ponto flutuante serão impressos na mesma linha com um único espaço entre eles (já que tem um único espaço entre as duas expressões "%f". Para os demais formatos temos
%c variável tipo char %d variável tipo int %f variável tipo float %lf variável tipo double
Exemplo: MRUA
Neste exemplo criamos um programa que gera a trajetória x(t) (uma dimensão) de um objeto com aceleração constante:
x(t) = x(0) + v(0)*t + 0.5*a*t²
// Programa mrua --- isto é um comentário, não é interpretado pelo compilador #include <stdio.h> #include <math.h> void main(void) { float x0, x, v0, a, t, dt; // variáveis ponto flutuante int i,N; // variáveis inteiras printf("entre x0, v0, a, t, N\n"); scanf("%f %f %f %d",&x0, &v0, &a, &t, &N); // leitura dos dados dt = t/N; // passo de tempo: definido pelo tempo máximo e o número de pontos da trajetória t = 0; for(i = 1; i<= N; i++) { x = x0 + v*t + 0.5*a*pow(t,2); printf("%f %f\n", t, x); // saída de dados t += dt; } }
Nota: este programa tem um erro que você deve descobrir
Notas em sintaxe - Pointers ou apontadores
O C é uma linguagem que possibilita o usuário ter acesso não só ao valor de uma variável (ou seja o conteúdo da memória onde esta variável é armazenada) mas também ao endereço na memória onde esta armazenada a variável. A existência destes dois tipos de informação introduz certas regras de sintaxe em C que se não são seguidas causam muita dor de cabeça. Por exemplo, se você utilizar o valor de uma certa variável x como argumento de um comando (ou função) de forma que este o valor seja usado mas não moficado pelo comando (ou função) você escreve simplesmente
func(x);
Mas se no entanto func for modificar x você deverá forçosamente escrever
func(&x);
onde "&x" é o valor do apontador da variável "x"( endereço na memória onde está o valor de "x"). E é esta a razão pela qual os argumentos do comando de leitura formatada "scanf" são os apontadores e não as variáveis. Um comando de leitura sempre modifica valores de variáveis.
Funções e comandos são sensíveis aos tipos de variáveis em seus argumentos. Colocar a variável onde deveria estar seu apontador ( e vice versa ) causam erro no programa.
Isto no começo parece mais dificultar do que ajudar o programador. Mas veremos mais adiante que a existência de apontadores possibilita escrever programas muito mais eficientes sendo isto uma das grandes vantagens da linguagem C.
Controle de Fluxo (if)
Possibilitam a escolha de rumos diferentes no programa dependendo de valores de variáveis ou condições entre elas. Sintaxe:
if (condição) { instruções executadas quando condição verdadeira } else { instruções executadas quando condição falsa }
Operadores relacionais e lógicos
== igual != diferente > maior < menor >= maior ou igual <= menor ou igual && E lógico || OU lógico ! NÃO lógico
Eles são usados junto com as instrucões de controle como o if (se), exemplo:
// exemplo de divisão a x b: float a,b,c; ... scanf("%f %f",&a, &b); if (b != 0) c = a/b; else break; printf(" a/b= %f/n",c); ...
Ciclos (Avançado)
Muitas vezes quando estamos lidando com um ciclo é conveniente poder interrompê-lo antes do número previsto de iterações. Isto pode acontecer porque algum erro é detectado ou porque o resultado desejado já foi obtido sendo desnecessário continuar no ciclo. O comando for em princípio aceita a introdução de uma série de condições de parada além do limite da variável contadora. Por exemplo
int i; float x; ... for( i=1; ( i < 100 && x > 3.1 );i++) { instrução1; instrução2; } ...
No exemplo acima se x assumir um valor menor que 3.1 o ciclo não é repetido novamente não importa o valor de i, isto porque a condição para a realização de um ciclo é que "i" seja menor que 100 e "x" seja maior que 3.1.
Quebra - Break
Outras vezes uma interrupção mais abrupta é necessária. Ou seja, talvez seja conveniente deixarmos um ciclo no meio dele, não realizando todas as instruções até o fim. Isto se pode fazer usando o comando break como é exemplificado abaixo
int i; float x; ... for( i=1; i < 100 ;i++) { instrução1 if( x < 3.1) break; instrução2 } ...
Os dois exemplos acima são quase iguais, salvo pelo fato que no último somente a instrução1 é realizada.
Ciclo condicionais - do-while e while
Os ciclos podem ser controlados de diversas formas. Como vimos anteriormente o for no seu uso mais simples repete um conjunto de instruções um número definido de vezes. Mas podemos adicionar mais condições de parada a ele.
Existem dois outros comandos equivalentes ao for que produzem ciclos. Nestes comandos os ciclos são interrompidos quando uma condição deixar de ser válida. São eles o do-while escrito como
... do{ instrução1; ... instruçãoN; } while( condição ); ...
e o while escrito como
... while( condição ) { instrução1; ... instruçãoN; } ...
A única diferença entre os dois esta no momento onde a condição é testada. Por exemplo, o do-while realiza as suas instruções pelo menos uma vez já que a condição é sempre testada ao final.
Não existe nada novo nos comandos acima, eles podem ser facilmente implementados com a combinação de comandos for e if.
Exercício - Tente escrever um do-while usando um for e if, e um for usando um while.