segunda-feira, 26 de outubro de 2009

Deixe que o computador decida... Parte I (if)

Continuando a nossa jornada pelo C, hoje vamos falar sobre como o computador toma decisões.

O computador não pensa, mas pode tomar decisões!
Parece estranho isto que falei; afinal, todas as vezes que precisamos tomar decisões temos que pensar (embora algumas pessoas não o façam ;).
Pois bem, se ele não pensa, como faz isto? Simples! Alguém tem que pensar por ele! Quem seria este alguém??? Você, programador.
Criar programas é pensar pelo computador e, é o que já fazemos. Definimos as variáveis, os tipos, como os dados serão processados, o que será impresso, etc.
Para nos ajudar nesta tarefa de 'ensinar' o computador a tomar decisões, o C nos fornece os comandos de decisão e os operadores relacionais.
Hoje falaremos sobre o comando de decisão if e os operadores relacionais.

E se...?
Já reparou que temos que tomar decisões em função dos acontecimentos? Quando você vai sair de casa, logo olha para as condições climáticas. Seria algo, mais ou menos, assim:
Está calor agora, mas o céu está com nuvens. Levo guarda-chuva ou não? Mas, e se chover? Então, é melhor levar o guarda-chuva. Se chover, e somente se chover, eu faço uso do guarda-chuva, senão ele fica fechado.
O comando de decisão if faz exatamente isto. Vamos ver na prática, como ele funciona?

"O prevenido vale por dois!"
Se você se lembra do programa que usei como exemplo para explicar o uso do scanf (aqui), verá que no comando da linha 11, que explica ao usuário o que digitar para que o programa funcione, existe uma sugestão para que ele não digite o valor 0 (zero). Imagina, o por quê disto?
O resultado de uma divisão por zero é indeterminado. Como não se consegue determinar, evita-se fazer esta divisão.
Agora, me responda esta pergunta. E se o usuário, mesmo sendo avisado antes, digitar zero?
Na gíria dos programadores, o programa vai 'capotar'.
Os micros mais antigos, com sistemas operacionais também antigos, travavam de uma forma que, para voltar a funcionar, só desligando e ligando novamente (reboot); e com isto se perdia tudo o que não tinha sido salvo ainda.
Eu mesmo já perdi várias horas de digitação, porque um programa fez uma divisão por zero (runtime error division by zero). Como 'xinguei' o computador! Hoje sei, que 'xinguei' a 'pessoa' errada rsrs!
Evite ser xingado e use o comando if!
No caso do nosso exemplo seria só fazer assim:
- Antes de fazer a operação da linha 13, a divisão de num1 por num2, temos que avaliar o valor de num2.
Fácil, não é? E como se faz isto?
Resposta: Usando os operadores relacionais! Vamos a eles.

Operadores relacionais (Qual a relação entre laranjas e bananas?)
Antes de mostrar os operadores relacionais, vamos pensar no nosso exemplo.
Não queremos que o divisor da nossa divisão seja zero. Ele pode ser maior que zero, ou menor que zero. Só não pode ser zero! Tem que ser diferente.
Pensando assim, achamos a relação entre o nosso divisor (num2) e zero.
Se num2 for igual a zero, não poderemos efetuar a divisão. O programa será finalizado.
É exatamente isto que devemos 'dizer' ao computador que faça.
A forma de 'dizer' isto em C, é:

if (num2 == 0)
    exit(1);


Vamos por partes ;).
O if é o se da nossa frase em português, e significa exatamente isto em inglês (língua 'mãe' do C).
Dentro dos ( ) está a relação que estamos avaliando: num2 igual a zero.
Não estamos atribuindo o valor 0 (zero) a num2! Estamos avaliando/testando se a variável do lado esquerdo do == é igual a variável/valor do lado direito.
O == é um dos operadores operacionais, e avalia a igualdade entre variáveis e valores.
(O operador de atribuição é o =, e o operador relacional de igualdade é o ==. A confusão entre os 2 é muito comum, e gera erros de lógica que fazem muitos programadores queimarem neurônios por horas (rsrs). Preste muita atenção ao usar este operador relacional!)
A tabela abaixo mostra todos os operadores relacionais, e o que cada um significa.



Depois retornaremos a eles, com mais calma. Vamos continuar a análise, do nosso comando.
Na linha de baixo, temos o comando que encerra o nosso programa antes que ele execute a divisão.
E finalmente o ; que encerra o comando. Como assim, encerra?
Apesar de estar um duas linhas, este é um único comando. Poderia estar em uma única linha, mas está em duas por questões de clareza. Esta é uma caracteristica (não somente) do if: unir-se a outro comando formando um único.
Se quiser, altere o código, fazendo esta modificação, compile e execute; digite 0 (zero) para o valor do dividendo e veja o que acontece.
Esta alteração evita um 'capotamento' (rsrs), mas não deixa claro ao usuário o por quê do programa ser finalizado.
Não ficaria mais 'bonito' se fosse informado ao usuário a causa deste encerramento?
Então vamos alterar nosso código de novo para que isto seja feito.

if (num2 == 0)
    printf("O DIVIDENDO NÃO PODE SER ZERO! O programa será encerrado.\n");
    system("pause");
    exit(1);


Faça essas alterações no código, compile e execute.
O que aconteceu?
Conforme você deve ter notado, o programa encerra independente do valor do dividendo ser zero ou outro qualquer. Por que?
O comando if se encerra no ; . Portanto, para o computador os comandos seguintes NÃO fazem parte do if, e serão executados independente do if ser executado. Como corrigir isto?
Usando blocos! Que nada mais são que os sinais {, antes da sequência de comandos que queremos agrupar; e }, após estes comandos agrupados. Já falamos sobre isto aqui.
Assim nosso código ficará assim:


//Exemplo de if
//Exemplo de if

#include <stdio.h>
#include "stdlib.h"
 
int main( )
{
 float num1, num2, resultado;
 
 printf("Digite o numero que sera dividido(dividendo)\n");
 scanf("%f",&num1);
 printf("Digite o numero que dividira o anterior (divisor), nao pode ser zero\n");
 scanf("%f",&num2);
 if (num2 == 0){
    printf("O DIVISOR NAO PODE SER ZERO! O programa sera encerrado.\n");
    system("pause");
    exit(1);
 }
 resultado = num1 / num2;
 printf("O resultado da divisao de %.2f por %.2f eh igual a %.2f.\n",num1, num2, resultado);
 system ("pause");
}


Ficou muito melhor, não é?
E se desejarmos que para o valor do dividendo só sejam aceitos números pares?
Veremos isto no próximo post.

Continua...

domingo, 25 de outubro de 2009

Lendo valores digitados (scanf)

No final do post sobre o comando printf, eu deixei um desafio sobre o que fazia o seguinte comando:


printf("O resultado da soma de %03d + %3d eh igual a %d.\n",num1, num2, resultado);



Conseguiu descobrir? É muito simples! O 1º especificador de formato/largura de campo exibe um inteiro completando-o com zeros à esquerda para que ele tenha 3 caracteres, e o 2º exibe um inteiro completando com espaços para que ele tenha também 3 caracteres. São quase iguais; a diferença é que um completa com zeros e o outro com espaços.

Sei que você já tinha descoberto isso! Só coloquei aqui para confirmar.

A partir de agora, quando eu fizer algum desafio, só responderei nos comentários. Quem quiser confirmar as respostas pode perguntar nos comentários.

Vamos ao assunto de hoje.


Criando um programa interativo
Neste mesmo post sobre o comando printf, falei sobre a capacidade de imprimir valores desconhecidos; isto é, desconhecidos na hora em que se está escrevendo o código fonte do programa, mas que serão conhecidos quando o programa for executado. Usando os devidos termos técnicos, dados desconhecidos em tempo de compilação.
Esta é a base da interatividade; a capacidade do usuário interagir com o computador (através de um programa), fornecendo dados para que ele execute uma tarefa.
O comando usado em C para permitir esta entrada de dados é o scanf. Na verdade existem outros, mas este é o preferido da maioria dos programadores (eu, inclusive), pois permite a entrada formatada.

Formatada? Eu já ouvi esta palavra...
Se você está tentando lembrar de onde 'ouviu' esta palavra, dá uma olhada no post do qual falei no começo deste (sobre o printf).
O scanf é quase o inverso do printf. O printf imprime a saída formatada e o scanf permite a entrada formatada. Além disto, os especificadores de formato dos 2 são os mesmos.
Vamos ver isto na prática?
Você já sabe o caminho, correto? Esta é a última vez que falo isto (para ganharmos tempo, e economizar meus dedos, evitando digitar sempre a mesma coisa).
Abra o Dev C++, crie um novo Arquivo fonte e copie o código abaixo.




//Exemplo de scanf
#include <stdio.h>
#include "stdlib.h"


int main( )
{
float num1, num2, resultado;


printf("Digite o numero que sera dividido(dividendo)\n");
scanf("%f",&num1);
printf("Digite o numero que dividira o anterior (divisor), nao pode ser zero\n");
scanf("%f",&num2);
resultado = num1 / num2;
printf("O resultado da divisao de %.2f por %.2f eh igual a %.2f.\n",num1, num2, resultado);
system ("pause");
}


Compile e execute.



Esta é a versão interativa do 2º código que usei como exemplo para mostrar os parametros do printf.
Vamos a análise dele.
Na linha 7, declaramos todas as variáveis com o tipo float, o que significa que o usuário pode digitar números com casas decimais.
Nas linhas 9 e 11, informamos ao usuário o que ele deve fazer para entrar os dados que o programa precisa para executar uma divisão.
Na linha 13, o resultado da divisão é armazenado na variável resultado.
Na linha 14, são impressos os números e o resultado da operação.
Acredito, que você já sabe o que fazem as linhas 1, 2, 3, 5, 6, 15 e 16! Se não sabe leia a série de posts sobre código fonte (começa aqui).
A novidade deste código está nas linhas 10 e 12. Que utilizam o comando scanf e com os seus devidos parametros.
Repare o uso do "%f", que indica que desejamos ler valores com casas decimais. Lembra em alguma coisa o comando printf? O scanf usa os mesmos especificadores de formato do printf. Especificadores de formato e não de largura de campo. Tentar usar um especificador de largura de campo junto com o comando scanf retorna valores 'malucos'. (Duvida? Faça alguns testes e veja por si mesmo).
Depois da vírgula, temos a variável que vai armazenar o valor digitado.
E que & é este na frente do nome da variável?

Alterando o conteúdo de uma variável
Diferente do printf, o scanf precisa alterar o conteúdo da variável que é 'passada' para ele.
Para fazer esta alteração, ele precisa saber (além do nome) do endereço (na verdade, sabendo o endereço, o nome é irrelevante).
Este & na frente do nome da variável, significa que estamos passando o endereço da variável para o comando scanf. O nome técnico disto é passagem por referência, que como a maioria das coisas mais complicadas que falo aqui, veremos depois (rsrsrs), quando virmos funções; embora não tenha muito mais o que falar sobre isto. Entendeu o porquê do &? Então vamos prosseguir.

Lendo 2 valores de uma vez
O printf pode imprimir várias variáveis, que são passadas como parametro, num mesmo comando. E o scanf? Pode ler mais de uma variável por vez?
A resposta é SIM. Observe o comando abaixo:

scanf("%f %f", &num1, &num2);

Ele lê 2 valores digitados e armazena nas variáveis do tipo float num1 e num2.
A leitura é feita assim: Digite o 1º valor e tecle espaço ou enter, depois digite o 2º valor e encerre a entrada obrigatóriamente com enter. Se eu não digitar enter no final? O que acontece?
Teste e descubra.

Por hora, isto é o que você precisa saber sobre o scanf.
Faça seus testes. Quer um desafio?

Faça um programa em C que peça ao usuário que digite uma distância em quilometros e a quantidade de litros de combustível gastos por um carro para percorrer esta distância, e calcule quantos litros/Km este carro faz.

Quem conseguir pode postar nos comentários.

Abraços e até o próximo post.

sábado, 24 de outubro de 2009

Imprimindo na tela (printf)

No último post da série sobre código fonte nós analisamos (pelo menos, tentamos analisar ;) linha a linha um típico código fonte em C. Eu deixei um desafio para que você descobrisse o que fazia o comando da linha 11 do código analisado, no caso, system ("pause"). Descobriu?
Antes que os mais puristas venham me criticar sobre o uso deste comando, já que existem outros que atingem o mesmo objetivo; e de forma melhor, já que não deixam o código fonte dependente do sistema (leia-se Rwindow$); deixem que eu me defenda. Também não gosto deste comando, mas utilizo-o por 2 motivos:
1 - É o comando ensinado pela maioria dos professores de C (não é verdade?);
2 - Como uso o Dev C++, estou seguindo a recomendação da página oficial desta IDE (duvida? veja aqui, em inglês).

Isto posto, vamos ao assunto de hoje.

O comando printf
Por falar no código fonte do post anterior, você deve lembrar que falamos que o comando printf (linha 10) era muito importante e iríamos fazer um post só para ele, não é? Pois bem, este é o post.

Imprimindo...
O comando printf foi criado para imprimir. Isso você já deve ter percebido, mas imprimir o que e onde?
É aí que entra você, programador (gostou de ser chamado de programador???)!
Quem diz o que e onde o printf vai imprimir é você. Como você vai fazer isto? É o que veremos agora. Vamos começar com o onde.

A saída padrão
O comando printf pode imprimir em qualquer lugar. Por qualquer lugar, entenda a tela, uma impressora, um arquivo (existe uma função especializada, construída a partir do printf, para imprimir em arquivos (fprintf)), etc.
O alvo da impressão feita pelo printf é a saída padrão (stdout) que, geralmente, é a tela (existem formas de alterar isto).

Impressão formatada
Certamente você já ouviu falar em formatar (dar formato, forma, organizar segundo um padrão). A impressão feita pelo printf é formatada, ou seja, tem uma forma definda.
A forma que esta impressão terá é definida pelos parametros que são passados à função printf. Estes parametros ficam entre os ( ), como já vimos antes.

Os parametros da printf
Seguindo a teoria de que é fazendo que se aprende, vamos ao Dev C++.
Abra o Dev C++, crie um novo Arquivo fonte e copie o código abaixo.

//Exemplo 01 de printf

#include <stdio.h>

#include "stdlib.h"


int main( )

{

printf("Ola mundo!");

system ("pause");

}



Este código simples, é a minha versão do "Hello world", o programa mais simples feito em C (o mais simples que exibe algo na tela).
Pode compilar e executar.
Reparou na saída?

Olá mundo!Pressione qualquer tecla para continuar. . .

Não era isto que queríamos escrever! Era para aparecer só o Ola mundo!.
A frase Pressione qualquer tecla para continuar. . . é impressa pelo system("pause"). Só que ela está 'colada' no texto que escrevemos. Não ficaria mais 'bonito' se esta frase ficasse numa linha separada do nosso texto? Para isto é só imprimir um "enter". E como se faz isso?
O printf consegue imprimir qualquer caracter imprimível (verdade?). E os não imprimíveis, como é o caso do "enter" que nós precisamos?

Imprimindo o que não pode ser impresso
Para resolver esta questão complicada, o C dispõe de um recurso simples. Qual recurso é este?
Os códigos de escape, também conhecidos como códigos de barra invertida.
O símbolo '\' é conhecido no C como símbolo de escape. Ele é usado para tornar possível a impressão de alguns caracteres de controle e alguns símbolos especiais do C.
Os mais usados estão nesta tabela:




Conforme podemos ver, o 'enter' que precisamos é o '\n'.
Quanto aos símbolos especiais, um exemplo é o caracter ". Este caracter delimita o que vai ser impresso pelo printf. Agora, imagine que você queira imprimir um texto que tenha um outro texto delimitado por ". Exemplo: ("alguma "coisa""). A forma correta seria ("alguma \"coisa\"").
Substitua o comando da linha nn por este:

printf("Alo mundo!\n");

Agora, recompile e execute.
Ficou 'bem melhor'.

Imprimindo valores desconhecidos
Salve o seu Arquivo fonte do exemplo anterior e crie um novo em branco.
Copie o código abaixo.


//Exemplo 2 de printf

#include <stdio.h>
#include "stdlib.h"

int main( )
{
int num1=5, num2=2, resultado;



resultado=num1 / num2;
printf("O resultado da divisao de num1 por num2 eh igual a resultado.\n");
system ("pause");
}



Compile e execute.

Repare na saída. Você pode dizer, só olhando para a frase impressa, qual o valor armazenado nas variáveis? É bem capaz que você diga quais são os valores, porque viu no código fonte quais são eles. Sendo assim poderíamos substituir o comando da linha 9 por este:

printf("O resultado da divisao de 5 por 2 eh igual a 2.5.\n");

E se não tivesse nenhum valor no código fonte? Se tivéssemos dado ao usuário do programa a possibilidade de digitar os valores para a nossa soma (o que é muito comum)?
Entra em cena aqui mais um parametro de formatação da função printf, os especificadores de formato.
Os principais estão na tabela abaixo:




Agora que conhecemos este recurso do C, vamos corrigir o nosso código fonte para exibir os dados que desejamos mesmo sem saber o valor deles. É só substituir o comando da linha 9 por este:

printf("O resultado da divisao de %d por %d eh igual a %d.\n",num1, num2,resultado);

Note que usamos o especificador %d que imprime um número inteiro com sinal (poderíamos usar %i ou %u, já que nossos números são 'pequenos').
Além disto, o número de parametros do nosso comando printf ficou maior. Vejamos o porque disto.
Os especificadores de formato funcionam como comandos de substituição. Onde aparece o especificador de formato deverá ficar o valor que queremos mostrar; neste caso, o conteúdo das variáveis num1, num2 e resultado, exatamente nesta ordem. É importante observar isto, a ordem de impressão dos valores é a mesma em que eles são passados para a função printf.
Pode recompilar e executar.
Funcionou?
Na verdade não, correto? Nós sabemos que 5 dividido por 2 é igual a 2,5. E por que foi impresso 2?
A resposta é o tipo.
O tipo escolhido para a variável resultado foi int que armazena números inteiros. O resultado da divisão de um número inteiro por outro número inteiro na matemática nem sempre dá um número inteiro, veja o nosso exemplo. Para resolver isto temos que mudar o tipo da variável resultado para float.
Assim as linhas 6 e 7 ficarão assim:

int num1, num2;
float resultado;

Corrija, recompile e execute.
Além de não funcionar, agora ficou pior. Tá aparecendo que o resultado é 0 (zero). Por quê?
Porque não alteramos o printf, que deveria ficar assim:

printf("O resultado da divisao de %d por %d eh igual a %f.\n",num1, num2, resultado);

Novamente, recompile e execute.
Funcionou agora? Nada ainda, não é? Por quê?
Simples: Apesar da variável resultado ser do tipo float, o resultado da divisão continua dando um inteiro para o computador (ele não sabe das regras matemáticas!).
Temos duas soluções para isto (tem outra, mais veremos isso mais tarde):
A 1ª é mudar o tipo da variável num2 para float. A divisão de um número armazenado numa variável do tipo inteiro por outro número armazenado numa variável do tipo float tem como resultado um número com casas decimais (tipo float).
A 2ª é mais drástica. Mudar o tipo de todas as variáveis para float.

Tente a 1ª que já resolve. Não esqueça de mudar o comando printf da linha 9. Sabe como, certo?
Experimente esquecer e veja o que acontece.

Agora funcionou, não é?
Funcionar, funcionou; mas ainda não tá legal. Tá aparecendo um monte de zeros desnecessários.

Os especificadores de largura de campo
Dentre os parametros de formatação do printf, tem um que ainda não vimos que resolve isso. São os especificadores de largura de campo. Pode ficar tranquilo, que esses não precisam de tabela (rsrsrs).
Na verdade, os especificadores de largura de campo trabalham juntos com os especificadores de formato. É um número (e ponto) que fica entre o símbolo % e a letra do formato.
No nosso exemplo, para imprimir 2 e 2.5, usaríamos o seguinte especificador de largura de campo:

printf("O resultado da divisao de %d por %.0f eh igual a %.1f.\n",num1, num2, resultado);

Que significa que desejamos imprimir o valor armazenado na variável num2 com 0 (nenhuma) casas decimais, e o valor armazenado na variável resultado com uma casa decimal.

Corrija, recompile e execute (De novo! De novo!).

Finalmente, funcionou da forma esperada.

Agora você já pode fazer seus próprios teste.
Altere o nosso código fonte de exemplo para que ele faça a soma de 2 inteiros e exiba o resultado usando o comando abaixo:

printf("O resultado da soma de %03d + %3d eh igual a %d.\n",num1, num2, resultado);

Sabe explicar o que está acontecendo?

Nos 'vemos' no próximo post.

sexta-feira, 23 de outubro de 2009

Código Fonte... Parte III - Final (Estrutura)

Com os conceitos que vimos no post anterior, já estamos próximos (na verdade hoje é o dia) de fazer um código fonte que compile (gere um programa executável). Não necessáriamente, que funcione; afinal um programa pode compilar e mesmo assim não funcionar rsrs. Veremos isto mais a frente.

No primeiro post desta série, falamos sobre a necessidade de estruturar um texto. Separá-lo em parágrafos, pontuar corretamente, etc.
Este é o assunto de hoje: a estrutura de um código fonte em C.

A estrutura de um código fonte
Um típico código fonte em C é igual a este aqui embaixo.



//Programa para apresentar resultado da soma de dois números inteiros
#include <stdio.h>
#include "stdlib.h"
const int NUM2 = 10; //ESTE VALOR É UMA CONSTANTE
int main( )
{
int num1, resultado;
num1 = 5;
resultado = num1 + NUM2;
printf("O resultado da soma %d + %d eh igual a %d.\n",num1,NUM2,resultado);
system ("pause");
}


Vamos analisar este código linha a linha.

Comentários
Os comentários servem para esclarecer alguns pontos obscuros (obscuros? que não estão claros). Viu para que serve um comentário?
Como você viu acima, eu uso (e muito) os parênteses para fazer comentários.
No C, a forma de fazer um comentário é usando as barras paralelas //. Na verdade este é um dos padrões do C++, é o mais usado hoje em dia. Existe outro, que não vou comentar aqui. Esteja livre para procurar no Google qual é ele.
Assim sendo, a linha 1 é um comentário, que diz o propósito deste código fonte de forma simplificada. Há programadores que fazem verdadeiros cabeçalhos utilizando os comentários. Embora eles não sejam necessários, ajudam a esclarecer o código fonte. Esclarecer para nós programadores, porque para o C eles não significam nada! O C simplesmente os ignora. Repare que não tem ponto final (;) no fim dele.
Os comentários não precisam ficar separados em uma linha. Eles podem ser colocados no meio do código, após os comandos, como você pode ver na linha 4.
Lembre-se que TUDO o que for colocado após as barras paralelas é ignorado pelo C, mesmo que seja um comando válido.

Que # é esse? E porque não tem ;?
No post em que falei sobre compilação, falei sobre um tal de pré-processador, que é responsável por fazer alguns ajustes no código antes de 'entregá-lo' ao compilador.
É aí que entram as linhas 2 e 3. Nelas estão comandos para o pré-processador, por isto elas não seguem o padrão C, e sim o padrão do pré-processador.
O que elas fazem? Elas incluem (compliquei mais ainda rsrs). Para explicar o que elas incluem temos que ver outro conceito do C: as bibliotecas.

Bibliotecas
O Natal está se aproximando e eu já começo a lembrar do cheirinho das comidas especiais desta época: chester, rabanada, panetone, etc.
E o que isso tem a ver com Bibliotecas? Não era melhor falar em livros?
Vamos falar em livros agora e você vai entender o porquê desta instrodução.
As comidas especiais de Natal são tão especiais que só são feitas no Natal. Por isto, quem as faz não lembra exatamente como fazê-las, e por isto, recorre a livros de receita. (Não falei que ia chegar nos livros?)
Pois bem, algumas receitas são tão complexas que às vezes precisam de duas ou mais receitas que nem sempre estão num livro só. São necessários alguns livros.
O C também trabalha com seus 'livros de receitas'. Cada um destes 'livros' é chamado de biblioteca. Voltando as receitas culinárias; se quisermos passar uma receita para alguém teremos que copiar todas as partes das receitas que usamos para fazer aquela comida, mesmo que ela esteja em vários livros.
Agora vejam que idéia brilhante!
Um código fonte é na verdade uma 'receita', onde dizemos ao computador o que desejamos que ele faça. Se nossa 'receita' for complexa, nós usamos as bibliotecas. Só que, ao invés de copiar cada pedaço das várias 'receitas' dos vários livros, só precisamos dizer em que livro, ou melhor biblioteca, a receita está.
Isto é feito neste código pelas linhas 2 e 3. Elas incluem as bibliotecas que contém as receitas dos comandos printf (linha 10) e system (linha 11). Neste recurso que estou usando para exibir os códigos aqui no blog (Syntax Highlight), esses comandos aparecem em vermelho.
Existem várias bibliotecas (que são chamadas de especializadas), para os mais variados propósitos.
Se você reparou bem existe uma pequena diferença entre as linhas 2 e 3. Na linha 2, o nome da biblioteca está entre <>; já na linha 3, está entre " ". Este é um padrão para o local em que estas bibliotecas estão instaladas no seu computador, e indicam onde o pré-processador vai procurar por elas para poder incluí-las no código.
Os <> dizem para o pré-processador começar a procurar por elas no diretório padrão das bibliotecas ( se você instalou o Dev C++ no diretório sugerido pelo seu programa de instalação, este diretório é o C:\Dev-Cpp\include ). Já as " ", dizem para começar a procura pelo diretório onde o código fonte está salvo. Você pode usar qualquer um dos dois modos, conforme a sua necessidade.

Voltando ao código
O comando da linha 4 já é um conhecido nosso. Ele declara uma constante inteira e a inicializa com o valor 10.

Na linha 5, temos a função main. Esta merece uma atenção toda especial. Então vamos sair do código de novo rsrs.

A função main (Amém rsrs)
Se você fosse fazer alguma coisa dentre um um conjunto de quaisquer outras coisas, qual iria escolher para fazer?
Seguindo algum critério próprio, você decidiria por alguma delas. E o computador? Qual critério ele usa para escolher o que fazer?
Ele não usa critério nenhum (lembra que computador não pensa... ainda), quem diz onde ele deve começar somos nós programadores.
É aí que entra a main. Ela é a função principal de um programa executável. Todo programa executável tem que ter uma main (eu não conheço nenhum que não tenha, quem conhecer pode nos apresentar ;).
Antes da main, existe um identificador de tipo inteiro int. Ele pode, até, ser ignorado (o Dev C++ acrescenta ele, 'por baixo dos panos', quando compila o programa), você já deve ter visto alguns códigos sem ele. O que ele faz?
Ainda é cedo para explicar, voltaremos a este assunto mais a frente. Pode cobrar depois.
Depois da palavra main tem ( ). Dentro deles ficam os parâmetros da função main; que neste caso, não são usados e por isto os ( ) estão vazios. Parametros?
Parametros são dados e 'informações' que as funções usam para fazer o seu trabalho.
Lembra da linha 10? Nela está um comando (printf) que, geralmente, exibe alguma coisa na tela. O que ela tem que exibir e da forma que tem que exibir é 'informando dentro dos ( ).
Por hora é isto o que precisamos saber sobre a main. Vamos voltar ao código novamente (ou não).

Voltando ao código novamente (será?)
Na linha 6 temos um {. Para saber o que ele faz vamos sair do código ( de novo!) e explicar outro conceito fundamental do C: os blocos de comando.

Os blocos de comando
Podemos comparar os blocos de comandos da linguagem C ao parágrafo da linguagem escrita.
O parágrafo é o conjunto de frases que formam uma sequência com sentido, com lógica (tirei isto daqui); ou seja, são frases que tem a ver umas com as outras.
Blocos de comandos são comandos que estão relacionados entre si (simples assim). Todos trabalham juntos para cumprir uma tarefa. Um de cada vez, mas o objetivo final é o mesmo.
Um bloco de comando é iniciado com { e encerrado com }.
O bloco de comandos da main começa na linha 6 e acaba na linha 12.

Vamos (tentar) voltar ao código agora?
A resposta é não rsrsrs. Os outros comandos já são nossos velhos conhecidos :). São feitas algumas atribuições e o resultado é exibido na tela pelo comando da linha 10, do qual já falamos.
Aliás, o comando da linha 10 (o printf) é um comando muito importante, por isto faremos um post só para ele.
Você deve estar dizendo: Tem um comando na linha 11. O que ele faz?
Resposta: Descubra!!! (kkkkk)

Este código do nosso exemplo funciona. Pode criar um Arquivo fonte novo no Dev C++ e digitá-lo (ou copiá-lo). Ele está pronto para ser compilado.
Pode fazer alterações nos valores. E fazer suas próprias descobertas.
Quer uma dica sobre a linha 11? Pense em comentários.

Por hoje é só. Até o próximo post.

quinta-feira, 22 de outubro de 2009

Código Fonte... Parte II

Conforme prometido no post anterior, hoje vamos falar sobre os padrões do C.

Sou adepto da filosofia que diz que é fazendo que se aprende. Então vamos seguir essa filosofia! (Ao menos quando for possível ;)

Para isto inicie o Dev C++ e abra um novo Arquivo Fonte. Se não sabe como fazê-lo, veja aqui.

Para não causar desapontamentos futuros, vou logo avisando que não vamos criar um código fonte completo hoje! Veremos algumas particularidades sobre os padrões do C e como a IDE trata deles. Ok?

Identificando os dados
Lembra dos 'quadrinhos' que vimos aqui? Pois bem, dentro deste quadrinhos podem ficar armazenados informações ou instruções. O computador sabe encontrar cada um deles de acordo com o seu endereço. Mas este endereço não fica visível para nós programadores (existe uma forma de encontrar este endereço, assunto de um post mais adiante).
Se não podemos saber o endereço de um 'quadrinho', como vamos usá-lo? Como vamos 'escrever' ou 'ler' o que tem dentro de um deles?
Para resolver isto, o C nos dá a possibilidade de identificar cada um deles. Isto mesmo! Podemos dar um 'nome' a um 'quadrinho'. Seria como 'colar uma etiqueta' nele com o nome desejado.
Todas as vezes que nos referirmos a este nome estaremos falando daquele 'quadrinho' específico.
Este nome deve seguir algumas regras simples:
-COMEÇAR COM UMA LETRA OU _ (CARACTER DE SUBLINHADO (UNDERLINE)). Os caracteres seguintes podem ser letras, o próprio caracter de sublinhado ou números. Não use caracteres acentuados, espaços, símbolos de pontuação ou símbolos especiais (lembre-se que estes não são padronizados).
-LETRAS MAIÚSCULAS E MINÚSCULAS SÃO DIFERENTES PARA O C. Assim podemos ter no mesmo código fonte 4 'quadrinhos' identificados como valor, Valor, vAlOr e VaLoR. Cada um deles tem um endereço diferente e podem armazenar valores diferentes. USE ESTA REGRA COM CAUTELA! O computador não se confunde quanto a eles, mas nós podemos nos confundir. Não fica nem um pouco claro usar nomes como estes num mesmo programa.
-SÓ 32 CARACTERES SÃO SIGNIFICATIVOS.
-NÃO PODEM SER USADAS 'PALAVRAS RESERVADAS'. Vejamos o que e quais são elas.

Palavras reservadas
Existem algumas palavras que exercem um papel fundamental no C. Um exemplo são os identificadores e modificadores de tipo, que vimos aqui. No total elas são 32. (como diminuo este espaço entre o texto e a tabela?)





  • auto

  • break

  • case

  • char

  • const

  • continue

  • default

  • do


  • double

  • else

  • enum

  • extern

  • float

  • for

  • goto

  • if


  • int

  • long

  • register

  • return

  • short

  • signed

  • sizeof

  • static


  • struct

  • switch

  • typedef

  • union

  • unsigned

  • void

  • volatile

  • while

  • Vamos à pratica
    Digite algumas dessas palavras naquele código fonte em branco que criamos no Dev C++.
    Note que assim que você acaba de digitá-la, ela fica, automaticamente, em negrito. Esta é a forma que o Dev C++ trata as palavras reservadas do C.

    Nomeando os 'quadrinhos'
    Para nomear um 'quadrinho' devemos 1º dizer ao C qual será o tamanho dele, ou seja, o seu tipo.
    Antes mesmo disto, se desejarmos que o seu conteúdo não se altere, devemos informar este desejo. Se não o fizermos, ele será, por padrão, variável.
    Depois disto, informamos o nome desejado para ele.
    Por exemplo, para dar o nome valor a um 'quadrinho' que armazenará um valor inteiro e terá seu conteúdo variável devemos digitar:

    int valor

    Experimente digitar isto no código fonte que está aberto no Dev C++.
    Isto é uma instrução que demos ao C. Ela significa: pegue um 'quadrinho' de tamanho suficiente para armazenar um valor inteiro e cole uma etiqueta nele com o 'nome' valor.
    Esta é uma instrução está quase completa. Falta uma coisa muito simples a ela: O ponto final.

    O ponto final do C (;)
    No post anterior, vimos alguns padrões da língua portuguesa. Um exemplo que usei foi o parágrafo e os sinais de pontuação. O C também tem parágrafos e sinais de pontuação.
    Vejamos os sinais de pontuação; mais precisamente, o ponto final.
    O ponto final define o final da frase (será que é por isso que ele tem este nome?). Sem ponto final não dá pra saber onde termina uma frase e começa a outra.
    O ponto final do C é o ponto e vírgula (;). Se você tentar compilar um código fonte que não tenha o ; no final de cada instrução, isto criará um erro de compilação.
    Parabéns! Você acabou de descobrir o erro de compilação que usei para mostrar como o Dev C++ encontra este tipo de erro.

    Sendo assim a nossa instrução só ficará completa com o seu (;) final.

    int valor;

    E se o nosso 'quadrinho' fosse constante? Como seria declarado? (Vá se acostumando com esta nomenclatura. Daqui pra frente, procurarei usar a linguagem técnica, o famoso jargão.)
    Para declarar uma constante a forma correta é:

    const int valor;

    Esta instrução declara uma constante do tipo inteira com o nome valor. Só que cria um problema! Será que você sabe que problema é este?

    Qual o valor do 'quadrinho'?
    Para responder a esta pergunta, precisamos ter em mente que a MEMÓRIA RAM é um área onde o PROCESSADOR guarda dados rápidos e realiza operações. Lembre do conceito do quadro na sala de aula.
    Só que tem um detalhe! O PROCESSADOR é um professor descansado, que não se preocupa em apagar o quadro depois de usar.
    Portanto, nunca se sabe o que estava escrito no quadro antes. (Algumas vezes, em situações específicas, quando uma variável é declarada, o 'quadrinho' correspondente a ela é automaticamente apagado.)

    Olha o problema aí: Declaramos uma constante inteira chamada valor, mas não sabemos qual o valor que está armazenado nela. E, ainda pior, por ser uma constante não pode ser alterada.
    Como resolver isto?

    Colocando um valor no 'quadrinho'
    Mais uma vez, o C vem nos socorrer rsrs.
    Nos podemos 'colocar' um valor no nosso 'quadrinho'. Quando este 'quadrinho' é variável, esta atribuição pode ser feita a qualquer momento, inclusive, na declaração desta variável. No caso de ser constante, SÓ pode ser feito na declaração desta constante. O símbolo que indica esta atribuição é o = (não confundir com o = de matemática, que significa é igual a).
    Vamos ver alguns exemplos:
    int valor;
    valor = 10;

    Traduzindo: Declaramos uma variável do tipo inteiro com o nome valor e, no comando seguinte, atribuimos o valor inteiro 10 a esta variável. Este valor pode mudar durante a execução do problema.
    Usamos 2 comandos para fazer isto. Poderíamos fazer a mesma coisa com um único comando.

    int valor = 10;

    Esta é uma atribuição na declaração, que é chamada de inicialização. Que é a única forma de criar constantes.
    Agora que sabemos disto, vamos corrigir o nosso problema anterior.

    const int valor = 10;

    Agora sim! Criamos uma constante inteira chamada valor que contém o valor 10.
    Eu, particularmente, goste de nomear constante com letras maiúsculas, pois acho que fica mais fácil de identificá-las no código fonte. Faça como achar melhor.

    Um pouco mais sobre atribuições
    Como você viu até agora, podemos atribuir um valor a uma variável, tanto na sua declaração, como no decorrer do código fonte.
    Existem outras coisas que podemos fazer com as atribuições. Vejamos duas delas.

    Podemos atribuir o valor de uma variável a outra variável.
    Quer um exemplo?

    int valor01 = 10;
    int valor02 = 5;
    valor02 = valor01;

    Os comandos acima declaram e inicializam duas variáveis (valor01 com o valor 10 e valor02 com o valor 5) e, depois, o valor da variável valor01 é atribuido a variável valor02; ou seja, o valor de valor02 agora é 10 (valor armazenado). Não quer dizer que as variáveis são iguais, e sim que o valor armazenado nas duas é o mesmo, no caso, 10. (Procure entender bem este conceito, pois ele causa um tipo de erro muito comum, o famoso erro de lógica.)

    Podemos atribuir o resultado de uma operação a uma variável.
    Exemplo:

    int total;
    total = 10 + 5;

    Olhando os comandos acima, você pode dizer qual é o valor de total após o 2º comando?
    Parabéns se você disse 15.

    Pode fazer os seus testes no Dev C++. Lembrando que ainda não dá pra ver o resultado disto, ou seja, o programa em execução.

    Essa hora está chegando. Aguarde e confie.

    quarta-feira, 21 de outubro de 2009

    Código Fonte... Parte I (A volta da teoria rsrs)

    Hoje vamos começar a analisar o CÓDIGO FONTE.

    No post anterior, falamos sobre a instalação da IDE Dev C++ e de uma funcionalidade de todas as IDEs (não conheço nenhuma que não tenha): a detecção de erros de compilação.

    (Note que eu disse de compilação e não apenas erros. Existem outros erros que não são 'detectáveis' (ainda ;), como é o caso dos erros 'lógicos' (ou seriam, ilógicos?).

    Como uma IDE detecta um erro de compilação?

    Imagino que você tenha se feito esta pergunta (se não fez, deveria rsrs). Agora vem a resposta.
    Leia com atenção o texto abaixo:
    nÁo mãgicaê?simPle5m ais FÂcil. paRece~eq.ue

    Entendeu alguma coisa? Nem eu rsrs.

    Na verdade, o que eu queria escrever era:
    Não é mágica! É mais fácil que parece.

    Por que você conseguiu ler a frase na 2ª vez e não na 1ª ? Simples! Porque ela foi escrita de forma errada na 1ª vez.
    Então, como saber se uma frase está certa ou errada? O que controla isto?

    Sintaxe e análise sintática

    O C é uma linguagem de programação de computadores, assim como o Português (idioma) é uma linguagem de comunicação (é isso mesmo?). O que as duas tem em comum? Por serem linguagens, elas são reguladas para que todos que as usam se entendam entre si? Imagine se cada pessoa falasse ou escrevesse o Português da forma que bem entendesse? (Tem gente que o faz, mas, para efeito de estudo, vamos ignorar isso!) Ninguém iria se entender.
    O que regula uma linguagem é a SINTAXE.
    Existe uma padronização na linguagem. Se alguma coisa está fora dos padrões se diz que está errada (conta uma novidade).
    Para saber se algo está errado, é feita uma análise chamada de ANÁLISE SINTÁTICA. Que nada mais é que uma comparação do que está sendo escrito/dito com o padrão.

    Conhecendo os padrões

    Existem alguns padrões no Português que são conhecidos. Às vezes, são 'atropelados', mas que existem existem. (Eu mesmo devo ter cometido barbaridades neste texto!)
    Exemplo simples:
    Nomes próprios começam sempre com letra maiúscula - Maria e João.
    Existem muitos outros, que eu acredito que você conheça; pelo menos os mais comuns.

    A linguagem C também possui os seus padrões. É fazendo uma comparação com estes padrões que as IDEs conseguem encontrar os erros de compilação.

    Um outro fato que deve ser levado em conta nesta análise, já que o código fonte é um texto, é a estrutura do texto.
    Um texto deve ter uma estrutura definida. Você não conseguirá se fazer entender se não seguir esta estrutura.
    Um exemplo claro disto é o conceito de sinais de pontuação e parágrafo. Nós não pensamos com parágrafos (ou pensamos?)! Mas, tente escrever um texto longo sem parágrafos ou sinais de pontuação.

    No próximo post, veremos os padrões do C.

    terça-feira, 20 de outubro de 2009

    Instalando o Dev C++

    Está chegando a hora de começarmos a ver na prática toda a teoria que vimos até agora. Para isto é necessário instalar uma IDE (se não sabe o que é, veja aqui). A IDE que escolhemos para começar foi a Dev C++ da Bloodshed.
    Neste post veremos a sua instalação, algumas configurações (uma só por enquanto rsrs) e como utilizá-la. Lembrando que são conceitos iniciais. Para uma visão completa, visite a lista de perguntas frequentes na página do fornecedor, aqui, em inglês.

    Instalando o Dev C++ 5.0 beta (4.9.9.2)
    Se você ainda não baixou o Dev C++, pode fazê-lo agora aqui.
    Salve o arquivo no seu HD, e execute. Você verá uma tela como esta aqui abaixo (clique na imagem para ampliar).




    É só clicar no OK, e seremos levados a esta tela, onde podemos escolher a linguagem dos botões do programa de instalação (a linguagem dos menus do programa será configurada depois).


    Escolhida a linguagem, OK novamente. Próxima tela (Licença).

    Esta é a licença do Dev C++. Esta licença é chamada de GPL, detalhes sobre ela aqui. É só aceitar para dar início a instalação. Próxima tela (Tipo de Instalação).

    Usaremos a Full (com todos os componentes instalados, tem menos de 60MB); se você quiser pode escolher quais componentes instalar, mas só o faça se tiver certeza do que está fazendo, pois alguns componentes são essenciais para o correto funcionamento do programa. Depois de escolhido o tipo de instalação, ou os componentes a serem instalados, é só clicar em Seguinte.
    Próxima tela (Diretório de Instalação).

    Aqui você escolhe onde o Dev C++ será instalado. É sugerido um diretório padrão. Eu mantenho o sugerido. Mude se quiser. Agora é só clicar em Instalar. Próxima tela (Progresso da Instalação).
    Os arquivos do Dev C++ serão copiados para o seu HD. Esta tela mostra o progresso deste processo. Próxima tela (Usuários).
    Deseja que os atalhos para o Dev C++ sejam instalados para todos os usuários? (Este programa é muito educado, não faz nada sem perguntar se pode rsrs). Próxima tela (Concluindo).

    Agora parece que acabou (pelo menos, é o que está dizendo ;)! Pode clicar em Terminar. Próxima tela (Configurações Iniciais).

    É aqui que será escolhida a linguagem dos menus do programa. Escolha a que lhe agradar (ju flasin shqip???). Se quiser pode mudar o tema (aparência) do programa. Depois de mudar o que desejar, clique em Next. Próxima tela (Funcão 'Auto-ajuda').

    O Dev C++ possui uma função 'Auto-ajuda', que dá sugestões para completar o código de funções comuns do C/C++ (veremos isto depois); para isto, ele faz uma pesquisa em certos arquivos, o que necessita de um pouco mais de processamento do computador (consumo de CPU e memória). Mantendo a educação de sempre, ele pergunta se você quer ativar esta função. Eu, particularmente, gosto muito desta função. Faça sua escolha e clique em Next. Próxima tela (Indexação).

    Se você escolheu usar a 'Auto-ajuda', é necessário fazer uma indexação (criação de atalhos para encontrar informações mais facilmente; isto é uma 'tradução' minha, se estiver errado, me corrijam). Você pode fazer agora ou depois. Se escolher fazer agora, se prepare para esperar um pouco (comigo nunca passou de 6 minutos, e isto em um 'dinossauro'). Clique em Next. Próxima tela (Indexando).

    Espere e confie rsrs. Próxima tela (Acabou???)

    Agora sim, acabou. Seu Dev C++, está com a configuração padrão, pronto para usar. Clique em OK.

    Esta é a 'cara' do Dev C++.

    Dica do dia. Você sabia... Qual a sua sorte hoje? rsrs.
    Fique a vontade para ler as dicas (algumas não serão tão claras ainda). Depois clique em Fechar.

    Agite antes de usar.

    Agora que o Dev C++, já está instalado, vamos fazer uma pequena mudança na configuração padrão que será muito útil depois (pode acreditar que você vai agradecer).
    Clique em Ferramentas, e a sua tela ficará como a figura abaixo.


    Clique agora em Opções do Editor. Na tela que se abre, clique em Display.

    E marque a opção Número das Linhas. Pode clicar em Ok.
    Com isto o Dev C++ vai numerar as linhas do nosso código fonte. Por quê? Você vai ver daqui a pouco.

    Criando um novo código fonte.

    Para criar um novo código fonte, é só clicar em novo e escolher Arquivo Fonte, ou usar o atalho Ctrl+N. Poderíamos criar um novo projeto; mas, como estamos começando, vamos dar um passo de cada vez: Arquivo fonte já é o suficiente.

    Um exemplo de Arquivo fonte.


    Este é um arquivo fonte em C. Repare que o nome dele é ex1.c.
    Arquivos da linguagem C, geralmente, e preferencialmente, tem extensão .c
    Arquivos da linguagem C++, extensão .cpp


    Compilando um código fonte:
    O Dev C++ é uma IDE, e portanto, possui um compilador 'integrado' (não necessariamente, se você escolheu não instalar o compilador, ignorando a sugestão do Dev C++).
    Para compilar o código fonte, você pode clicar no menu Executar e depois em Compilar, ou usar o atalho Ctrl+F9, ou clicar no 1º ícone da 2ª barra de ferramentas (os 4 quadradinhos coloridos separados).
    Se você ainda não salvou o código fonte, o Dev C++ recomenda que você o faça antes de compilar (conselho: Aceite a sugestão). Um vez feito isto, o programa compilado será salvo no disco no mesmo diretório onde você salvou o código fonte.
    Compilei, mas não aconteceu nada! Onde foi que eu errei???
    Acredito que em nada. Lembra que falei que o computador só faz o que é mandado? Você mandou compilar, e não executar!
    Para compilar e executar, é só clicar em Compilar & Executar, ou usar o atalho F9 (sem o Ctrl), ou clicar no 3º botão da 2ª barra de ferramentas (agora os 4 quadrinhos coloridos estão 'grudados'). Feito isto deve aparecer uma tela como esta abaixo.

    Tela preta e com letras brancas??? Cadê os ícones, janelas e botões do Windows???
    Não fique frustrado! Você ainda fará um programa com a 'cara' do Windows (aguarde e confie, e acima de tudo não se desanime).
    Lembra das nossas analogias? Vou usar outra agora.
    Quantos filmes você já viu? Já reparou que o 'mocinho' sempre está arrumadinho, mesmo depois de saltos, explosões, tiros, etc.? Sabe por quê?
    Porque não é ele que salta, que fica no meio do fogo, dos tiros. Quem faz isto é um dublê!
    No computador; aquelas janelas, botões e ícones são o 'mocinho', e esta 'tela preta' é o dublê.
    Quem assiste o filme no cinema não vê o dublê, mas quem está dirigindo o filme, sabe da existência dele e, inclusive, dá as instruções do que ele tem que fazer.
    Nós estamos criando os programas, 'fazendo o filme'. Por isto vemos o dublê.
    Mais tarde, vamos aprender a esconder este 'dublê' dos olhos do grande público.
    Mas, voltando ao tema deste post, vamos ver o porquê daquela alteração que fizemos na configuração do Dev C++, para que ele numerasse as linhas para nós.

    Poderíamos ter feito o nosso código fonte em qualquer editor de texto não-formatado. O editor do Dev C++ além de ser não-formatado, tem ainda algumas funções adicionais que facilitam a nossa vida de programador, por exemplo a numeração das linhas.
    Outra função essencial é a indicação de erros no código fonte.
    Propositalmente, introduzi um erro no código fonte que estamos usando como exemplo neste post. Se tentarmos compilar esta versão com erro, nossa tela ficará assim:
    Tá notando a linha marcada em vermelho? E o quadro que apareceu na parte inferior da tela?
    Eles são a forma que o Dev C++ usa para 'mostrar' onde está o erro. Note que ele informa o número da linha e o erro que ela apresenta. Neste caso: syntax error before "valor2" (erro de sintaxe antes de "valor2"). Um erro da linha anterior que se refletiu na seguinte.
    Como as linhas estão numeradas fica muito mais fácil de encontrar o erro. Neste código simples, talvez não fosse necessário, mas imagine se este código tivesse 1.000 ou 2.000 linhas? (o que não é nenhum absurdo.)
    Que erro foi este?

    Assunto para o próximo post.