Parte 1: Introdução a Algoritmos Computacionais
1.1 Introdução
A cada dia torna-se mais notável a participação da máquina no auxílio de tarefas humanas. Em destaque, o computador (PC) se faz cada vez mais presente nos lares e, principalmente, em empresas, indo da micro até a algumas grandes empresas que não sentem a necessidade de um computador "especial". O grande sucesso do PC se deu por vários fatores, como: baixo custo, compatibilidade de recursos internos e externos (exemplo interno: o barramento PCI; externo: os dispositivos USB) entre outros fatores. Porém pode-se dizer que os principais fatores, entre todos os outros, são a grande quantidade de programas disponíveis e a fácil utilização destes.
Aqui vamos falar sobre os algoritmos computacionais que podemos chamar de o b-a-bá das linguagens de programação1. Utilizaremos inicialmente uma linguagem conhecida por pseudo-linguagem, que é uma linguagem fictícia, ou seja, os principais comandos de programação escritos em português de forma fácil de entender. Após, utilizaremos a linguagem C2 como ferramenta para nossos estudos.1.2 Programa e o ato de programar
O primeiro passo é entender que, como o computador trata-se de uma máquina, ele em si, não possui nenhuma inteligência. Mas e todas aquelas "maravilhas" que os computadores são capazes de realizar? É neste ponto que desejamos chegar. Se existe alguma inteligência num computador, esta é devido a seus softwares (programas), que "ensinam" a seu conjunto de hardware (parte física), em especial o processador, à realizar cada tarefa, tudo direitinho, passo-a-passo. Nisto se define um programa de computador, e podemos concluir resumidamente que: Um programa de computador é um conjunto de instruções escritas de maneira que um computador possa entender, e assim, realizar determinadas tarefas.Após termos entendido o que são os programas, para nós, se faz necessário entender alguns pontos importantes no ato de programar. Vamos pensar em um programa simples que, dado um número, retorne seu valor ao quadrado. Em primeiro lugar o programa precisa perguntar ao usuário qual é o número que ele deseja saber seu quadrado, não é mesmo? Após ter pedido o número é necessário guarda-lo em algum lugar, para que após seja possível trabalhar com ele, no nosso exemplo, calcular seu quadrado. O local onde guardamos os dados chama-se variável, mas este conceito ficará mais claro quando escrevermos este programa. Agora, com os dados (neste exemplo apenas um número) armazenados nas variáveis, podemos processa-los (aqui o processamento consiste em pegarmos o número lido e armazenado em uma variável e multiplicarmos por ele mesmo, resultando assim em seu valor ao quadrado) para depois retornarmos a resposta ao usuário. Vamos ver como ficaria este programa escrito em uma pseudo-linguagem:
1 - inicio //Calcula o quadrado de um número informado pelo usuário.
2 -
3 - tipo_inteiro num; //Declaração das variáveis
4 - tipo_inteiro resultado; //;
5 -
6 - imprima "Informe o número a ser calculado: "; //Escreve o texto entre aspas na tela
7 - leia num; //Ler o valor caractere digitado pelo usuário e armazena na variável num.
8 -
9 - resultado = num * num;
10 - imprima resultado;
11 -
12 - fim
Entendendo o programa "Calcula quadrado": Na linha 1, inicio marca o começo do programa. Ainda na linha 1 e em boa parte do programa encontramos textos escritos após uma barra dupla "//". Esta, diz ao compilador que o texto que vem após ela deve ser ignorado, pois não trata-se de comandos, e sim de comentários. Este, por sua vez, serve para documentarmos o programa, tornando sua leitura e compreensão mais clara.
Nas linhas 3 e 4 temos a declaração das variáveis num e resultado, ambas do tipo inteiro. Falaremos mais sobre os tipos de dados na próxima seção. O ponto-e-vírgula ";" marca o fim da instrução.
Na linha 6 informamos ao computador para exibir o texto entre aspas duplas na tela.
A linha 7, ler, do teclado, o valor digitado pelo usuário e armazena-o na variável num.
Um ponto importante da linha 9 está em sua leitura, que deve ser: resultado recebe num multiplicado por num. O sinal "=" é um atribuidor e não um comparador ( o comparador seria "==" ), logo ele atribui o valor de num * num (sempre da direita para a esquerda) a resultado e não, faz comparação entre os valores, ou seja, é errado ler: resultado é igual a num vezes num. Mas não dá no mesmo? Mais pra frente, quando falarmos sobre comparações veremos que a última leitura citada pode nos levar a conclusões erradas. Conclusão da linha 9: é calculado o valor de num * num e este é atribuído a resultado. resultado passa a possuir o valor de num * num.
Na linha 10 imprimimos o resultado na tela.
A linha 12 diz ao compilador que o código do programa chegou ao fim.
Após visto o programa "calcula quadrado" e termos discutido cada linha, fica clara a idéia do ato programar, que consiste num passo-a-passo detalhado de uma tarefa que desejamos que o computador execute. Note que, ao contrário do que muitos podem imaginar, na maioria das vezes a programação é realizada utilizando métodos bastantes primitivos, como por exemplo, não usamos um comando "calcule o quadrado", mas sim, ensinamos o processador que a multiplicação de um número por ele mesmo resulta em seu quadrado. Na verdade não existem comandos deste tipo. O que existe são funções, "pedaços" de programas, que outros programadores já escreveram. Entenderemos isso melhor quando programarmos em C, onde utilizaremos suas bibliotecas3. Lá veremos a math.h por exemplo, que é uma biblioteca de funções matemáticas. Ela possui funções que calculam não só o quadrado de um número, como seu seno, cosseno e etc. Note que todas estas funções avançadas são constituídas de apenas soma, subtração, multiplicação, divisão e comparação. Acredite! Isso é tudo que um processador sabe fazer.
1.3 Tipos de dados
Vimos anteriormente um número sendo armazenado em uma variável do tipo inteiro. Isto significa que o programa "Calcula quadrado" escrito anteriormente não aceita números reais, que é mais conhecido entre os programadores como número de ponto flutuante. Com isso, concluímos que uma variável só aceita valores que correspondam a seu tipo de dado, não necessariamente sendo do mesmo tipo. Por exemplo, uma variável do tipo real pode perfeitamente aceitar um dado inteiro já que o conjunto dos números reais abrange o conjunto de números inteiros.
Existem quatro tipos de dados primitivos: Inteiro, Real, Caractere e Booleano. Dos quais podem existir derivações. Vejamos um exemplo real. Na linguagem C dispomos de dois tipos de variáveis diferentes mas que representam o mesmo tipo de dado primitivo, o tipo dos números reais. float e double, diferem apenas em terem a capacidade de armazenar valores numéricos menores ou maiores, respectivamente.
Como nosso foco é algoritmos computacionais, falaremos apenas sobre os tipos de dados primitivos. Os tipos de variáveis derivados variam de linguagem para linguagem.
Inteiro: Tipo de dado numérico inteiro. Ao armazenar um número real numa variável de tipo inteiro temos a perda de sua fração restando apenas o valor inteiro do número (ao passar 4.7 a um inteiro teremos armazenado o valor 4). Ao atribuirmos um caractere a um tipo inteiro o que temos é o valor ASCII4 desse caractere, que é um número inteiro, armazenado na variável.
Real ou de Ponto Flutuante: Tipo de dado numérico real. Um tipo real aceita um número inteiro sem problemas. A atribuição de um caractere a um número de ponto flutuante se sucede igualmente ao inteiro.
Caractere: Tipo de dado para caracteres, sejam eles letras números ou caracteres especiais. Vale apena citar que o caractere "1" armazenado em char é apenas um símbolo e não possui valor um.
Booleano: Tipo de dado condicional que pode assumir apenas dois valores, "verdadeiro" ou "falso", true ou false. É muito usado para representar estados, como fechado ou aberto, cheio ou vazio.
1.4 Operações e comparações
Agora veremos como realizar comparações e operações aritméticas e ainda operações lógicas.
A sintaxe apresentada a seguir é própria da linguagem C.
1.4.1 Operadores aritméticos
= - Atribuição: Como citado anteriormente ele atribui um valor a uma variável. É utilizado também, para atribuir, a uma variável, o resultado de outra operação, como nos exemplos seguintes.
+ - Soma: Realiza a adição entre dois valores. Para atribuirmos o resultado desta operação em uma outra variável escreveríamos: a = b + c; que diz que a recebe o resultado da soma entre b e c.
Analogamente ao operador + se comportam os operadores -, /, * e %, que realizam subtração, divisão, multiplicação e resto respectivamente.
1.4.2 Comparações
Na parte 3 falaremos sobre tomada de decisão o que não faria sentido existir sem a possibilidade de comparar dados. Abaixo explicaremos as seis formas de comprar valores:
< - Menor que: Verifica se um primeiro valor é menor que um segundo. Ex.: a < b.
> - Maior que: Verifica se um primeiro valor é maior que um segundo. Ex.: a > b.
<= - Menor ou igual: Verifica se um primeiro valor é menor ou igual a um segundo valor. Ex.: a <= b.
>= - Maior ou igual: Verifica se um primeiro valor é maior ou igual a um segundo valor. Ex.: a >= b.
== - Igual: Verifica se dois valores são iguais. Ex.: a == b.
!= - Diferente: Verifica se dois valores são diferentes. Ex.: a != b.
1.4.3 Operadores Lógicos
Servem para juntar duas ou mais comparações ou negar (inverter) seu resultado.
&& - E lógico: O operador && retorna as comparações como verdadeiro se e somente se todas estas forem verdadeiras.
|| - OU lógico: Para que o operador || retorne verdadeiro basta apenas que uma das comparações seja verdadeira. || retorna falso se e somente se todas comparações forem falsas.
! - NÃO lógico: O operador ! nega o valor booleano (verdadeiro ou falso) de uma comparação. Se esta for verdadeira será "vista" como falsa e vice-versa.
1- Conjuntos de comandos e regras que serão entendidas e transformadas (compilada) em uma linguagem que o computador entende (linguagem de máquina).
2- O C foi desenvolvido durante a década de 70, mas ainda é largamente utilizado. A grande vantagem do C é permitir escrever tanto programas extremamente otimizados para a máquina, como seria possível apenas em Assembly, e ao mesmo tempo vir com várias funções prontas, como uma linguagem de alto nível, que podem ser utilizadas quando não for necessário gerar um código tão otimizado.
3- Conjunto de funções (pedaços de programas prontos) que podemos ser reaproveitadas em outros programas.
4- Código de caracteres de texto. Ocupa 8 bits de dados, o suficiente para 256 combinações diferentes.