Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
1 O que é um computador ?
Na maioria dos computadores (micros de mesa, notebooks) há um software chamado Sistema Op-
eracional que gerencia os dispositivos do computador e permite que vários programas independentes
sejam executados ao mesmo tempo, compartilhando os recursos (dispositivos e memórias) do com-
putador. Windows, Linux e Mac OS são exemplos de sistemas operacionais. Quando programamos
um computador gerenciado por um (bom) sistema operacional, não temos acesso direto aos dispos-
itivos do computador. Quando precisamos de memória, é preciso “pedir” ao sistema operacional,
que decidirá se há memória disponı́vel e permitirá que o seu programa use uma parte especı́fica
1
Input/Output – Entrada/Saı́da
1
dela. Quando queremos desenhar uma linha ou escrever uma frase na tela, enviamos um comando
ao sistema operacional solicitando a operação, e o sistema se encarrega de enviar os comandos
apropriados aos dispositivos. Por isso, embora a organização fı́sica de um computador seja a da
Figura 1, a abstração de computador que temos ao programar é a da Figura 2.
Neste curso vamos exercitar principalmente a implementação de algoritmos que usam a CPU para
tomar decisões baseadas em dados armazenados em memória primária. Todas as interações com
dispositivos (teclado, mouse, tela) serão realizadas como pedidos ao sistema operacional.
Computadores podem ser programados em diversos nı́veis de abstração. Neste curso implementare-
mos Algoritmos como programas escritos em código de alto nı́vel na linguagem C. É possı́vel tratar
o computador em nı́veis mais baixos (considerando detalhes de temporização de seus circuitos
eletrônicos) ou ainda mais altos e especializados (usando uma linguagem de resolução de predica-
dos lógicos, por exemplo).
Exemplo (culinário):
2
Algoritmo 1
1. Ir à padaria.
2. Comprar Bolo.
3. Voltar para casa.
Algoritmo 2
1. Bater 3 Ovos.
2. Adicionar 500gr. de farinha.
3. Adicionar 300ml. de leite.
4. Bater até a massa ficar homog^
enea.
5. Untar tabuleiro com manteiga.
6. Despejar a massa no tabuleiro.
7. Aquecer o forno a 250 graus Celsius.
8. Assar por 45 minutos.
9. Retirar da Forma.
(e mais uns 10 passos para preparar a cobertura e enfeitar o bolo)
Estes algoritmos não utilizam a capacidade mais poderosa dos computadores: tomada de decisões
baseada nos dados do contexto. Considere a seguinte versão melhorada do algoritmo 1, que mini-
miza o preço do bolo:
Algoritmo 1B
1. preco_minimo := infinito
2. padaria_mais_barata := desconhecida
3. Selecione P, o próximo item da lista de padarias
4. Vá até a padaria P.
5. Tem bolo na Padaria P ?
6. Se sim: preco := preco do bolo. Se n~ ao, vá para o passo 8.
7. Se preco < preco_minimo,
faça preco_minimo := preco e padaria_mais_barata := P
8. Enquanto P n~ ao for a última padaria da lista, retorne ao passo 3.
9. Vá até a padaria padaria_mais_barata.
10. Compre o bolo.
11. Volte para casa.
3
Figura 3: Algoritmo 1B representado como um fluxograma.
Algoritmo 1B (Linguagem C)
main() {
float preco_minimo = 500.00;
float preco;
int padaria_mais_barata = -1;
int p;
do {
p = proxima_padaria();
va_ate(p);
preco = preco_bolo(p);
if (preco < preco_minimo) {
preco_minimo = preco;
padaria_mais_barata = p;
}
} while(p != ultima_padaria() );
va_ate(p);
compre_bolo(p);
volte_para_casa();
}
4
Definição de Algoritmo: “É um procedimento para resolver um problema matemático em um
número finito de passos que frequentemente envolve a repetição de uma operação; ou de forma
mais abrangente: um procedimento passo-a-passo para resolver um problema ou realizar algum
objetivo.” [Manber, 1989]
O Algoritmo mais antigo é o Algoritmo de Euclides para Máximo Divisor Comum de dois números
inteiros positivos (400 a 300 a.C.):
MDC Euclides
Cada computador particular (Pentium, Macintosh, telefones celulares, palmtop, etc.) tem car-
acterı́sticas de hardware diferentes, e a programação em código de máquina (linguagem nativa)
depende dos componentes eletrônicos presentes em cada computador, que envolvem o tratamento
de um grande número de detalhes. Por isso usamos linguagens de Alto Nı́vel, que são um meio
termo entre a necessidade que a máquina tem por espeficações formais e a linguagem humana.
Cada famı́lia de processadores tem uma linguagem de montagem (Assembly) que representa o
código de máquina como algo mais “legı́vel por humanos”, mas que ainda é dependente da CPU
especı́fica:
5
Uma linguagem de alto nı́vel codifica um trecho de programa como este em uma notação mais
próxima da notação matemática comum:
A = 100;
B = 115;
A = (A + B) / 4;
Dado um programa em linguagem de alto nı́vel, existem duas formas de fazer um computador
executá-lo (seguir os passos do programa):
• interpretação
• compilação
Em linguagens interpretadas, a tradução de cada comando de alto nı́vel para instruções em código
de máquina é feita em tempo real. Seria como ler um livro de receitas em alemão (assumindo que
você não fale alemão) ao mesmo tempo em que prepara a receita. As pausas para consultar
dicionários e obter ingredientes que você não sabia que eram necessários tornarão o processo lento
e penoso.
Em linguagens compiladas, toda a tradução do programa de linguagem de alto nı́vel para lin-
guagem de máquina é realizada de uma vez só, através do processo de compilação, que gera um
programa executável.
Desvantagens Para cada tipo de computador diferente é necessário compilar um executável difer-
ente. Durante o desenvolvimento, o ciclo escreve-compila-executa pode tornar-se maçante
(especialmente para programas grandes que podem levar vários minutos para serem compi-
lados).
No exemplo do livro de receitas, você primeiro traduziria o livro para a sua lı́ngua para depois tentar
preparar alguma receita. Se você tiver cozinheiros de várias nacionalidades, terá que traduzir o
livro para várias lı́nguas. Se as receitas forem modificadas constantemente, o trabalho de tradução
terá de ser repetido várias vezes.
Algoritmo 1:
1. Girar 72 graus para a direita.
2. Pegar chave da porta da casa.
3. Girar 15 graus para a direita até ver a porta.
6
4. Inserir chave na fechadura.
5. Girar chave para destrancar porta.
6. Girar a maçaneta.
7. Puxar a porta.
8. Dar dois passos para a frente.
(...)
(8 passos e ainda nem completamos o passo 1 de alto nı́vel, que era “Ir à padaria”). O programa
teria forma diferente dependendo da casa de cada um, localização da padaria, se dá para ir a pé ou
é preciso ir de carro... Por isso é mais adequado representar algoritmos em linguagem de alto nı́vel,
e na hora de efetivamente executar o algoritmo, cada um ”vai à padaria”da forma mais adequada
ao seu contexto. É problema do compilador escolher a melhor forma de ”ir à padaria”para cada
computador ou sistema operacional.
Neste curso utlizaremos a linguagem C, que é compilada. Os programas desenvolvidos neste curso
serão pequenos, e o processo de compilação levará poucos segundos para cada programa.
4 Ambiente de programação
Em alguns ambientes de programação (ex: Microsoft Visual Studio, Delphi) estas duas tarefas estão
presentes em um mesmo programa.
5 Linguagem C
Todas as linguagens de programação usam arquivos texto sem formatação: não há negrito, itálico,
cores, fontes ou desenhos; apenas texto puro. Por isso não usamos editores como o Word para
programar.
7
Um programa C pode ser composto por vários arquivos-fonte, mas durante boa parte deste curso
nossos programas terão apenas um. É importante adotar a extensão .c (como em programa.c) para
os programas – o GCC compila algumas outras linguagens além do C (C++, Fortran, Objective
C) e usa a extensão para decidir qual linguagem compilar.
A linguagem C foi inventada em 1972 por Dennis Ritchie, e é uma das linguagens mais utilizadas
desde então, nas mais diversas áreas. É uma linguagem abrangente, usada tanto para a programação
de sistemas embarcados minúsculos (celulares, módulos de injeção eletrônica de automóveis), como
para sistemas operacionais (a maior parte do Linux e do Windows foram escritas em C) e aplicativos
em geral. Sua sintaxe “seca” sem floreios e sua decisão de deixar a especificação de bibliotecas para
cada sistema mantêm a linguagem viva e atual após 3 décadas de uso. Mesmo linguagens mais
recentes, como C++, Java e C#, têm sua sintaxe baseada no C. O C++ nasceu literalmente como
uma extensão do C.
Apesar de não especificar bibliotecas (os comandos para imprimir texto na tela, ler dados do teclado,
desenhar uma linha na tela, etc.), a ISO padronizou uma biblioteca padrão, que praticamente todos
os compiladores fornecem. Os comandos ensinados neste curso fazem parte desta biblioteca padrão.
Nas próximas aulas examinaremos em detalhes a sintaxe do C. Por enquanto, algumas notas im-
portantes:
• A formatação dos espaços em branco não modifica a funcionalidade do programa, mas afeta
a estética do programa - recomenda-se indentar adequadamente os programas para que eles
realmente aparentem o que são - este conselho se mostrará mais útil quando os nossos pro-
gramas implementarem fluxogramas complexos.
• Em C, letras minúsculas são diferentes de maiúsculas. Palavra, palavra e PaLaVRA repre-
sentam entidades diferentes para a linguagem C.
• As palavras reservadas da linguagem estão sempre em minúsculas.
#include <stdio.h>
main()
{
printf("Oi, Mundo.\n");
}
Ele tem 5 linhas, uma delas em branco (apenas por motivos estéticos).
#include <stdio.h> – A linguagem C não fornece comandos para interagir com dispositivos do
computador – discos, terminais, impressoras. Em vez disso, bibliotecas para ambientes especı́ficos
8
são oferecidas para cada ambiente computacional. Esta linha está indicando que o nosso programa
utilizará a biblioteca stdio (STanDard Input/Output - Entrada/Saı́da padrão), que nos fornece
diversos comandos para interagir com o terminal do comandos – imprimir texto, receber comandos
do usuário a partir do teclado, etc.
main() – Esta linha especifica o bloco principal do programa, onde o programa começará a ser
executado (a caixa inicial do fluxograma). A linguagem C define que este bloco deve se chamar
main. Todo programa C deve ter um bloco main().
printf(”Oi, Mundo.\n”); – o comando printf, parte da biblioteca stdio (que é parte da bib-
lioteca padrão C), imprime mensagens de texto no terminal de comando. Neste caso, a mensagem
a ser impressa é ”Oi, Mundo.”, sem as aspas e seguida de uma quebra de linha. Em algumas
situações não podemos digitar o texto exato a ser impresso, pois uma quebra de linha após o ponto
final confundiria a linguagem C. Para estes casos, a linguagem oferece escapes (códigos especiais).
Neste caso, \n (note a barra invertida) é traduzida para uma quebra de linha (n vem de newline).
Outros casos: \¨(aspas) e \\ (para gerar uma barra invertida). Existem outros escapes, que serão
apresentados na atividade de laboratório.
• printf é uma função: ela recebe parâmetros de entrada e pode retornar um valor de saı́da.
Aprenderemos a definir nossas próprias funções em aulas futuras, mas a sintaxe de chamada
de função é
C admite funções com número fixo ou variável de parâmetros. Se quisermos usar o valor de retorno
da função, podemos incluir a chamada de função em uma expressão, como uma atribuição:
Neste exemplo sin() e cos() são funções da biblioteca padrão que computam o seno e o cosseno de
um ângulo (em radianos). resultado deve dar 1 neste caso (sin2 a + cos2 a = 1).
9
printf("O Brasil venceu %d copas do mundo e é %s-campe~
ao.",5,"penta");
float pi = 3.1415926535;
printf("Pi: %.3f, %.4f, %.5f\n",pi);
imprime π com 3, 4 e 5 casas decimais. O comando acima do printf declara uma variável chamada
pi que armazena números de ponto flutuante (float) e inicializa seu valor com uma aproximação
de π digitada manualmente. O tipo float é uma das formas de representar números reais em
computadores.
Outros tipos de variáveis: int (números inteiros), char (representa um caractere - letra ou dı́gito).
Na primeira aula de laboratório vamos nos familiarizar com o ambiente de programação e explorar
outras sequências de formatação do printf.
Toda linguagem de alto nı́vel permite que o código tenha comentários. Comentários são trechos
ignorados pelo compilador, em que o programador explica o que está fazendo. Em programas muito
grandes e complexos o próprio programador pode precisar ler os comentários para lembrar o que
tinha em mente quando escreveu um determinado trecho. A linguagem C permite duas formas de
comentários:
• Comentários “até o fim da linha”, iniciados por // e terminados pela quebra de linha. O
texto antes do // na mesma linha ainda não é comentário, e não é ignorado.
É importante nos familiarizarmos com um modelo “padrão” de programa C, que será a base de
nossos programas. O modelo abaixo exemplifica os dois tipos de comentários permitidos pela
linguagem e os recursos da linguagem apresentados até o momento. Este modelo será ampliado à
medida que outros recursos da linguagem forem apresentados no curso.
/* as inclus~
oes de bibliotecas devem estar acima de todas
as outras declaraç~
oes do programa */
#include <biblioteca1>
#include <biblioteca2>
(...)
10
// em nossos programas.
main() {
/*
no inicio dos blocos declaramos todas as
variáveis que vamos utilizar. O comando de
declaraç~
ao de variáveis tem a sintaxe
tipo nome1[=valor][,nome2[=valor]]...[,nomeN[=valor]];
// após as declaraç~
oes de variáveis, voc^
e coloca
// a sequ^encia de comandos do seu programa.
/* fim do modelo */
11