Mudanças entre as edições de "SOP-2010-2-tiago"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
 
(152 revisões intermediárias por 2 usuários não estão sendo mostradas)
Linha 17: Linha 17:
 
* Demais referências contidas na [[Sistemas Operacionais e Introdução a Programação (página)#Sobre_a_Disciplina|página principal de SOP]].
 
* Demais referências contidas na [[Sistemas Operacionais e Introdução a Programação (página)#Sobre_a_Disciplina|página principal de SOP]].
  
=29/07: Sistemas Operacionais=
+
= Sistemas Operacionais=
  
 +
==29/07: Introdução==
 +
* Aula inaugural
 
* Tópicos: Apresentação da disciplina, plano de aula, trabalhos e métodos de avaliação.
 
* Tópicos: Apresentação da disciplina, plano de aula, trabalhos e métodos de avaliação.
  
Linha 53: Linha 55:
 
* Usar o manual online (man);
 
* Usar o manual online (man);
  
 +
===Roteiro desta aula:===
 +
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/AulaSOP_2.pdf Aula 2]
  
'''Roteiro desta aula:'''
+
===Exercícios Extras:===
* [http://http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/AulaSOP_2.pdf Aula 2]
 
  
 
# Partindo do subdiretório /home/aluno/Desktop, e usando somente caminhos (''pathnames'') relativos, indique a sequência de comandos necessária para visitar sucessivamente os seguintes subdiretórios:
 
# Partindo do subdiretório /home/aluno/Desktop, e usando somente caminhos (''pathnames'') relativos, indique a sequência de comandos necessária para visitar sucessivamente os seguintes subdiretórios:
Linha 85: Linha 88:
 
#* ../..
 
#* ../..
  
=Lógica de Programação=
+
==09/08: Introdução ao Linux==
Segundo módulo da disciplina de Sitemas Operacionais.
+
 
Baseado no material [http://wiki.sj.ifsc.edu.br/images/0/02/Lógica_de_Programação.pdf Lógica de Programação], de Paulo Sérgio de Moraes - uma  das [[Sistemas Operacionais e Introdução a Programação#Referências_Bibliográficas|referências bibliográficas]] da disciplina.
+
* Rever as operações sobre arquivos e diretórios com mais detalhes;
 +
* Compreender o que é shell e a expansão do shell;
 +
* Operar sobre diretórios e arquivos usando os coringas: *, ? e [ ];
 +
* Remover recursivamente diretórios e seus conteúdos;
 +
* Usar seta para recuperar comandos da história de comandos;
  
==08/04: Introdução==
+
===Roteiros desta aula:===  
* Tópicos: instrução, sequência, problemas do dia a dia.
+
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/AulaSOP_3.pdf Aula 3]
* Páginas da apostila: 4 a 7.
+
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/lab1/aula_lab1.pdf Transparências]
  
==09/04: Desenvolvendo algoritmos==
+
===Exercícios Extras:===
* Tópicos: resolvendo problemas, linguagens e instrução disponíveis (vocabulário).
 
* Páginas da apostila: 8 a 11.
 
  
=== Exercícios: desenho de figuras geométricas ===
+
* [http://www.sj.ifsc.edu.br/~msobral/SOP/roteiros/ex-dirs.tgz Arquivo para o exercício de reorganização de arquivos]
  
* Usando apenas as instruções:<syntaxhighlight lang=text>
+
# Usando a interface gráfica, organize os arquivos contidos [http://www.sj.ifsc.edu.br/~msobral/SOP/roteiros/sop.tar.bz2 aqui]. Eles devem ser colocados nos subdiretórios ''Imagens'', ''Videos'' e ''Documentos'', de acordo com seus tipos.
limpa
+
# Refaça a questão anterior, porém usando a interface de linha de comando (o ''shell'').
avança X
 
giraDireita angulo
 
giraEsquerda angulo
 
</syntaxhighlight> escreva algoritmos para desenhar as seguintes figuras:
 
** triângulo equilátero
 
** triângulo isósceles
 
** triângulo escaleno
 
** quadrado
 
** hexágono
 
** octógono
 
** 7 hexágonos interligados (um central e seis periféricos).
 
* [http://edu.kde.org/kturtle/ kturtle] é um software educacional para ajudar no ensino de matemática, geometria e introdução à programação. Ele possibilita fazer desenhos facilmente, seguindo um programa com instruções de desenho. Usando as instruções: <syntaxhighlight lang=bash>
 
reset
 
forward X
 
turnright angulo
 
turnleft angulo
 
</syntaxhighlight> ... escreva programas para os algoritmos criados no ítem  anterior.
 
  
==15/04: Pseudocódigo e diagrama de blocos (fluxograma)==
+
''Obs: para extrair os arquivos do exercício faça assim:''
* Adoção do [http://www.dei.estt.ipt.pt/portugol/node/33 Portugol IDE] como ferramenta didática.
+
<syntaxhighlight lang=bash>
*  Páginas da apostila: 12 a 14.
+
aluno@DX~$ tar xjf sop.tar.bz2
 +
</syntaxhighlight>
  
=== Portugol ===
+
... e veja que aparecerá um subdiretório ''sop'' com todos os arquivos do exercício lá dentro.
  
As aulas de Lógica de Programação usarão um software de auxílio ao ensino de algoritmos chamado [http://orion.ipt.pt/%7Emanso/Portugol/ Portugol], desenvolvido na [http://www.dei.estt.ipt.pt/portal/ Escola Superior de Engenharia do Instituto Politécnico de Tomar], em Portugal.
+
==12/08: Introdução ao Linux==
* [http://www.sj.ifsc.edu.br/~msobral/SOP/portugol.html Guia rápido de instalação e utilização do Portugol].
+
* Rever operações sobre diretórios
 +
* Usar editores de texto para criar e editar arquivos
 +
* Uso dos comandos cat, more e less para visualizar o conteúdo de arquivo
 +
* Fazer, remover e visualizar links simbólicos
 +
 
 +
===Roteiro desta aula:===
 +
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/AulaSOP_4.pdf Aula 4]
 +
 
 +
==16/08: Utilização Editor de texto vi e redirecionamento==
 +
* Aprender a utilizar minimamente o editor vi
 +
* Redirecionamento de saída padrão
 +
 
 +
=== Entrada e saída padrão ===
 +
 
 +
Todo processo possui uma saída padrão, que corresponde a um arquivo ou dispositivo onde os dados de saída do processo (ex: mensagens de texto) serão mostrados. E assim como existe uma saída padrão, todo processo possui uma entrada padrão que corresponde ao arquivo ou dispositivo de onde por ''default'' são obtidos os dados de entrada.
 +
 
 +
[[imagem:Sop-redir.png|800px]]
  
==== Guia rápido de instalação e utilização do Portugol ====
+
=== Redirecionamento de saída padrão ===
  
Abaixo segue uma breve ajuda de como obtê-lo, instalá-lo e usá-lo. Esse guia assume que você esteja usando o Ubuntu Linux 9.04 ou superior.
+
Normalmente a saída padrão de um processo é a tela do terminal, mas ela pode ser redirecionada para um arquivo ou para outro dispositivo. Assim, as mensagens de texto que um processo gera podem ser guardadas em um arquivo para posterior utilização. No exemplo abaixo, a listagem dos processos foi guardada no arquivo ''processos.txt'':
  
# Faça o [http://www.sj.ifsc.edu.br/%7Emsobral/SOP/soft/portugol23.tar.gz download] do Portugol.
+
<syntaxhighlight lang=bash>
# Descompacte-o com o seguinte comando: <syntaxhighlight lang=bash>
+
aluno@D1:~$ ps ax > processos.txt
tar xzf portugol23.tar.gz
+
aluno@D1:~$
 
</syntaxhighlight>
 
</syntaxhighlight>
# Repare que existe agora um subdiretório portugol no diretório onde você o descompactou. Execute o Portugol com o seguinte comando: <syntaxhighlight lang=bash>
 
java -jar portugol/Portugol.jar
 
</syntaxhighlight> Obs: você precisará ter Java instalado. Caso não o tenha, execute o comando: <syntaxhighlight lang=bash>
 
sudo apt-get install openjdk-6-jre
 
</syntaxhighlight>
 
# Copie esse [http://www.sj.ifsc.edu.br/%7Emsobral/SOP/exemplos/fluxogramas.cfg arquivo] para poder ver fluxogramas coloridos, e grave-o no memso diretório onde está o Portugol.
 
# Veja a [http://www.sj.ifsc.edu.br/%7Emsobral/SOP/soft/help/index.html ajuda] do Portugol, e use-a sempre que tiver dúvidas !
 
  
<br>A tela inicial do Portugol segue abaixo, junto com um programa demonstrativo.<br>
+
O redirecionamento de saída padrão se faz com o símbolo '''>''' seguido do nome do arquivo. Note que nada aparece na tela, uma vez que a saída se tornou o arquivo ''processos.txt''. Após executar o comando acima, veja o conteúdo de ''processos.txt'':
 +
 
 +
<syntaxhighlight lang=bash>
 +
aluno@D1:~$ less processos.txt
 +
  PID TTY      STAT  TIME COMMAND
 +
    1 ?        Ss    0:03 /sbin/init
 +
    2 ?        S<    0:00 [kthreadd]
 +
    3 ?        S<    0:00 [migration/0]
 +
    4 ?        S<    0:00 [ksoftirqd/0]
 +
    5 ?        S<    0:00 [watchdog/0]
 +
    6 ?        S<    0:00 [migration/1]
 +
    7 ?        S<    0:00 [ksoftirqd/1]
 +
    8 ?        S<    0:00 [watchdog/1]
 +
    9 ?        S<    0:00 [events/0]
 +
  10 ?        S<    0:00 [events/1]
 +
  11 ?        S<    0:00 [khelper]
 +
  12 ?        S<    0:00 [kstop/0]
 +
  13 ?        S<    0:00 [kstop/1]
 +
  14 ?        S<    0:00 [kintegrityd/0]
 +
  15 ?        S<    0:00 [kintegrityd/1]
 +
  16 ?        S<    0:00 [kblockd/0]
 +
  17 ?        S<    0:00 [kblockd/1]
 +
  18 ?        S<    0:00 [kacpid]
 +
  19 ?        S<    0:00 [kacpi_notify]
 +
  20 ?        S<    0:00 [cqueue]
 +
  21 ?        S<    0:00 [ata/0]
 +
  22 ?        S<    0:00 [ata/1]
 +
processos.txt
  
[[Imagem:Editor-Portugol.png]]
+
</syntaxhighlight>
  
Exemplos de programas iniciais em Portugol:
+
Como se pode ver, o texto que apareceria na tela foi guardado em ''processos.txt''. Experimente executar novamente o comando ''ps ax > processos.txt'' e veja o resultado. O que aconteceu com o arquivo ''processos.txt'' ?
  
# ''Lendo um número e mostrando-o na tela em seguida:'' <syntaxhighlight lang=text>
+
Quando se deseja redirecionar a saída de um processo para um arquivo, porém preservando o conteúdo original desse arquivo, deve-se executar o comando da seguinte forma:
Inicio
 
  inteiro x
 
  
  Escrever "Digite um numero: ",
+
<syntaxhighlight lang=bash>
  Ler X
+
aluno@D1:~$ ps ax >> processos.txt
  Escrever "Numero digitado: ", x
+
aluno@D1:~$
Fim
 
 
</syntaxhighlight>
 
</syntaxhighlight>
# ''Lendo dois números, somando-os e mostrando o resultado na tela:'' <syntaxhighlight lang=text>
 
Inicio
 
  inteiro x, y
 
  
  Escrever "Digite um numero: ",
+
... quer dizer, em vez de usar '''>''' usa-se '''>>'''.
  Ler x
+
 
  Escrever "Digite outro numero: ",
+
=== Redirecionamento de entrada padrão ===
  Ler y
+
 
  Escrever "Soma = ", x+y
+
Normalmente a entrada padrão corresponde ao teclado do terminal, mas pode ser redirecionada para outro arquivo ou dispositivo. No exemplo abaixo, usa-se o programa '''wc''' para contar as linhas, palavras e caracteres contidos no arquivo ''processos.txt'':
Fim
 
</syntaxhighlight>O programa abaixo é equivalente:<syntaxhighlight lang=text>
 
Inicio
 
  inteiro x, y, z
 
  
  Escrever "Digite um numero: ",
+
<syntaxhighlight lang=bash>
  Ler x
+
aluno@D1:~$ ps ax > processos.txt
  Escrever "Digite outro numero: ",
+
aluno@D1:~$ wc < processos.txt
  Ler y
+
137  810 7807 begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting processos.txt
  z <- x + y
+
aluno@D1:~$
  Escrever "Soma = ", z
 
Fim
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== Atividades ===
+
No exemplo acima, gravou-se em ''processos.txt'' o resultado do comando '''ps ax''' , e depois usou-se '''wc'' para contar linhas, palavras e caracteres desse arquivo. O efeito combinado é a contagem de quantos processos existem no sistema nesse momento (representado pelo número de linhas contidas em ''processos.txt'').
  
# ''Média de três números:'' escreva um programa para calcular a média de três números. <syntaxhighlight lang=text>
+
Ao contrário do caso da saída padrão, não é tão comum se usar redirecionamento de entrada padrão. No entanto há um recurso adicional provido pelo sistema operacional que explora a combinação de ambas, e que possibilita combinar as funcionalidades de diferentes programas.
Inicio
 
  Inteiro n1, n2, n3, r
 
  
  Escrever "Primeiro numero: "
+
=== Pipes ===
  ler n1
 
  Escrever "Segundo numero: "
 
  ler n2
 
  Escrever "Terceiro numero: "
 
  ler n3
 
  
  r <- (n1 + n2 + n3) /3
+
Em sistemas operacionais Unix, é possível conectar a saída padrão de um processo à entrada padrão de outro processo, e a isto se chama ''pipe'' (que pode ser traduzido como ''duto'' ou ''tubo''). Com isto, os dados de saída de um processo serão os dados de entrada de outro processo, o que pode ser explorado para realizar diferentes tarefas. Por exemplo, retomando a contagem de processos vista na seção anterior:
  
  Escrever "Media=", r
+
<syntaxhighlight lang=bash>
Fim
+
aluno@D1:~$ ps ax | wc
 +
137  810 7807
 +
aluno@D1:~$
 +
</syntaxhighlight>
 +
 
 +
O símbolo de ''pipe'' é a barra vertical '''|'''. Ao se executarem os comandos acima unidos pelo ''pipe'', a listagem de processos gerada pelo '''ps ax''' é automaticamente enviada para a entrada padrão do comando '''wc'''. O resultado é a contagem de processos existentes no sistema.
 +
 
 +
Podem-se ligar mais de dois processos usando ''pipes''. Assim, cria-se um encadeamento de processos, em que a saída padrão de um processo alimenta a entrada padrão do próximo processo. Por exemplo, para se contarem os processos do usuário aluno:
 +
 
 +
<syntaxhighlight lang=bash>
 +
aluno@D1:~$ ps aux | grep aluno | wc
 +
    47    568    5195
 +
aluno@D1:~$
 
</syntaxhighlight>
 
</syntaxhighlight>
# ''Sequência de Fibonacci:'' em matemática corresponde aos números: <syntaxhighlight lang=text>
 
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
 
</syntaxhighlight>... que pode ser descrita pela relação de recorrência <br><br><math>F_{n} = F_{n-1} + F_{n-2}</math><br><br>... com valores iniciais <math>F_{0} = 1</math> e <math>F_{1} = 1</math>.<br><br>Numerosas formas na natureza apresentam essa sequência, como neste girassol (cujas flores se dispõem em uma espiral):<br><br>[[Imagem:Sunflower.jpg]]  [[Imagem:espiral_fibonacci.png]] [[Imagem:FibonacciBlocks.png]]<br><br>Usando o Portugol escreva um programa que mostre os 10 primeiros números dessa sequência.
 
  
==16/04: Fluxogramas, constantes e Variáveis==
+
===Roteiros desta aula:===
 +
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/AulaSOP_6.pdf Aula 5 (editor vi)]
 +
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/AulaSOP_9.pdf Aula 5 (redirecionamento)]
 +
 
 +
===Material complementar sobre editor vi===
 +
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/vi.pdf Editor vi]
 +
*[http://www.infowester.com/linuxvi.php Editor vi]
 +
 
 +
==19/08: Gerenciamento de processos==
 +
 
 +
'''Processos e multiprogramação:''' uma visão geral sobre programas, processos, ciclos de um processo, multiprogramação e escalonamento. Ver [[Media:Gerencia_de_redes.pdf|apostila do prof. Odilson]], capítulo 3, e [http://www.guiafoca.org/guia/iniciante/ch-run.html capítulo 5] do Guia Foca Linux Iniciante.
 +
 
 +
'''Gerência de memória:''' visão geral sobre o uso de memória no sistema operacional e pelos processos
 +
Uso do laboratório para ilustrar conceitos.
 +
 
 +
* [http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/lab2 Programas para estudo do escalonamento de processos]
 +
** '''fominha:''' tenta usar todo o tempo de processador disponível
 +
** '''crash:''' cria processos indefinidamente
 +
** '''lento:''' processo que trabalha pouco, ficando a maior parte do tempo ocioso
 +
 
 +
Vários utilitários (programas auxiliares) existem para obter informações do sistema operacional sobre processos e memória. Alguns trabalham em modo texto, como:
 +
 
 +
* '''[http://manpages.ubuntu.com/manpages/karmic/en/man1/ps.1.html ps]:''' lista os processos existentes
 +
* '''[http://manpages.ubuntu.com/manpages/karmic/en/man1/pstree.1.html pstree]:''' lista os processos existentes mas de forma hierárquica
 +
* '''[http://manpages.ubuntu.com/manpages/karmic/en/man1/top.1.html top]:''' lista os processos mais ativos, junto com informações globais sobre uso dos recursos no sistema operacional (memória, processador, memória virtual, quantidade de processos, carga de trabalho)
 +
* '''[http://manpages.ubuntu.com/manpages/karmic/en/man1/atop.1.html atop]:''' o mesmo que '''top''', mas com maior detalhamento do uso de recursos mantidos pelo sistema operacional
 +
* '''[http://manpages.ubuntu.com/manpages/karmic/en/man1/mpstat.1.html mpstat]:''' mostra estatísticas  de uso do processador
 +
* '''[http://manpages.ubuntu.com/manpages/karmic/en/man1/free.1.html free]:''' mostra o uso de memória
 +
* '''[http://manpages.ubuntu.com/manpages/karmic/en/man8/vmstat.8.html vmstat]:''' mostra o uso de memória, discos e processador no último intervalo de tempo.
 +
 
 +
Existem também utilitários no modo gráfico. Por exemplo, no Ubuntu há o "Monitor do sistema":
 +
 
 +
[[Imagem:Monitor1.png|600px|center]]
 +
<center>''Para executar o Monitor do Sistema</center><br><br>
  
* Diagrama de blocos (fluxograma)
+
[[Imagem:Monitor2.png|400px]] [[Imagem:Monitor3.png|400px]]
* Variáveis e constantes
+
<center>''Telas do monitor do Sistema</center>
  
=== Fluxogramas ===
+
===Roteiros desta aula:===
 +
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/AulaSOP_12.pdf Aula 6]
 +
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/lab2/aula_lab2.pdf Slides]
 +
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/lab2/lista_lab2.pdf Lista de apoio]
  
Diagramas de bloco para auxiliar a descrição de algoritmos. Ajudam na compreensão do algoritmo, por poder visualizar o fluxo de execução.
+
==23/08: Permissionamento Unix==
  
 +
*Expor os conceitos associados as permissões de acesso a arquivos e diretórios
 +
*Explorar as permissões em nível do usuário proprietário
  
[[imagem:Fluxograma-soma.png]] Fluxograma para o algoritmo da média de trẽs números.
+
===Roteiro desta aula:===
 +
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/AulaSOP_7.pdf Aula 8]
  
<br>
+
==26/08: Compactação de arquivos==
  
'''Blocos de uso mais comum'''<br>
+
Uma primeira forma de compactar arquivos no Linux é usando o gerenciador de arquivos ''nautilus''. Por exemplo, ra compactar um diretório deve-se selecioná-lo e em seguida chamar o ''pop-up menu'' (botão direito do mouse):
{| border="1" cellpadding="2"
 
!Bloco
 
!Descrição
 
!Exemplo
 
|-
 
|[[Imagem:Inicio.png]]||Inicio do fluxograma||
 
|-
 
|[[Imagem:Processamento.png]]||Processamento||
 
|-
 
|[[Imagem:Entrada.png]]||Entrada de dados (ler do teclado)||
 
|-
 
|[[Imagem:Saida.png]]||Saída de dados (mostrar na tela)||
 
|-
 
|[[Imagem:Decisao.png]]||Decisão (testar uma condição e bifurcar)||[[imagem:Ex-decisao.png]]
 
|-
 
|[[Imagem:Conector.png]]||Conector (juntar dos ou mais ramos do fluxograma)||[[imagem:Ex-conector.png]]
 
|-
 
|[[Imagem:Fim.png]]||Fim||
 
|}
 
  
Obs: [http://www.sj.ifsc.edu.br/%7Emsobral/SOP/exemplos/fluxogramas.cfg Arquivo de configuração das cores do fluxograma ] do Portugol.
 
  
=== Variáveis e constantes ===
+
[[imagem:Compress1.png|600px]]
  
* '''Variável:''' capaz de guardar um dado a ser usado no algoritmo. Pode ser entendida como uma caixa, onde se coloca um dado e se pode consultá-lo quantas vezes for necessário. O dado pode ser modificado (substituído por outro). Exemplo em Portugol: <syntaxhighlight lang=text>
 
Inicio
 
  inteiro anos, dias
 
  
  Escrever "Quantos anos se passaram ? "
+
Ao se escolher a opção ''Comprimir'', uma  janela irá surgir para que se defina o nome do arquivo compactado e o tipo de compactação a ser usada:
  Ler anos
 
  dias <- anos * 365
 
  Escrever "... então se passaram ", dias, " dias"
 
Fim
 
</syntaxhighlight> Nesse exemplo há duas variáveis: ''dias'' e ''anos''
 
* '''Constante:''' semelhante à variável, porém o dado armazenado não pode ser modificado. Exemplo em Portugol:<syntaxhighlight lang=text>
 
Inicio
 
  constante inteiro diasPorAno <- 365
 
  inteiro anos, dias
 
  
  Escrever "Quantos anos se passaram ? "
 
  Ler anos
 
  dias <- anos * diasPorAno
 
  Escrever "... então se passaram ", dias, " dias"
 
Fim
 
</syntaxhighlight> Nesse exemplo há uma constante: ''diasPorAno''
 
  
<br>
+
[[imagem:Compress2.png|600px]]
Variáveis e constantes devem ser declaradas antes de serem usadas (algumas poucas linguagens, como [http://www.python.org Python] e [http://www.perl.org Perl], não exigem isto). A declaração consiste do tipo e identificador da variável. O tipo corresponde ao tipo de valor que pode ser guardado, e o identificador é o nome da variável. No exemplo abaixo:
 
  
<syntaxhighlight lang=text>
 
  constante inteiro diasPorAno <- 365
 
  inteiro anos, dias
 
Fim
 
</syntaxhighlight>
 
  
Há duas variáveis do tipo ''inteiro'', e seus identificadores são ''dias'' e ''anos''. O tipo ''inteiro'' indica que essas variáveis podem guardar somente números inteiros.
+
O arquivo compactado aparecerá na listagem de arquivos do ''nautilus'':
  
'''''Tipos de variáveis e constantes no Portugol:'''''
 
  
{| border="1" cellpadding="2"
+
[[imagem:Compress3.png|600px]]
!Tipo
 
!Descrição
 
!Exemplo
 
|-
 
|Inteiro||Número inteiro entre -2 147 483 648 e 2 147 483 647 begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting || Inteiro x <- 10
 
|-
 
|Real||Número real entre -1.7 E 308 e 1.7 E 308 || Real y <- 10.789
 
|-
 
|Lógico||Valor booleano, com valores "Verdadeiro" e "Falso" || Logico ok <- Falso
 
|-
 
|Caracter||Um caractere da [http://pt.wikipedia.org/wiki/ASCII tabela ASCII] || Caracter letra <- "A"
 
|-
 
|Texto||Uma sequência de caracteres (ou ''string'') || Texto palavra <- "um teste"
 
|}
 
  
A declaração de constantes é semelhante à de variáveis, bastanto prefixá-las com a palavra-chave ''constante''.
 
  
=== Atividade ===
+
Para descompactá-lo e visualizar seu conteúdo, basta clicar duas vezes nele:
  
Para os exercícios abaixo, desenhe o fluxograma e escreva o algoritmo no Portugol.
 
  
# Faça um algoritmo que calcule a média de quatro números, porém mostrando as casas decimais (caso existam).
+
[[imagem:Compress4.png|600px]]
# Escreva um algoritmo que mostre, em sequência: 9, 9^2 (ao quadrado), 9^3 (ao cubo) e a soma desses 3 números.  
 
# Escreva um algoritmo que leia o nome, sobrenome e idade de uma pessoa, e escreva na tela: <syntaxhighlight lang=text>
 
sobrenome, nome
 
idade anos
 
</syntaxhighlight>
 
  
==22/04: Expressões lógicas e aritméticas==
+
=== Compactadores no modo texto ===
  
'''Expressão aritmética''': um conjunto de operações sobre variáveis, constantes e funções numéricas, e que gera um determinado resultado numérico.
+
Vários compactadores de arquivos existem no Linux, e o ''nautilus'' simplifica sua seleção e uso. Esses compactadores podem ser usados também no modo texto ... aliás, eles originalmente foram criados para serem usados dessa forma ! O que o ''nautilus'' faz é facilitar seu uso por meio de uma interface gráfica.
  
Exemplos de expressões aritméticas: <syntaxhighlight lang=text>
+
Os principais compactadores são:
# Uma expressão que calcula quantos segundos existem em um horário do tipo horas, minutos e segundos
+
* [http://manpages.ubuntu.com/manpages/karmic/en/man1/compress.1.html compress]: compactador mais antigo e comum nos Unix em geral, porém em desuso. Gera arquivos compactados com extensão .Z. Precisa do pacote de software ''ncompress'' no Ubuntu. Exemplo de uso: <syntaxhighlight lang=bash>
3600*horas + 60*minutos + segundos
+
msobral@dell-iron:~$ ls -l API-changes.txt
 +
-rw-r--r-- 1 msobral professores 51759 2010-03-24 11:32 API-changes.txt
 +
msobral@dell-iron:~$ compress API-changes.txt
 +
msobral@dell-iron:~$ ls -l API*
 +
-rw-r--r-- 1 msobral professores 22781 2010-03-24 11:32 API-changes.txt.Z
 +
msobral@dell-iron:~$ uncompress API-changes.txt.Z
 +
msobral@dell-iron:~$ ls -l API*
 +
-rw-r--r-- 1 msobral professores 51759 2010-03-24 11:32 API-changes.txt
 +
msobral@dell-iron:~$
 +
</syntaxhighlight>
 +
* [http://manpages.ubuntu.com/manpages/karmic/en/man1/gzip.1.html GNU zip]: compactador bastante utilizado, com maior poder de compactação que ''compress''. Gera arquivos compactados com extensão .gz. Já vem instalado no Ubuntu. Exemplo de uso: <syntaxhighlight lang=bash>
 +
msobral@dell-iron:~$ gzip API-changes.txt
 +
msobral@dell-iron:~$ ls -l API*
 +
-rw-r--r-- 1 msobral professores 17651 2010-03-24 11:32 API-changes.txt.gz
 +
msobral@dell-iron:~$ gunzip API-changes.txt.gz
 +
msobral@dell-iron:~$ ls -l API*
 +
-rw-r--r-- 1 msobral professores 51759 2010-03-24 11:32 API-changes.txt
 +
msobral@dell-iron:~$
 +
</syntaxhighlight>
 +
* [http://manpages.ubuntu.com/manpages/karmic/en/man1/bzip2.1.html bzip2]: vem sendo bastante usado por ter um poder de compactação ainda maior, porém à custa de maior processamento (compactação fica mais lenta). Gera arquivos compactados com extensão .bz2. Também já vem instalado no Ubuntu. <syntaxhighlight lang=bash>
 +
msobral@dell-iron:~$ bzip2 API-changes.txt
 +
msobral@dell-iron:~$ ls -l API*
 +
-rw-r--r-- 1 msobral professores 15804 2010-03-24 11:32 API-changes.txt.bz2
 +
msobral@dell-iron:~$ bunzip2 API-changes.txt.gz
 +
msobral@dell-iron:~$ ls -l API*
 +
-rw-r--r-- 1 msobral professores 51759 2010-03-24 11:32 API-changes.txt
 +
msobral@dell-iron:~$
 +
</syntaxhighlight>
 +
* ... outros menos populares no mundo do Linux, tais como [http://manpages.ubuntu.com/manpages/karmic/en/man1/zip.1.html zip], [http://manpages.ubuntu.com/manpages/karmic/en/man1/rar.1.html rar] e [http://manpages.ubuntu.com/manpages/karmic/en/man1/zoo.1.html zoo].
  
# Uma expressão que calcula a velocidade instantânea, segundo um MRV
+
Note que os compactadores ''compress'', ''gzip'', e ''bzip2'' compactam um arquivo por vez. Assim, com eles não é possível juntar vários arquivos e diretórios dentro de um único arquivo compactado (o que se faz corriqueiramente com '''zip''' ou '''rar''' ...). Portanto, se for necessário compactar um diretório ou um conjunto de arquivos, o melhor é combinar um compactador com o programa [http://manpages.ubuntu.com/manpages/karmic/en/man1/tar.1.html tar].
vel_inicial + aceleracao*tempo;
 
  
# Uma expressão que calcula o módulo de um vetor bidimensional, que possui coordenadas x e y
+
=== tar ===
raiz(x^2 + y^2)
 
</syntaxhighlight>
 
  
Os resultados de expressões podem ser mostrados na tela, ou armazenados em variáveis:
+
O programa ''tar'' é um  utilitário do mundo Unix originalmente criado para backups em fita (daí seu nome: ''TApe aRchiver'', se bem que ''tar'' é também um trocadilho que pode significar piche, pois ele de certa forma gruda um arquivo ao outro). O resultado da execução do ''tar'' é um arquivo contendo todos os arquivos e diretórios que foram selecionados para inclusão. Esse arquivo ''tar'' pode ser então compactado, obtendo-se algo parecido com o que faz zip ou rar.
  
<syntaxhighlight lang=text>
+
Mas porque não usar então zip e rar ? Afinal, eles existem também no Linux ... No entanto, esses compactadores nasceram no mundo do antigo MS-DOS, e assim não são capazes de armazenar todos os atributos de arquivos que existem em sistemas Unix (informações tais como usuário e grupo dono do arquivo, permissões de acesso, tipo do arquivo, datas de último acesso e modificação). O ''tar'', pelo contrário, consegue preservar esses atributos, e por isto se torna mais adequado para uso no Unix em geral.
# Uma expressão que calcula quantos segundos existem em um horário do tipo horas, minutos e segundos
 
segundos <- 3600*horas + 60*minutos + segundos
 
  
# Uma expressão que calcula a velocidade instantânea, segundo um MRV
+
Uso do ''tar'':
escrever 'Velocidade no instante ', tempo, ' = ', vel_inicial + aceleracao*tempo;
+
* '''Criação de arquivo tar:''' <syntaxhighlight lang=bash>tar cf nome_arquivo.tar arquivo_ou_diretorio1 [arquivo_ou_diretorio2 ...]</syntaxhighlight>
 +
* '''Mostrar o conteúdo de arquivo tar:''' <syntaxhighlight lang=bash>tar tvf nome_arquivo.tar </syntaxhighlight>
 +
* '''Extrair conteúdo de arquivo tar:''' <syntaxhighlight lang=bash>tar xf nome_arquivo.tar</syntaxhighlight>
  
# Uma expressão que calcula o módulo de um vetor bidimensional, que possui coordenadas x e y
+
Os usos acima não compactam os arquivos incluídos dentro do arquivo ''tar''. Para compactá-los deve-se adicionar uma opção de compactação:
modulo <- raiz(x^2 + y^2)
+
* '''Criação de arquivo tar compactado:'''
</syntaxhighlight>
+
** '''''Com compress:''''' <syntaxhighlight lang=bash>tar cZf nome_arquivo.tar.Z arquivo_ou_diretorio1 [arquivo_ou_diretorio2 ...]</syntaxhighlight>
 +
** '''''Com gzip:''''' <syntaxhighlight lang=bash>tar czf nome_arquivo.tar.gz arquivo_ou_diretorio1 [arquivo_ou_diretorio2 ...]</syntaxhighlight>
 +
** '''''Com bzip2:''''' <syntaxhighlight lang=bash>tar cjf nome_arquivo.tar.bz2 arquivo_ou_diretorio1 [arquivo_ou_diretorio2 ...]</syntaxhighlight>
 +
* '''Mostrar o conteúdo de arquivo tar:'''
 +
** '''''Com compress:''''' <syntaxhighlight lang=bash>tar tvZf nome_arquivo.tar.Z </syntaxhighlight>
 +
** '''''Com gzip:''''' <syntaxhighlight lang=bash>tar tvzf nome_arquivo.tar.gz </syntaxhighlight>
 +
** '''''Com bzip2:''''' <syntaxhighlight lang=bash>tar tvjf nome_arquivo.tar.bz2 </syntaxhighlight>
 +
* '''Extrair conteúdo de arquivo tar:'''
 +
** '''''Com compress:''''' <syntaxhighlight lang=bash>tar xZf nome_arquivo.tar.Z </syntaxhighlight>
 +
** '''''Com gzip:''''' <syntaxhighlight lang=bash>tar xzf nome_arquivo.tar.gz </syntaxhighlight>
 +
** '''''Com bzip2:''''' <syntaxhighlight lang=bash>tar xjf nome_arquivo.tar.bz2 </syntaxhighlight>
  
Repare que uma expressão fica sempre do lado direito, quando atribuída a uma variável. A expressão é primeiro calculada, e em seguida seu resultado é armazenado na variável:
+
===Roteiro desta aula:===
 +
*[http://www.sj.ifsc.edu.br/~tisemp/SOP/aulas/aula_compactadores.pdf Aula 9]
  
<syntaxhighlight lang=text>
+
==30/08: Revisão para avaliação SOP==
segundos <- 3600*horas + 60*minutos + segundos
 
</syntaxhighlight>
 
  
=== Operadores aritméticos ===
+
==02/09: Avaliação SOP==
  
Expressões aritméticas sao compostas por números e operadores aritméticos:
+
* Primeira avaliação de SOP:
 +
* [http://www.sj.ifsc.edu.br/~tisemp/SOP/avaliacoes/prova1a.tgz Avaliação]
 +
* [http://www.sj.ifsc.edu.br/~tisemp/SOP/avaliacoes/conceitos_av1.pdf Conceitos]
  
Obs: para os exemplos abaixo são usadas estas variáveis: <syntaxhighlight lang=text>
+
===Recuperação SOP===
Real x, area, lado
+
* [http://www.sj.ifsc.edu.br/~tisemp/SOP/prova1_rec.tar.gz Recuperação]
inteiro dias, horas
+
* [http://www.sj.ifsc.edu.br/~tisemp/SOP/conceitos_rec.pdf Conceitos Recuperação]
</syntaxhighlight>
 
  
{| border="1" cellpadding="2"
+
=Lógica de Programação=
!Operador
+
Segundo módulo da disciplina de Sitemas Operacionais.
!Descrição
+
Baseado no material [http://wiki.sj.ifsc.edu.br/images/0/02/Lógica_de_Programação.pdf Lógica de Programação], de Paulo Sérgio de Moraes - uma  das [[Sistemas Operacionais e Introdução a Programação#Referências_Bibliográficas|referências bibliográficas]] da disciplina.
!Exemplo
+
 
|-
+
==06/09: Introdução==
|<nowiki>+</nowiki>||Adição|| x <- x + 1
+
* Revisão da avaliação de SOP 1
|-
+
* Tópicos: instrução, sequência, problemas do dia a dia.
|<nowiki>-</nowiki>||Subtração|| x <- x - 1
+
* Páginas da apostila: 4 a 7.
|-
 
|*||Multiplicação|| x <- x*x*xhttp://www.facebook.com/profile.php?id=100000215067732&ref=profile#!/?ref=home
 
|-
 
|/||Divisão|| dias <- horas / 24
 
|-
 
|%||Módulo (resto de divisão)|| horas <- horas % 24
 
|-
 
|^||Potenciação|| area <- lado^2
 
|}
 
  
Precedência dos operadores (nesta ordem): ^, *, /, %, + e -
+
==09/09: Resolução de exercícios==
 +
* Aula cedida ao Prof. Wolney
 +
* Resolução de exercícios propostos aos alunos na aula do dia 06/09
  
A precedência pode ser modificada com o uso de parênteses. Ex:
+
==13/09: Desenvolvendo algoritmos==
 +
* Tópicos: resolvendo problemas, linguagens e instrução disponíveis (vocabulário).
 +
* Páginas da apostila: 8 a 11.
  
<syntaxhighlight lang=text>
+
'''Exemplificando com ''shell scripts'':'''
escrever 1 + 2 * 3
 
escrever (1 + 2)*3
 
</syntaxhighlight>
 
  
No Portugol, existem também algumas [http://www.sj.ifsc.edu.br/%7Emsobral/SOP/soft/help/funcoes_biblioteca.html funções úteis], como a função '''''raiz''''': <syntaxhighlight lang=text>
+
<syntaxhighlight lang=bash>
r <- raiz(x^2 + y^2)
+
#!/bin/bash
</syntaxhighlight>
 
  
O resultado de expressões aritméticas depende dos tipos numéricos das variáveis e constantes: <syntaxhighlight lang=text>
+
# Cada linha no script abaixo corresponde a uma instrução ...
inicio
+
# O conjunto de instruções na ordem apresentada forma uma sequência lógica ...
  real x
+
 
  inteiro y
+
echo Iniciando o script ...
  inteiro resultadoInteiro
+
echo Vou procurar todos os arquivos de texto existentes neste diretório
  real resultadoReal
+
 
 
+
find . -type f -name "*.doc" > .tmp
  x <- 9
+
find . -type f -name "*.txt" >> .tmp
  y <- 9
+
find . -type f -name "*.rtf" >> .tmp
 
+
find . -type f -name "*.odt" >> .tmp
  escrever "O resultado de uma expressão aritmética depende dos tipos das variá¡veis e constantes\n"
+
 
  escrever "usadas na expressão. Se forem todas inteiras, então o resultado será inteiro.\n"
+
echo Os arquivos são:
  escrever "Veja este exemplo: \n"
 
  escrever "Variável inteira y=", y
 
  escrever "\nExpressão: y/2=", y/2
 
 
 
  escrever "\n\nNeste segundo exemplo, repete-se a mesma expressão, porém usando-se uma\n"
 
  escrever "variável real:\n"
 
  escrever "variável real x=", x
 
  escrever "\nExpressão: x/2=", x/2
 
 
 
  x <- 4
 
  y <- 5
 
  escrever "\n\nSe as variáveis de diferentes tipos forem combinadas, o resultado da\n"
 
  escrever "expressão será real:\n"
 
  escrever "Variável real x=", x, " e inteira y=", y
 
  escrever "\nExpressão: (x+y)/2=", (x+y)/2
 
  
  escrever "\n\nNo entanto, se uma expressão tiver um resultado real, mas este for\n"
+
cat .tmp
  escrever "atribuí­do a uma variável inteira, então apenas a parte inteira será guardada:\n"
+
 
  escrever "Variável real x=", x, " e inteira y=", y
+
rm -f .tmp
  y <- (x+y)/2
 
  escrever "\nExpressão: y <- (x+y)/2 ... após executada, y=", y
 
 
 
fim
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== Atividades ===
+
=== Problemas exemplo ===
 +
 
 +
'''Problema dos três recipientes'''
 +
 
 +
Há três recipientes com tamanhos distintos: um com 8 litros, outro com 5 litros e o terceiro com 3 litros. O recipiente com 8
 +
litros está completamente cheio. Deseja-se colocar 4 litros em dois recipientes. Considere que os recipientes não são graduados.
  
# Escreva um algoritmo que calcule a raiz de uma equação de 1o grau.
 
# Escreva um algoritmo que calcule as raízes de uma equação de 2o grau. Assuma que existam duas raízes reais.
 
# Um equipamento conta o tempo desde que foi ligado. No entanto, essa contagem é feita em segundos. Faça um algoritmo que converta o valor desse contador para horas, minutos e segundos.
 
# Faça um algoritmo que converta um número decimal para sua representação binária. Assuma que o número decimal tenha até dois dígitos.
 
  
==23/04: Estruturas de decisão==
+
'''Problema da travessia'''
 +
 +
Um barqueiro precisa levar um saco de milho, uma galinha e uma raposa para o outro lado do rio. Porém o barco somente é capaz de levar uma coisa de cada vez (além do barqueiro). Qual a sequência de travessias necessário para atravessar o milho, a galinha e a raposa ?
  
Páginas da apostila: 26 a 31.
+
'''Torres de Hanoi'''
  
Estruturas de decisão possibilitam que se executem diferentes sequências de instruções de um programa, dependendo de uma condição a ser avaliada. Por exemplo, um jogo poderia armazenar a maior pontuação já obtida, e verificar se foi ultrapassada ao final de cada partida:
+
Há três hastes. Uma das hastes serve de suporte para três discos de tamanhos diferentes. Um disco menor sempre é colocado sobre um disco maior. A figura abaixo ilustra as hastes e os discos:
  
<syntaxhighlight lang=text>
+
[[imagem:Hanoi.png]]
  Se pontuacao > recorde então
 
    recorde <- pontuação
 
  FimSe
 
</syntaxhighlight>
 
  
O exemplo acima mostra a estrutura de decisão ''Se condição entao comandos Fimse''. Veja o próximo exemplo:
+
Desejam-se mover os três discos para a haste da direita. Porém só pode se mover um disco por vez, e um disco maior nunca pode ficar sobre um disco menor.
  
<syntaxhighlight lang=text>
+
Operação possível: '''Move''' ''disco'' para ''haste''
  Se conceito > 70 entao
 
    escrever 'Voce esta aprovado'
 
  senao
 
    escrever 'Desta vez não deu ... tente de novo !'
 
  Fimse
 
</syntaxhighlight>
 
  
O uso de ''Se condição entao comandos Senao comandos Fimse'' possibilita que se execute uma sequência de comandos se a condição for verdadeira, e outra sequência se for falsa.
+
Qual a sequência de operações para mover os discos de uma haste para outra ?
  
Para fazer um bom uso de estruturas de decisão deve-se primeiro conseguir identificar as condições a serem avaliadas. Condições são escritas com expressões lógicas, e estas são compostas de operadores lógicos e relacionais aplicados a variáveis e constantes.
+
=== Atividade extra ===
  
=== Condições ===
+
* O jogo [http://armorgames.com/play/2205/light-bot LightBot] mostra de uma forma divertida como criar pequenos algoritmos. Até que fase desse jogo você consegue chegar ?
  
Obs: para os exemplos abaixo são usadas estas variáveis: <syntaxhighlight lang=text>
+
=== Exercícios: desenho de figuras geométricas ===
Logico correto, multa, aprovado, barato, bombear_agua
 
Logico descartar, baixo, reprovado, erro, enviado, recebido
 
inteiro erros, pontuacao, preco, endereco, velocidade
 
Real faltas, nivel_agua, altura
 
</syntaxhighlight>
 
  
''Operadores relacionais''
+
* Usando apenas as instruções:<syntaxhighlight lang=text>
{| border="1" cellpadding="2"
+
limpa
!Operador
+
avança X
!Descrição
+
giraDireita angulo
!Exemplo
+
giraEsquerda angulo
|-
+
</syntaxhighlight> escreva algoritmos para desenhar as seguintes figuras:
|=||Igualdade|| correto <- (erros = 0)
+
** triângulo equilátero
|-
+
** triângulo isósceles
|>||Maior|| multa <- (velocidade > 80)
+
** triângulo escaleno
|-
+
** quadrado
|>=||Maior ou igual|| aprovado <- (pontuacao >= 70)
+
** hexágono
|-
+
** octógono
|<||Menor|| barato <- (preco < 100)
+
** 7 hexágonos interligados (um central e seis periféricos).
|-
+
* [http://edu.kde.org/kturtle/ kturtle] é um software educacional para ajudar no ensino de matemática, geometria e introdução à programação. Ele possibilita fazer desenhos facilmente, seguindo um programa com instruções de desenho. Usando as instruções: <syntaxhighlight lang=bash>
|<=||Menor ou igual|| bombear_agua <- (nivel_agua <= 0.7)
+
reset
|-
+
forward X
|=/=||Diferente|| descartar <- (endereco =/= 12345)
+
turnright angulo
|}
+
turnleft angulo
 +
</syntaxhighlight> ... escreva programas para os algoritmos criados no ítem  anterior.
  
 +
* [http://docs.kde.org/stable/pt/kdeedu/kturtle/reference.html Guia de referência Kturtle]
  
''Operadores lógicos''
+
==16/09: Pseudocódigo e diagrama de blocos (fluxograma)==
{| border="1" cellpadding="2"
+
* Adoção do [http://www.dei.estt.ipt.pt/portugol/node/33 Portugol IDE] como ferramenta didática.
!Operador
+
* Páginas da apostila: 12 a 14.
!Descrição
 
!Exemplo
 
|-
 
|NAO||Negação|| baixo <- NOT (altura > 1.8)  
 
|-
 
|E||Conjunção|| aprovado <- NOT (conceito = "D") E (faltas <= 0.25)
 
|-
 
  |OU||Disjunção|| reprovado <- (conceito = "D") OU (faltas > 0.25)
 
|-
 
|XOU||Disjunção exclusiva|| erro <- enviado XOU recebido
 
|}
 
  
Precedência dos operadores (nesta ordem): NAO, E, OU e XOU
+
=== Portugol ===
  
Lembre que a precedência pode ser modificada com o uso de parênteses.
+
As aulas de Lógica de Programação usarão um software de auxílio ao ensino de algoritmos chamado [http://orion.ipt.pt/%7Emanso/Portugol/ Portugol], desenvolvido na [http://www.dei.estt.ipt.pt/portal/ Escola Superior de Engenharia do Instituto Politécnico de Tomar], em Portugal.
 +
* [http://www.sj.ifsc.edu.br/~msobral/SOP/portugol.html Guia rápido de instalação e utilização do Portugol].
  
=== Atividades ===
+
==== Guia rápido de instalação e utilização do Portugol ====
 +
 
 +
Abaixo segue uma breve ajuda de como obtê-lo, instalá-lo e usá-lo. Esse guia assume que você esteja usando o Ubuntu Linux 9.04 ou superior.
 +
 
 +
# Faça o [http://www.sj.ifsc.edu.br/%7Emsobral/SOP/soft/portugol23.tar.gz download] do Portugol.
 +
# Descompacte-o com o seguinte comando: <syntaxhighlight lang=bash>
 +
tar xzf portugol23.tar.gz
 +
</syntaxhighlight>
 +
# Repare que existe agora um subdiretório portugol no diretório onde você o descompactou. Execute o Portugol com o seguinte comando: <syntaxhighlight lang=bash>
 +
java -jar portugol/Portugol.jar
 +
</syntaxhighlight> Obs: você precisará ter Java instalado. Caso não o tenha, execute o comando: <syntaxhighlight lang=bash>
 +
sudo apt-get install openjdk-6-jre
 +
</syntaxhighlight>
 +
# Copie esse [http://www.sj.ifsc.edu.br/%7Emsobral/SOP/exemplos/fluxogramas.cfg arquivo] para poder ver fluxogramas coloridos, e grave-o no memso diretório onde está o Portugol.
 +
# Veja a [http://www.sj.ifsc.edu.br/%7Emsobral/SOP/soft/help/index.html ajuda] do Portugol, e use-a sempre que tiver dúvidas !
  
# Faça um programa que leia um número e então informe se ele é par ou ímpar.
+
<br>A tela inicial do Portugol segue abaixo, junto com um programa demonstrativo.<br>
# Faça um algoritmo que leia três números do teclado, e mostre o maior e menor números.
 
# Em uma rede de computadores, o ''firewall'' restringe o acesso a Internet, dependendo do horário e do tipo de usuário que faz o acesso. Os tipos de usuário abaixo têm as seguintes restrições:
 
#* Funcionario: apenas entre 0:00 e 7:30, entre 18:30 e 0:00, e entre 12:00 e 13:30
 
#* Financeiro: qualquer horario
 
#* Diretoria: qualquer horário<br>Escreva um algoritmo que informe se um acesso foi permitido, em função do horário e do tipo de usuário.
 
# Modifique o algoritmo acima para adicionar a seguinte restrição:
 
#* Funcionario: nao pode acessar sites de jornal (ex: www.rbs.com.br)
 
#* Financeiro: nao pode acessar sites de jornal durante o expediente
 
#* Diretoria: sem restrições a sites
 
# Faça um algoritmo para fazer a divisão de dois números reais. Antes de dividi-los deve ser feito um teste de validade. Caso não seja possível dividi-los, deve ser mostrada uma mensagem de erro. Se for possível, deve-se mostrar o resultado da divisão.
 
# Faça um jogo de par ou ímpar, em que o jogador aposta contra o computador. O jogador deve digitar um número entre 0 e 5 e optar entre par ou ímpar. O computador deve sortear um número também entre 0 e 5. Se a paridade da soma dos números do jogador e do computador for a mesma que o jogador optou, então ele ganha a partida, senão o computador vence.
 
  
Solução exercício 2 proposto.
+
[[Imagem:Editor-Portugol.png]]
  
<syntaxhighlight lang=text>
+
Exemplos de programas iniciais em Portugol:
  
inicio
+
# ''Lendo um número e mostrando-o na tela em seguida:'' <syntaxhighlight lang=text>
    inteiro num<-0,maior<-0,menor<-0, i<-0
+
Inicio
    constante inteiro valores<-2 //declaração da constante
+
  inteiro x
   
 
    escrever "Digite um valor: \n"
 
    ler num
 
    maior <- num
 
    menor <- num
 
    para i de 1 até valores passo 1
 
        ler num
 
        se (num > maior) então
 
            maior <- num
 
        fimse
 
        se (num < menor) então
 
            menor <- num
 
        fimse
 
    proximo
 
    escrever "O maior valor digitado é: ", maior
 
    escrever "\n"
 
    escrever "O menor valor digitado é: ", menor
 
fim
 
  
 +
  Escrever "Digite um numero: ",
 +
  Ler X
 +
  Escrever "Numero digitado: ", x
 +
Fim
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
# ''Lendo dois números, somando-os e mostrando o resultado na tela:'' <syntaxhighlight lang=text>
 +
Inicio
 +
  inteiro x, y
  
==23/04: Estruturas de decisão==
+
  Escrever "Digite um numero: ",
 
+
  Ler x
Há situações em que se precisa fazer um conjunto de comparações, como mostrado abaixo:
+
  Escrever "Digite outro numero: ",
 
+
  Ler y
<syntaxhighlight lang=text>
+
  Escrever "Soma = ", x+y
// Lê a data no formato numérico dia, mes, ano, e mostra a data no formato
+
Fim
// dia, nome do mês, ano.
+
</syntaxhighlight>O programa abaixo é equivalente:<syntaxhighlight lang=text>
 
Inicio
 
Inicio
   inteiro dia, mes, ano
+
   inteiro x, y, z
   texto nome_mes
+
 
 +
  Escrever "Digite um numero: ",
 +
  Ler x
 +
  Escrever "Digite outro numero: ",
 +
  Ler y
 +
  z <- x + y
 +
   Escrever "Soma = ", z
 +
Fim
 +
</syntaxhighlight>
  
  escrever "Dia: "
+
=== Atividades ===
  ler dia
 
  escrever "Mes: "
 
  ler mes
 
  escrever "Ano: "
 
  ler ano
 
  
  se mes = 1 entao
+
# ''Média de três números:'' escreva um programa para calcular a média de três números. <syntaxhighlight lang=text>
    nome_mes <- "Janeiro"
+
Inicio
  senao
+
   Inteiro n1, n2, n3, r
    se mes = 2 entao
 
      nome_mes <- "Fevereiro"
 
    senao
 
      se mes = 2 entao
 
        nome_mes <- "Março"
 
      senao
 
        se mes = 2 entao
 
          nome_mes <- "Abril"
 
        senao
 
          se mes = 2 entao
 
            nome_mes <- "Maio"
 
          senao
 
            se mes = 2 entao
 
              nome_mes <- "Junho"
 
            senao
 
              se mes = 2 entao
 
                nome_mes <- "Julho"
 
              senao
 
                se mes = 2 entao
 
                  nome_mes <- "Agosto"
 
              senao
 
                  se mes = 2 entao
 
                    nome_mes <- "Setembro"
 
                  senao
 
                    se mes = 2 entao
 
                      nome_mes <- "Outubro"
 
                    senao
 
                      se mes = 2 entao
 
                        nome_mes <- "Novembro"
 
                      senao
 
                        nome_mes <- "Dezembro"
 
                      fimSe
 
                    fimSe
 
                  fimSe
 
                fimSe
 
              fimSe
 
            fimSe
 
          fimSe
 
        fimSe
 
      fimSe
 
    fimSe
 
   fimSe
 
  
   escrever dia, " de ", nome_mes, " de ", ano
+
   Escrever "Primeiro numero: "
fim
+
  ler n1
 +
  Escrever "Segundo numero: "
 +
  ler n2
 +
  Escrever "Terceiro numero: "
 +
  ler n3
 +
 
 +
  r <- (n1 + n2 + n3) /3
 +
 
 +
  Escrever "Media=", r
 +
Fim
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
# ''Sequência de Fibonacci:'' em matemática corresponde aos números: <syntaxhighlight lang=text>
 +
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
 +
</syntaxhighlight>... que pode ser descrita pela relação de recorrência <br><br><math>F_{n} = F_{n-1} + F_{n-2}</math><br><br>... com valores iniciais <math>F_{0} = 1</math> e <math>F_{1} = 1</math>.<br><br>Numerosas formas na natureza apresentam essa sequência, como neste girassol (cujas flores se dispõem em uma espiral):<br><br>[[Imagem:Sunflower.jpg]]  [[Imagem:espiral_fibonacci.png]] [[Imagem:FibonacciBlocks.png]]<br><br>Usando o Portugol escreva um programa que mostre os 10 primeiros números dessa sequência.
 +
 +
==20/09: Fluxogramas, constantes e Variáveis==
  
Além de ser trabalhoso esse encadeamento de ''Se ... entao ... senao'', o algoritmo resultante fica pouco legível. Quer dizer, ele fica feio e difícil de entender.
+
* Diagrama de blocos (fluxograma)
 +
* Variáveis e constantes
  
Existe uma estrutura de decisão criada justamente para casos como esse, e que resulta em um algoritmo mais limpo e compreensível:
+
=== Fluxogramas ===
  
<syntaxhighlight lang=text>
+
Diagramas de bloco para auxiliar a descrição de algoritmos. Ajudam na compreensão do algoritmo, por poder visualizar o fluxo de execução.
// Lê a data no formato numérico dia, mes, ano, e mostra a data no formato
 
// dia, nome do mês, ano.
 
Inicio
 
  inteiro dia, mes, ano
 
  texto nome_mes
 
  
  escrever "Dia: "
 
  ler dia
 
  escrever "Mes: "
 
  ler mes
 
  escrever "Ano: "
 
  ler ano
 
  
  Escolhe mes
+
[[imagem:Fluxograma-soma.png]] Fluxograma para o algoritmo da média de trẽs números.
    caso 1:
+
 
      nome_mes <- "Janeiro"
+
<br>
    caso 2:
 
      nome_mes <- "Fevereiro"
 
    caso 3:
 
      nome_mes <- "Março"
 
    caso 4:
 
      nome_mes <- "Abril"
 
    caso 5:
 
      nome_mes <- "Maio"
 
    caso 6:
 
      nome_mes <- "Junho"
 
    caso 7:
 
      nome_mes <- "Julho"
 
    caso 8:
 
      nome_mes <- "Agosto"
 
    caso 9:
 
      nome_mes <- "Setembro"
 
    caso 10:
 
      nome_mes <- "Outubro"
 
    caso 11:  
 
      nome_mes <- "Novembro"
 
    Defeito:
 
      nome_mes <- "Dezembro"
 
  fimEscolhe
 
  
  escrever dia, " de ", nome_mes, " de ", ano
+
'''Blocos de uso mais comum'''<br>
fim
+
{| border="1" cellpadding="2"
</syntaxhighlight>
+
!Bloco
 +
!Descrição
 +
!Exemplo
 +
|-
 +
|[[Imagem:Inicio.png]]||Inicio do fluxograma||
 +
|-
 +
|[[Imagem:Processamento.png]]||Processamento||
 +
|-
 +
|[[Imagem:Entrada.png]]||Entrada de dados (ler do teclado)||
 +
|-
 +
|[[Imagem:Saida.png]]||Saída de dados (mostrar na tela)||
 +
|-
 +
|[[Imagem:Decisao.png]]||Decisão (testar uma condição e bifurcar)||[[imagem:Ex-decisao.png]]
 +
|-
 +
|[[Imagem:Conector.png]]||Conector (juntar dos ou mais ramos do fluxograma)||[[imagem:Ex-conector.png]]
 +
|-
 +
|[[Imagem:Fim.png]]||Fim||
 +
|}
  
A estrutura de decisão ''escolhe ... caso'' tem uma certa flexibilidade. No exemplo abaixo, mostra-se a possibilidade de testar mais de um valor no mesmo ''caso'':
+
Obs: [http://www.sj.ifsc.edu.br/%7Emsobral/SOP/exemplos/fluxogramas.cfg Arquivo de configuração das cores do fluxograma ] do Portugol.
  
<syntaxhighlight lang=text>
+
=== Variáveis e constantes ===
inicio   
 
  caracter sexo   
 
  
  escrever "Qual o seu sexo (f/m):"   
+
* '''Variável:''' capaz de guardar um dado a ser usado no algoritmo. Pode ser entendida como uma caixa, onde se coloca um dado e se pode consultá-lo quantas vezes for necessário. O dado pode ser modificado (substituído por outro). Exemplo em Portugol: <syntaxhighlight lang=text>
   ler sexo   
+
Inicio
 +
   inteiro anos, dias
  
   escrever "Olá "    
+
   Escrever "Quantos anos se passaram ? "
 +
  Ler anos
 +
  dias <- anos * 365
 +
  Escrever "... então se passaram ", dias, " dias"
 +
Fim
 +
</syntaxhighlight> Nesse exemplo há duas variáveis: ''dias'' e ''anos''
 +
* '''Constante:''' semelhante à variável, porém o dado armazenado não pode ser modificado. Exemplo em Portugol:<syntaxhighlight lang=text>
 +
Inicio
 +
  constante inteiro diasPorAno <- 365
 +
  inteiro anos, dias
  
   escolhe sexo       
+
   Escrever "Quantos anos se passaram ? "
    caso "m", "M" :           
+
  Ler anos
      escrever "senhor"       
+
  dias <- anos * diasPorAno
    caso "f","F" :           
+
  Escrever "... então se passaram ", dias, " dias"
      escrever "senhorita"       
+
Fim
    defeito :            
+
</syntaxhighlight> Nesse exemplo há uma constante: ''diasPorAno''
      escrever "Sexo indefinido"   
 
  fimescolhe   
 
  
  escrever ", benvindo ao portugol"
+
<br>
fim
+
Variáveis e constantes devem ser declaradas antes de serem usadas (algumas poucas linguagens, como [http://www.python.org Python] e [http://www.perl.org Perl], não exigem isto). A declaração consiste do tipo e identificador da variável. O tipo corresponde ao tipo de valor que pode ser guardado, e o identificador é o nome da variável. No exemplo abaixo:
</syntaxhighlight>
 
  
=== Atividades ===
+
<syntaxhighlight lang=text>
 +
  constante inteiro diasPorAno <- 365
 +
  inteiro anos, dias
 +
Fim
 +
</syntaxhighlight>
  
# Faça um algoritmo que converta um número de 1 a 7 para o respectivo dia da semana (ex: 1 = domingo, 2 = 2a feira, e assim por diante).
+
Há duas variáveis do tipo ''inteiro'', e seus identificadores são ''dias'' e ''anos''. O tipo ''inteiro'' indica que essas variáveis podem guardar somente números inteiros.
# Faça uma calculadora com as quatro operações aritméticas. Sua calculadora deve ler (nesta ordem) o primeiro número, a operação aritmética (que deve ser informada usando o símbolo da respectiva operação: +, -, * ou /), e depois o segundo número. Ao final, seu algoritmo deve mostrar o resultado, ou uma mensagem de erro se a operação não for possível de realizar (ex: divisão por zero).
 
# A previsão do tempo na costa brasileira pode ser feita de forma aproximada usando-se um barômetro e um termômetro. Uma estimativa com boa chance de acerto se baseia na tabela abaixo: <br>[[imagem:Previsao-barometro.png|800px]]<br><br>Faça um algoritmo que forneça uma estimativa da previsão do tempo, usando essa tabela.
 
# Faça um algoritmo que mostre qual o último dia de um determinado mês informado pelo teclado. Caso seja informado o mês 2 (fevereiro), seu algoritmo deve identificar se é ano bissexto (assim o mês tem 29 dias), ou não (mês tem 28 dias). Obs: anos bissextos são dados pelas regras (segundo o calendário Gregoriano):
 
## De 4 em 4 anos é ano bissexto.
 
## De 100 em 100 anos não é ano bissexto.
 
## De 400 em 400 anos é ano bissexto.
 
## Prevalecem as últimas regras sobre as primeiras.
 
  
=== Solução Ex. 4 ===
+
'''''Tipos de variáveis e constantes no Portugol:'''''
  
<code>
 
inicio
 
texto B, T
 
 
Escrever "O barômetro está: "
 
ler B
 
 
Escrever "O termômetro está: "
 
ler T
 
 
escolhe B
 
 
caso "+":
 
 
  escolhe T
 
  caso "+":
 
    escrever "Tempo bom, ventos quentes e secos"
 
  caso "=":
 
    escrever "Tempo bom, ventos de leste frescos"
 
  caso "-":
 
    escrever "Tempo bom, ventos de sul a sudeste"
 
 
 
  fimescolhe
 
 
caso "=":
 
 
 
  escolhe T
 
 
 
  caso "+":
 
    escrever "Tempo mudando para bom, ventos de leste"
 
  caso "=":
 
    escrever "Tempo incerto, ventos variáveis"
 
  caso "-":
 
    escrever "Chuva provável, ventos de sul para sudeste"
 
 
 
    fimescolhe
 
 
 
caso "-":
 
 
 
  escolhe T
 
 
 
    caso "+":
 
    escrever "Tempo instável, aproximação de frente"
 
  caso "=":
 
    escrever "Frente quente, com chuvas prováveis"
 
  caso "-":
 
    escrever "Chuvas abundantes e ventos de sul a sudeste fortes"
 
 
 
  fimescolhe
 
 
 
fimescolhe
 
 
fim
 
  
</syntaxhighlight>
+
{| border="1" cellpadding="2"
 +
!Tipo
 +
!Descrição
 +
!Exemplo
 +
|-
 +
|Inteiro||Número inteiro entre -2 147 483 648 e 2 147 483 647 begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting || Inteiro x <- 10
 +
|-
 +
|Real||Número real entre -1.7 E 308 e 1.7 E 308 || Real y <- 10.789
 +
|-
 +
|Lógico||Valor booleano, com valores "Verdadeiro" e "Falso" || Logico ok <- Falso
 +
|-
 +
|Caracter||Um caractere da [http://pt.wikipedia.org/wiki/ASCII tabela ASCII] || Caracter letra <- "A"
 +
|-
 +
|Texto||Uma sequência de caracteres (ou ''string'') || Texto palavra <- "um teste"
 +
|}
 +
 
 +
A declaração de constantes é semelhante à de variáveis, bastanto prefixá-las com a palavra-chave ''constante''.
 +
 
 +
=== Atividade ===
  
==29/04: Estruturas de repetição==
+
Para os exercícios abaixo, desenhe o fluxograma e escreva o algoritmo no Portugol.
  
Páginas da apostila: 32 a 35.
+
# Faça um algoritmo que calcule a média de quatro números, porém mostrando as casas decimais (caso existam).
 +
# Escreva um algoritmo que mostre, em sequência: 9, 9^2 (ao quadrado), 9^3 (ao cubo) e a soma desses 3 números.  
 +
# Escreva um algoritmo que leia o nome, sobrenome e idade de uma pessoa, e escreva na tela: <syntaxhighlight lang=text>
 +
sobrenome, nome
 +
idade anos
 +
</syntaxhighlight>
  
Alguns algoritmos vistos anteriormente possuem sequências repetitivas de instruções. Por exemplo, o algoritmo da média de quatro avaliações:
+
==23/09: Algoritmos==
 +
* Resolução de exercícios
  
<syntaxhighlight lang=text>
+
* Exemplo de um algoritmo simples, onde após calculado os valores de entrada de um usuário, apresenta-se os valores na tele. Observe a declaração de variáveis e constantes, além dos comentários e identação do código portugol:
Inicio
 
  real m1, m2, m3, m4
 
  real media
 
  
  escrever 'Avaliação 1:'
+
<code>
  Ler m1
+
inicio
  escrever 'Avaliação 2:'
+
    //declaração das variáveis
  Ler m2
+
    texto nome<-"", sobrenome<-"", endereco<-""
  escrever 'Avaliação 3:'
+
    inteiro ano<-0, idade<-0
  Ler m3
+
    constante inteiro ano_atual <- 2010
  escrever 'Avaliação 4:'
+
    caracter sexo<-"X"
  Ler m4
 
 
 
  media <- (m1 + m2 + m3 + m4) / 4
 
  
  escrever 'Média: ', media
+
    //área de leitura de valores
Fim
+
    escrever "Informe o Nome: "
</syntaxhighlight>
+
    ler nome
 +
    escrever "Informe o Sobrenome: "
 +
    ler sobrenome
 +
    escrever "Informa o endereço: "
 +
    ler endereco
 +
    escrever "Informe o ano de nascimento: "
 +
    ler ano
 +
    escrever "Informe o sexo (M ou F): "
 +
    ler sexo
  
O algoritmo acima repete quatro vezes a sequência que lê uma nota do teclado. Porém há uma forma de expressar a repetição de sequências de instruções, usando-se o que se chama de ''estrutura de repetição''. A estrutura de repetição '''''enquanto''''' ''condição'' '''''faz''''' repete todas as instruções enquanto a condição for verdadeira. A condição é escrita como uma expressão lógica, da mesma forma que na estrutura de decisão '''''se''''' ''condição'' '''''então ... senão'''''. Veja como fica o algoritmo acima ao ser reescrito para usar essa estrutura de repetição:
+
    //calcula idade
 +
    idade <- (ano_atual - ano)
  
<syntaxhighlight lang=text>
 
Inicio
 
  constante inteiro NUMEROS <- 4
 
  real m
 
  real media
 
  inteiro contador <- 0
 
  
  enquanto contador < NUMEROS faz 
+
    //Mostra valores
     escrever 'Avaliação ', contador, ':'
+
     escrever "\n ****** Dados Pessoais ******"
    ler m
 
    media <- media + m
 
    contador <- contador + 1
 
  fimEnquanto
 
  
  escrever 'Média: ', media/NUMEROS
+
    escrever "\nNome Completo: ", nome, " ",sobrenome
Fim
+
    escrever "\nEndereço: ", endereco
 +
    escrever "\nAno de Nascimento: ", ano
 +
    escrever "\nIdade: ", idade
 +
    escrever "\nSexo: ", sexo
 +
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Esse algoritmo funciona somente para médias de quatro números. Porém calcular a média de qualquer quantidade de números usa a mesma lógica: ler os números, somá-los e dividir o total pela quantidade de números lidos. Por exemplo, para fazer com que ele calcule a média de 7 números é necessário escrevê-lo assim:
+
* Solução do exercício das poltronas no cinema, proposta pelo Ismael:
  
<syntaxhighlight lang=text>
+
<code>
Inicio
+
inicio
  constante inteiro NUMEROS <- 7
+
    // variaveis
  real m
+
    inteiro ncadeira <- 0 , fila <- 0 , cadeira <- 0 , calculo <- 0
  real media
+
 
  inteiro contador <- 0
+
    // area de leitura
 +
    escrever "informe o número de sua cadeira:\n"
 +
    ler ncadeira
  
  enquanto contador < NUMEROS faz 
+
     // area de calculo
    escrever 'Avaliação ', contador, ':'
+
     fila <- ( ncadeira / 20 ) + 1
     ler m
+
     cadeira <- ( ncadeira % 20 )
     media <- media + m
 
     contador <- contador + 1
 
  fimEnquanto
 
  
  escrever 'Média: ', media/NUMEROS
+
    // mostrar valores
Fim
+
    escrever "Fila: " , fila
 +
    escrever "\nCadeira: " , cadeira
 +
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Note que o algoritmo praticamente não foi modificado, pois somente se alterou o valor da constante NUMEROS.
+
==27/09: Expressões lógicas e aritméticas==
  
A estrutura de repetição junto com a sequência de instruções a ser repetida é comumente chamada de '''laço''. Assim, no algoritmo acima o laço aparece em:
+
'''Expressão aritmética''': um conjunto de operações sobre variáveis, constantes e funções numéricas, e que gera um determinado resultado numérico.
  
<syntaxhighlight lang=text>
+
Exemplos de expressões aritméticas: <syntaxhighlight lang=text>
  enquanto contador < NUMEROS faz 
+
# Uma expressão que calcula quantos segundos existem em um horário do tipo horas, minutos e segundos
    escrever 'Avaliação ', contador, ':'
+
3600*horas + 60*minutos + segundos
    ler m
 
    media <- media + m
 
    contador <- contador + 1
 
  fimEnquanto
 
</syntaxhighlight>
 
  
----
+
# Uma expressão que calcula a velocidade instantânea, segundo um MRV
 +
vel_inicial + aceleracao*tempo;
 +
 
 +
# Uma expressão que calcula o módulo de um vetor bidimensional, que possui coordenadas x e y
 +
raiz(x^2 + y^2)
 +
</syntaxhighlight>
  
Um outro exemplo ainda mais simples é mostrar na tela uma contagem numérica:
+
Os resultados de expressões podem ser mostrados na tela, ou armazenados em variáveis:
  
 
<syntaxhighlight lang=text>
 
<syntaxhighlight lang=text>
inicio
+
# Uma expressão que calcula quantos segundos existem em um horário do tipo horas, minutos e segundos
    inteiro contador
+
segundos <- 3600*horas + 60*minutos + segundos
    contador <- 0
+
 
 +
# Uma expressão que calcula a velocidade instantânea, segundo um MRV
 +
escrever 'Velocidade no instante ', tempo, ' = ', vel_inicial + aceleracao*tempo;
  
    enquanto contador < 10 faz
+
# Uma expressão que calcula o módulo de um vetor bidimensional, que possui coordenadas x e y
        escrever contador , " "
+
modulo <- raiz(x^2 + y^2)
        contador <- contador + 1
 
    fimenquanto
 
fim
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Ao executar esse algoritmo, tem-se como resultado:
+
Repare que uma expressão fica sempre do lado direito, quando atribuída a uma variável. A expressão é primeiro calculada, e em seguida seu resultado é armazenado na variável:
  
 
<syntaxhighlight lang=text>
 
<syntaxhighlight lang=text>
0 1 2 3 4 5 6 7 8 9
+
segundos <- 3600*horas + 60*minutos + segundos
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Repare no uso de uma variável auxiliar ''contador'' para controlar a quantidade de repetições. Essa é uma técnica comum para
+
=== Operadores aritméticos ===
controlar a estrutura de repetição, e já foi usada no exemplo da média. Ela pode também ser combinada com outras condições, como mostrado abaixo:
 
  
<syntaxhighlight lang=text>
+
Expressões aritméticas sao compostas por números e operadores aritméticos:
inicio
+
 
    inteiro contador <- 1
+
Obs: para os exemplos abaixo são usadas estas variáveis: <syntaxhighlight lang=text>
    caracter opcao <- "s"
+
Real x, area, lado
       
+
inteiro dias, horas
    enquanto ((opcao = "s") ou (opcao = "S")) e contador < 11 faz
 
        escrever contador, "\n"
 
        contador <- contador + 1
 
       
 
        escrever "\nContinuar (S/N) ? "
 
        ler opcao
 
    fimenquanto
 
   
 
    escrever "Terminou com contador = " , contador
 
fim
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Nesse exemplo se usa um laço para mostrar uma contagem de 1 a 10. Porém há a possibilidade de encerrar o algoritmo. Observe a condição para continuidade do laço: ela é verdadeira somente se ''contador < 11'' e se a variável ''opcao'' for igual a "s" ou "S".
+
{| border="1" cellpadding="2"
 
+
!Operador
Finalmente, apesar de ser comum o uso de contadores para controle do laço, pode-se usar qualquer condição para essa finalidade. Então podem existir laços que não usam contadores para controlar a quantidade de repetições, como no próximo exemplo:
+
!Descrição
 
+
!Exemplo
<syntaxhighlight lang=text>
+
|-
inicio
+
|<nowiki>+</nowiki>||Adição|| x <- x + 1
    constante texto segredo <- "secreto"
+
|-
    texto senha
+
|<nowiki>-</nowiki>||Subtração|| x <- x - 1
   
+
|-
    ler senha
+
|*||Multiplicação|| x <- x*x*x
    enquanto senha =/= segredo faz
+
|-
        escrever "Voce continua preso ! Digite a senha correta: "
+
|/||Divisão|| dias <- horas / 24
        ler senha
+
|-
    fimenquanto
+
|%||Módulo (resto de divisão)|| horas <- horas % 24
    escrever "Voce foi liberado ..."
+
|-
fim
+
|^||Potenciação|| area <- lado^2
</syntaxhighlight>
+
|}
 +
 
 +
Precedência dos operadores (nesta ordem): ^, *, /, %, + e -
  
 +
A precedência pode ser modificada com o uso de parênteses. Ex:
  
 +
<syntaxhighlight lang=text>
 +
escrever 1 + 2 * 3
 +
escrever (1 + 2)*3
 +
</syntaxhighlight>
  
=== Solução do problema proposto em sala (aula dia 29/04/2010) feita pelo Thiarles ===
+
No Portugol, existem também algumas [http://www.sj.ifsc.edu.br/%7Emsobral/SOP/soft/help/funcoes_biblioteca.html funções úteis], como a função '''''raiz''''': <syntaxhighlight lang=text>
 +
r <- raiz(x^2 + y^2)
 +
</syntaxhighlight>
  
<code>
+
O resultado de expressões aritméticas depende dos tipos numéricos das variáveis e constantes: <syntaxhighlight lang=text>
 
inicio
 
inicio
    inteiro opcao <- 0
+
  real x
    real numero1 <- 0 , numero2 <- 0 , resultado <- 0
+
  inteiro y
    enquanto opcao =/= 5 faz
+
  inteiro resultadoInteiro
        escrever "\n Entre com a opção desejada: 1- Adição; 2- Subtração; 3- Multiplicação; 4- Divisão , 5- Sair."
+
  real resultadoReal
        ler opcao
+
 
        se opcao = 5 entao
+
  x <- 9
            escrever "\n Você saiu com sucesso!"
+
  y <- 9
        senao
+
 
            escrever "\n Lembre-se: Na subtração e na divisão a ordem dos números é importante!"
+
  escrever "O resultado de uma expressão aritmética depende dos tipos das variá¡veis e constantes\n"
            escrever "\n Entre com o primeiro número: "
+
  escrever "usadas na expressão. Se forem todas inteiras, então o resultado será inteiro.\n"
            ler numero1
+
  escrever "Veja este exemplo: \n"
            escrever "\n Entre com o segundo número: "
+
  escrever "Variável inteira y=", y
            ler numero2
+
  escrever "\nExpressão: y/2=", y/2
            se opcao = 1 entao
+
 
                resultado <- ( numero1 + numero2 )
+
  escrever "\n\nNeste segundo exemplo, repete-se a mesma expressão, porém usando-se uma\n"
                escrever "\n A soma dos dois números é: " , resultado
+
  escrever "variável real:\n"
            fimse
+
  escrever "variável real x=", x
            se opcao = 2 entao
+
  escrever "\nExpressão: x/2=", x/2
                resultado <- ( numero1 - numero2 )
+
 
                escrever "\n A subtração dos dois números é: " , resultado
+
  x <- 4
            fimse
+
  y <- 5
            se opcao = 3 entao
+
  escrever "\n\nSe as variáveis de diferentes tipos forem combinadas, o resultado da\n"
                resultado <- ( numero1 * numero2 )
+
  escrever "expressão será real:\n"
                escrever "\n O produto dos dois números é: " , resultado
+
  escrever "Variável real x=", x, " e inteira y=", y
            fimse
+
  escrever "\nExpressão: (x+y)/2=", (x+y)/2
            se opcao = 4 entao
+
 
                se numero2 = 0 entao
+
  escrever "\n\nNo entanto, se uma expressão tiver um resultado real, mas este for\n"
                    escrever "\n Não existe divisão por 0 (zero)."
+
  escrever "atribuí­do a uma variável inteira, então apenas a parte inteira será guardada:\n"
                senao
+
  escrever "Variável real x=", x, " e inteira y=", y
                    resultado <- ( numero1 / numero2 )
+
  y <- (x+y)/2
                    escrever "\n A divisão dos dois números é: " , resultado
+
  escrever "\nExpressão: y <- (x+y)/2 ... após executada, y=", y
                fimse
+
 
            fimse
+
fim
            se ( opcao =/= 1 e opcao =/= 2 ) e ( opcao =/= 3 e opcao =/= 4 ) entao
 
                escrever "\n Esta operação não está definida."
 
            fimse
 
        fimse
 
    fimenquanto
 
fim
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 
  
 
=== Atividades ===
 
=== Atividades ===
  
# Escreva um algoritmo que mostre a tabuada de um número fornecido pelo teclado. Esse número deve estar entre 1 e 10.
+
# Escreva um algoritmo que calcule a raiz de uma equação de 1o grau.
# Modifique o exemplo da média para que a quantidade de números a serem lidos seja previamente informada pelo teclado.
+
# Escreva um algoritmo que calcule as raízes de uma equação de 2o grau. Assuma que existam duas raízes reais
# Modifique novamente o exemplo da média para que ela funcione para um quantidade de números desconhecida de antemão. Quer dizer, o algoritmo deve ler os números para calcular a média, mas não sabe quantos números existem (e isto não pode ser informado pelo teclado).  
+
# Um equipamento conta o tempo desde que foi ligado. No entanto, essa contagem é feita em segundos. Faça um algoritmo que converta o valor desse contador para horas, minutos e segundos.
# Modifique o exemplo da senha para que o usuário tenha somente três tentativas permitidas para digitar a senha correta. caso ao final as três senhas estejam erradas, o algoritmo deve informar que a conta foi bloqueada.
+
# Faça um algoritmo que converta um número decimal para sua representação binária. Assuma que o número decimal tenha até dois dígitos.
# Escreva um algoritmo que leia até 10 números do teclado, e informe ao final qual o maior e o menor deles.
 
# Escreva um algoritmo que teste se um número informado pelo teclado é primo.
 
  
==30/04: Estruturas de repetição==
+
* Resolução do ecercício 2, proposta pelo Giovanni e Francisco:
  
=== Variáveis multidimensionais ===
+
<syntaxhighlight lang=text>
 +
inicio
 +
    real va , vb , vc , x1,delta,x2 <- 0.0
 +
    escrever "Digite um valor para A: "
 +
    ler va
 +
    escrever "Digite um valor para B: "
 +
    Ler vb
 +
    escrever "Digite um valor para C: "
 +
    Ler vc
 +
   
 +
    escrever "Sua equação é: " ,va,"x^2+",vb,"x+",vc, "=0\n"
 +
    delta <- (vb ^ 2) - (4*va*vc)
 +
    escrever delta ,"\n"
 +
    x1 <- ((-vb) + (raiz(delta))) / (2*va)
 +
    Escrever " x ' = " , x1
 +
    x2 <- ((-vb) - (raiz(delta))) / (2*va)
 +
    Escrever "\n x '' = " , x2
 +
fim
 +
</syntaxhighlight>
  
Em matemática existem matrizes e vetores, que são variáveis multidimensionais. Por exemplo, uma matriz 3 x 3 (3 linhas e 3 colunas) pode ser:
+
==30/09: Estruturas de decisão==
  
<math>A = \begin{pmatrix}
+
Páginas da apostila: 26 a 31.
1 & 6 \\
 
3 & 5
 
\end{pmatrix}</math>
 
  
Vetores são matrizes unidimensionais, portanto possuem somente uma linha ou uma coluna:
+
Estruturas de decisão possibilitam que se executem diferentes sequências de instruções de um programa, dependendo de uma condição a ser avaliada. Por exemplo, um jogo poderia armazenar a maior pontuação já obtida, e verificar se foi ultrapassada ao final de cada partida:
  
<math>v = \begin{pmatrix}
+
<syntaxhighlight lang=text>
1 & 6 & 2 & 18 & 5
+
  Se pontuacao > recorde então
\end{pmatrix}</math>
+
    recorde <- pontuação
 +
  FimSe
 +
</syntaxhighlight>
  
Cada elemento em uma matriz ou vetor é identificado pela sua posição. Por exemplo, na posição ''1, 2'' da matriz A acima está o valor 6, e na posição ''4'' do vetor ''v'' está o valor 18. Assim, a matriz A do exemplo pode ser entendida da seguinte forma:
+
O exemplo acima mostra a estrutura de decisão ''Se condição entao comandos Fimse''. Veja o próximo exemplo:
  
<math>A = \begin{pmatrix}
+
<syntaxhighlight lang=text>
A_{11} & A_{12} \\
+
  Se conceito > 70 entao
A_{21} & A_{22}
+
    escrever 'Voce esta aprovado'
\end{pmatrix}</math>
+
  senao
 +
    escrever 'Desta vez não deu ... tente de novo !'
 +
  Fimse
 +
</syntaxhighlight>
  
... e o vetor ''v'' do exemplo:
+
O uso de ''Se condição entao comandos Senao comandos Fimse'' possibilita que se execute uma sequência de comandos se a condição for verdadeira, e outra sequência se for falsa.
  
<math>v = \begin{pmatrix}
+
Para fazer um bom uso de estruturas de decisão deve-se primeiro conseguir identificar as condições a serem avaliadas. Condições são escritas com expressões lógicas, e estas são compostas de operadores lógicos e relacionais aplicados a variáveis e constantes.
v_{1} & v_{2} & v_{3} & v_{4} & v_{5}
 
\end{pmatrix}</math>
 
  
Nas linguagens de programação em geral existe um conceito muito parecido, chamado de variáveis multidimensionais ou simplesmente ''matrizes'' (''arrays'' em inglẽs). Para exemplificar, no Portugol se poderiam definir a matriz ''A'' e o vetor ''v'':
+
=== Condições ===
  
<syntaxhighlight lang=text>
+
Obs: para os exemplos abaixo são usadas estas variáveis: <syntaxhighlight lang=text>
inicio
+
Logico correto, multa, aprovado, barato, bombear_agua
  inteiro A[2][2] <- {{1, 6}, {3, 5}}
+
Logico descartar, baixo, reprovado, erro, enviado, recebido
  inteiro M[3][2];
+
inteiro erros, pontuacao, preco, endereco, velocidade
  inteiro v[5] <- {1, 6, 2, 18, 5}
+
Real faltas, nivel_agua, altura
  inteiro i, j
 
 
 
  escrever "Valor de A[0][0]: ", A[0][0], "\n"
 
  escrever "Valor de A[0][1]: ", A[0][1], "\n"
 
  escrever "Valor de A[1][0]: ", A[1][0], "\n"
 
  escrever "Valor de A[1][1]: ", A[1][1], "\n"
 
 
 
  escrever "Valor de v[0]: ", v[0], "\n"
 
  escrever "Valor de v[1]: ", v[1], "\n"
 
  escrever "Valor de v[2]: ", v[2], "\n"
 
  escrever "Valor de v[3]: ", v[3], "\n"
 
  escrever "Valor de v[4]: ", v[4], "\n"
 
 
 
fim
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
A declaração da matriz se faz como uma variável comum, porém indicando-se suas dimensões:
+
''Operadores relacionais''
 
+
{| border="1" cellpadding="2"
<syntaxhighlight lang=text>
+
!Operador
  inteiro A[2][2] <- {{1, 6}, {3, 5}}
+
!Descrição
  inteiro M[3][2];
+
!Exemplo
</syntaxhighlight>
+
|-
 +
|=||Igualdade|| correto <- (erros = 0)
 +
|-
 +
|>||Maior|| multa <- (velocidade > 80)
 +
|-
 +
|>=||Maior ou igual|| aprovado <- (pontuacao >= 70)
 +
|-
 +
|<||Menor|| barato <- (preco < 100)
 +
|-
 +
|<=||Menor ou igual|| bombear_agua <- (nivel_agua <= 0.7)
 +
|-
 +
|=/=||Diferente|| descartar <- (endereco =/= 12345)
 +
|}
  
Exemplo de preenchimento e impressão de matrizes não quadradas
 
  
<syntaxhighlight lang=text>
+
''Operadores lógicos''
inicio
+
{| border="1" cellpadding="2"
inteiro i,j, mat[2][4]
+
!Operador
   
+
!Descrição
      //leitura (preenchimento da matriz)
+
!Exemplo
      para i de 0 ate 1 passo 1
+
|-
          para j de 0 ate 3 passo 1
+
|NAO||Negação|| baixo <- NOT (altura > 1.8)
              ler mat[i][j]
+
|-
          proximo
+
|E||Conjunção|| aprovado <- NOT (conceito = "D") E (faltas <= 0.25)
      proximo
+
|-
     
+
|OU||Disjunção|| reprovado <- (conceito = "D") OU (faltas > 0.25)
      //impressão da matriz
+
|-
      para i de 0 ate 1 passo 1
+
|XOU||Disjunção exclusiva|| erro <- enviado XOU recebido
          para j de 0 ate 3 passo 1
+
|}
              escrever "O valor na linha: ",i, "Coluna: ", j, "eh: ", mat[i][j]
 
              escrever "\n"
 
          proximo
 
      proximo
 
fim
 
</syntaxhighlight>
 
  
Veja que a matriz ''M'' foi declarada sem valores iniciais, porém a matriz ''A'' foi inicializada na declaração.
+
Precedência dos operadores (nesta ordem): NAO, E, OU e XOU
  
O acesso aos elementos da matriz se faz usando-se ''índices'', que funcionam como coordenadas dos elementos que se quer acessar. Os índices iniciam em ''0'':
+
Lembre que a precedência pode ser modificada com o uso de parênteses.
  
<syntaxhighlight lang=text>
+
==03/10: Exercícios estruturas de decisão==
  # índice 0,0
+
* Prof. Tiago ausente, participação na 10 ERRC =)
  escrever "Valor de A[0][0]: ", A[0][0], "\n"
+
* Resolvam os exercícios, aproveitem o tempo em sala. Os exercícios serão cobrados e vistos na próxima aula.
</syntaxhighlight>
 
  
O exemplo acima pode ser reescrito usando-se estruturas de repetição:
+
===Atividades para serem desenvolvidas em sala no dia 04/10:===
  
<syntaxhighlight lang=text>
+
# Faça um programa que leia um número e então informe se ele é par ou ímpar.
inicio
+
# Um radar de trânsito faz a medição de velocidade de veículos e, dependendo do valor, calcula a multa a ser aplicada. Em uma determinada via esse radar foi configurado da seguinte forma:
  inteiro A[2][2] <- {{1, 6}, {3, 5}}
+
#* Se a velocidade for maior que 80 km/h, a multa é de R$ 360.
  inteiro v[5] <- {1, 6, 2, 18, 5}
+
#* Se a velocidade for maior que 60 km/h, a multa é de R$ 180.
  inteiro i, j
+
#* Se a velocidade for menor ou igual a 60 km/h, não há multa.<br><br>Escreva um algoritmo que calcule a multa de acordo com a velocidade de um veículo.
 +
# Faça um algoritmo que leia três números do teclado, e mostre o maior e menor números.
 +
#O objetivo  de um  estudo médico feito entre os anos 70 e 80 foi o desenvolvimento de um método para identificar pacientes de alto risco (que não sobreviverão ao menos 30 dias) com  base nos dados obtidos nas primeiras 24 horas. O diagrama abaixo mostra uma regra de classificação que foi produzida nesse estudo. A letra F  significa que não há um risco alto, e a letra G quer dizer paciente de alto risco.[[imagem:Crt-decisao.png]]
  
  enquanto i < 2 faz
+
Essa regra classifica os pacientes como F ou G dependendo de respostas do tipo sim/não a no máximo três perguntas. Como  seria um algoritmo que a implementasse ? Escreva um  algoritmo  que faça o teste de risco de paciente cardíaco de um paciente, conforme descrito acima.
    j <- 0
+
# Um estudo sobre sensibilidade de pessoas a temperaturas da água identificou que a maioria das pessoas considera fria a água com temperaturas abaixo de 25 graus, morna entre 25 e 30 graus, e quente acima de 30 graus. Escreva um algoritmo que mostre as palavras "fria", "morna" ou "quente" dependendo da temperatura da água que for informada.
    enquanto j < 2 faz
+
# Em uma rede de computadores, o ''firewall'' restringe o acesso a Internet dependendo do horário e do tipo de usuário que faz o acesso. Os tipos de usuário abaixo têm as seguintes restrições:
      escrever "Valor do elemento de A na posição ", i, ", ", j, ": ", A[i][j], "\n"
+
#* Funcionário: apenas entre 0:00 e 7:30, entre 18:30 e 0:00, e entre 12:00 e 13:30
      j <- j + 1
+
#* Financeiro: qualquer horário
    fimenquanto
+
#* Diretoria: qualquer horário<br>Escreva um algoritmo que informe se um acesso foi permitido, em função do horário e do tipo de usuário.
    i <- i + 1
+
# Modifique o algoritmo acima para adicionar a seguinte restrição:
  fimenquanto
+
#* Funcionário: não pode acessar sites de jornal (ex: www.rbs.com.br)
 
+
#* Financeiro: não pode acessar sites de jornal durante o expediente
  i <- 0
+
#* Diretoria: sem restrições a sites
  enquanto i < 5 faz
+
# Faça um algoritmo para fazer a divisão de dois números reais. Antes de dividi-los deve ser feito um teste de validade. Caso não seja possível dividi-los, deve ser mostrada uma mensagem de erro. Se for possível, deve-se mostrar o resultado da divisão.
    escrever "valor de v na posição ", i, ": ", v[i], "\n"
+
# Faça um jogo de par ou ímpar, em que o jogador aposta contra o computador. O jogador deve digitar um número entre 0 e 5 e optar entre par ou ímpar. O computador deve sortear um número também entre 0 e 5. Se a paridade da soma dos números do jogador e do computador for a mesma que o jogador optou, então ele ganha a partida, senão o computador vence.
    i <- i + 1
+
# Escreva um algoritmo para identificar se há, dentre três palavras lidas do teclado, ao menos duas palavras distintas que pertençam ao conjunto {azul, preto, vermelho}. Exemplos:
  fimenquanto
+
#* Se o usuário digitar ''verde'', ''preto'', ''vermelho'', o programa deve mostrar na tela ''verdadeiro''
 
+
#* Se o usuário digitar ''verde'', ''preto'', ''preto'', o programa deve mostrar na tela ''falso''
fim
+
#* Se o usuário digitar ''azul'', ''preto'', ''azul'', o programa deve mostrar na tela ''verdadeiro''
</syntaxhighlight>
 
  
Como se vê, matrizes e vetores casam perfeitamente com estruturas de repetição, e são úteis para a resolução de inúmeros problemas. Por exemplo, o problema de mostrar o nome do mês a partir do número do mês, feito anteriormente com ''escolhe ... caso'' pode ser feito assim com um vetor:
+
===Solução Exercício 3 proposto:===
  
 
<syntaxhighlight lang=text>
 
<syntaxhighlight lang=text>
 +
 
inicio
 
inicio
  texto nome_mes[12] <- {"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro",  
+
    inteiro num<-0,maior<-0,menor<-0, i<-0
                        "Outubro", "Novembro, "Dezembro"}
+
    constante inteiro valores<-2 //declaração da constante
   inteiro dia, mes, ano
+
   
 
+
    escrever "Digite um valor: \n"
 +
    ler num
 +
    maior <- num
 +
    menor <- num
 +
    para i de 1 até valores passo 1
 +
        ler num
 +
        se (num > maior) então
 +
            maior <- num
 +
        fimse
 +
        se (num < menor) então
 +
            menor <- num
 +
        fimse
 +
    proximo
 +
    escrever "O maior valor digitado é: ", maior
 +
    escrever "\n"
 +
    escrever "O menor valor digitado é: ", menor
 +
fim
 +
 
 +
</syntaxhighlight>
 +
 
 +
==07/10: Estruturas de decisão==
 +
 
 +
Há situações em que se precisa fazer um conjunto de comparações, como mostrado abaixo:
 +
 
 +
<syntaxhighlight lang=text>
 +
// Lê a data no formato numérico dia, mes, ano, e mostra a data no formato
 +
// dia, nome do mês, ano.
 +
Inicio
 +
   inteiro dia, mes, ano
 +
  texto nome_mes
 +
 
 
   escrever "Dia: "
 
   escrever "Dia: "
 
   ler dia
 
   ler dia
Linha 1 081: Linha 1 006:
 
   ler ano
 
   ler ano
  
   escrever dia, " de ", nome_mes[mes], " de ", ano
+
   se mes = 1 entao
fim
+
    nome_mes <- "Janeiro"
</syntaxhighlight>
+
  senao
 
+
    se mes = 2 entao
Outro problema comum é precisar guardar um conjunto de valores, e depois ordená-los:
+
      nome_mes <- "Fevereiro"
 
+
    senao
<syntaxhighlight lang=text>
+
      se mes = 3 entao
inicio
+
        nome_mes <- "Março"
  inteiro v[10]
+
      senao
  inteiro i
+
        se mes = 4 entao
  inteiro quantidade
+
          nome_mes <- "Abril"
 
+
        senao
  escrever "Quantos valores serão digitados (máximo = 10) ? "
+
          se mes = 5 entao
  ler quantidade
+
            nome_mes <- "Maio"
 
+
          senao
  i <- 0
+
            se mes = 6 entao
  enquanto i < quantidade faz
+
              nome_mes <- "Junho"
    escrever "valor ", i, ": "
+
            senao
    ler v[i]
+
              se mes = 7 entao
     i <- i + 1
+
                nome_mes <- "Julho"
   fimenquanto
+
              senao
 +
                se mes = 8 entao
 +
                  nome_mes <- "Agosto"
 +
              senao
 +
                  se mes = 9 entao
 +
                    nome_mes <- "Setembro"
 +
                  senao
 +
                    se mes = 10 entao
 +
                      nome_mes <- "Outubro"
 +
                    senao
 +
                      se mes = 11 entao
 +
                        nome_mes <- "Novembro"
 +
                      senao
 +
                        se mes = 12 entao
 +
                            nome_mes <- "Dezembro"
 +
                        fimSe
 +
                    fimSe
 +
                  fimSe
 +
                fimSe
 +
              fimSe
 +
            fimSe
 +
          fimSe
 +
        fimSe
 +
      fimSe
 +
     fimSe
 +
   fimSe
  
  // ordena os valores ...
+
   escrever dia, " de ", nome_mes, " de ", ano
 
 
   escrever "valores ordenados: "
 
  i <- 0
 
  enquanto i < quantidade
 
    escrever v[i], " "
 
    i <- i + 1
 
  fimenquanto
 
 
fim
 
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== Atividades ===
+
Além de ser trabalhoso esse encadeamento de ''Se ... entao ... senao'', o algoritmo resultante fica pouco legível. Quer dizer, ele fica feio e difícil de entender.
  
# Escreva um algoritmo que leia 5 números do teclado, e depois mostre-os em ordem inversa à que foi digitada.
+
Existe uma estrutura de decisão criada justamente para casos como esse, e que resulta em um algoritmo mais limpo e compreensível:
# Escreva um algoritmo que leia dois vetores de 5 números, e depois mostre se os vetores são iguais.
+
 
# Escreva um algoritmo que leia um palavra do teclado e depois procure-a numa lista de palavras preexistente. Essa lista deve ser implementada usando um vetor.
+
<syntaxhighlight lang=text>
# Escreva um algoritmo que leia 5 números, e mostre-os em ordem crescente.
+
// Lê a data no formato numérico dia, mes, ano, e mostra a data no formato
# Modifique o algoritmo anterior para mostrá-los em ordem decrescente.
+
// dia, nome do mês, ano.
# Em um  jogo de bingo devem-se contar quantos números de uma aposta foram sorteados no bingo. Faça um algoritmo que, dados os números sorteados e uma aposta, conta quantos números apostados forma sorteados.
+
Inicio
 +
  inteiro dia, mes, ano
 +
  texto nome_mes
  
=== Solução exercício 4 e 6 propostos pelo Luiz Gustavo===
+
  escrever "Dia: "
 +
  ler dia
 +
  escrever "Mes: "
 +
  ler mes
 +
  escrever "Ano: "
 +
  ler ano
  
<code>
+
  Escolhe mes
inicio
+
     caso 1:
    //declaração da variáveis
+
      nome_mes <- "Janeiro"
    inteiro v [ 5 ] , i , j , troca
+
    caso 2:
     //entrada de dados
+
      nome_mes <- "Fevereiro"
    para i de 0 ate 4 passo 1
+
     caso 3:
        ler v [ i ]
+
      nome_mes <- "Março"
    proximo
+
     caso 4:
    //organizar em ordem crescente
+
      nome_mes <- "Abril"
    para i de 0 ate 4 passo 1
+
     caso 5:
        para j de 0 ate 4 passo 1
+
      nome_mes <- "Maio"
            se v [ i ] > v [ j ] entao
+
    caso 6:
                troca <- v [ i ]
+
      nome_mes <- "Junho"
                v [ i ] <- v [ j ]
+
    caso 7:
                v [ j ] <- troca
+
      nome_mes <- "Julho"
            fimse
+
     caso 8:
        proximo
+
      nome_mes <- "Agosto"
    proximo
+
     caso 9:
    //impressão dos dados
+
      nome_mes <- "Setembro"
    para i de 0 ate 4 passo 1
+
    caso 10:
        escrever "\n" , v [ i ]
+
      nome_mes <- "Outubro"
     proximo
+
    caso 11:
fim
+
      nome_mes <- "Novembro"
</syntaxhighlight>
+
    Defeito:
 
+
      nome_mes <- "Dezembro"
<code>
+
  fimEscolhe
inicio
+
 
     //declaração das variáveis
+
  escrever dia, " de ", nome_mes, " de ", ano
    inteiro lista_num [5][5] <- {{10, 5, 20, 31, 33}, {51, 12, 13, 15, 29}, {25, 28, 22, 26, 36},
+
fim
{11, 24, 34, 54, 44}, {1, 2, 55, 3, 5}}
+
</syntaxhighlight>
    inteiro numero [5][5],i,j,cont
+
 
    //entrada de dados
+
A estrutura de decisão ''escolhe ... caso'' tem uma certa flexibilidade. No exemplo abaixo, mostra-se a possibilidade de testar mais de um valor no mesmo ''caso'':
    escrever "Informe os números do Bingo: "
+
 
     enquanto i < 5 faz
+
<syntaxhighlight lang=text>
        j <- 0
+
inicio   
        enquanto j < 5 faz
+
  caracter sexo   
            ler numero [ i ] [ j ]
 
            j <- j + 1
 
        fimenquanto
 
        i <- i + 1
 
     fimenquanto
 
    //verificando quantos números são iguais
 
    i <- 0
 
     enquanto i < 5 faz
 
        j <- 0
 
        enquanto j < 5 faz
 
            se (numero [i][j] = lista_num [i][j]) entao
 
                cont <- cont + 1
 
            fimse
 
            j <- j + 1
 
        fimenquanto
 
        i <- i + 1
 
    fimenquanto
 
    //Imprimindo os dados
 
    escrever "A quantidade de números sorteados nesta aposta foi: " , cont
 
fim
 
</syntaxhighlight>
 
  
== 06/05: Revisão para avaliação de Lógica de Programação ==
+
  escrever "Qual o seu sexo (f/m):"   
 +
  ler sexo   
  
1. Crie um programa que lê três inteiros e informa '''VERDADEIRO''' se apenas o maior deles é par ou se o menor deles é ímpar ou informa '''FALSO''' em caso contrário.
+
  escrever "Olá "   
  
2. Desenvolva um programa que recebe do usuário o placar de um jogo de futebol (os gols de cada time) e informa se o resultado foi um empate, a vitória do primeiro time ou do segundo time.
+
  escolhe sexo       
 +
    caso "m", "M" :           
 +
      escrever "senhor"       
 +
    caso "f","F" :           
 +
      escrever "senhorita"       
 +
    defeito :           
 +
      escrever "Sexo indefinido"   
 +
  fimescolhe   
  
3. Elabore um programa que recebe do usuário três cadeias de caracteres e informa VERDADEIRO se há pelo menos duas diferentes cadeias iguais aos valores 'azul', 'preto'ou 'vermelho' ou FALSO em caso contrário. Exemplos: {'azul', 'preto', 'branco'} é VERDADEIRO; {'azul', 'roxo', 'azul'} é FALSO; {'preto', vermelho', 'vermelho'} é VERDADEIRO.
+
  escrever ", benvindo ao portugol"
 +
fim
 +
</syntaxhighlight>
 +
 
 +
=== Atividades ===
 +
 
 +
# Faça um algoritmo que converta um número de 1 a 7 para o respectivo dia da semana (ex: 1 = domingo, 2 = 2a feira, e assim por diante).
 +
# Faça uma calculadora com as quatro operações aritméticas. Sua calculadora deve ler (nesta ordem) o primeiro número, a operação aritmética (que deve ser informada usando o símbolo da respectiva operação: +, -, * ou /), e depois o segundo número. Ao final, seu algoritmo deve mostrar o resultado, ou uma mensagem de erro se a operação não for possível de realizar (ex: divisão por zero).
 +
# A previsão do tempo na costa brasileira pode ser feita de forma aproximada usando-se um barômetro e um termômetro. Uma estimativa com boa chance de acerto se baseia na tabela abaixo: <br>[[imagem:Previsao-barometro.png|800px]]<br><br>Faça um algoritmo que forneça uma estimativa da previsão do tempo, usando essa tabela.
 +
# Faça um algoritmo que mostre qual o último dia de um determinado mês informado pelo teclado. Caso seja informado o mês 2 (fevereiro), seu algoritmo deve identificar se é ano bissexto (assim o mês tem 29 dias), ou não (mês tem 28 dias). Obs: anos bissextos são dados pelas regras (segundo o calendário Gregoriano):
 +
## De 4 em 4 anos é ano bissexto.
 +
## De 100 em 100 anos não é ano bissexto.
 +
## De 400 em 400 anos é ano bissexto.
 +
## Prevalecem as últimas regras sobre as primeiras.
 +
 
 +
==12/10: Feriado Nacional ==
 +
* Feriado Nacional
  
4. Tendo-se como dados de entrada a altura e o sexo de uma pessoa, construa um algoritmo que calcule seu peso ideal, utilizando as seguintes fórmulas:
+
==14/10: Estruturas de repetição==
#* para homens: (72,7 * h) – 58;
 
#* para mulheres: (62,1 * h) – 44,7.
 
  
5. Escrever um algoritmo, que leia um conjunto de 23 dados, cada um, contendo o peso e o código do sexo ("F" ou "M") dos alunos de uma classe, calcule e imprima:
+
Páginas da apostila: 32 a 35.
#* Maior e o menor peso da turma;
 
#* A média de peso dos homens;
 
#* A média de peso da turma;
 
  
Solução proposta pelo Manfred Ex. 1
+
Alguns algoritmos vistos anteriormente possuem sequências repetitivas de instruções. Por exemplo, o algoritmo da média de quatro avaliações:
  
<code>
+
<syntaxhighlight lang=text>
inicio
+
Inicio
    inteiro n1 <- 0 , n2 <- 0 , n3 <- 0 , maior <- 0 , menor <- 0
+
  real m1, m2, m3, m4
    escrever "Digite o primeiro número: "
+
  real media
    ler n1
 
    escrever "Digite o segundo número: "
 
    ler n2
 
    escrever "Digite o terceiro número: "
 
    ler n3
 
    maior <- n1
 
    se ( n2 > maior ) entao
 
        maior <- n2
 
    fimse
 
    se ( n3 > maior ) entao
 
        maior <- n3
 
    fimse
 
    menor <- n1
 
    se ( n2 < menor ) entao
 
        menor <- n2
 
    fimse
 
    se ( n3 < menor ) entao
 
        menor <- n3
 
    fimse
 
    se ( maior % 2 ) = 0 ou ( menor % 2 ) =/= 0 entao
 
        escrever "Verdadeiro"
 
    senao
 
        escrever "Falso"
 
    fimse
 
fim
 
  
 
+
  escrever 'Avaliação 1:'
</syntaxhighlight>
+
  Ler m1
 
+
  escrever 'Avaliação 2:'
Proposta do Luiz para exercício 5
+
  Ler m2
 +
  escrever 'Avaliação 3:'
 +
  Ler m3
 +
  escrever 'Avaliação 4:'
 +
  Ler m4
 +
 
 +
  media <- (m1 + m2 + m3 + m4) / 4
 +
 
 +
  escrever 'Média: ', media
 +
Fim
 +
</syntaxhighlight>
 +
 
 +
O algoritmo acima repete quatro vezes a sequência que lê uma nota do teclado. Porém há uma forma de expressar a repetição de sequências de instruções, usando-se o que se chama de ''estrutura de repetição''. A estrutura de repetição '''''enquanto''''' ''condição'' '''''faz''''' repete todas as instruções enquanto a condição for verdadeira. A condição é escrita como uma expressão lógica, da mesma forma que na estrutura de decisão '''''se''''' ''condição'' '''''então ... senão'''''. Veja como fica o algoritmo acima ao ser reescrito para usar essa estrutura de repetição:
  
 
<syntaxhighlight lang=text>
 
<syntaxhighlight lang=text>
inicio
+
Inicio
    //declaração das variaveis
+
  constante inteiro NUMEROS <- 4
    real peso [ 5 ] <- 0 , menor <- 0 , maior <- 0 , pesom <- 0 , pesot <- 0
+
  real m
    inteiro i , cont <- 0
+
  real media
    caracter sexo [ 5 ]
+
  inteiro contador <- 0
    //entrada de dados
+
 
     para i de 0 ate 4 passo 1
+
  enquanto contador < NUMEROS faz 
        escrever "Informe o peso do " , ( i + 1 ) , "º aluno: "
+
     escrever 'Avaliação ', contador, ':'
        ler peso [ i ]
+
    ler m
        escrever "Informe o código do sexo do " , ( i + 1 ) , "º aluno (Masculino= M; Feminino= F): "
+
     media <- media + m
        ler sexo [ i ]
+
     contador <- contador + 1
        escrever "\n"
+
  fimEnquanto
     proximo
+
 
    //testando o maior e menor peso
+
  escrever 'Média: ', media/NUMEROS
    maior <- peso [ 1 ]
+
Fim
     menor <- peso [ 1 ]
+
</syntaxhighlight>
    para i de 0 ate 4 passo 1
+
 
        se ( peso [ i ] > maior ) entao
+
Esse algoritmo funciona somente para médias de quatro números. Porém calcular a média de qualquer quantidade de números usa a mesma lógica: ler os números, somá-los e dividir o total pela quantidade de números lidos. Por exemplo, para fazer com que ele calcule a média de 7 números é necessário escrevê-lo assim:
            maior <- peso [ i ]
+
 
        fimse
+
<syntaxhighlight lang=text>
        se ( peso [ i ] < menor ) entao
+
Inicio
            menor <- peso [ i ]
+
  constante inteiro NUMEROS <- 7
        fimse
+
  real m
    proximo
+
  real media
    //calculando a media de peso dos homens
+
  inteiro contador <- 0
    para i de 0 ate 4 passo 1
+
 
        se ( sexo [ i ] = "M" ) ou ( sexo [ i ] = "m" ) entao
+
  enquanto contador < NUMEROS faz 
            pesom <- ( pesom + peso [ i ] )
+
     escrever 'Avaliação ', contador, ':'
            cont <- ( cont + 1 )
+
    ler m
        fimse
+
     media <- media + m
    proximo
+
     contador <- contador + 1
    //calculando a media de peso da turma
+
  fimEnquanto
    para i de 0 ate 4 passo 1
+
 
        pesot <- ( peso [ i ] + pesot )
+
  escrever 'Média: ', media/NUMEROS
    proximo
+
Fim
    //impressão dos dados
 
     escrever "\nO maior peso é: " , maior , "\nO menor peso é: " , menor
 
     escrever "\nA média de peso dos homens é: " , ( pesom / cont )
 
     escrever "\nA média de peso da turma é: " , ( pesot / 5 )
 
fim
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
== 07/05: Revisão Lógica de Programação, com respostas :) ==
+
Note que o algoritmo praticamente não foi modificado, pois somente se alterou o valor da constante NUMEROS.
  
1. Desenvolver um programa que efetue a leitura de 5 elementos de uma matriz A do tipo vetor. Construir uma matriz B de mesmo tipo, observando a seguinte lei de formação: Se o valor do índice for par, o valor deverá ser multiplicado por 5, sendo ímpar deverá ser somado por 5. Ao final mostrar os conteúdos das duas matrizes.
+
A estrutura de repetição junto com a sequência de instruções a ser repetida é comumente chamada de '''laço''. Assim, no algoritmo acima o laço aparece em:
  
 +
<syntaxhighlight lang=text>
 +
  enquanto contador < NUMEROS faz 
 +
    escrever 'Avaliação ', contador, ':'
 +
    ler m
 +
    media <- media + m
 +
    contador <- contador + 1
 +
  fimEnquanto
 +
</syntaxhighlight>
 +
 +
----
 +
 +
Um outro exemplo ainda mais simples é mostrar na tela uma contagem numérica:
  
<code>
+
<syntaxhighlight lang=text>
 
 
 
inicio
 
inicio
      //declaração dos vetores A e B
+
    inteiro contador
inteiro i,a[5],b[5]
+
     contador <- 0
      
+
 
      //formação do vetor A
+
    enquanto contador < 10 faz
      para i de 0 ate 4 passo 1
+
        escrever contador , " "
          ler a[i]
+
        contador <- contador + 1
      proximo
+
    fimenquanto
     
+
fim
      //guarda valor na posição par
+
</syntaxhighlight>
      para i de 0 ate 4 passo 2
+
 
          b[i]<-a[i]*5
+
Ao executar esse algoritmo, tem-se como resultado:
      proximo
+
 
     
+
<syntaxhighlight lang=text>
      //guarda valor na posição ímpar
+
0 1 2 3 4 5 6 7 8 9
      para i de 1 ate 4 passo 2
 
          b[i]<-a[i]+5
 
      proximo
 
     
 
      //apresenta valor B resposta
 
      escrever "Formação do vetor B (vetor respota):"
 
      escrever "\n"
 
     
 
      para i de 0 ate 4 passo 1
 
          escrever "O valor da posição ",i, " é: ", b[i]
 
          escrever "\n"
 
      proximo
 
fim
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Solução para o exercício 1 desenvolvida pelo Thiarlles e Manfred:
+
Repare no uso de uma variável auxiliar ''contador'' para controlar a quantidade de repetições. Essa é uma técnica comum para
 +
controlar a estrutura de repetição, e já foi usada no exemplo da média. Ela pode também ser combinada com outras condições, como mostrado abaixo:
  
<code>
+
<syntaxhighlight lang=text>
 
inicio
 
inicio
real matrizA[10], matrizB[10] 
+
    inteiro contador <- 1
          inteiro i<-0
+
    caracter opcao <- "s"
          escrever "\n Construa a matriz A."
+
       
          enquanto i <= 9 faz
+
    enquanto ((opcao = "s") ou (opcao = "S")) e contador < 11 faz
              escrever  "\n Entre com a posição ", i
+
        escrever contador, "\n"
              ler matrizA[i]
+
        contador <- contador + 1
              i <- i+1
+
       
          fimEnquanto
+
        escrever "\nContinuar (S/N) ? "
          i <- 0
+
        ler opcao
          enquanto i <= 9 faz  
+
    fimenquanto
              escrever matrizA[i], " "
+
   
              i <- i+1  
+
    escrever "Terminou com contador = " , contador
          fimEnquanto 
 
          escrever "\n "
 
          i <- 0
 
          enquanto i <= 9 faz
 
              matrizB[i] <- ((matrizA[i])*5)
 
              matrizB[i+1] <- ((matrizA[i+1])+5)
 
              i <- i+2
 
          fimEnquanto
 
          i <- 0
 
          escrever "\n A matriz B será: "
 
          enquanto i <= 9 faz
 
              escrever matrizB[i], "  "
 
              i <- i+1
 
          fimenquanto
 
 
fim
 
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
  
2. Desenvolver um programa que efetue a leitura de 5 elementos de uma matriz A do tipo vetor. No final, apresente o total da soma de todos os elementos que sejam ímpares.
+
Nesse exemplo se usa um laço para mostrar uma contagem de 1 a 10. Porém há a possibilidade de encerrar o algoritmo. Observe a condição para continuidade do laço: ela é verdadeira somente se ''contador < 11'' e se a variável ''opcao'' for igual a "s" ou "S".
  
<code>
+
Finalmente, apesar de ser comum o uso de contadores para controle do laço, pode-se usar qualquer condição para essa finalidade. Então podem existir laços que não usam contadores para controlar a quantidade de repetições, como no próximo exemplo:
 +
 
 +
<syntaxhighlight lang=text>
 
inicio
 
inicio
     //declaração das variáveis
+
     constante texto segredo <- "secreto"
    inteiro a [5] , i , soma <- 0
+
     texto senha
     //entrada de dados
+
      
     para i de 0 ate 4 passo 1
+
    ler senha
        ler a [i]
+
     enquanto senha =/= segredo faz
     proximo
+
        escrever "Voce continua preso ! Digite a senha correta: "
    //construindo a matriz "B"
+
         ler senha
    para i de 0 ate 4 passo 1
+
     fimenquanto
        se ( a [i] % 2 =/= 0 ) entao
+
     escrever "Voce foi liberado ..."
            soma <- soma + a [ i ]
 
         fimse
 
     proximo
 
    //impressão dos dados
 
     escrever "O valor da soma dos numero ímpares é: " , soma
 
 
fim
 
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
  
3. Ler 15 elementos de uma matriz A do tipo vetor. Construir uma matriz B de mesmo tipo. Observando a seguinte lei de formação: “Todo elemento de B deverá ser o quadrado do elemento de A correspondente”.
+
=== Solução do problema proposto em sala)===
  
 
<code>
 
<code>
 
inicio
 
inicio
     //declaração das variáveis
+
     inteiro opcao <- 0
     inteiro a[15] ,b[15] ,i
+
     real numero1 <- 0 , numero2 <- 0 , resultado <- 0
     //entrada de dados
+
     enquanto opcao =/= 5 faz
    para i de 0 ate 14 passo 1
+
        escrever "\n Entre com a opção desejada: 1- Adição; 2- Subtração; 3- Multiplicação; 4- Divisão , 5- Sair."
         ler a[i]
+
         ler opcao
    proximo
+
        se opcao = 5 entao
    //construindo a matriz "B"
+
            escrever "\n Você saiu com sucesso!"
    para i de 0 ate 14 passo 1
+
        senao
        b[i] <- a[i] * a[i]
+
            escrever "\n Lembre-se: Na subtração e na divisão a ordem dos números é importante!"
    proximo
+
            escrever "\n Entre com o primeiro número: "
    //impressão dos dados
+
            ler numero1
    escrever "\nMatriz A:"
+
            escrever "\n Entre com o segundo número: "
    para i de 0 ate 14 passo 1
+
            ler numero2
        escrever "" , a[i]
+
            se opcao = 1 entao
    proximo
+
                resultado <- ( numero1 + numero2 )
    escrever "\nMatriz B:"
+
                escrever "\n A soma dos dois números é: " , resultado
    para i de 0 ate 14 passo 1
+
            fimse
        escrever "" , b [i]
+
            se opcao = 2 entao
     proximo
+
                resultado <- ( numero1 - numero2 )
fim
+
                escrever "\n A subtração dos dois números é: " , resultado
 +
            fimse
 +
            se opcao = 3 entao
 +
                resultado <- ( numero1 * numero2 )
 +
                escrever "\n O produto dos dois números é: " , resultado
 +
            fimse
 +
            se opcao = 4 entao
 +
                se numero2 = 0 entao
 +
                    escrever "\n Não existe divisão por 0 (zero)."
 +
                senao
 +
                    resultado <- ( numero1 / numero2 )
 +
                    escrever "\n A divisão dos dois números é: " , resultado
 +
                fimse
 +
            fimse
 +
            se ( opcao =/= 1 e opcao =/= 2 ) e ( opcao =/= 3 e opcao =/= 4 ) entao
 +
                escrever "\n Esta operação não está definida."
 +
            fimse
 +
        fimse
 +
     fimenquanto
 +
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
  
4. Escreva um algoritmo que:
+
=== Atividades ===
#*Leia uma matriz 5 x 5 de elementos reais;
 
#* Divida cada elemento de uma linha da matriz pelo elemento da diagonal principal desta linha;
 
#* Imprima a matriz assim modificada.
 
  
<code>
+
# Escreva um  algoritmo que mostre a tabuada de um número fornecido pelo teclado. Esse número deve estar entre 1 e 10.
inicio
+
# Modifique o exemplo da média para que a quantidade de números a serem lidos seja previamente informada pelo teclado.
    //declaração das variáveis
+
# Modifique novamente o exemplo da média para que ela funcione para um quantidade de números desconhecida de antemão. Quer dizer, o algoritmo deve ler os números para calcular a média, mas não sabe quantos números existem (e isto não pode ser informado pelo teclado).
    real a [5] [5] , b [5] [5]
+
# Modifique o exemplo da senha para que o usuário tenha somente três tentativas permitidas para digitar a senha correta. caso ao final as três senhas estejam erradas, o algoritmo deve informar que a conta foi bloqueada.
    inteiro i , j
+
# Escreva um algoritmo que leia até 10 números do teclado, e informe ao final qual o maior e o menor deles.
    //entrada de dados
+
# Escreva um algoritmo que teste se um número informado pelo teclado é primo.
    para i de 0 ate 4 passo 1
 
        para j de 0 ate 4 passo 1
 
            ler a [i] [j]
 
        proximo
 
    proximo
 
    //dividindo a linha da matriz por sua diagonal principal
 
    para i de 0 ate 4 passo 1
 
        para j de 0 ate 4 passo 1
 
            b [i] [j] <- ( a [i] [j] / a [i] [i] )
 
        proximo
 
    proximo
 
    //impressão dos dados
 
    escrever "\nMatriz: "
 
    escrever "\n"
 
    para i de 0 ate 4 passo 1
 
        escrever "\n" , a [i] [0] , " " , a [i] [1] , " " , a [i] [2] , " " , a [i] [3] , " " , a [i] [4]
 
    proximo
 
    escrever "\n\nMatriz modificada: "
 
    escrever "\n"
 
    para i de 0 ate 4 passo 1
 
        escrever "\n" , b [i] [0] , " " , b [i] [1] , " " , b [i] [2] , " " , b [i] [3] , " " , b [i] [4]
 
    proximo
 
fim
 
</syntaxhighlight>
 
  
5. Elabore um algoritmo para corrigir provas de múltipla escolha. Assuma que em cada prova encontraremos os seguintes dados: RM, NOME DO ALUNO, MATÉRIA e BIMESTRE, além de 10 questões numeradas de 1 até 10 e que cada questão possui 5 alternativas identificadas pelas letras de “a” até “e”. Primeiramente, o algoritmo deve ler o gabarito e o número de provas a serem corrigidas . A seguir, os dados das provas a serem corrigidas devem ser lidas. Ainda, o algoritmo deverá calcular e escrever:
+
==18/10: Estruturas de repetição==
 +
* Resolução de exercícios
 +
* Introdução a variáveis multidimencionais
 +
 
 +
==21/10: Estruturas de repetição==
 +
 
 +
=== Variáveis multidimensionais ===
 +
 
 +
Em matemática existem matrizes e vetores, que são variáveis multidimensionais. Por exemplo, uma matriz 3 x 3 (3 linhas e 3 colunas) pode ser:
 +
 
 +
<math>A = \begin{pmatrix}
 +
1 & 6 \\
 +
3 & 5
 +
\end{pmatrix}</math>
 +
 
 +
Vetores são matrizes unidimensionais, portanto possuem somente uma linha ou uma coluna:
  
#* O RM, NOME DO ALUNO, MATÉRIA, BIMESTRE e a NOTA de cada aluno (assumindo que cada questão correta vale 1 ponto).
+
<math>v = \begin{pmatrix}
#* A porcentagem de aprovação, assumindo que a nota mínima para aprovação é 6.
+
1 & 6 & 2 & 18 & 5
 +
\end{pmatrix}</math>
  
<code>
+
Cada elemento em uma matriz ou vetor é identificado pela sua posição. Por exemplo, na posição ''1, 2'' da matriz A acima está o valor 6, e na posição ''4'' do vetor ''v'' está o valor 18. Assim, a matriz A do exemplo pode ser entendida da seguinte forma:
inicio
+
 
    //declaração das variáveis
+
<math>A = \begin{pmatrix}
    caracter gab [10] , resp [10]
+
A_{11} & A_{12} \\
    inteiro i , qtdprova , cont <- 0 , aprovados <- 0
+
A_{21} & A_{22}
    real nota <- 0
+
\end{pmatrix}</math>
    texto rm <- "" , aluno <- "" , mat <- "" , bimestre <- ""
+
 
   
+
... e o vetor ''v'' do exemplo:
    //entrada de dados
+
 
    para i de 0 ate 9 passo 1
+
<math>v = \begin{pmatrix}
        escrever "Informe o gabarito da " , (i + 1) , "ª questão:"
+
v_{1} & v_{2} & v_{3} & v_{4} & v_{5}
        ler gab [i]
+
\end{pmatrix}</math>
    proximo
+
 
   
+
Nas linguagens de programação em geral existe um conceito muito parecido, chamado de variáveis multidimensionais ou simplesmente ''matrizes'' (''arrays'' em inglẽs). Para exemplificar, no Portugol se poderiam definir a matriz ''A'' e o vetor ''v'':
    escrever "Informe a quantidade de provas: "
+
 
    ler qtdprova
+
<syntaxhighlight lang=text>
   
+
inicio
    //dados das provas
+
  inteiro A[2][2] <- {{1, 6}, {3, 5}}
    enquanto cont < qtdprova faz
+
  inteiro M[3][2];
        escrever "**************************************************"
+
  inteiro v[5] <- {1, 6, 2, 18, 5}
        escrever "\nInforme RM: "
+
  inteiro i, j
        ler rm
 
        escrever "Informe o nome do aluno: "
 
        ler aluno
 
        escrever "Informe a matéria: "
 
        ler mat
 
        escrever "Informe o bimestre: "
 
        ler bimestre
 
        //informando as respostas
 
        para i de 0 ate 9 passo 1
 
            escrever "Informe a resposta da " , (i + 1) , "ª questão:"
 
            ler resp [i]
 
        proximo
 
       
 
        //corrigindo a prova
 
        nota <- 0
 
        para i de 0 ate 9 passo 1
 
            se ( gab [i] = resp [i] ) entao
 
                nota <- nota + 1
 
            fimse
 
        proximo
 
       
 
        //informando a nota
 
        escrever "A nota do(a) " , aluno , " é: " , nota , "\n\n"
 
       
 
        //verificando aprovação do aluno
 
        se ( nota >= 6 ) entao
 
            aprovados <- ( aprovados + 1 )
 
        fimse
 
        cont <- ( cont + 1 )
 
    fimenquanto
 
   
 
    //imprimindo valores
 
    escrever "\n**************************************************"
 
    escrever "\nA quantidade de aprovados é: " , aprovados
 
fim
 
</syntaxhighlight>
 
  
== 13/05: Avaliação de Lógica de Programação (não será alterada) ==
+
  escrever "Valor de A[0][0]: ", A[0][0], "\n"
 +
  escrever "Valor de A[0][1]: ", A[0][1], "\n"
 +
  escrever "Valor de A[1][0]: ", A[1][0], "\n"
 +
  escrever "Valor de A[1][1]: ", A[1][1], "\n"
  
Dicas para a avaliação (vale a pena revisar conceitos):
+
  escrever "Valor de v[0]: ", v[0], "\n"
 +
  escrever "Valor de v[1]: ", v[1], "\n"
 +
  escrever "Valor de v[2]: ", v[2], "\n"
 +
  escrever "Valor de v[3]: ", v[3], "\n"
 +
  escrever "Valor de v[4]: ", v[4], "\n"
  
#* Números primos
+
fim
#* Fatorial
+
</syntaxhighlight>
#* MDC: Máximo Divisor Comum
 
#* MMC: Mínimo Múltiplo Comum
 
#* Cálculo para série de Fibonacci
 
  
== 14/05: Linguagem C ==
+
A declaração da matriz se faz como uma variável comum, porém indicando-se suas dimensões:
  
#* Introdução a linguagem C
+
<syntaxhighlight lang=text>
#* Primeiros Programas
+
  inteiro A[2][2] <- {{1, 6}, {3, 5}}
#* Compilador Gcc
+
  inteiro M[3][2];
 +
</syntaxhighlight>
  
* Para provocar: [http://norvig.com/21-days.html Teach Yourself Programming in Ten Years]
+
Exemplo de preenchimento e impressão de matrizes não quadradas
* Apostila adotada: [http://www.ead.cpdee.ufmg.br/cursos/C/c.html Curso de Linguagem C - Engenharia Elétrica -  UFMG]
 
  
==20/05: Projeto Final da Disciplina==
+
<syntaxhighlight lang=text>
===O jogo: Batalha Naval===
+
inicio
* Etapas de desenvolvimento:
+
inteiro i,j, mat[2][4]
#Desenha 1 onda
+
   
#Desenha 1 linha de ondas
+
      //leitura (preenchimento da matriz)
#Desenha 1 matriz de tamanho fixo de ondas
+
      para i de 0 ate 1 passo 1
#Desenha 1 matriz de tamanho variável de ondas (o usuário informa as dimensões)
+
          para j de 0 ate 3 passo 1
#Mapeia 1 barco: latitude e longitude (vetor)
+
              ler mat[i][j]
#Desenha o mar com 1 barco
+
          proximo
#Mapeia 10 barcos: latitude e longitude (matriz)
+
      proximo
#Desenha os 10 barcos
+
     
#Mapeia 10 barcos: latitude, longitude e se já foi atingido
+
      //impressão da matriz
#Pede ao usuário atirar
+
      para i de 0 ate 1 passo 1
#Se o barco foi atingido, desenhar um X
+
          para j de 0 ate 3 passo 1
#Ao final (todo os barcos atingidos): informar o usuário que venceu em 'n' movimentos
+
              escrever "O valor na linha: ",i, "Coluna: ", j, "eh: ", mat[i][j]
 
+
              escrever "\n"
* Proposta de código que contempla:
+
          proximo
** Bibliotecas e definições
+
      proximo
** Declaração de constantes e variáveis
+
fim
*** Uso de variáveis com mesmo nome e diferentes escopos
+
</syntaxhighlight>
*** Vetor e matriz
 
** Operadores lógicos e matemáticos
 
** Expressões
 
*** E/S
 
*** Estruturas de decisão e repetição
 
** Funções
 
*** Passagem de parâmetro por valor e por referência
 
** Acesso a uma matriz através de um vetor linear (função <tt>iniciaJogo</tt>)
 
** Ponteiros
 
  
===Introdução a Linguagem C===
+
Veja que a matriz ''M'' foi declarada sem valores iniciais, porém a matriz ''A'' foi inicializada na declaração.
  
=== Compilando o primeiro programa ===
+
O acesso aos elementos da matriz se faz usando-se ''índices'', que funcionam como coordenadas dos elementos que se quer acessar. Os índices iniciam em ''0'':
* O clássico ''Hello World!''
 
<syntaxhighlight lang=c n>
 
#include <stdio.h>
 
  
int main(int argc, char *argv[])
+
<syntaxhighlight lang=text>
{
+
  # índice 0,0
printf("Alô mundo!\n");
+
  escrever "Valor de A[0][0]: ", A[0][0], "\n"
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
* Mostrando mensagens de na tela: [http://manpages.ubuntu.com/manpages/karmic/en/man3/puts.3.html puts] e [http://manpages.ubuntu.com/manpages/karmic/en/man3/printf.3.html printf]: <syntaxhighlight lang=c n>
+
O exemplo acima pode ser reescrito usando-se estruturas de repetição:
#include <stdio.h>
 
  
int main() {
+
<syntaxhighlight lang=text>
   int n;
+
inicio
 +
  inteiro A[2][2] <- {{1, 6}, {3, 5}}
 +
  inteiro v[5] <- {1, 6, 2, 18, 5}
 +
   inteiro i, j
  
   n = 5;
+
   enquanto i < 2 faz
 
+
    j <- 0
  puts("Demonstração de puts e printf");
+
    enquanto j < 2 faz
 +
      escrever "Valor do elemento de A na posição ", i, ", ", j, ": ", A[i][j], "\n"
 +
      j <- j + 1
 +
    fimenquanto
 +
    i <- i + 1
 +
  fimenquanto
  
   printf("Valor de n: %d\n", n);
+
   i <- 0
 +
  enquanto i < 5 faz
 +
    escrever "valor de v na posição ", i, ": ", v[i], "\n"
 +
    i <- i + 1
 +
  fimenquanto
  
  n = n + 1;
+
fim
 
 
  printf("Novo valor de n: %d\n", n);
 
 
 
  return 0;
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
* Lendo dados do teclado: [http://manpages.ubuntu.com/manpages/karmic/en/man3/scanf.3.html scanf]<syntaxhighlight lang=c n>
 
#include <stdio.h>
 
  
int main() {
+
Como se vê, matrizes e vetores casam perfeitamente com estruturas de repetição, e são úteis para a resolução de inúmeros problemas. Por exemplo, o problema de mostrar o nome do mês a partir do número do mês, feito anteriormente com ''escolhe ... caso'' pode ser feito assim com um vetor:
  int n;
 
  
   printf("Digite um número inteiro: ");
+
<syntaxhighlight lang=text>
 +
inicio
 +
   texto nome_mes[12] <- {"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro",
 +
                        "Outubro", "Novembro, "Dezembro"}
 +
  inteiro dia, mes, ano
  
   scanf("%d", &n);
+
   escrever "Dia: "
 +
  ler dia
 +
  escrever "Mes: "
 +
  ler mes
 +
  escrever "Ano: "
 +
  ler ano
  
   printf("Valor digitado foi %d\n", n);
+
   escrever dia, " de ", nome_mes[mes], " de ", ano
 
+
fim
  return 0;
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
** Outras formas de ler do teclado: [http://manpages.ubuntu.com/manpages/karmic/man3/fgets.3.html getchar],  [http://manpages.ubuntu.com/manpages/karmic/en/man3/fgets.3.html fgets]
 
* Tipos de dados:
 
{| border="1" cellpadding="2"
 
!Portugol
 
!C
 
!Exemplo
 
|-
 
|inteiro||int|| int x;
 
|-
 
|caracter||char|| char letra;
 
|-
 
|real||float ou double|| float pi = 3.1416;
 
|-
 
|texto||char * ou vetor de char || char * mensagem = "Hello world";<br>char palavra[16];
 
|-
 
|logico||qualquer tipo (valor 0 = Falso, qualquer outro valor = Verdadeiro)||int ok = 1;<br>char teste = 0;
 
|}
 
  
=== Atividades ===
+
Outro problema comum é precisar guardar um conjunto de valores, e depois ordená-los:
  
* Traduza para C os seguintes algoritmos Portugol:
+
<syntaxhighlight lang=text>
1. <syntaxhighlight lang=text>
+
inicio
Inicio
+
  inteiro v[10]
   inteiro x, y
+
  inteiro i
+
   inteiro quantidade
   Escrever "Digite um numero: ",
+
 
   Ler x
+
  escrever "Quantos valores serão digitados (máximo = 10) ? "
   Escrever "Digite outro numero: ",
+
  ler quantidade
   Ler y
+
 
   Escrever "Soma = ", x+y
+
  i <- 0
Fim
+
   enquanto i < quantidade faz
 +
    escrever "valor ", i, ": "
 +
    ler v[i]
 +
    i <- i + 1
 +
   fimenquanto
 +
 
 +
   // ordena os valores ...
 +
 
 +
  escrever "valores ordenados: "
 +
   i <- 0
 +
   enquanto i < quantidade
 +
    escrever v[i], " "
 +
    i <- i + 1
 +
  fimenquanto
 +
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
2. <syntaxhighlight lang=text>
+
 
Inicio
+
=== Atividades ===
  inteiro x, y, z
+
 
+
# Escreva um algoritmo que leia 5 números do teclado, e depois mostre-os em ordem inversa à que foi digitada.
  Escrever "Digite um numero: ",
+
# Escreva um algoritmo que leia dois vetores de 5 números, e depois mostre se os vetores são iguais.
  Ler x
+
# Escreva um algoritmo que leia um palavra do teclado e depois procure-a numa lista de palavras preexistente. Essa lista deve ser implementada usando um vetor.
  Escrever "Digite outro numero: ",
+
# Escreva um algoritmo que leia 5 números, e mostre-os em ordem crescente.
  Ler y
+
# Modifique o algoritmo anterior para mostrá-los em ordem decrescente.
  z <- x + y
+
# Em um  jogo de bingo devem-se contar quantos números de uma aposta foram sorteados no bingo. Faça um algoritmo que, dados os números sorteados e uma aposta, conta quantos números apostados forma sorteados.
  Escrever "Soma = ", z
+
 
Fim
+
=== Solução exercício 4 e 6 propostos pelo Luiz Gustavo===
</syntaxhighlight>
+
 
3. <syntaxhighlight lang=text>
+
<code>
Inicio
+
inicio
  Inteiro n1, n2, n3, r
+
    //declaração da variáveis
+
    inteiro v [ 5 ] , i , j , troca
  Escrever "Primeiro numero: "
+
    //entrada de dados
  ler n1
+
    para i de 0 ate 4 passo 1
  Escrever "Segundo numero: "
+
        ler v [ i ]
  ler n2
+
    proximo
  Escrever "Terceiro numero: "
+
    //organizar em ordem crescente
  ler n3
+
    para i de 0 ate 4 passo 1
+
        para j de 0 ate 4 passo 1
  r <- (n1 + n2 + n3) /3
+
            se v [ i ] > v [ j ] entao
+
                troca <- v [ i ]
  Escrever "Media=", r
+
                v [ i ] <- v [ j ]
Fim
+
                v [ j ] <- troca
 +
            fimse
 +
        proximo
 +
    proximo
 +
    //impressão dos dados
 +
    para i de 0 ate 4 passo 1
 +
        escrever "\n" , v [ i ]
 +
    proximo
 +
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
4. <syntaxhighlight lang=text>
+
 
Inicio
+
<code>
  inteiro anos, dias
+
inicio
+
    //declaração das variáveis
  Escrever "Quantos anos se passaram ? "
+
    inteiro lista_num [5][5] <- {{10, 5, 20, 31, 33}, {51, 12, 13, 15, 29}, {25, 28, 22, 26, 36},
  Ler anos
+
{11, 24, 34, 54, 44}, {1, 2, 55, 3, 5}}
  dias <- anos * 365
+
     inteiro numero [5][5],i,j,cont
  Escrever "... então se passaram ", dias, " dias"
 
Fim
 
</syntaxhighlight>
 
5. <syntaxhighlight lang=text>
 
Inicio
 
  constante inteiro diasPorAno <- 365
 
  inteiro anos, dias
 
 
  Escrever "Quantos anos se passaram ? "
 
  Ler anos
 
  dias <- anos * diasPorAno
 
  Escrever "... então se passaram ", dias, " dias"
 
Fim
 
</syntaxhighlight>
 
 
 
==21/05: Constantes e Variáveis==
 
* Leitura das páginas da [http://www.ead.cpdee.ufmg.br/cursos/C/c.html apostila online de C]:
 
** [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c320.html Os tipos do C]
 
 
 
===Atividade===
 
 
 
* Traduza para C os seguintes algoritmos Portugol:
 
 
 
1 <code>
 
inicio
 
    //declaração da variáveis
 
     inteiro v [ 5 ] , i , j , troca
 
 
     //entrada de dados
 
     //entrada de dados
     para i de 0 ate 4 passo 1
+
     escrever "Informe os números do Bingo: "
         ler v [ i ]
+
    enquanto i < 5 faz
     proximo
+
        j <- 0
     //organizar em ordem crescente
+
         enquanto j < 5 faz
     para i de 0 ate 4 passo 1
+
            ler numero [ i ] [ j ]
         para j de 0 ate 4 passo 1
+
            j <- j + 1
             se v [ i ] > v [ j ] entao
+
        fimenquanto
                troca <- v [ i ]
+
        i <- i + 1
                v [ i ] <- v [ j ]
+
     fimenquanto
                 v [ j ] <- troca
+
     //verificando quantos números são iguais
 +
     i <- 0
 +
    enquanto i < 5 faz
 +
         j <- 0
 +
        enquanto j < 5 faz
 +
             se (numero [i][j] = lista_num [i][j]) entao
 +
                 cont <- cont + 1
 
             fimse
 
             fimse
         proximo
+
            j <- j + 1
     proximo
+
        fimenquanto
     //impressão dos dados
+
         i <- i + 1
     para i de 0 ate 4 passo 1
+
     fimenquanto
        escrever "\n" , v [ i ]
+
     //Imprimindo os dados
    proximo
+
     escrever "A quantidade de números sorteados nesta aposta foi: " , cont
 
fim
 
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
  
2 <code>
+
== 25/10: Revisão para avaliação de Lógica de Programação ==
 +
 
 +
1. Crie um programa que lê três inteiros e informa '''VERDADEIRO''' se apenas o maior deles é par ou se o menor deles é ímpar ou informa '''FALSO''' em caso contrário.
  
inicio
+
2. Desenvolva um programa que recebe do usuário o placar de um jogo de futebol (os gols de cada time) e informa se o resultado foi um empate, a vitória do primeiro time ou do segundo time.
      //declaração dos vetores A e B
 
inteiro i,a[5],b[5]
 
 
      //formação do vetor A
 
      para i de 0 ate 4 passo 1
 
          ler a[i]
 
      proximo
 
 
      //guarda valor na posição par
 
      para i de 0 ate 4 passo 2
 
          b[i]<-a[i]*5
 
      proximo
 
 
      //guarda valor na posição ímpar
 
      para i de 1 ate 4 passo 2
 
          b[i]<-a[i]+5
 
      proximo
 
 
      //apresenta valor B resposta
 
      escrever "Formação do vetor B (vetor respota):"
 
      escrever "\n"
 
 
      para i de 0 ate 4 passo 1
 
          escrever "O valor da posição ",i, " é: ", b[i]
 
          escrever "\n"
 
      proximo
 
fim
 
  
</syntaxhighlight>
+
3. Elabore um programa que recebe do usuário três cadeias de caracteres e informa VERDADEIRO se há pelo menos duas diferentes cadeias iguais aos valores 'azul', 'preto'ou 'vermelho' ou FALSO em caso contrário. Exemplos: {'azul', 'preto', 'branco'} é VERDADEIRO; {'azul', 'roxo', 'azul'} é FALSO; {'preto', vermelho', 'vermelho'} é VERDADEIRO.
  
 +
4. Tendo-se como dados de entrada a altura e o sexo de uma pessoa, construa um algoritmo que calcule seu peso ideal, utilizando as seguintes fórmulas:
 +
#* para homens: (72,7 * h) – 58;
 +
#* para mulheres: (62,1 * h) – 44,7.
 +
 +
5. Escrever um algoritmo, que leia um conjunto de 23 dados, cada um, contendo o peso e o código do sexo ("F" ou "M") dos alunos de uma classe, calcule e imprima:
 +
#* Maior e o menor peso da turma;
 +
#* A média de peso dos homens;
 +
#* A média de peso da turma;
 +
 +
Solução proposta pelo Manfred Ex. 1
  
3 <syntaxhighlight lang=text>
+
<code>
 
 
 
inicio
 
inicio
real matrizA[10], matrizB[10] 
+
    inteiro n1 <- 0 , n2 <- 0 , n3 <- 0 , maior <- 0 , menor <- 0
          inteiro i<-0
+
    escrever "Digite o primeiro número: "
          escrever "\n Construa a matriz A."
+
    ler n1
          enquanto i <= 9 faz
+
    escrever "Digite o segundo número: "
              escrever "\n Entre com a posição ", i
+
    ler n2
              ler matrizA[i]
+
    escrever "Digite o terceiro número: "
              i <- i+1
+
    ler n3
          fimEnquanto
+
    maior <- n1
          i <- 0
+
    se ( n2 > maior ) entao
          enquanto i <= 9 faz
+
        maior <- n2
              escrever matrizA[i], " "
+
    fimse
              i <- i+1 
+
    se ( n3 > maior ) entao
          fimEnquanto 
+
        maior <- n3
          escrever "\n "
+
    fimse
          i <- 0
+
    menor <- n1
          enquanto i <= 9 faz
+
    se ( n2 < menor ) entao
              matrizB[i] <- ((matrizA[i])*5)
+
        menor <- n2
              matrizB[i+1] <- ((matrizA[i+1])+5)
+
    fimse
              i <- i+2
+
    se ( n3 < menor ) entao
          fimEnquanto
+
        menor <- n3
          i <- 0
+
    fimse
          escrever "\n A matriz B será: "
+
    se ( maior % 2 ) = 0 ou ( menor % 2 ) =/= 0 entao
          enquanto i <= 9 faz
+
        escrever "Verdadeiro"
              escrever matrizB[i], "   "  
+
    senao
              i <- i+1
+
        escrever "Falso"
          fimenquanto
+
    fimse
 
fim
 
fim
 +
  
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
Proposta do Luiz para exercício 5
  
4 <syntaxhighlight lang=text>
+
<syntaxhighlight lang=text>
 
 
 
inicio
 
inicio
     //declaração das variáveis
+
     //declaração das variaveis
     inteiro a [5] , i , soma <- 0
+
     real peso [ 5 ] <- 0 , menor <- 0 , maior <- 0 , pesom <- 0 , pesot <- 0
 +
    inteiro i , cont <- 0
 +
    caracter sexo [ 5 ]
 
     //entrada de dados
 
     //entrada de dados
 
     para i de 0 ate 4 passo 1
 
     para i de 0 ate 4 passo 1
         ler a [i]
+
        escrever "Informe o peso do " , ( i + 1 ) , "º aluno: "
 +
        ler peso [ i ]
 +
        escrever "Informe o código do sexo do " , ( i + 1 ) , "º aluno (Masculino= M; Feminino= F): "
 +
         ler sexo [ i ]
 +
        escrever "\n"
 
     proximo
 
     proximo
     //construindo a matriz "B"
+
     //testando o maior e menor peso
 +
    maior <- peso [ 1 ]
 +
    menor <- peso [ 1 ]
 
     para i de 0 ate 4 passo 1
 
     para i de 0 ate 4 passo 1
         se ( a [i] % 2 =/= 0 ) entao
+
         se ( peso [ i ] > maior ) entao
             soma <- soma + a [ i ]
+
             maior <- peso [ i ]
 +
        fimse
 +
        se ( peso [ i ] < menor ) entao
 +
            menor <- peso [ i ]
 
         fimse
 
         fimse
 
     proximo
 
     proximo
     //impressão dos dados
+
     //calculando a media de peso dos homens
    escrever "O valor da soma dos numero ímpares é: " , soma
+
     para i de 0 ate 4 passo 1
fim
+
         se ( sexo [ i ] = "M" ) ou ( sexo [ i ] = "m" ) entao
 
+
            pesom <- ( pesom + peso [ i ] )
</syntaxhighlight>
+
            cont <- ( cont + 1 )
 
+
        fimse
5 <syntaxhighlight lang=text>
 
 
 
inicio
 
    //declaração das variáveis
 
    inteiro a[15] ,b[15] ,i
 
    //entrada de dados
 
     para i de 0 ate 14 passo 1
 
         ler a[i]
 
 
     proximo
 
     proximo
     //construindo a matriz "B"
+
     //calculando a media de peso da turma
     para i de 0 ate 14 passo 1
+
     para i de 0 ate 4 passo 1
         b[i] <- a[i] * a[i]
+
         pesot <- ( peso [ i ] + pesot )
 
     proximo
 
     proximo
 
     //impressão dos dados
 
     //impressão dos dados
     escrever "\nMatriz A:"
+
     escrever "\nO maior peso é: " , maior , "\nO menor peso é: " , menor
    para i de 0 ate 14 passo 1
+
     escrever "\nA média de peso dos homens é: " , ( pesom / cont )
        escrever "" , a[i]
+
     escrever "\nA média de peso da turma é: " , ( pesot / 5 )
    proximo
 
     escrever "\nMatriz B:"
 
     para i de 0 ate 14 passo 1
 
        escrever "" , b [i]
 
    proximo
 
 
fim
 
fim
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==27/05: Batalha Naval ==
+
== 25/10: Revisão Lógica de Programação, com respostas :) ==
  
Para referência: [http://www.ead.cpdee.ufmg.br/cursos/C/c.html apostila online sobre linguagem C].
+
1. Desenvolver um programa que efetue a leitura de 5 elementos de uma matriz A do tipo vetor. Construir uma matriz B de mesmo tipo, observando a seguinte lei de formação: Se o valor do índice for par, o valor deverá ser multiplicado por 5, sendo ímpar deverá ser somado por 5. Ao final mostrar os conteúdos das duas matrizes.
  
* Etapas de desenvolvimento:
 
#Desenha 1 onda
 
#Desenha 1 linha de ondas
 
#Desenha 1 matriz de tamanho fixo de ondas
 
#Desenha 1 matriz de tamanho variável de ondas (o usuário informa as dimensões)
 
#Mapeia 1 barco: latitude e longitude (vetor)
 
#Desenha o mar com 1 barco
 
#Mapeia 10 barcos: latitude e longitude (matriz)
 
#Desenha os 10 barcos
 
#Mapeia 10 barcos: latitude, longitude e se já foi atingido
 
#Pede ao usuário atirar
 
#Se o barco foi atingido, desenhar um X
 
#Ao final (todo os barcos atingidos): informar o usuário que venceu em 'n' movimentos
 
  
* Proposta de código que contempla:
+
<code>
** Bibliotecas e definições
 
** Declaração de constantes e variáveis
 
*** Uso de variáveis com mesmo nome e diferentes escopos
 
*** Vetor e matriz
 
** Operadores lógicos e matemáticos
 
** Expressões
 
*** E/S
 
*** Estruturas de decisão e repetição
 
** Funções
 
*** Passagem de parâmetro por valor e por referência
 
** Acesso a uma matriz através de um vetor linear (função <tt>iniciaJogo</tt>)
 
** Ponteiros
 
  
* Uma versão do jogo implementado:
+
inicio
 
+
      //declaração dos vetores A e B
<syntaxhighlight lang=c>
+
inteiro i,a[5],b[5]
#include <stdio.h>
+
   
 
+
      //formação do vetor A
#define QTDE_BARCOS 2
+
      para i de 0 ate 4 passo 1
 
+
          ler a[i]
 
+
      proximo
int iniciaJogo(int *barcos, int *tiros, int *atingidos)
+
     
{
+
      //guarda valor na posição par
int barco;
+
      para i de 0 ate 4 passo 2
for(barco=0; barco<QTDE_BARCOS; barco++)
+
          b[i]<-a[i]*5
{
+
      proximo
printf("\nBarco número %d:\n", barco + 1); // O primeiro barco é o de no. zero :-)
+
     
printf("Informe a latitude do barco: ");
+
      //guarda valor na posição ímpar
scanf("%d", barcos + 3*barco); // end. inicial (barcos)
+
      para i de 1 ate 4 passo 2
// + qtde. objetos por linha
+
          b[i]<-a[i]+5
// * linhas
+
      proximo
// + coluna (1o. elemento)
+
     
printf("Informe a longitude do barco: ");
+
      //apresenta valor B resposta
scanf("%d", barcos + 3*barco + 1); // end. inicial (barcos)
+
      escrever "Formação do vetor B (vetor respota):"
// + qtde. objetos por linha
+
      escrever "\n"
// * linhas
+
     
// + coluna (2o. elemento)
+
      para i de 0 ate 4 passo 1
*(barcos + 3*barco + 2) = 0; // endereço inicial (barcos)
+
          escrever "O valor da posição ",i, " é: ", b[i]
// + qtde. objetos por linha
+
          escrever "\n"
// * linhas
+
      proximo
// + coluna (3o. elemento)
+
fim
}
 
*tiros = 0;
 
*atingidos = 0;
 
}
 
 
 
char desenhaPonto(int linha, int coluna, int barcos[QTDE_BARCOS][3])
 
{
 
int barco;
 
 
for (barco=0; barco<QTDE_BARCOS; barco++)
 
{
 
if (linha==barcos[barco][0] & coluna==barcos[barco][1])
 
{
 
if (barcos[barco][2] == 1)
 
{
 
return 'X';
 
}
 
}
 
}
 
return '~';
 
}
 
 
 
desenhaMar(int linhas, int colunas, char onda, int barcos[QTDE_BARCOS][3])
 
{
 
int linha;
 
int coluna;
 
int barco;
 
int tinhaBarco;
 
 
for (linha=1; linha<linhas; linha++)
 
{
 
for (coluna=1; coluna<colunas; coluna++)
 
{
 
printf("%c", desenhaPonto(linha, coluna, barcos));
 
}
 
printf("\n");
 
}
 
}
 
 
 
int seVenceu(int barcos[QTDE_BARCOS][3])
 
{
 
int barco;
 
int atingidos = 0;
 
 
for (barco=0; barco<QTDE_BARCOS; barco++)
 
{
 
if (barcos[barco][2] == 1)
 
atingidos++;
 
}
 
return atingidos;
 
}
 
 
 
int main(int argc, char* argv[])
 
{
 
const char onda= '~';
 
int barcos[QTDE_BARCOS][3];
 
int latitude;
 
int longitude;
 
int barco;
 
int tiros;
 
int atingidos;
 
 
if (argc < 3)
 
{
 
printf("Use: %s (qtde. de linhas) (qtde. de colunas).\n", argv[0]);
 
return -1;
 
}
 
 
// Inicia o jogo
 
iniciaJogo(&barcos, &tiros, &atingidos);
 
 
// Estrutura principal de repetição: vai atirando sem parar... :-P
 
while (1)
 
{
 
// Limpa a tela
 
system("clear");
 
// Desenha o mar
 
desenhaMar(atoi(argv[1]), atoi(argv[2]), onda, barcos);
 
 
atingidos = seVenceu(barcos);
 
if (atingidos == QTDE_BARCOS)
 
{
 
printf("\nParabéns! Venceu o jogo com %d tiros!\n", tiros);
 
return 0;
 
}
 
else
 
{
 
printf("\nTiros: %d\n", tiros);
 
printf("Alvos atingidos: %d.\n", atingidos);
 
printf("\nDigite latitude e longitude:\n");
 
printf("- Latitude: ");
 
scanf("%d", &latitude);
 
printf("- Longitude: ");
 
scanf("%d", &longitude);
 
for (barco=0; barco<QTDE_BARCOS; barco++)
 
{
 
if (latitude == barcos[barco][0] & longitude == barcos[barco][1])
 
{
 
barcos[barco][2] = 1;
 
atingidos++;
 
}
 
}
 
tiros++;
 
}
 
}
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== O tabuleiro ===
+
Solução para o exercício 1 desenvolvida pelo Thiarlles e Manfred:
  
Representar o tabuleiro: etapas 1 a 4.
+
<code>
 +
inicio
 +
real matrizA[10], matrizB[10] 
 +
          inteiro i<-0
 +
          escrever "\n Construa a matriz A."
 +
          enquanto i <= 9 faz
 +
              escrever  "\n Entre com a posição ", i
 +
              ler matrizA[i]
 +
              i <- i+1
 +
          fimEnquanto
 +
          i <- 0
 +
          enquanto i <= 9 faz
 +
              escrever matrizA[i], " "
 +
              i <- i+1 
 +
          fimEnquanto 
 +
          escrever "\n "
 +
          i <- 0
 +
          enquanto i <= 9 faz
 +
              matrizB[i] <- ((matrizA[i])*5)
 +
              matrizB[i+1] <- ((matrizA[i+1])+5)
 +
              i <- i+2
 +
          fimEnquanto
 +
          i <- 0
 +
          escrever "\n A matriz B será: "
 +
          enquanto i <= 9 faz
 +
              escrever matrizB[i], "  "
 +
              i <- i+1
 +
          fimenquanto
 +
fim
 +
</syntaxhighlight>
  
==== Etapa 1: desenhar uma onda ====
+
2. Desenvolver um programa que efetue a leitura de 5 elementos de uma matriz A do tipo vetor. No final, apresente o total da soma de todos os elementos que sejam ímpares.
  
Conteúdos abordados:
+
<code>
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c300.html declaraçao de variáveis]
+
inicio
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c940.html saída de dados na tela]
+
    //declaração das variáveis
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c410.html estrutura de decisão: ''if'']
+
    inteiro a [5] , i , soma <- 0
 
+
    //entrada de dados
Nessa etapa se deseja mostrar o estado de uma única posição do tabuleiro. Se o estado for "água", mostra-se uma onda (símbolo ''~''), e se for "navio" mostra-se ''X''.
+
    para i de 0 ate 4 passo 1
 
+
        ler a [i]
<syntaxhighlight lang=c>
+
    proximo
#include <stdio.h>
+
    //construindo a matriz "B"
 
+
    para i de 0 ate 4 passo 1
int main() {
+
        se ( a [i] % 2 =/= 0 ) entao
  // 0: agua
+
            soma <- soma + a [ i ]
  // 1: navio
+
        fimse
  int posicao = 1;
+
     proximo
 
+
    //impressão dos dados
  if (posicao == 0) {
+
     escrever "O valor da soma dos numero ímpares é: " , soma
     printf("~");
+
fim
  } else {
 
     printf("X");
 
  }
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Usou-se uma variável inteira para representar o estado da posição do tabuleiro. O valor 0 (zero) corresponde a "água", e 1 corresponde a "navio". Para testar o valor dessa variável, e mostrar ''~'' ou ''X'', precisou-se de uma estrutura de decisão do tipo '''''se''' (condição) '''então''' bloco_de instruções '''senão''' outro_bloco_de_instruções''. Na linguagem C isso se faz com '''''if''' (condição) { bloco de instruções } '''else''' {outro bloco de instruções}''.
+
3. Ler 15 elementos de uma matriz A do tipo vetor. Construir uma matriz B de mesmo tipo. Observando a seguinte lei de formação: “Todo elemento de B deverá ser o quadrado do elemento de A correspondente”.
  
==== Etapa 2: desenhar uma linha de ondas ====
+
<code>
 
+
inicio
Nessa etapa deseja-se mostrar uma linha do tabuleiro. Por exemplo, para um tabuleiro de 10 colunas, uma linha deve aparecer assim (se tiver só "água'":
+
    //declaração das variáveis
~ ~ ~ ~ ~ ~ ~ ~ ~ ~
+
    inteiro a[15] ,b[15] ,i
 
+
    //entrada de dados
O problema é parecido com o da etapa 1, mas agora deve-se mostrar o estado de cada posição de uma linha. Foi sugerido o uso de um vetor para representar os estados das posições em uma linha. Assim, imaginando-se uma linha com 10 posições, o vetor abaixo poderia ser usado para representar seus estados:
+
    para i de 0 ate 14 passo 1
 
+
        ler a[i]
<syntaxhighlight lang=c>
+
    proximo
int linha[10];
+
    //construindo a matriz "B"
 +
    para i de 0 ate 14 passo 1
 +
        b[i] <- a[i] * a[i]
 +
    proximo
 +
    //impressão dos dados
 +
    escrever "\nMatriz A:"
 +
    para i de 0 ate 14 passo 1
 +
        escrever "" , a[i]
 +
    proximo
 +
    escrever "\nMatriz B:"
 +
    para i de 0 ate 14 passo 1
 +
        escrever "" , b [i]
 +
    proximo
 +
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Repare na semelhança entre a declaração de um vetor em C e em Portugol. A ideia é a mesma: ao declarar o vetor deve-se informar sua capacidade (quantas posições ele possui, o que corresponde a quantos valores ele é capaz de armazenar). No exemplo acima, o vetor de inteiros ''linha'' possui 10 posições, e assim é capaz de guardar 10 números inteiros.
+
4. Escreva um algoritmo que:  
 +
#*Leia uma matriz 5 x 5 de elementos reais;
 +
#* Divida cada elemento de uma linha da matriz pelo elemento da diagonal principal desta linha;
 +
#* Imprima a matriz assim modificada.
  
A tarefa da etapa 2 portanto é testar cada posição do vetor ''linha'': se for 0 deve-se mostrar ''~''(água), e se for 1 deve-se mostrar ''X'' (navio).
+
<code>
 
+
inicio
Conteúdos abordados:
+
    //declaração das variáveis
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c300.html declaraçao de variáveis]
+
    real a [5] [5] , b [5] [5]
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c940.html saída de dados na tela]
+
    inteiro i , j
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c410.html estrutura de decisão: ''if'']
+
    //entrada de dados
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c440.html estrutura de repetição: ''while'']
+
    para i de 0 ate 4 passo 1
 +
        para j de 0 ate 4 passo 1
 +
            ler a [i] [j]
 +
        proximo
 +
    proximo
 +
    //dividindo a linha da matriz por sua diagonal principal
 +
    para i de 0 ate 4 passo 1
 +
        para j de 0 ate 4 passo 1
 +
            b [i] [j] <- ( a [i] [j] / a [i] [i] )
 +
        proximo
 +
    proximo
 +
    //impressão dos dados
 +
    escrever "\nMatriz: "
 +
    escrever "\n"
 +
    para i de 0 ate 4 passo 1
 +
        escrever "\n" , a [i] [0] , " " , a [i] [1] , " " , a [i] [2] , " " , a [i] [3] , " " , a [i] [4]
 +
    proximo
 +
    escrever "\n\nMatriz modificada: "
 +
    escrever "\n"
 +
    para i de 0 ate 4 passo 1
 +
        escrever "\n" , b [i] [0] , " " , b [i] [1] , " " , b [i] [2] , " " , b [i] [3] , " " , b [i] [4]
 +
    proximo
 +
fim
 +
</syntaxhighlight>
  
<syntaxhighlight lang=c>
+
5. Elabore um algoritmo para corrigir provas de múltipla escolha. Assuma que em cada prova encontraremos os seguintes dados: RM, NOME DO ALUNO, MATÉRIA e BIMESTRE, além de 10 questões numeradas de 1 até 10 e que cada questão possui 5 alternativas identificadas pelas letras de “a” até “e”. Primeiramente, o algoritmo deve ler o gabarito e o número de provas a serem corrigidas . A seguir, os dados das provas a serem corrigidas devem ser lidas. Ainda, o algoritmo deverá calcular e escrever:
#include <stdio.h>
 
  
int main() {
+
#* O RM, NOME DO ALUNO, MATÉRIA, BIMESTRE e a NOTA de cada aluno (assumindo que cada questão correta vale 1 ponto).
  // 0: agua
+
#* A porcentagem de aprovação, assumindo que a nota mínima para aprovação é 6.
  // 1: navio
 
  int linha[10] = {0,1,0,0,0,0,0,0,0,0};
 
  int y;
 
  
  y = 0;
+
<code>
  while (y < 10) {
+
inicio
 
+
     //declaração das variáveis
     // Mostra ~ se posicao for agua, e X se for navio
+
     caracter gab [10] , resp [10]
     if (linha[y] == 0) {
+
    inteiro i , qtdprova , cont <- 0 , aprovados <- 0
      printf("~ ");
+
    real nota <- 0
     } else {
+
    texto rm <- "" , aluno <- "" , mat <- "" , bimestre <- ""
      printf("X ");
+
      
     }
+
    //entrada de dados
 
+
    para i de 0 ate 9 passo 1
     y = y + 1;
+
        escrever "Informe o gabarito da " , (i + 1) , "ª questão:"
  }
+
        ler gab [i]
 
+
     proximo
}
+
   
</syntaxhighlight>
+
     escrever "Informe a quantidade de provas: "
 
+
    ler qtdprova
 
+
   
 
+
    //dados das provas
==28/05: O tabuleiro (etapas 3 e 4) ==
+
    enquanto cont < qtdprova faz
 
+
        escrever "**************************************************"
Conteúdos abordados:
+
        escrever "\nInforme RM: "
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c300.html declaração de variáveis]
+
        ler rm
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c530.html matrizes de números]
+
        escrever "Informe o nome do aluno: "
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c940.html saída de dados na tela]
+
        ler aluno
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c410.html estrutura de decisão: ''if'']
+
        escrever "Informe a matéria: "
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c440.html estrutura de repetição: ''while'']
+
        ler mat
* [http://www.ead.cpdee.ufmg.br/cursos/C/c.html funções]
+
        escrever "Informe o bimestre: "
 
+
        ler bimestre
=== Desenhando o tabuleiro completo ===
+
        //informando as respostas
 
+
        para i de 0 ate 9 passo 1
Dando continuidade à visualização do tabuleiro, agora deve-se desenhá-lo por completo na tela. Quer dizer, mostrar um tabuleiro com 10 linhas e 10 colunas, seguindo a abordagem das etapas 1 e 2.
+
            escrever "Informe a resposta da " , (i + 1) , "ª questão:"
 
+
            ler resp [i]
* Para mostrar uma única casa do tabuleiro (etapa 1) usou-se uma variável inteira, cujo conteúdo representa o estado daquela casa (se água ou navio). Para mostrar uma linha usou-se um vetor com capacidade 10, com cada posição do vetor representando o estado da casa correspondente. Como se deve então fazer para mostrar todo o tabuleiro ?<br>''Possível solução: usando uma matriz bidimensional para representar todas suas casas:'' <syntaxhighlight lang=c>
+
        proximo
#include <stdio.h>
+
       
 
+
        //corrigindo a prova
int main() {
+
        nota <- 0
  // 0: agua
+
        para i de 0 ate 9 passo 1
  // 1: navio
+
            se ( gab [i] = resp [i] ) entao
  int tabuleiro[10][10] = {{0,1,1,0,1,0,0,0,0,0}, {0,0,1,0,0,0,0,0,0,0},
+
                nota <- nota + 1
                          {0,0,0,0,1,0,0,0,0,1}, {0,1,1,0,1,0,0,0,0,0},
+
            fimse
                          {0,0,0,0,1,0,0,0,0,0}, {0,1,1,0,1,0,0,0,0,0},
+
        proximo
                          {0,1,0,0,0,0,0,0,0,0}, {0,1,1,0,1,0,0,0,0,0},
+
       
                          {0,0,0,0,0,0,0,0,0,0}, {0,1,1,0,1,0,0,0,0,0}};
+
        //informando a nota
  int linha, coluna;
+
        escrever "A nota do(a) " , aluno , " é: " , nota , "\n\n"
 
+
       
  linha = 0;
+
         //verificando aprovação do aluno
  while (linha < 10) {
+
         se ( nota >= 6 ) entao
      coluna = 0;
+
            aprovados <- ( aprovados + 1 )
      while (coluna < 10) {
+
         fimse
 
+
        cont <- ( cont + 1 )
         // Mostra ~ se posicao for agua, e X se for navio
+
    fimenquanto
         if (tabuleiro[linha][coluna] == 0) {
+
   
          printf("~ ");
+
    //imprimindo valores
         } else {
+
    escrever "\n**************************************************"
          printf("X ");
+
    escrever "\nA quantidade de aprovados é: " , aprovados
        }
+
fim
 
 
        coluna = coluna + 1;
 
      }
 
      printf("\n");
 
      linha = linha + 1;
 
  }
 
 
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
* Mostrar o tabuleiro na tela parece ser em si um algoritmo. Ele precisa apenas  que se informem quais os estados das casas do tabuleiro. Esse algoritmo ficaria bem se implementado em uma [http://wiki.sj.cefetsc.edu.br/wiki/index.php/SOP-funcoes função]. <syntaxhighlight lang=c>
+
== 28/10: Avaliação de Lógica de Programação==
#include <stdio.h>
 
 
 
  // 0: agua
 
  // 1: navio
 
  
// Obs: a matriz "tabuleiro" foi tornada uma variável global porque é difícil
+
Dicas para a avaliação (vale a pena revisar conceitos):
// passar uma matriz como argumento de função. Assim ela pode ser acessada
 
// pela função "mostra_tabuleiro".
 
  
int tabuleiro[10][10] = {{0,1,1,0,1,0,0,0,0,0}, {0,0,1,0,0,0,0,0,0,0},
+
#* Números primos
                          {0,0,0,0,1,0,0,0,0,1}, {0,1,1,0,1,0,0,0,0,0},
+
#* Fatorial
                          {0,0,0,0,1,0,0,0,0,0}, {0,1,1,0,1,0,0,0,0,0},
+
#* MDC: Máximo Divisor Comum
                          {0,1,0,0,0,0,0,0,0,0}, {0,1,1,0,1,0,0,0,0,0},
+
#* MMC: Mínimo Múltiplo Comum
                          {0,0,0,0,0,0,0,0,0,0}, {0,1,1,0,1,0,0,0,0,0}};
+
#* Cálculo para série de Fibonacci
 +
 
 +
===Conceitos Avaliação de Lógica:===
 +
* Conceitos avaliação de Lógica de Programação [http://www.sj.ifsc.edu.br/~tisemp/SOP/conceitos_logica.pdf clique aqui]
 +
 
 +
==02/11: Feriado Nacional ==
 +
 
 +
* Finados (sem atividades).
  
int mostra_tabuleiro() {
+
== 04/11: Linguagem C ==
  int linha, coluna;
 
  
  linha = 0;
+
#* Introdução a linguagem C
  while (linha < 10) {
+
#* Primeiros Programas
      coluna = 0;
+
#* Compilador Gcc
      while (coluna < 10) {
 
  
        // Mostra ~ se posicao for agua, e X se for navio
+
* Para provocar: [http://norvig.com/21-days.html Teach Yourself Programming in Ten Years]
        if (tabuleiro[linha][coluna] == 0) {
+
* Apostila adotada: [http://www.ead.cpdee.ufmg.br/cursos/C/c.html Curso de Linguagem C - Engenharia Elétrica -  UFMG]
          printf("~ ");
 
        } else {
 
          printf("X ");
 
        }
 
  
        coluna = coluna + 1;
+
Obs: durante as aulas usaremos o [http://www.netbeans.org NetBeans], um Ambiente Integrado de Desenvolvimento (''IDE - Integrated Development Environment''). Um IDE é um programa que auxilia o programador. Ele integra um  editor de programas, um gerenciador de projetos, compilador e um depurador (''debugger'').
      }
 
      printf("\n");
 
      linha = linha + 1;
 
  }
 
}
 
  
 +
'''''Para instalar o Netbeans:'''''
 +
# Faça o [http://netbeans.c3sl.ufpr.br/6.8/bundles/netbeans-6.8-ml-cpp-linux.sh download do instalador]. Salve-o em algum subdiretório.
 +
# Abrindo um terminal, entre no subdiretório onde está o instalador e execute esse comando: <syntaxhighlight lang=bash>
 +
bash netbeans-6.8-ml-cpp-linux.sh
 +
</syntaxhighlight>
 +
#* Caso o instalador falhe porque não encontrou a JVM (Máquina Virtual Java), instale-a com esse comando: <syntaxhighlight lang=bash>
 +
sudo apt-get install -y sun-java6-jdk
 +
</syntaxhighlight>
 +
# Aceite as opções de instalação sugeridas pelo instalador.
 +
# Ao final da instalação, o Netbeans 6.8 estará acessível pelo menu ''Aplicativos -> Programação''.
 +
# Sempre que for escrever um novo programa com o Netbeans, crie um novo projeto (ver menu Arquivo->Novo Projeto). Selecione um projeto do tipo "Aplicativo C/C++".
  
int main() {
+
=== Compilando o primeiro programa ===
  mostra_tabuleiro();
+
* O clássico ''Hello World!''
 +
<syntaxhighlight lang=c n>
 +
#include <stdio.h>
  
 +
int main(int argc, char *argv[])
 +
{
 +
printf("Alô mundo!\n");
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==== Funções ====
+
* Mostrando mensagens de na tela: [http://manpages.ubuntu.com/manpages/karmic/en/man3/puts.3.html puts] e [http://manpages.ubuntu.com/manpages/karmic/en/man3/printf.3.html printf]: <syntaxhighlight lang=c n>
A função ''mostra_tabuleiro'' corresponde ao algoritmo para desenhar o tabuleiro na tela. O tabuleiro em si é representado pela variável ''tabuleiro'', que tem escopo global (visível em todas as funções do programa). Neste momento é bom ler um pouco mais sobre funções na linguagem C:
+
#include <stdio.h>
* [[SOP-funcoes|Texto introdutório sobre funções na linguagem C]]
 
  
==== Escopo de variáveis ====
+
int main() {
 
+
  int n;
* Texto obtido de: [http://www.inf.pucrs.br/~pinho/LaproI/Funcoes/AulaDeFuncoes.htm Uso de funções em C]
 
  
Por escopo de uma variável entende-se o bloco de código onde esta variável é válida. Com base nisto, temos as seguintes afirmações:
+
  n = 5;
* As variáveis valem no bloco que são definidas;
+
 
* As variáveis definidas  dentro de uma função recebem o nome de '''''variáveis locais'''''
+
  puts("Demonstração de puts e printf");
* As variáveis declaradas fora de qualquer função são chamadas de '''''variáveis globais'''''
+
 
* Os parâmetros formais de uma função (também conhecidos como ''argumentos da função'') valem também somente dentro da função;
+
  printf("Valor de n: %d\n", n);
* Uma variável definida dentro de uma função não é acessível em outras funções, MESMO QUE ESSAS VARIÁVEIS TENHAM NOMES IDÊNTICOS.
 
  
===== Variáveis locais =====
+
  n = n + 1;
  
No trecho de código a seguir tem-se um exemplo com funções e variáveis com nomes iguais.
+
  printf("Novo valor de n: %d\n", n);
  
<syntaxhighlight lang=c>
+
  return 0;
 +
}
 +
</syntaxhighlight>
 +
* Lendo dados do teclado: [http://manpages.ubuntu.com/manpages/karmic/en/man3/scanf.3.html scanf]<syntaxhighlight lang=c n>
 
#include <stdio.h>
 
#include <stdio.h>
  
void FUNC1() {
+
int main() {
  int B;
+
  int n;
  
  B = -100;
+
  printf("Digite um número inteiro: ");
  printf("Valor de B dentro da função FUNC1: %d\n", B);
 
}
 
  
void FUNC2() {
+
  scanf("%d", &n);
  int B;
 
  
  B = -200;
+
  printf("Valor digitado foi %d\n", n);
  printf("Valor de B dentro da função FUNC2: %d\n", B);
 
}
 
  
void main() {
+
  return 0;
  int B;
 
 
 
  B = 10;
 
  printf("Valor de B: %d\n", B);
 
  B = 20;
 
  FUNC1();
 
  printf("Valor de B: %d\n", B);
 
  B = 30;
 
  FUNC2();
 
  printf("Valor de B: %d\n", B);
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
** Outras formas de ler do teclado: [http://manpages.ubuntu.com/manpages/karmic/man3/fgets.3.html getchar],  [http://manpages.ubuntu.com/manpages/karmic/en/man3/fgets.3.html fgets]
  
O resultado de sua execução deve ser:
+
==== Tipos de dados ====
 +
{| border="1" cellpadding="2"
 +
!Portugol
 +
!C
 +
!Exemplo
 +
|-
 +
|inteiro||int|| int x;
 +
|-
 +
|caracter||char|| char letra;
 +
|-
 +
|real||float ou double|| float pi = 3.1416;
 +
|-
 +
|texto||char * ou vetor de char || char * mensagem = "Hello world";<br>char palavra[16];
 +
|-
 +
|logico||qualquer tipo (valor 0 = Falso, qualquer outro valor = Verdadeiro)||int ok = 1;<br>char teste = 0;
 +
|}
  
<syntaxhighlight lang=text>
 
Valor de B: 10
 
Valor de B dentro da função FUNC1: -100
 
Valor de B: 20
 
Valor de B dentro da função FUNC2: -200
 
Valor de B: 30
 
</syntaxhighlight>
 
  
===== Variáveis globais =====
+
==== Comandos/funções e Estruturas de controle ====
 +
{| border="1" cellpadding="2"
 +
!Portugol
 +
!C
 +
!Exemplo
 +
|-
 +
|<syntaxhighlight lang=text>inteiro n, m
 +
 
 +
escrever "Ola, mundo!\n"
 +
escrever "valor de n: ", n, "\n"
 +
escrever "valor de n: ", n, ", e valor de x: ", x, "\n"
 +
</syntaxhighlight>||<syntaxhighlight lang=c>int n, m;
  
O seguinte exemplo mostra o mesmo programa, porém fazendo com que a variável B seja global:
+
printf("Ola, mundo!\n");
 +
printf("valor de n: %d\n", n);
 +
printf("valor de n: %d, e valor de x: %d\n", n, x);</syntaxhighlight>||
 +
|-
 +
|<syntaxhighlight lang=text>inteiro n
  
<syntaxhighlight lang=c>
+
ler n</syntaxhighlight>||<syntaxhighlight lang=c>int n;
#include <stdio.h>
 
  
// Declaração da variável global B
+
scanf("%d", &n);</syntaxhighlight>||
int B;
+
|-
 +
|<syntaxhighlight lang=text>se condição então
 +
//comandos
 +
fimse</syntaxhighlight> ||<syntaxhighlight lang=c>if (condição) {
 +
//comandos
 +
}</syntaxhighlight>||
 +
|-
 +
|<syntaxhighlight lang=text>se condição então
 +
  //comandos
 +
senão
 +
  //comandos
 +
fimse</syntaxhighlight> ||<syntaxhighlight lang=c>if (condição) {
 +
//comandos
 +
} else {
 +
//comandos
 +
}</syntaxhighlight> ||
 +
|-
 +
|<syntaxhighlight lang=text>escolhe expressão
 +
  caso valor1: 
 +
    //comandos
 +
  caso valor2:
 +
    //comandos
 +
  defeito:
 +
    //comandos
 +
fimescolhe</syntaxhighlight>||<syntaxhighlight lang=c>switch (expressão) {
 +
  case valor1:
 +
    //comandos
 +
  case valor2:
 +
    //comandos
 +
  default:
 +
    //comandos
 +
}</syntaxhighlight>||
 +
|-
 +
|<syntaxhighlight lang=text>enquanto condição faz
 +
//comandos
 +
fimenquanto</syntaxhighlight>||<syntaxhighlight lang=c>while (condição) {
 +
  //comandos
 +
}</syntaxhighlight>||
 +
|-
 +
|<syntaxhighlight lang=text>para variavel de inicio ate fim passo incremento
 +
//comandos
 +
proximo</syntaxhighlight>||<syntaxhighlight lang=c>for (variavel=inicio; variavel <= fim; variavel++) {
 +
//comandos
 +
}</syntaxhighlight>||
 +
|}
  
void FUNC1() {
+
=== Atividades ===
  B = -100;
 
  printf("Valor de B dentro da função FUNC1: %d\n", B);
 
}
 
  
void FUNC2() {
+
* Traduza para C os seguintes algoritmos Portugol:
  B = -200;
+
*# <syntaxhighlight lang=text>
  printf("Valor de B dentro da função FUNC2: %d\n", B);
+
Inicio
}
+
  inteiro x, y
 
+
void main() {
+
  Escrever "Digite um numero: ",
  B = 10;
+
  Ler x
  printf("Valor de B: %d\n", B);
+
  Escrever "Digite outro numero: ",
  B = 20;
+
  Ler y
  FUNC1();
+
  Escrever "Soma = ", x+y
  printf("Valor de B: %d\n", B);
+
Fim
  B = 30;
 
  FUNC2();
 
  printf("Valor de B: %d\n", B);
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 
+
*# <syntaxhighlight lang=text>
O resultado de sua execução deve ser:
+
Inicio
 
+
  inteiro x, y, z
<syntaxhighlight lang=text>
+
Valor de B: 10
+
  Escrever "Digite um numero: ",
Valor de B dentro da função FUNC1: -100
+
  Ler x
Valor de B: -100
+
  Escrever "Digite outro numero: ",
Valor de B dentro da função FUNC2: -200
+
  Ler y
Valor de B: -200
+
  z <- x + y
 +
  Escrever "Soma = ", z
 +
Fim
 
</syntaxhighlight>
 
</syntaxhighlight>
 
+
*# <syntaxhighlight lang=text>
E se existir um variável local  com mesmo nome que uma global ? nesse caso, a variável local vai ''esconder'' a sua homônima global:
+
Inicio
 
+
  Inteiro n1, n2, n3, r
<syntaxhighlight lang=c>
+
   
#include <stdio.h>
+
  Escrever "Primeiro numero: "
 
+
  ler n1
// Declaração da variável global B
+
  Escrever "Segundo numero: "
int B;
+
  ler n2
 
+
  Escrever "Terceiro numero: "
void FUNC1() {
+
  ler n3
  // no escopo desta função, esta variável local vai esconder a variável global B!
+
  int B;
+
  r <- (n1 + n2 + n3) /3
 
+
  B = -100;
+
  Escrever "Media=", r
  printf("Valor de B dentro da função FUNC1: %d\n", B);
+
Fim
}
 
 
 
void FUNC2() {
 
  B = -200;
 
  printf("Valor de B dentro da função FUNC2: %d\n", B);
 
}
 
 
 
void main() {
 
  B = 10;
 
  printf("Valor de B: %d\n", B);
 
  B = 20;
 
  FUNC1();
 
  printf("Valor de B: %d\n", B);
 
  B = 30;
 
  FUNC2();
 
  printf("Valor de B: %d\n", B);
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 
+
*# <syntaxhighlight lang=text>
O resultado de sua execução deve ser:
+
Inicio
 
+
  inteiro anos, dias
<syntaxhighlight lang=text>
+
Valor de B: 10
+
  Escrever "Quantos anos se passaram ? "
Valor de B dentro da função FUNC1: -100
+
  Ler anos
Valor de B: 20
+
  dias <- anos * 365
Valor de B dentro da função FUNC2: -200
+
  Escrever "... então se passaram ", dias, " dias"
Valor de B: -200
+
Fim
 +
</syntaxhighlight>
 +
*# <syntaxhighlight lang=text>
 +
Inicio
 +
  constante inteiro diasPorAno <- 365
 +
  inteiro anos, dias
 +
 +
  Escrever "Quantos anos se passaram ? "
 +
  Ler anos
 +
  dias <- anos * diasPorAno
 +
  Escrever "... então se passaram ", dias, " dias"
 +
Fim
 
</syntaxhighlight>
 
</syntaxhighlight>
 
+
*# <syntaxhighlight lang=text>
=== Outra solução seria: ===
+
inicio
 
+
  real massa
<syntaxhighlight lang=c n>
+
  real forca
 
+
  real aceleracao
 
+
  constante real g <- 9.8
#include <stdio.h>
+
  constante real ac <- 0.01
 
+
 
void main(void) {
+
  escrever "força: "
    int tabuleiroLinhas, tabuleiroColunas;
+
  ler forca
    printf("Por favor, digite quantas linhas para o mar: ");
+
 
    scanf("%d", &tabuleiroLinhas);
+
  escrever "massa: "
    printf("Agora, digite quantas colunas para o mar: ");
+
  ler massa
    scanf("%d", &tabuleiroColunas);
+
 
    char mar[tabuleiroLinhas][tabuleiroColunas];
+
  aceleracao <- forca/massa - ac*massa*g
 
+
 
    int barcoLinha, barcoColuna;
+
  escrever "aceleracao=", aceleracao, " m/s2"
    printf("Informe a linha do barco: ");
+
 
    scanf("%d", &barcoLinha);
+
fim
    printf("E a coluna (do barco): ");
+
</syntaxhighlight>
    scanf("%d", &barcoColuna);
+
*# <syntaxhighlight lang=text>
 
+
inicio
    int linha, coluna;
+
  real a, b, c
    for (linha = 0; linha < tabuleiroLinhas; linha++) {
+
  real delta
        for (coluna = 0; coluna < tabuleiroColunas; coluna++) {
+
  real x1, x2
            mar[linha][coluna] = '~';
+
 
            if (linha == barcoLinha-1 && coluna == barcoColuna-1) {
+
  escrever "Forneça os coeficientes da equação de 2o grau (formato: ax^2 + bx + c):\n"
                printf("*");
+
  escrever "a="
            } else {
+
  ler a
                printf("%c", mar[linha][coluna]);
+
  escrever "b="
            }
+
  ler b
         }
+
  escrever "c="
         printf("\n");
+
  ler c
    }
+
 
}
+
  delta <- b^2 - 4*a*c
 +
  x1 <- (-b + delta^0.5)/(2*a)
 +
  x2 <- (-b - delta^0.5)/(2*a)
 +
 
 +
  escrever "1a raiz=", x1
 +
  escrever "\n2a raiz=", x2 
 +
fim
 +
</syntaxhighlight>
 +
*# <syntaxhighlight lang=text>
 +
inicio
 +
      real x1, x2, x3, x4, x5
 +
      real media
 +
      real desvioPadrao
 +
      constante inteiro N <- 5
 +
     
 +
      // Ler os cinco valores pelo teclado
 +
      ler x1
 +
      ler x2
 +
      ler x3
 +
      ler x4
 +
      ler x5
 +
     
 +
      // Calcular a media
 +
      media <- (x1 + x2 + x3 + x4 + x5) / N
 +
     
 +
      // Calcular o desvio padrao
 +
      desvioPadrao <- (x1 - media)^2 + (x2 - media)^2 + (x3 - media)^2 + (x4 - media)^2 + (x5 - media)^2
 +
      desvioPadrao <- (desvioPadrao / (N-1))^0.5
 +
     
 +
      escrever "Media=", media
 +
      escrever "\nDesvio padrao=", desvioPadrao
 +
fim
 +
</syntaxhighlight>
 +
*# <syntaxhighlight lang=text>
 +
inicio
 +
      real renda
 +
      real irpf
 +
     
 +
      escrever "Informe sua renda: "
 +
      ler renda
 +
     
 +
      se renda < 1372.81 entao
 +
        irpf <- 0
 +
      senao
 +
         se renda < 2743.25 entao
 +
          irpf <- (renda - 205.92)*0.15
 +
         senao
 +
          irpf <- (renda - 548.82)*0.275
 +
        fimSe
 +
      fimSe
 +
     
 +
      escrever "Imposto devido: ", irpf 
 +
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
*# <syntaxhighlight lang=text>
 +
inicio
 +
    inteiro dividendo
 +
    inteiro divisor
 +
    inteiro resto , quociente
  
=== Para fixar ===
+
    escrever "Dividendo: "
 +
    ler dividendo
 +
    escrever "Divisor: "
 +
    ler divisor
  
# Escreva  o programa para mostrar a tabuada de um  número lido do teclado. <syntaxhighlight lang=c>
+
    se divisor = 0 entao
#include <stdlib.h>
+
        escrever "Nao pode dividir: divisor = 0 !!!"
#include <stdio.h>
+
    senao
 
+
        resto <- dividendo % divisor
/*
+
        se resto = 0 entao
*  
+
            quociente <- dividendo / divisor
*/
+
            escrever dividendo , " / " , divisor , " = " , quociente
int main(int argc, char** argv) {
+
        senao
 +
            escrever "Nao pode fazer divisao inteira"
 +
            escrever " (resto = " , resto , ")"
 +
        fimse
 +
    fimse
 +
fim
 +
</syntaxhighlight>
 +
*# <syntaxhighlight lang=text>
 +
inicio
 +
    inteiro termometro , barometro , tempo
  
     int numero, c;
+
     escrever "Qual a condição do termômetro: \n"
 +
    escrever "Digite 1 para baixando , 2 para estacionário e 3 para subindo. \n"
 +
    ler termometro
  
     printf("Numero: ");
+
     escrever "Informe a condição do barômetro: \n"
     scanf("%d", &numero);
+
     escrever "Digite 1 para baixando , 2 para estacionário e 3 para subindo. \n"
 +
    ler barometro
  
     c = 1;
+
     tempo <- termometro*10 + barometro
    while (c < 11) {
 
        printf("%d X %d = %d\n", numero, c, numero*c);
 
        c++;
 
    }
 
  
     return (EXIT_SUCCESS);
+
     escolhe tempo
}
+
        caso 11:
 +
            escrever "Chuvas abundantes e ventos de sul a sudoeste fortes"
 +
        caso 12:
 +
            escrever "Chuva Provavel , ventos de sul a sudeste"
 +
        caso 13:
 +
            escrever "Tempos Bons , ventos de sul a sudeste"
 +
        caso 21:
 +
            escrever "Frente quente com chuva provavel"
 +
        caso 22:
 +
            escrever "Tempo Incerto , ventos variaveis"
 +
        caso 23:
 +
            escrever "Tempos Bons , ventos do leste frescos"
 +
        caso 31:
 +
            escrever " Tempo instavel , aproximaçao de frente"
 +
        caso 32:
 +
            escrever "Tempo Mudando para bom , ventos de leste"
 +
        caso 33:
 +
            escrever "Tempos Bons , ventos quentes e secos"
 +
        defeito:
 +
            escrever "Utilize somente os algorismos de 1 a 3 para indicar as condiçoes do equipamentos"
 +
    fimescolhe
 +
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
# Reescreva o programa anterior, mas usando uma função para mostrar a tabuada. <syntaxhighlight lang=c>
+
*# <syntaxhighlight lang=text>
#include <stdio.h>
+
inicio
 
+
     // coeficientes do polinomio  [ax^2 + bx + c = 0 ]
int tabuada(int num) {
+
     real a , b , c
     int c = 1;
+
   
     while (c < 11) {
+
    escrever "Forneça os coeficientes da equação de 2o grau:\n"
        printf("%d X %d = %d\n", num, c, num*c);
+
     escrever "a="
        c++;
+
     ler a
     }
+
     escrever "b="
 
+
     ler b
}
+
    escrever "c="
int main(int argc, char** argv) {
+
     ler c
 
 
     int numero, c;
 
 
 
     printf("Numero: ");
 
     scanf("%d", &numero);
 
 
 
     tabuada(numero);
 
 
      
 
      
     return (EXIT_SUCCESS);
+
     // equação do tipo [ bx + c = 0 ]
}
+
    se a = 0 entao
 +
        escrever " não é uma equação de 2o grau !!!"
 +
    senao
 +
        // calcular o delta => interior da raiz
 +
        real delta
 +
       
 +
        delta <- b ^ 2 - 4 * a * c
 +
       
 +
        // não existem raizes  reais de números negativos
 +
        se delta < 0 entao
 +
            escrever " não tem raizes reais"
 +
        senao
 +
            // -----------  raiz dupla  ----------------
 +
            se delta = 0 entao
 +
                real x1
 +
                x1 <- -b / 2 * a
 +
                escrever "\nraiz dupla : " , x1
 +
            senao
 +
                // - ---------- duas raizes ---------------
 +
                real x1 , x2
 +
                x1 <- ( -b + raiz ( delta ) ) / 2 * a
 +
                x2 <- ( -b - raiz ( delta ) ) / 2 * a
 +
                escrever "\nraiz x1 : " , x1
 +
                escrever "\nraiz x2 : " , x2
 +
            fimse//raiz dupla
 +
        fimse// delta >0
 +
    fimse// a <> 0
 +
fim
 
</syntaxhighlight>
 
</syntaxhighlight>
# Modifique o programa anterior para mostrar a tabuada de todos os números entre 1 e 10. Obs: não modifique a função tabuada!
+
*# <syntaxhighlight lang=text>
# Escreva um programa para ler 10 números do teclado, e em seguida mostrar o maior e o menor número.
+
inicio
# Reescreva o programa anterior, mas criando as função "maior" e "menor", que retornam o maior e menor número de um vetor de tamanho arbitrário.
+
    inteiro num, bit
 +
    inteiro base
 +
   
 +
    escrever "Este algoritmo converte um número inteiro para sua representação binária.\n"
 +
    Escrever "O número deve estar entre 0 e 131071, e a representação binária\n"
 +
    escrever "terá 17 bits\n\n"
 +
    escrever "Digite o numero a ser convertido para binário: "
 +
    ler num
  
==03/06 e 04/06: Feriado Nacional ==
+
    base <- 65536
 +
    enquanto base > 0 faz
 +
        bit <- ( num / base ) % 2
 +
        escrever bit, " "
 +
        base <- base / 2
 +
    fimenquanto
 +
fim
 +
</syntaxhighlight>
 +
*# <syntaxhighlight lang=text>
 +
inicio
 +
    inteiro n , fat
 +
    ler n
 +
    fat <- 1
 +
    enquanto n > 1 faz
 +
      fat <- fat * n
 +
      n <- n - 1       
 +
    fimenquanto
 +
   
 +
    escrever "Fatorial=" , fat
 +
fim
 +
</syntaxhighlight>
 +
*# <syntaxhighlight lang=text>
 +
inicio
 +
    inteiro valor , menor , contador
 +
    ler menor
 +
    contador <- 9
 +
    enquanto contador > 0 faz
 +
        ler valor
 +
        se valor < menor entao
 +
            menor <- valor
 +
        fimse
 +
        contador <- contador - 1
 +
    fimenquanto
 +
    escrever "menor valor = ", menor
 +
fim
 +
</syntaxhighlight>
 +
*# <syntaxhighlight lang=text>
 +
inicio
 +
    inteiro numero , n , resto <- 1
 +
    escrever "Forneçaa um número: "
 +
    ler numero
 +
    n <- 2
 +
    enquanto n <= numero / 2 e resto =/= 0 faz
 +
        resto <- numero % n
 +
        escrever "n=" , n , ": resto=" , resto , "\n"
 +
        n <- n + 1
 +
    fimenquanto
 +
   
 +
    se resto = 0 entao
 +
        escrever "nao primo: divisivel por " , n - 1
 +
    senao
 +
        escrever "primo"
 +
    fimse
 +
fim
 +
</syntaxhighlight>
 +
*# <syntaxhighlight lang=text>
 +
// Le 5 valores e identifica os dois maiores.
 +
inicio
 +
    inteiro valor , maior1 , maior2 , contador
 +
   
 +
    ler valor
 +
    maior1 <- valor
 +
   
 +
    ler valor
 +
    se valor > maior1 entao
 +
      maior2 <- maior1
 +
      maior1 <- valor
 +
    senao
 +
      maior2 <- valor
 +
    fimse
 +
 
 +
    contador <- 3
 +
    enquanto contador > 0 faz
 +
        ler valor
 +
        se valor > maior1 entao
 +
            maior2 <- maior1
 +
            maior1 <- valor
 +
        senao
 +
            se valor > maior2 entao
 +
                maior2 <- valor
 +
            fimse
 +
        fimse
 +
        contador <- contador - 1
 +
    fimenquanto
 +
 
 +
    escrever "maior valor = " , maior1
 +
    escrever "\nsegundo maior valor = " , maior2
 +
fim
 +
</syntaxhighlight>
  
 +
== 08/11: Linguagem C ==
  
==10/06: Os navios (etapas 4, 5, 6 e 7) ==
+
* Vista de prova (Lógica de programação)
 
+
* Refaça a avaliação completa em linguagem C
* '''Continuando a representar os navios ...  por enquanto somente os submarinos'''
+
* Utilize a IDE NetBeans.
** Ainda há o problema de ''esconder'' as casas do tabuleiro ainda não acertadas por tiros: a existência de um navio ou água em uma casa somente pode ser revelada após ser atingida por um tiro.
+
 
 
+
==11/11: Projeto Final da Disciplina==
* '''A primeira versão do jogo: atirando no tabuleiro até descobrir todos os submarinos'''
+
=== O jogo: Campo Minado ===
** Como ler do teclado as coordenadas de um tiro ?
+
 
** Como contabilizar se acertou em mais um submarino, ou se foi água ?
+
O [http://pt.wikipedia.org/wiki/Campo_minado ''Campo Minado''] é um jogo clássico disponível em diferentes sistemas operacionais. Basicamente devem-se procurar as minas existentes em um campo quadriculado, perdendo-se o jogo se ''pisar'' em uma mina, e vencendo se descobrir todas as minas. O jogo  oferece pistas sobre a localização das minas, e usando-se um  pouco de lógica podem-se encontrá-las. Uma  versão desse jogo para Linux aparece na figura a seguir .
** Como identificar que o jogador acertou todos os submarinos, e assim terminar o jogo ?
+
 
** Como contabilizar quantos tiros foram dados até descobrir todos os submarinos ?
+
[[imagem:Minas-linux.png]]
 
+
 
* '''Tópico sobre linguagem C: continuando [[SOP-funcoes|funções]]'''
+
A cada jogada deve-se escolher uma casa do tabuleiro, optando-se por ''pisá-la'' (revelando-a) ou marcá-la como uma provável mina. Ao ''pisar'' numa casa, três ações podem ocorrer:
** ... mais especificamente: passagem de parâmetros por '''''valor''''' e por '''''referência'''''
+
# A casa contém uma mina, o que revela  todas as demais minas e encerra o jogo com derrota.
 
+
# A casa é vizinha a uma ou mais minas, e assim em seu lugar aparece o número de minas em casas vizinhas.
=== O laço principal do jogo ... ===
+
# Nenhuma mina existe em casas vizinhas, então a casa aparece vazia. Além disso, todas as casas vizinhas que também  não possuam minas são reveladas.
 
+
 
O jogo funciona com um laço principal, que lê as coordenadas do tiro e atualiza o tabuleiro apropriadamente:
+
Ao final do jogo, a pontuação é dada pelo tempo que se levou para se descobrirem as minas. O jogo contabiliza uma lista de melhores jogadas, contendo o nome do jogador e o tempo de jogo. Melhores jogadas são aquelas com menores tempos de jogo.
 
+
 
[[imagem:Batalha-naval1.png|300px]]
+
A versão do jogo a ser desenvolvida será baseada em texto ''(mas quem quiser fazer uma versão gráfica fique à vontade !)''. Basicamente  deve ser apresentado o tabuleiro, mostrando-se apenas as casas já reveladas e o tempo de jogo decorrido, e um ''prompt'' pedindo as coordenadas da próxima casa assim como o tipo de ação (se ''pisar'' na casa ou marcar a provável existência de uma mina).
 
+
 
Note que nesse laço devem-se contabilizar tanto quantos tiros já foram dados, quanto os navios que foram acertados. Esse último valor é necessário para decidir se o jogo já acabou.
+
=== Etapas de desenvolvimento ===
 
+
 
==11/06: Desenvolvimento do Projeto Final==
+
* Proposta de código que contempla:
 
+
** Bibliotecas e definições
===Expansões Propostas===
+
** Declaração de constantes e variáveis
 
+
*** Uso de variáveis com mesmo nome e diferentes escopos
* Limitar a quantidade de tiros (dobro do número de barcos, por exemplo) e, caso o usuário não atinja todos os barcos, deve-se mostrá-los na tela.
+
*** Vetor e matriz
* Oferecer a opção para o usuário escolher a dificuldade do jogo:
+
** Operadores lógicos e matemáticos
**''''1' - Nível Fácil''' (número de tiros igual ao número de posições da matriz),
+
** Expressões
**''''2' - Nível Normal''' (número de tiros igual a 3 vezes o número de barcos no tabuleiro),
+
*** E/S
**''''3' - Nível Difícil''' (número de tiros igual a quantidade de barcos inseridos no tabuleiro).
+
*** Estruturas de decisão e repetição
* Tratar exceções de E/S, incluindo números fora dos limites - como por exemplo um barco fora do "mar".
+
** Funções
* Alterar a interface para utilizar números para linhas e letras para colunas, além de permitir barcos de 3 tamanhos (sempre desenhados na horizontal): uma "casa", três "casas" e quatro "casas".
+
*** Passagem de parâmetro por valor e por referência
* Os barcos podem ser desenhados tanto na horizontal como na vertical.
+
** Acesso a uma matriz através de um vetor linear (função <tt>iniciaJogo</tt>)
* Gerar tiros aleatórios caso seja solicitado pelo usuário.
+
** Ponteiros
* Posicionamento dos barcos no tabuleiro também de forma aleatória caso seja solicitado pelo usuário.
+
 
* Informar a posição dos tiros e barcos por letra e número (como no jogo tradicional). Ex.: posição <tt>A1</tt>.
+
=== O laço principal do jogo ... ===
 
+
 
===Dicas===
+
O jogo funciona com um laço principal, que lê as coordenadas da pŕoxima casa e a ação a ser feita, e atualiza o tabuleiro apropriadamente:
* Entenda o problema, modele-o: utilize sempre que possível pseudocódigo / diagrama de bloco.
+
 
* Defina entradas, processamento e saídas do programa.
+
[[imagem:Fluxo-Campo-Minado.png|400px]]
* Primeiro declare as variáveis, depois realize as expressões lógicas e matemáticas.
+
 
* Deixe claro (documente e idente o seu código) o escopo de cada função (principalmente o fim) das estrutura de decisão e de repetição (quando não forem visíveis início e fim na mesma tela).
+
Note que nesse laço devem-se contabilizar quantas minas fora descobertas. Esse valor é necessário para decidir se o jogo já acabou.
 
+
 
==17/06: Desenvolvimento do Projeto Final==
+
=== O tabuleiro ===
 
+
 
* Dicas para utilização da função '''rand()''':
+
Representar o tabuleiro: etapas X a Y.
 
+
 
<syntaxhighlight lang=c>
+
O tabuleiro do campo minado deve ser representado em formato de texto conforme a figura abaixo. Nesta figura, o tabuleiro está completamente revelado.
 
+
 
#include <stdio.h>
+
[[imagem:Tabuleiro-Minado.png]]
#include <stdlib.h>
+
 
#include <time.h>
+
As colunas são identificadas por letras maiúsculas, e as linhas por números. Cada casa do tabuleiro pode conter uma mina ou um número que conta quantas minas existem em casas vizinhas. Casas já reveladas devem mostrar essa contagem de minas vizinhas, sendo que se não houver  minas a casa deve ser mostrada vazia (preenchida com espaço). Casa em  que se marcou a existência de uma mina deve mostrar a letra '''M'''. Por fim, casas ainda não reveladas devem ser preenchidas com o caractere '''?'''. Um tabuleiro parcialmente revelado apareceria como a figura abaixo.
 
+
 
int main (){
+
[[imagem:Tabuleiro-Minado2.png]]
 +
 
 +
==== Etapa 1: Modelando  o tabuleiro ====
 +
 
 +
Conteúdos abordados:
 +
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c300.html declaração de variáveis]
 +
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c940.html saída de dados na tela]
 +
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c500.html Matrizes]
 +
 
 +
Deve-se nessa etapa escolher uma forma de representar o tabuleiro dentro do programa. Devem-se pensar também  em como representar as casas do campo minado:
 +
* Como definir que uma casa possui uma mina ?
 +
* Como definir que uma casa está  vazia ? Nesse caso, como informar a quantidade de minas em casas vizinhas ?
 +
* Como definir se uma casa já foi pisada ?
 +
 
 +
Ponto de partida para mostrar um tabuleiro na tela. O tabuleiro foi modelado como uma matriz de inteiros bidimensional.
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
int main(int argc, char** argv) {
 +
    int tabuleiro[5][5] = { {0,0,1,1,0}, {1,1,2,0,0}, {10,1,0,0,0},
 +
                          {1,1,1,0,0}, {0,0,0,0,10} };
 +
    int i, j;
 +
 
 +
    //i indica a linha, j a coluna
 +
 
 +
    for (i=0;i<5;i++){
 +
        printf("\n");
 +
        for (j=0;j<5;j++){
 +
            printf("%d ", tabuleiro[i][j]);
 +
 
 +
        }
 +
    }
 +
    return (EXIT_SUCCESS);
 +
}
 +
 
 +
</syntaxhighlight>
 +
 
 +
Cada casa dessa matriz contém um número inteiro. Para representar o estado de cada casa do tabuleiro sugeriu-se um código numérico:
 +
* ''Casa com mina:'' algum número > 8
 +
* ''Casa sem mina:'' um número que conte quantas minas existem em casas vizinhas. Tal número estará entre 0 e 8.
 +
 
 +
==18/11: Montando o tabuleiro completo==
 +
 
 +
Conteúdos abordados:
 +
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c300.html declaração de variáveis]
 +
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c530.html matrizes de números]
 +
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c940.html saída de dados na tela]
 +
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c410.html estrutura de decisão: ''if'']
 +
* [http://www.ead.cpdee.ufmg.br/cursos/C/aulas/c440.html estrutura de repetição: ''while'']
 +
 
 +
=== Desenhando o tabuleiro completo ===
 +
 
 +
Dando continuidade à visualização do tabuleiro, agora deve-se desenhá-lo por completo na tela.
 +
Mostrar um tabuleiro com 10 linhas e 10 colunas, seguindo a abordagem da [[SOP-2010-2-sobral#08.2F11:_Come.C3.A7o_do_projeto|aula anterior]].
 +
 
 +
==== Explorando ''printf'' para mostrar dados na tela ====
 +
 
 +
A função [http://manpages.ubuntu.com/manpages/intrepid/man3/printf.3.html printf] mostra dados na tela de acordo com um formato (daí seu nome: ''printf = print formatted'', ou ''imprima formatado''). O exemplo mais simples de uso do ''printf'' faz com que seja mostrada somente uma constante de texto, como a seguir:
 +
 
 +
<syntaxhighlight lang=c>
 +
printf("Apenas uma constante de texto ...\n");
 +
</syntaxhighlight>
 +
 
 +
O resultado na tela é:
 +
 
 +
Apenas uma constante de texto ...<br>
 +
 
 +
Porém ''printf'' faz muito mais do que isso. Um segundo uso envolve mostrar dados que misturam constantes de texto e valores numéricos:
 +
 
 +
<syntaxhighlight lang=c>
 +
int voltas = 15;
 +
float pi = 3.1416;
 +
 
 +
printf("Contador de voltas = %d\n", voltas);
 +
printf("Angulo da volta atual = %f radianos\n", pi);
 +
</syntaxhighlight>
 +
 
 +
Na tela será mostrado o seguinte:
 +
 
 +
Contador  de voltas = 15
 +
Angulo da volta atual = 3.1416 radianos
 +
 
 +
Esse segundo exemplo mostra como especificar o formato do que deve aparecer na tela. O formato é o primeiro argumento da função ''printf'', e ele contém uma especificação do texto que deve aparecer na tela. Nesse texto podem-se indicar valores a serem substituídos (eles aparecem prefixados com ''%''), os quais devem ser fornecidos nos demais argumentos da função. No primeiro ''printf'' do exemplo acima, o formato é:
 +
 
 +
"Contador de voltas = %d\n"
 +
 
 +
Nesse texto, toda sequência de caracteres que iniciar com ''%'' indica que ali deve-se substituir por um valor. Dependendo da letra que vier depois de ''%'', o tipo de valor será ''int'' (inteiro), ''float'' (real), ''double'' (real com mais casas), ''char'' (caractere), ''string'' (texto). A tabela  abaixo exemplifica os diferentes tipos de valores que podem ser especificados no formato da função ''printf'':
 +
 
 +
{| border="1" cellpadding="2"
 +
!Tipo de dados
 +
!Formato
 +
!Exemplo
 +
!O que aparece na tela
 +
|-
 +
|int||%d||<syntaxhighlight lang=c>int horas=2;
 +
 
 +
printf("Já se passaram %d horas ...\n", horas);</syntaxhighlight>||Já se passaram 2 horas ...
 +
|-
 +
|char||%c||<syntaxhighlight lang=c>char letra = 'S';
 +
 
 +
printf("Você digitou a letra %c !\n", letra);</syntaxhighlight>|| Você digitou a letra S !
 +
|-
 +
|float||%f||<syntaxhighlight lang=c>float media = 4.5;
 +
 
 +
printf("Média calculada=%f\n", media);</syntaxhighlight>|| Média calculada=4.5
 +
|-
 +
|double||%g||<syntaxhighlight lang=c>double angulo = 0.1122333;
 +
 
 +
printf("Angulo=%g\n", angulo);</syntaxhighlight>|| Angulo=0.111222333
 +
|-
 +
|char * ''(string)''||%s||<syntaxhighlight lang=c>char * nome = "Filomena";
 +
 
 +
printf("Cara sra. %s ...",  nome);</syntaxhighlight>||Cara sra. Filomena ...
 +
|}
 +
 
 +
Para substituir mais de um valor,  basta especificar no formato e fornecer os valores nos demais argumentos:
 +
 
 +
<syntaxhighlight lang=c>
 +
int hora = 10, minuto = 5, segundo = 0;
 +
 
 +
printf("Horario: %d:%d:%d\n", hora, minuto, segundo);
 +
</syntaxhighlight>
 +
 
 +
... o que faz aparecer na tela:
 +
 
 +
Horario: 10:5:0
 +
 
 +
Esse último exemplo poderia ser melhorado, pois o horário ficou esquisito de ler ... normalmente costumamos ver horas,  minutos e segundos com dois algarismos, como a seguir:
 +
 
 +
Horario: 10:05:00
 +
 
 +
É possível fazer com que ''printf'' faça isso automaticamente, bastando especificar o seguinte no formato:
 +
 
 +
<syntaxhighlight lang=c>
 +
int hora = 10, minuto = 5, segundo = 0;
 +
 
 +
printf("Horario: %02d:%02d:%02d\n", hora, minuto, segundo);
 +
</syntaxhighlight>
 +
 
 +
Note que ao invés de ''%d'' se especificou ''%02d''. Esse formato  faz com que se mostre um número  inteiro com no mínimo dois algarismos. Caso o número tenha somente  um algarismo, ''printf'' automaticamente  adiciona  um ''0'' à esquerda. Isso funciona somente para formatos  numéricos.
 +
 
 +
Além de acrescentar zeros à esquerda de valores numéricos, é possível tabular os valores mostrados de forma que ocupem uma certa quantidade de colunas. Por exemplo, caso se deseje mostrar o seguinte:
 +
 
 +
Nome        Idade        Sexo
 +
Marcelo      39          M
 +
Marina      9            F
 +
Luis        11          M
 +
 
 +
... pode-se fazer assim:
 +
 
 +
<syntaxhighlight lang=c>
 +
printf("%-12s %-12s %s\n", "Nome", "Idade", "Sexo");
 +
printf("%-12s %-12d %c\n", "Marcelo", 39, 'M');
 +
printf("%-12s %-12d %c\n", "Marina", 9, 'F');
 +
printf("%-12s %-12d %c\n", "Luis", 11, 'M');
 +
</syntaxhighlight>
 +
 
 +
Note que desta vez adicionou-se após ''%'' a sequência ''-12''. Isso indica que o valor a ser mostrado deve ocupar no mínimo 12 posições, preenchendo-se com espaços caso necessário. Veja  que os valores foram alinhados à esquerda. Caso se deseje que sejam  alinhados à direita,  basta fazer assim:
 +
 
 +
<syntaxhighlight lang=c>
 +
printf("%12s %12s %s\n", "Nome", "Idade", "Sexo");
 +
printf("%12s %12d %c\n", "Marcelo", 39, 'M');
 +
printf("%12s %12d %c\n", "Marina", 9, 'F');
 +
printf("%12s %12d %c\n", "Luis", 11, 'M');
 +
</syntaxhighlight>
 +
 
 +
... e assim aparecerá o seguinte na tela:
 +
 
 +
        Nome        Idade Sexo
 +
    Marcelo          39 M
 +
      Marina            9 F
 +
        Luis          11 M
 +
 
 +
=== Colocando as minas ===
 +
 
 +
No tabuleiro devem ser colocadas 10 minas aleatoriamente. Isso significa que para cada uma dessas minas, devem-se gerar aleatoriamente  suas coordenadas no tabuleiro. A geração de números aleatórios pode ser feita usando-se a função [http://manpages.ubuntu.com/manpages/lucid/man3/random.3.html random()]. Essa função gera um número inteiro entre 0 e 2147483647. Para usá-la no tabuleiro, pode-se fazer o seguinte:
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdlib.h>
 +
 
 +
int main() {
 +
  int x, y;
 +
 
 +
  // gera dois números aleatórios entre 0 e 9, e guarda-os nas variáveis x e y
 +
  x = random() % 10;
 +
  y = random() % 10;
 +
 
 +
}
 +
</syntaxhighlight>
 +
 
 +
=== Mais sobre a função random() ===
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <sys/time.h>
 +
 
 +
int main() {
 +
  int x,y,z;
 +
  time_t t;
 +
 
 +
  // Lê o valor do relógio
 +
  t = time(NULL);
 +
 
 +
  // Usa o valor do relógio como semente do gerador de números
 +
  // pseudo-aleatórios.
 +
  srandom(t);
 +
 
 +
  // Sorteia três números pseudo-aleatórios
 +
  x = random() % 10;
 +
  y = random() % 10;
 +
  z = random() % 10;
 +
 
 +
  printf("x=%d, y=%d, z=%d\n", x, y, z);
 +
}
 +
</syntaxhighlight>
 +
 
 +
A versão atual do jogo está assim:
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
 
 +
#define MINAS 10
 +
#define LINHAS 10
 +
#define COLUNAS 10
 +
 
 +
#define TEM_MINA 10
 +
 
 +
/*
 +
*
 +
*/
 +
int main(int argc, char** argv) {
 +
    int tabuleiro[LINHAS][COLUNAS];
 +
    int i, j;
 +
 
 +
    // Zerar todas as posições do tabuleiro !
 +
    i = 0;
 +
    while ( i < LINHAS) {
 +
        j = 0;
 +
        while (j < COLUNAS) {
 +
            tabuleiro[i][j] = 0;
 +
            j++;
 +
        }
 +
        i++;
 +
    }
 +
   
 +
    // Colocar as minas aqui !!!
 +
 
 +
    //Agora mostrar o tabuleiro que foi gerado
 +
 
 +
    //i indica a linha, j a coluna
 +
    i = 0;
 +
    while (i < LINHAS) {
 +
        // O while abaixo mostra todas as colunas da linha "i"
 +
        j = 0;
 +
        while (j < COLUNAS) {
 +
            if (tabuleiro[i][j] == TEM_MINA) {
 +
                printf("* ");
 +
            } else {
 +
                if (tabuleiro[i][j] == 0) {
 +
                    printf("  ");
 +
                } else {
 +
                    if ((tabuleiro[i][j] >= 1) && (tabuleiro[i][j] <= 8)) {
 +
                        printf("%d ", tabuleiro[i][j]);
 +
                    }
 +
                }
 +
            }
 +
            j++;
 +
        }
 +
 
 +
        printf("\n");
 +
        i++;
 +
    }
 +
 
 +
    return (EXIT_SUCCESS);
 +
}
 +
</syntaxhighlight>
 +
 
 +
=== Meta desta semana ===
 +
 
 +
Nesta semana  o seu programa deve ser capaz de:
 +
# Representar o tabuleiro com uma matriz de inteiros bidimensional.
 +
# Mostrar o tabuleiro na tela, indicando o que existe em cada casa. O tabuleiro deve ser apresentado  ''enfeitado'', o que significa que deve mostrar uma grade para separar as casas e a identificação de linhas e colunas. Linhas  devem ser identificadas numericamente, e colunas devem ser identificadas por letras (ex: primeira coluna=A, segunda coluna=B, ...).
 +
# Colocar minas aleatoriamente no tabuleiro.
 +
 
 +
O seu programa cumprindo as metas acima '''deve ser apresentado ao professor na próxima aula (22/11), já sendo parte da avaliação desta unidade'''.
 +
 
 +
 
 +
===Funções===
 +
 
 +
* Material de aula Prof. Marcelo [http://wiki.sj.ifsc.edu.br/index.php/SOP-funcoes funções]
 +
* [[SOP-funcoes|Texto introdutório sobre funções na linguagem C]]
 +
 
 +
==== Escopo de variáveis ====
 +
 
 +
* Texto obtido de: [http://www.inf.pucrs.br/~pinho/LaproI/Funcoes/AulaDeFuncoes.htm Uso de funções em C]
 +
 
 +
Por escopo de uma variável entende-se o bloco de código onde esta variável é válida. Com base nisto, temos as seguintes afirmações:
 +
* As variáveis valem no bloco que são definidas;
 +
* As variáveis definidas  dentro de uma função recebem o nome de '''''variáveis locais'''''
 +
* As variáveis declaradas fora de qualquer função são chamadas de '''''variáveis globais'''''
 +
* Os parâmetros formais de uma função (também conhecidos como ''argumentos da função'') valem também somente dentro da função;
 +
* Uma variável definida dentro de uma função não é acessível em outras funções, MESMO QUE ESSAS VARIÁVEIS TENHAM NOMES IDÊNTICOS.
 +
 
 +
===== Variáveis locais =====
 +
 
 +
No trecho de código a seguir tem-se um exemplo com funções e variáveis com nomes iguais.
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
void FUNC1() {
 +
  int B;
 +
 
 +
  B = -100;
 +
  printf("Valor de B dentro da função FUNC1: %d\n", B);
 +
}
 +
 
 +
void FUNC2() {
 +
  int B;
 +
 
 +
  B = -200;
 +
  printf("Valor de B dentro da função FUNC2: %d\n", B);
 +
}
 +
 
 +
void main() {
 +
  int B;
 +
 
 +
  B = 10;
 +
  printf("Valor de B: %d\n", B);
 +
  B = 20;
 +
  FUNC1();
 +
  printf("Valor de B: %d\n", B);
 +
  B = 30;
 +
  FUNC2();
 +
  printf("Valor de B: %d\n", B);
 +
}
 +
</syntaxhighlight>
 +
 
 +
O resultado de sua execução deve ser:
 +
 
 +
<syntaxhighlight lang=text>
 +
Valor de B: 10
 +
Valor de B dentro da função FUNC1: -100
 +
Valor de B: 20
 +
Valor de B dentro da função FUNC2: -200
 +
Valor de B: 30
 +
</syntaxhighlight>
 +
 
 +
===== Variáveis globais =====
 +
 
 +
O seguinte exemplo mostra o mesmo programa, porém fazendo com que a variável B seja global:
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
// Declaração da variável global B
 +
int B;
 +
 
 +
void FUNC1() {
 +
  B = -100;
 +
  printf("Valor de B dentro da função FUNC1: %d\n", B);
 +
}
 +
 
 +
void FUNC2() {
 +
  B = -200;
 +
  printf("Valor de B dentro da função FUNC2: %d\n", B);
 +
}
 +
 
 +
void main() {
 +
  B = 10;
 +
  printf("Valor de B: %d\n", B);
 +
  B = 20;
 +
  FUNC1();
 +
  printf("Valor de B: %d\n", B);
 +
  B = 30;
 +
  FUNC2();
 +
  printf("Valor de B: %d\n", B);
 +
}
 +
</syntaxhighlight>
 +
 
 +
O resultado de sua execução deve ser:
 +
 
 +
<syntaxhighlight lang=text>
 +
Valor de B: 10
 +
Valor de B dentro da função FUNC1: -100
 +
Valor de B: -100
 +
Valor de B dentro da função FUNC2: -200
 +
Valor de B: -200
 +
</syntaxhighlight>
 +
 
 +
E se existir um variável local  com mesmo nome que uma global ? nesse caso, a variável local vai ''esconder'' a sua homônima global:
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
// Declaração da variável global B
 +
int B;
 +
 
 +
void FUNC1() {
 +
  //  no escopo desta função, esta variável local vai esconder a variável global B!
 +
  int B;
 +
 
 +
  B = -100;
 +
  printf("Valor de B dentro da função FUNC1: %d\n", B);
 +
}
 +
 
 +
void FUNC2() {
 +
  B = -200;
 +
  printf("Valor de B dentro da função FUNC2: %d\n", B);
 +
}
 +
 
 +
void main() {
 +
  B = 10;
 +
  printf("Valor de B: %d\n", B);
 +
  B = 20;
 +
  FUNC1();
 +
  printf("Valor de B: %d\n", B);
 +
  B = 30;
 +
  FUNC2();
 +
  printf("Valor de B: %d\n", B);
 +
}
 +
</syntaxhighlight>
 +
 
 +
O resultado de sua execução deve ser:
 +
 
 +
<syntaxhighlight lang=text>
 +
Valor de B: 10
 +
Valor de B dentro da função FUNC1: -100
 +
Valor de B: 20
 +
Valor de B dentro da função FUNC2: -200
 +
Valor de B: -200
 +
</syntaxhighlight>
 +
 
 +
=== Para fixar ===
 +
 
 +
# Escreva  o programa para mostrar a tabuada de um  número lido do teclado. <syntaxhighlight lang=c>
 +
#include <stdlib.h>
 +
#include <stdio.h>
 +
 
 +
/*
 +
*
 +
*/
 +
int main(int argc, char** argv) {
 +
 
 +
    int numero, c;
 +
 
 +
    printf("Numero: ");
 +
    scanf("%d", &numero);
 +
 
 +
    c = 1;
 +
    while (c < 11) {
 +
        printf("%d X %d = %d\n", numero, c, numero*c);
 +
        c++;
 +
    }
 +
 
 +
    return (EXIT_SUCCESS);
 +
}
 +
</syntaxhighlight>
 +
# Reescreva o programa anterior, mas usando uma função para mostrar a tabuada. <syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
int tabuada(int num) {
 +
    int c = 1;
 +
    while (c < 11) {
 +
        printf("%d X %d = %d\n", num, c, num*c);
 +
        c++;
 +
    }
 +
 
 +
}
 +
int main(int argc, char** argv) {
 +
 
 +
    int numero, c;
 +
 
 +
    printf("Numero: ");
 +
    scanf("%d", &numero);
 +
 
 +
    tabuada(numero);
 +
   
 +
    return (EXIT_SUCCESS);
 +
}
 +
</syntaxhighlight>
 +
# Modifique o programa anterior para mostrar a tabuada de todos os números entre 1 e 10. Obs: não modifique a função tabuada!
 +
# Escreva um  programa para ler 10 números do teclado, e em seguida mostrar o maior e o menor número.
 +
# Reescreva o programa anterior, mas criando as função "maior" e "menor", que retornam o maior e menor número de um vetor de tamanho arbitrário.
 +
 
 +
==22/11: Campo Minado ==
 +
 
 +
Para referência: [http://www.ead.cpdee.ufmg.br/cursos/C/c.html apostila online sobre linguagem C].
 +
 
 +
* '''Tópico sobre linguagem C: continuando [[SOP-funcoes|funções]]'''
 +
** ... mais especificamente: passagem de parâmetros por '''''valor''''' e por '''''referência'''''
 +
 
 +
=== Escondendo as casas não pisadas ===
 +
 
 +
No momento você deve já conseguir mostrar todo o tabuleiro, porém no jogo apenas as casas já pisadas devem ser reveladas. Pense em como modelar o seu tabuleiro de forma a esconder as casas ainda não pisadas.
 +
 
 +
=== Retomando o laço principal do jogo ... ===
 +
 
 +
O jogo funciona com um laço principal, que lê as coordenadas da casa a ser pisada ou marcada e atualiza o tabuleiro apropriadamente:
 +
 
 +
Note que nesse laço devem-se contabilizar quantas minas foram realmente descobertas - o que não corresponde necessariamente a quantas minas foram  marcadas ... A quantidade de minas descobertas é necessária para decidir se o jogo já acabou.
 +
 
 +
[[imagem:Fluxo-Campo-Minado.png|400px]]
 +
 
 +
==25/11: Campo Minado==
 +
 
 +
===Ponteiros em linguagem C===
 +
 
 +
Ponteiros é uma característica poderosa oferecida pela linguagem C. A linguagem de programação C depende muito dos ponteiros, assim, um bom programador em C precisa dominar bem ponteiros.
 +
 
 +
Ponteiro é visto pela maior parte dos programadores  iniciantes como uma das partes mais difíceis na linguagem C, pois o conceito de ponteiros pode ser novo ou um mesmo símbolo usado para certa finalidade e usado para outra diferente, tornando mais difícil o entendimento.
 +
 
 +
Entendendo o que é um ponteiro
 +
 
 +
Um ponteiro é uma variável que guarda um endereço de memória de outra variável. Os ponteiros da linguagem C proporcionam uma forma fácil de acesso ao valor de variáveis sem referenciá-las diretamente. Um ponteiro possui tipo, por exemplo, inteiros, ponto flutuante e caracteres. O tipo do ponteiro indica que tipo é a variável para qual ele aponta.
 +
 
 +
Um ponteiro é declarado a seguinte forma:
 +
 
 +
<syntaxhighlight lang=text>
 +
tipo_do_ponteiro *nome_do_ponteiro
 +
</syntaxhighlight>
 +
 
 +
Exemplo:
 +
<syntaxhighlight lang=c>
 +
 
 +
int *p, *a;
 +
char *pt, *ponteiro;
 +
 
 +
</syntaxhighlight>
 +
 
 +
No exemplo acima foram criados quatro ponteiros, dois de tipo inteiro e dois de tipo caractere. É importante não confundir o asterisco (*), que indica que a variável é um ponteiro, com o mesmo sinal indicando uma multiplicação.
 +
 
 +
Conhecendo os operadores
 +
 
 +
Sempre é importante iniciar o ponteiro. Um ponteiro sempre é iniciado com o local na memória onde se localiza o valor da variável. Para iniciar a variável desejada como o endereço de memória, segue o exemplo:
 +
 
 +
<syntaxhighlight lang=c>
 +
 
 +
int variavel_apontada=2;
 +
int *ponteiro;
 +
ponteiro=&variavel_apontada;
 +
 
 +
</syntaxhighlight>
 +
 
 +
No exemplo foi criada uma variável e iniciada com valor 2, foi criado também um ponteiro que logo abaixo foi iniciado com o endereço da variável chamada variável_apontada.
 +
 
 +
A linguagem de programação C oferece dois operadores unitários, o operador de endereço (&) e o operador indireto (*). O operador de endereço retorna o endereço de memória onde fica localizado a variável, como foi mostrado no exemplo acima. O operador indireto retorna o valor da variável para qual o ponteiro aponta. Por exemplo:
 +
 
 +
<syntaxhighlight lang=c>
 +
 
 +
main() {
 +
  int var, *p;
 +
  var=10;
 +
  p=&var;
 +
  printf("O valor da variavel eh: %d \n", *p);
 +
  printf("O endereco de memoria da variavel eh: %p \n", p);
 +
  printf("O endereco de memoria do ponteiro eh: %p \n", &p);
 +
  *p=15;
 +
  printf("O novo valor da variavel e': %d \n", var);
 +
  return (0);   
 +
}
 +
</syntaxhighlight>
 +
 
 +
A saída será:
 +
 
 +
<syntaxhighlight lang=text>
 +
O valor da variavel eh: 10
 +
O endereco de memoria da variavel eh: 00AE4F6
 +
O endereco de memoria do ponteiro eh: 00AE4F8
 +
O novo valor da variavel eh: 15
 +
</syntaxhighlight>
 +
 
 +
No exemplo, usam-se os operadores para imprimir e aterá o valor da variável. Onde o endereço de memória varia de cada computador.
 +
 
 +
O ponteiro é usado em situações em que a passagem de valores é complicada, por isso é muito importante seu aprendizado. O conceito de ponteiro e seu uso podem, aparentemente, ser complicado, porém, não é muito difícil. O uso indevido e insensato de ponteiros pode causar sérios bugs em um programa e até comprometer todo o sistema, assim, é necessário cuidado quando se usa eles.
 +
 
 +
===Outro exemplo===
 +
 
 +
Considere a declaração do ponteiro abaixo:
 +
<syntaxhighlight lang=text>
 +
int *pa
 +
</syntaxhighlight>
 +
 
 +
A instrução acima indica que pa é um ponteiro do tipo int. Agora veremos como atribuir valor ao ponteiro declarado. Para isto é necessário saber que existem dois operadores unitários que são utilizados com os ponteiros. O primeiro é o operador (*) através dele é possível retornar o valor da variável que está localizada no ponteiro. E o segundo é o operador (&) que retorna o endereço de memória que está localizado o valor da variável contida no ponteiro. Portanto para atribuirmos um valor para o ponteiro é necessário referencia o valor da variável que se encontra no ponteiro utilizando o operador (*), como será demonstrado a seguir.
 +
 
 +
<syntaxhighlight lang=text>
 +
*pa=25
 +
</syntaxhighlight>
 +
 
 +
Desta forma estamos atribuindo o valor 24 para a variável que está contida no ponteiro. Para entender melhor quando e como utilizar os operadores (*) e (&), veja o programa mostrado abaixo.
 +
 
 +
<syntaxhighlight lang=c>
 +
#include<stdio.h>
 +
 
 +
int main (){
 +
    int a, b;
 +
    int *pa, *pb; //declaração  de ponteiros
 +
 
 +
    /*inicializando variáveis*/
 +
    a=25;
 +
    b=12;
 +
 
 +
    /*fazendo os ponteiros pa e pb apontarem para os endereços de
 +
    memórias das bariáves a e b, respectivamente*/
 +
    pa=&a;
 +
    pb=&b;
 +
 
 +
    /*Imprimindo os dados na tela*/
 +
    printf("\n O endereco do ponteiro pa: %d", pa);
 +
    printf("\n O endereco da variavel contida no ponteiro pa: %d", &pa);
 +
    printf("\n O valor da variavel contida no ponteiro pa: %d", *pa);
 +
 
 +
    printf("\n\n");
 +
 
 +
    printf("\n O endereco do ponteiro pb: %d", pb);
 +
    printf("\n O endereco da variavel contida no ponteiro pb: %d", &pb);
 +
    printf("\n O valor da variavel contida no ponteiro pb: %d\n", *pb);
 +
 
 +
}
 +
</syntaxhighlight>
 +
 
 +
Quando os ponteiros são declarados, eles são inicializados com um endereço não valido, portanto antes de usa-los é necessário atribuir um endereço e isso é feito através do operador (&) como demonstra a instrução pa=&a e pb=&b que atribui aos ponteiros pa e pb o endereço das varieis a e b.
 +
 
 +
Uma outra novidade do programa anterior é quando queremos imprimir o endereço do próprio ponteiro isto é feito referenciando pa normalmente. Porém para imprimir o endereço contido no ponteiro é usado &pa e por ultimo para imprimir o valor do endereço contido no ponteiro usamos *pa.
 +
 
 +
Através do programa abaixo é possível verificar que se pode fazer comparações entre ponteiros.
 +
 
 +
<syntaxhighlight lang=c>
 +
#include<stdio.h>
 +
 
 +
int main (){
 +
    int x1=34, x2=78;
 +
    int *px1, *px2;
 +
 
 +
    /*Iniciando os ponteiros com os endereços das variáveis
 +
    x1 e x2*/
 +
    px1=&x1;
 +
    px2=&x2;
 +
 
 +
    printf("\n px1= %d", px1);
 +
    printf("\n px2= %d", px2);
 +
 
 +
    if(px1 > px2){
 +
        printf("\n\n px1-px2=%d\n", px1-px2);
 +
    }else{
 +
        printf("\n\n px2-px1=%d\n", px2-px1);
 +
        }
 +
}
 +
</syntaxhighlight>
 +
 
 +
A comparação entre ponteiros em uma expressão relacional (>=,<=,> e <) é possível quando os dois ponteiros são do mesmo tipo. Isso é feito no programa mostrado através da linha “if (px1>px2)”, Caso a instrução seja verdadeira será feita a diferença entre os dois ponteiros “px1-px2”. E caso seja falso será feito ao contrario “px2-px1”. É importante dizer que os dados de saída deste programa não são iguais em todos os computadores, depende muito da memória disponível. Mas como pode-se observar em nosso exemplo, se px1=1245064 e px2=1245060 então px1-px2 será igual a um. Isso ocorre, pois a diferença depende da unidade tipo apontado.
 +
 
 +
==29/11: Campo Minado==
 +
 
 +
=== A contagem de minas ===
 +
 
 +
Para ajudar a visualizar o algoritmo de contagem de minas vizinhas, segue o fluxograma abaixo. As coordenadas ''(x,y)'' correspondem à casa cujas minas vizinhas se desejam contar. Veja sua semelhança com o [[SOP-2010-2-sobral#Zerando_o_tabuleiro|algoritmo para zerar o tabuleiro]].
 +
 
 +
[[imagem:Conta-minas.png|300px]]
 +
 
 +
A sugestão é por o algoritmo de contagem em uma [[SOP-funcoes|função]], e dentro do programa chamá-lo para cada casa do tabuleiro:
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
 
 +
#define MINAS 10
 +
#define LINHAS 10
 +
#define COLUNAS 10
 +
 
 +
#define TEM_MINA 10
 +
 
 +
// O tabuleiro como variável global: necessário para poder ser usado e modificado por outras funções
 +
int tabuleiro[LINHAS][COLUNAS];
 +
 
 +
 
 +
// Função para contar as minas vizinhas da casa x, y
 +
void conta(int x, int y) {
 +
 
 +
 
 +
}
 +
 
 +
/*
 +
*
 +
*/
 +
int main(int argc, char** argv) {
 +
    int i, j;
 +
 
 +
    // Zerar todas as posições do tabuleiro !
 +
    i = 0;
 +
    while ( i < LINHAS) {
 +
        j = 0;
 +
        while (j < COLUNAS) {
 +
            tabuleiro[i][j] = 0;
 +
            j++;
 +
        }
 +
        i++;
 +
    }
 +
   
 +
    // Colocar as minas aqui !!!
 +
 
 +
    // contar as minas vizinhas de cada casa do tabuleiro
 +
    i = 0;
 +
    while ( i < LINHAS) {
 +
        j = 0;
 +
        while (j < COLUNAS) {
 +
            // chama a função de contagem de minas, para contar as minas
 +
            // vizinhas da casa com coordenadas i,j
 +
            conta(i, j);
 +
            j++;
 +
        }
 +
        i++;
 +
    }
 +
 
 +
    //Agora mostrar o tabuleiro que foi gerado
 +
</syntaxhighlight>
 +
 
 +
Obs: cuidado com o seguinte ao fazer o algoritmo de contagem de minas:
 +
* Casas na borda do tabuleiro possuem menos casas vizinhas (casas fora do tabuleiro devem ser ignoradas).
 +
* O algoritmo não pode ser aplicado em casas que contêm minas. Quer dizer, não faz sentido calcular as minas vizinhas de uma casa que tem uma mina.
 +
 
 +
Levando em conta as restrições acima, o algoritmo deve ficar parecido com o seguinte:
 +
 
 +
[[imagem:Conta-minas2.png|320px]]
 +
 
 +
* Desenvolvimento do projeto
 +
* Arquivos em linguagem C
 +
* Armazenar pontuação dos jogadores em arquivo modo texto
 +
 
 +
==02/12: Campo Minado==
 +
* Desenvolvimento do projeto
 +
* O código abaixo faz uso da biblioteca <time.h>, necessário para cálculo do tempo transcorrido pelo jogador
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
#include <time.h>
 +
#include <string.h>
 +
 
 +
 
 +
void calcula(){ //função calcula tempo transcorrido para executar uma operação.
 +
   
 +
  time_t inicio, fim;
 +
  char nome[51];
 +
 
 +
  inicio= time(NULL);
 +
  printf("Digite seu nome: ");
 +
  scanf("%s",nome);
 +
  //fgets(nome, 51, stdin);
 +
  fim= time(NULL);
 +
 
 +
  printf("%s, voce demorou %.2f segundos para digitar seu nome.\n", nome, difftime(inicio,fim)*(-1));
 +
 
 +
}
 +
 
 +
void tempo()
 +
{
 +
  time_t segundos, inicio;
 +
 
 +
  inicio = time(NULL); //captura tempo nesse instante
 +
  printf("O valor lido neste instante eh %ld \n", inicio);
 +
 
 +
  segundos= time(NULL); //captura e apresenta o tempo em segundos
 +
  printf("%ld horas desde 1 de Janeiro de 1970.\n", segundos/3600);
 +
 
 +
}
 +
 
 +
int main() {
 +
 
 +
    tempo();
 +
    calcula();
 +
 
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
 
 +
==06/12: Campo Minado==
 +
* Desenvolvimento do projeto
 +
 
 +
===Expansões propostas para o projeto===
 +
* Cada jogo implementado deve apresentar ao menos uma das espansões propostas abaixo:
 +
** Ao término do jogo, com a descoberta de todas as minas pelo jogador, o programa desenvolvido deve informar o tempo de jogo transcorrido.
 +
** Ao término do jogo, o programa deve armazenar o nome do jogador juntamente com o tempo de jogo em um arquivo.
 +
** Antes do início do jogo, na fase de inicialização deve-se solicitar ao jogador o grau de dificuldade do jogo. O grau de dificuldade do jogo refere-se a quantidade de bombas no tabuleiro. Sugere-se três níveis possíveis:
 +
***1) Iniciante, 2) Intermediário, 3) Avançado.
 +
 
 +
===Exemplo de utilização de funções no programa===
 +
 
 +
<syntaxhighlight lang=c>
 +
#include<stdio.h>
 +
 
 +
//define as dimensões da matriz
 +
#define LIN 10
 +
#define COL 10
 +
 
 +
//declaração das funções do programa
 +
void inicia_tabela(int tab[LIN][COL]);
 +
void imprime_tabela(int tab[LIN][COL]);
 +
 
 +
//função que inicia a tabela com zeros
 +
void inicia_tabela(int tab[LIN][COL]){
 +
    int i=0,j=0;
 +
 
 +
    for(i=0; i<LIN; i++){
 +
        for (j=0; j<COL;j++){
 +
            tab[i][j]=0;
 +
        }
 +
    }
 +
}
 +
 
 +
//função para impressão da tabela
 +
void imprime_tabela(int tab[LIN][COL]){
 +
    int i=0,j=0;
 +
 
 +
    for(i=0; i<LIN; i++){
 +
        printf("\n");
 +
        for (j=0; j<COL;j++){
 +
            printf("| %d ", tab[i][j]);
 +
        }
 +
    }
 +
    printf("\n \n");
 +
}
 +
 
 +
//função principal
 +
int main (){
 +
    int tabela[10][10];
 +
 
 +
    inicia_tabela(tabela);
 +
    imprime_tabela(tabela);
 +
}
 +
</syntaxhighlight>
 +
 
 +
* O código acima apresenta o uso de funções para atividades básicas como zerar a matriz e apresentar o tabuleiro.
 +
* A passagem de parâmetro da matriz é sempre realizada por referencia.
 +
* Não é possível utilizar tamanhos variáveis (informada pelo usuário), pois a matriz deve conter ao menos as dimensões das colunas na passagem dos parâmetro na função (delimitado aqui pelas constantes LIN e COL). No projeto pode-se adotar uma solução desse tipo =)
 +
 
 +
==09/12: Campo Minado==
 +
 
 +
= Arquivos na linguagem C =
 +
 
 +
Para um programador, arquivos são repositórios permanentes de dados, os quais usualmente ficam em midia não volátil (disco rígido, CD ou DVD, pendrive, e outros). Arquivos servem para guardar informações que devem continuar a existir mesmo que termine o processo que as criou. Um exemplo é a agenda, cujo conteúdo deve ser preservado para futuras consultas e modificações. Mas além de serem depósitos de dados, arquivos possuem características bem definidas do ponto de vista de programação.
 +
 
 +
Um arquivo é uma sequência de bytes, que pode ser acessada, lida e modificada por meio de funções específicas existentes na [http://pt.wikipedia.org/wiki/Biblioteca_padr%C3%A3o_do_C biblioteca padrão da linguagem C]. Essas funções servem para abrir e fechar um arquivo, ler e escrever uma certa quantidade de bytes, e mudar a posição da próxima leitura ou escrita.
 +
 
 +
== Escrevendo em um arquivo ==
 +
 
 +
Abaixo segue um exemplo de um programa para escrever uma linha em um arquivo:
 +
 
 +
<syntaxhighlight lang=c>
 +
#include<stdio.h>
 +
 
 +
int main() {
 +
  char linha[256];
 +
  FILE * arquivo;
 +
 
 +
  printf("Digite uma linha: ");
 +
  scanf("%[^\n]", linha);
 +
 
 +
  printf("Vou gravar isto no arquivo teste.txt\n");
 +
  arquivo = fopen("teste.txt", "w");
 +
  if (arquivo == NULL) {
 +
    perror("Nao conseguiu abrir o arquivo");
 +
    return 1;
 +
  }
 +
  fprintf(arquivo, "%s\n", linha);
 +
  fclose(arquivo);
 +
 
 +
  printf("Pronto ... veja o arquivo teste.txt !\n");
 +
}
 +
</syntaxhighlight>
 +
 
 +
Esse pequeno programa evidencia que trabalhar com arquivos é muito parecido a trabalhar com escrita na tela e leitura do teclado. Mas primeiro deve-se focar nas linhas do programa que têm relação direta com arquivos. Para começar, um arquivo é referenciado por uma variável do tipo ''FILE *'':
 +
 
 +
<syntaxhighlight lang=c>
 +
  FILE * arquivo;
 +
</syntaxhighlight>
 +
 
 +
Em seguida, o arquivo a ser lido ou escrito deve ser aberto, usando-se a função ''FILE * fopen(char * nome_arquivo, char * modo)'':
 +
 
 +
<syntaxhighlight lang=c>
 +
  arquivo = fopen("teste.txt", "w");
 +
</syntaxhighlight>
 +
 
 +
Como se pode ver, a função ''fopen'' precisa de dois parâmetros do tipo ''char *'' (quer dizer, dois parâmetros ''string''). O primeiro é o caminho do arquivo a ser aberto, e o segundo é o modo de abertura (o que se pretende fazer com ele: ler, escrever, adicionar dados ao final, ler e escrever). No exemplo acima, vai-se abrir o arquivo ''teste.txt'' para escrita (modo "w", de ''write''). O valor de retorno de ''fopen'' é do tipo ''FILE *'', e corresponde a uma descrição do arquivo que foi aberto. Caso aconteça algum erro (ex: não há permissão para criar o arquivo), ''fopen'' retorna o valor ''NULL''. O exemplo testa se isto acontece da seguinte forma:
 +
 
 +
<syntaxhighlight lang=c>
 +
  if (arquivo == NULL) {
 +
    perror("Nao conseguiu abrir o arquivo");
 +
    return 1;
 +
  }
 +
</syntaxhighlight>
 +
 
 +
Uma vez o arquivo estando aberto para escrita, pode-se escrever nele usando-se a função ''fprintf''. Essa função é idêntica à função ''printf'' que se usa para escrever na tela. Porém ''fprintf'' precisa de um parâmetro adicional, deve ser a variável que corresponde ao arquivo aberto (primeiro parâmetro da função):
 +
 
 +
<syntaxhighlight lang=c>
 +
  fprintf(arquivo, "%s\n", linha);
 +
</syntaxhighlight>
 +
 
 +
Finalmente, quando não se quer mais escrever no arquivo deve-se chamar a função ''fclose'' para fechá-lo:
 +
 
 +
<syntaxhighlight lang=c>
 +
  fclose(arquivo);
 +
</syntaxhighlight>
 +
 
 +
== Lendo uma linha de um arquivo ==
 +
 
 +
A leitura de um arquivo é parecida, com algumas pequenas modificações em sua abertura (deve-se indicar que o mode de operação será "r", de "read"), e usando-se a função ''fscanf'' para ler dados do arquivo. O exemplo abaixo mostra um programa para ler a primeira linha de um arquivo:
 +
 
 +
<syntaxhighlight lang=c>
 +
#include<stdio.h>
 +
 
 +
int main() {
 +
  char linha[1024];
 +
  char nome[256];
 +
  FILE * arquivo;
 +
 
 +
  printf("Digite o nome de um arquivo: ");
 +
  scanf("%s", nome);
 +
 
 +
  printf("Vou mostrar a primeira linha do arquivo %s\n", nome);
 +
 
 +
  arquivo = fopen(nome, "r");
 +
  if (arquivo == NULL) {
 +
    perror("Ops ... erro ao acessar esse arquivo: ");
 +
    return 1;
 +
  }
 +
 
 +
  fgets(linha, 1024, arquivo);
 +
  fclose(arquivo);
 +
 
 +
  printf("Eis a primeira linha do arquivo: \n\n%s\n\n", linha);
 +
 
 +
}
 +
</syntaxhighlight>
 +
 
 +
Como adiantado, na abertura com ''fopen'' deve-se usar o valor "r" para o modo:
 +
 
 +
<syntaxhighlight lang=c>
 +
  arquivo = fopen(nome, "r");
 +
</syntaxhighlight>
 +
 
 +
Já a leitura de uma linha pode ser feita mais facilmente com a função ''fgets'':
 +
 
 +
<syntaxhighlight lang=c>
 +
  fgets(linha, 1024, arquivo);
 +
</syntaxhighlight>
 +
 
 +
A função ''char * fgets(char * resultado, int max_caracteres, FILE * arquivo)'' lê uma linha de um arquivo com até ''max_caracteres'' e a guarda na variável passada no parâmetro ''resultado''. No exemplo acima, ''fgets'' lê uma linha com até 1024 caracteres e a guarda na variável ''linha''.
 +
 
 +
== Lendo todas as linhas de um arquivo ==
 +
 
 +
Nesse próximo exemplo, abre-se um arquivo para leitura e lêem-se todas suas linhas, mostrando-as na tela:
 +
 
 +
<syntaxhighlight lang=c>
 +
#include<stdio.h>
 +
 
 +
int main() {
 +
  char linha[1024];
 +
  char nome[256];
 +
  char * ok;
 +
  FILE * arquivo;
 +
 
 +
  printf("Digite o nome de um arquivo: ");
 +
  scanf("%s", nome);
 +
 
 +
  printf("\nVou mostrar todas as linhas do arquivo %s\n\n", nome);
 +
 
 +
  arquivo = fopen(nome, "r");
 +
  if (arquivo == NULL) {
 +
    perror("Ops ... erro ao acessar esse arquivo: ");
 +
    return 1;
 +
  }
  
srand(time(NULL)); //Plantando a semente :) função time() utiliza a biblioteca <time.h>
+
  do {
 +
    ok = fgets(linha, 1024, arquivo);
 +
    if (ok != NULL) printf("%s", linha);
 +
  } while (! feof(arquivo));
  
printf ("Um numero entre 0 e RAND_MAX (%d): %d\n", RAND_MAX, rand());
+
  fclose(arquivo);
printf ("Um numero entre 0 e 99: %d\n", rand()%100);
 
printf ("Um numero entre 20 e 29: %d\n", rand()%10+20);
 
printf ("Um numero entre 0 e 5: %d\n", rand()%6); //pode ser interessante usar algo nesse estilo para o projeto.
 
printf("\a");
 
  
return 0;
 
 
}
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  
* para atribuir os valores aleatórios gerados pode-se utilizar a função da seguinte forma:
+
A diferença em relação ao exemplo anterior está na sequência que lê as linhas do arquivo:
  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
variavel1 = rand() % 10;   // até 10.
+
do {
variavel2 = rand() % 30; // até 30.
+
    ok = fgets(linha, 1024, arquivo); // Lê a próxima linha do arquivo
 +
    if (ok != NULL) printf("%s", linha); // se conseguiu ler algo, mostra na tela
 +
  } while (! feof(arquivo)); // para se chegou ao fim de arquivo
 
</syntaxhighlight>
 
</syntaxhighlight>
  
==18/06: Desenvolvimento do Projeto Final==
+
Há algumas novidades aqui:  
 
 
==24/06: Desenvolvimento do Projeto Final==
 
 
 
==25/06: Desenvolvimento do Projeto Final==
 
 
 
* Em virtude do jogo do Brasil x Portugal, as aulas nesse dia terão início as 14:15 h.
 
 
 
==01/07: Entrega do Projeto Final==
 
 
 
* Itens a serem avaliados:
 
 
 
** Funcionalidades básicas:
 
 
 
* Organização e legibilidade do código (indentação e comentários).
 
* E/S: Montagem do tabuleiro.
 
* Posicionamento dos barcos no tabuleiro.
 
* Tiros disparados pelo usuário e contabilização de erros e acertos.
 
* Finalização do jogo quando forem acertados todos os barcos.
 
  
* Funcionalidades desejadas (expansões propostas).
+
# '''''O valor de retorno de ''fgets'' é testado quanto a sua validade:''''' a função ''fgets'' retorna o valor ''NULL'' se não conseguiu ler algo do arquivo. Isto pode ter ocorrido por um erro de leitura (ex: disco com defeito) ou porque se chegou ao fim do arquivo, e assim nada mais existe para ser lido. Esse teste aparece na linha: <syntaxhighlight lang=c>if (ok != NULL) printf("%s", linha)</syntaxhighlight>.
 +
#'''''A leitura continua enquanto não se chegar ao fim de arquivo:''''' o teste de fim de arquivo se faz com a função ''int feof(FILE * arquivo)'', que retorna 0 se ainda não se chegou ao final do arquivo, ou 1 caso contrário. A chamada de ''feof'' se faz ao final do laço: <syntaxhighlight lang=c>  } while (! feof(arquivo));</syntaxhighlight>
  
* Entrevista com cada integrante da equipe:
+
* Desenvolvimento do projeto final da disciplina
 +
* Preparação para apresentação
  
** Cada integrante será arguido pelo professor com duas ou três questões.
+
==13/12: Entrega projeto da disciplina==
** Cada integrante participará do processo de avaliação do colega de equipe.
+
* Entrega do projeto final da disciplina
  
==02/07: Recuperação==
+
===ATENÇÃO===
 +
* Avaliação realizada individualmente
 +
* Entrega de avaliações e conceitos.
  
* Atenção alunos que '''não conseguiram conceito mínimo''' (conceito C), no módulo de Lógica de programação:
+
===Conceitos Projeto Final disciplina===
** Avaliação de recuperação de lógica, utilizando linguagem C. Serão propostos dois problemas.  
+
* Conceitos projeto final disciplina: [http://www.sj.ifsc.edu.br/~tisemp/SOP/avaliacoes/conceitos.pdf conceitos projeto]
 +
* Critério: código clonado, soluções apresentadas sem explicação ou integração entre os membros considerou-se conceito insuficiente.
  
* Atenção alunos que '''não conseguiram conceito mínimo''' (conceito C) no projeto final da disciplina:
+
==16/12: Recuperação Lógica e Programação em linguagem C==
** Avaliação de recuperação de programação C. Serão propostos dois problemas.
+
* Recuperação Lógica de Programação em Linguagem C
 +
* Recuperação realizada utilizando linguagem C
  
==08/07: Encerramento Disciplina==
+
==20/12: Encerramento disciplina==
 +
* Aproveito para desejar à todos Feliz Natal e que 2011 seja repleto de boas surpresas =)
  
* Entrega de provas, conceitos finais.
+
===Conceitos Finais:===
* Discussões sobre os tipos de linguagens de programação utilizadas atualmente no mercado e as tendências para a área de telecomunicações.
+
* Conceitos finais da disciplina: [http://www.sj.ifsc.edu.br/~tisemp/SOP/avaliacoes/conceitos_finais.pdf Conceitos Finais]
  
 +
* Encerramento disciplina
 +
* Discussões sobre os tipos de linguagens de programação utilizadas atualmente no mercado e tendências
 
* [http://langpop.com/ Popularidade das linguagens de programação]
 
* [http://langpop.com/ Popularidade das linguagens de programação]

Edição atual tal como às 18h08min de 19 de dezembro de 2010

Diário de aula de SOP - 2010-2 - Prof. Tiago Semprebom

Instrutor

Professor: Tiago Semprebom
Email: tisemp@ifsc.edu.br
Atendimento paralelo: 2a feira 10h - 11 h e 5a feira 15h - 17h (Lab. de Desenvolvimento de Tele)

Referências adicionais

Sistemas Operacionais

29/07: Introdução

  • Aula inaugural
  • Tópicos: Apresentação da disciplina, plano de aula, trabalhos e métodos de avaliação.

02/08: Introdução à computação

Sistemas computacionais; visão geral de sistemas operacionais; histórico de sistemas operacionais (resumo).

Videos ilustrativos:


Alguns textos interessantes sobre história dos sistemas operacionais:

05/08: Introdução ao Linux

  • Iniciar e encerrar uma sessão no Linux;
  • Se familizarizar com a interface do GNOME;
  • Usar o navegador de arquivos Nautilus;
  • Operar sobre diretórios: navegar, criar, remover, remover recursivamente, listar, copiar e renomear;
  • Trabalhar o conceito de nomes absolutos e relativos usando ".", "..", "~" e "-"
  • Trabalhar o conceito de diretório de trabalho e de diretório de entrada;
  • Criar, remover, renomear e listar arquivos ordinários;
  • Outros: trabalhar o conceito de arquivo escondido e usar TAB para autocompletar nomes no shell;
  • Usar o manual online (man);

Roteiro desta aula:

Exercícios Extras:

  1. Partindo do subdiretório /home/aluno/Desktop, e usando somente caminhos (pathnames) relativos, indique a sequência de comandos necessária para visitar sucessivamente os seguintes subdiretórios:
    • /home/aluno
    • /home/visita
    • /home/visita/Documentos
    • /home/visita/public_html/imagens
    • /etc/default
    • /usr/share/docs
    • /usr/share/docs/python/manual/html
    • /usr/lib/browser-plugins
    • /usr/local/etc
    • /usr/local/man/man1
    • /home/aluno
    • /home/aluno/Desktop
  2. Partindo do subdiretório /home/aluno/Desktop, informe a sequência de subdiretórios (indique-os com seus caminhos absolutos) visitados se forem seguidos os seguintes caminhos relativos:
    • ../Imagens/Fotos
    • 2010/07
    • ../../2009
    • ../../../bin
    • ../../manuel/docs
    • ../../../etc/init.d
    • ../rc5.d
    • ../../var/log/apache2
    • ../../tmp
    • ../../lib/modules
    • ../../usr/bin
    • ../lib/X11
    • ../..

09/08: Introdução ao Linux

  • Rever as operações sobre arquivos e diretórios com mais detalhes;
  • Compreender o que é shell e a expansão do shell;
  • Operar sobre diretórios e arquivos usando os coringas: *, ? e [ ];
  • Remover recursivamente diretórios e seus conteúdos;
  • Usar seta para recuperar comandos da história de comandos;

Roteiros desta aula:

Exercícios Extras:

  1. Usando a interface gráfica, organize os arquivos contidos aqui. Eles devem ser colocados nos subdiretórios Imagens, Videos e Documentos, de acordo com seus tipos.
  2. Refaça a questão anterior, porém usando a interface de linha de comando (o shell).

Obs: para extrair os arquivos do exercício faça assim:

aluno@DX~$ tar xjf sop.tar.bz2

... e veja que aparecerá um subdiretório sop com todos os arquivos do exercício lá dentro.

12/08: Introdução ao Linux

  • Rever operações sobre diretórios
  • Usar editores de texto para criar e editar arquivos
  • Uso dos comandos cat, more e less para visualizar o conteúdo de arquivo
  • Fazer, remover e visualizar links simbólicos

Roteiro desta aula:

16/08: Utilização Editor de texto vi e redirecionamento

  • Aprender a utilizar minimamente o editor vi
  • Redirecionamento de saída padrão

Entrada e saída padrão

Todo processo possui uma saída padrão, que corresponde a um arquivo ou dispositivo onde os dados de saída do processo (ex: mensagens de texto) serão mostrados. E assim como existe uma saída padrão, todo processo possui uma entrada padrão que corresponde ao arquivo ou dispositivo de onde por default são obtidos os dados de entrada.

Sop-redir.png

Redirecionamento de saída padrão

Normalmente a saída padrão de um processo é a tela do terminal, mas ela pode ser redirecionada para um arquivo ou para outro dispositivo. Assim, as mensagens de texto que um processo gera podem ser guardadas em um arquivo para posterior utilização. No exemplo abaixo, a listagem dos processos foi guardada no arquivo processos.txt:

aluno@D1:~$ ps ax > processos.txt
aluno@D1:~$

O redirecionamento de saída padrão se faz com o símbolo > seguido do nome do arquivo. Note que nada aparece na tela, uma vez que a saída se tornou o arquivo processos.txt. Após executar o comando acima, veja o conteúdo de processos.txt:

aluno@D1:~$ less processos.txt
  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:03 /sbin/init
    2 ?        S<     0:00 [kthreadd]
    3 ?        S<     0:00 [migration/0]
    4 ?        S<     0:00 [ksoftirqd/0]
    5 ?        S<     0:00 [watchdog/0]
    6 ?        S<     0:00 [migration/1]
    7 ?        S<     0:00 [ksoftirqd/1]
    8 ?        S<     0:00 [watchdog/1]
    9 ?        S<     0:00 [events/0]
   10 ?        S<     0:00 [events/1]
   11 ?        S<     0:00 [khelper]
   12 ?        S<     0:00 [kstop/0]
   13 ?        S<     0:00 [kstop/1]
   14 ?        S<     0:00 [kintegrityd/0]
   15 ?        S<     0:00 [kintegrityd/1]
   16 ?        S<     0:00 [kblockd/0]
   17 ?        S<     0:00 [kblockd/1]
   18 ?        S<     0:00 [kacpid]
   19 ?        S<     0:00 [kacpi_notify]
   20 ?        S<     0:00 [cqueue]
   21 ?        S<     0:00 [ata/0]
   22 ?        S<     0:00 [ata/1]
processos.txt

Como se pode ver, o texto que apareceria na tela foi guardado em processos.txt. Experimente executar novamente o comando ps ax > processos.txt e veja o resultado. O que aconteceu com o arquivo processos.txt ?

Quando se deseja redirecionar a saída de um processo para um arquivo, porém preservando o conteúdo original desse arquivo, deve-se executar o comando da seguinte forma:

aluno@D1:~$ ps ax >> processos.txt
aluno@D1:~$

... quer dizer, em vez de usar > usa-se >>.

Redirecionamento de entrada padrão

Normalmente a entrada padrão corresponde ao teclado do terminal, mas pode ser redirecionada para outro arquivo ou dispositivo. No exemplo abaixo, usa-se o programa wc para contar as linhas, palavras e caracteres contidos no arquivo processos.txt:

aluno@D1:~$ ps ax > processos.txt
aluno@D1:~$ wc < processos.txt
 137  810 7807 begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting begin_of_the_skype_highlighting              137 810 7807      end_of_the_skype_highlighting processos.txt
aluno@D1:~$

No exemplo acima, gravou-se em processos.txt o resultado do comando ps ax' , e depois usou-se wc para contar linhas, palavras e caracteres desse arquivo. O efeito combinado é a contagem de quantos processos existem no sistema nesse momento (representado pelo número de linhas contidas em processos.txt).

Ao contrário do caso da saída padrão, não é tão comum se usar redirecionamento de entrada padrão. No entanto há um recurso adicional provido pelo sistema operacional que explora a combinação de ambas, e que possibilita combinar as funcionalidades de diferentes programas.

Pipes

Em sistemas operacionais Unix, é possível conectar a saída padrão de um processo à entrada padrão de outro processo, e a isto se chama pipe (que pode ser traduzido como duto ou tubo). Com isto, os dados de saída de um processo serão os dados de entrada de outro processo, o que pode ser explorado para realizar diferentes tarefas. Por exemplo, retomando a contagem de processos vista na seção anterior:

aluno@D1:~$ ps ax | wc
 137  810 7807
aluno@D1:~$

O símbolo de pipe é a barra vertical |. Ao se executarem os comandos acima unidos pelo pipe, a listagem de processos gerada pelo ps ax é automaticamente enviada para a entrada padrão do comando wc. O resultado é a contagem de processos existentes no sistema.

Podem-se ligar mais de dois processos usando pipes. Assim, cria-se um encadeamento de processos, em que a saída padrão de um processo alimenta a entrada padrão do próximo processo. Por exemplo, para se contarem os processos do usuário aluno:

aluno@D1:~$ ps aux | grep aluno | wc
     47     568    5195
aluno@D1:~$

Roteiros desta aula:

Material complementar sobre editor vi

19/08: Gerenciamento de processos

Processos e multiprogramação: uma visão geral sobre programas, processos, ciclos de um processo, multiprogramação e escalonamento. Ver apostila do prof. Odilson, capítulo 3, e capítulo 5 do Guia Foca Linux Iniciante.

Gerência de memória: visão geral sobre o uso de memória no sistema operacional e pelos processos Uso do laboratório para ilustrar conceitos.

Vários utilitários (programas auxiliares) existem para obter informações do sistema operacional sobre processos e memória. Alguns trabalham em modo texto, como:

  • ps: lista os processos existentes
  • pstree: lista os processos existentes mas de forma hierárquica
  • top: lista os processos mais ativos, junto com informações globais sobre uso dos recursos no sistema operacional (memória, processador, memória virtual, quantidade de processos, carga de trabalho)
  • atop: o mesmo que top, mas com maior detalhamento do uso de recursos mantidos pelo sistema operacional
  • mpstat: mostra estatísticas de uso do processador
  • free: mostra o uso de memória
  • vmstat: mostra o uso de memória, discos e processador no último intervalo de tempo.

Existem também utilitários no modo gráfico. Por exemplo, no Ubuntu há o "Monitor do sistema":

Monitor1.png
Para executar o Monitor do Sistema



Monitor2.png Monitor3.png

Telas do monitor do Sistema

Roteiros desta aula:

23/08: Permissionamento Unix

  • Expor os conceitos associados as permissões de acesso a arquivos e diretórios
  • Explorar as permissões em nível do usuário proprietário

Roteiro desta aula:

26/08: Compactação de arquivos

Uma primeira forma de compactar arquivos no Linux é usando o gerenciador de arquivos nautilus. Por exemplo, ra compactar um diretório deve-se selecioná-lo e em seguida chamar o pop-up menu (botão direito do mouse):


Compress1.png


Ao se escolher a opção Comprimir, uma janela irá surgir para que se defina o nome do arquivo compactado e o tipo de compactação a ser usada:


Compress2.png


O arquivo compactado aparecerá na listagem de arquivos do nautilus:


Compress3.png


Para descompactá-lo e visualizar seu conteúdo, basta clicar duas vezes nele:


Compress4.png

Compactadores no modo texto

Vários compactadores de arquivos existem no Linux, e o nautilus simplifica sua seleção e uso. Esses compactadores podem ser usados também no modo texto ... aliás, eles originalmente foram criados para serem usados dessa forma ! O que o nautilus faz é facilitar seu uso por meio de uma interface gráfica.

Os principais compactadores são:

  • compress: compactador mais antigo e comum nos Unix em geral, porém em desuso. Gera arquivos compactados com extensão .Z. Precisa do pacote de software ncompress no Ubuntu. Exemplo de uso:
    msobral@dell-iron:~$ ls -l API-changes.txt 
    -rw-r--r-- 1 msobral professores 51759 2010-03-24 11:32 API-changes.txt
    msobral@dell-iron:~$ compress API-changes.txt
    msobral@dell-iron:~$ ls -l API* 
    -rw-r--r-- 1 msobral professores 22781 2010-03-24 11:32 API-changes.txt.Z
    msobral@dell-iron:~$ uncompress API-changes.txt.Z 
    msobral@dell-iron:~$ ls -l API*
    -rw-r--r-- 1 msobral professores 51759 2010-03-24 11:32 API-changes.txt
    msobral@dell-iron:~$
    
  • GNU zip: compactador bastante utilizado, com maior poder de compactação que compress. Gera arquivos compactados com extensão .gz. Já vem instalado no Ubuntu. Exemplo de uso:
    msobral@dell-iron:~$ gzip API-changes.txt
    msobral@dell-iron:~$ ls -l API* 
    -rw-r--r-- 1 msobral professores 17651 2010-03-24 11:32 API-changes.txt.gz
    msobral@dell-iron:~$ gunzip API-changes.txt.gz
    msobral@dell-iron:~$ ls -l API*
    -rw-r--r-- 1 msobral professores 51759 2010-03-24 11:32 API-changes.txt
    msobral@dell-iron:~$
    
  • bzip2: vem sendo bastante usado por ter um poder de compactação ainda maior, porém à custa de maior processamento (compactação fica mais lenta). Gera arquivos compactados com extensão .bz2. Também já vem instalado no Ubuntu.
    msobral@dell-iron:~$ bzip2 API-changes.txt
    msobral@dell-iron:~$ ls -l API* 
    -rw-r--r-- 1 msobral professores 15804 2010-03-24 11:32 API-changes.txt.bz2
    msobral@dell-iron:~$ bunzip2 API-changes.txt.gz
    msobral@dell-iron:~$ ls -l API*
    -rw-r--r-- 1 msobral professores 51759 2010-03-24 11:32 API-changes.txt
    msobral@dell-iron:~$
    
  • ... outros menos populares no mundo do Linux, tais como zip, rar e zoo.

Note que os compactadores compress, gzip, e bzip2 compactam um arquivo por vez. Assim, com eles não é possível juntar vários arquivos e diretórios dentro de um único arquivo compactado (o que se faz corriqueiramente com zip ou rar ...). Portanto, se for necessário compactar um diretório ou um conjunto de arquivos, o melhor é combinar um compactador com o programa tar.

tar

O programa tar é um utilitário do mundo Unix originalmente criado para backups em fita (daí seu nome: TApe aRchiver, se bem que tar é também um trocadilho que pode significar piche, pois ele de certa forma gruda um arquivo ao outro). O resultado da execução do tar é um arquivo contendo todos os arquivos e diretórios que foram selecionados para inclusão. Esse arquivo tar pode ser então compactado, obtendo-se algo parecido com o que faz zip ou rar.

Mas porque não usar então zip e rar ? Afinal, eles existem também no Linux ... No entanto, esses compactadores nasceram no mundo do antigo MS-DOS, e assim não são capazes de armazenar todos os atributos de arquivos que existem em sistemas Unix (informações tais como usuário e grupo dono do arquivo, permissões de acesso, tipo do arquivo, datas de último acesso e modificação). O tar, pelo contrário, consegue preservar esses atributos, e por isto se torna mais adequado para uso no Unix em geral.

Uso do tar:

  • Criação de arquivo tar:
    tar cf nome_arquivo.tar arquivo_ou_diretorio1 [arquivo_ou_diretorio2 ...]
    
  • Mostrar o conteúdo de arquivo tar:
    tar tvf nome_arquivo.tar
    
  • Extrair conteúdo de arquivo tar:
    tar xf nome_arquivo.tar
    

Os usos acima não compactam os arquivos incluídos dentro do arquivo tar. Para compactá-los deve-se adicionar uma opção de compactação:

  • Criação de arquivo tar compactado:
    • Com compress:
      tar cZf nome_arquivo.tar.Z arquivo_ou_diretorio1 [arquivo_ou_diretorio2 ...]
      
    • Com gzip:
      tar czf nome_arquivo.tar.gz arquivo_ou_diretorio1 [arquivo_ou_diretorio2 ...]
      
    • Com bzip2:
      tar cjf nome_arquivo.tar.bz2 arquivo_ou_diretorio1 [arquivo_ou_diretorio2 ...]
      
  • Mostrar o conteúdo de arquivo tar:
    • Com compress:
      tar tvZf nome_arquivo.tar.Z
      
    • Com gzip:
      tar tvzf nome_arquivo.tar.gz
      
    • Com bzip2:
      tar tvjf nome_arquivo.tar.bz2
      
  • Extrair conteúdo de arquivo tar:
    • Com compress:
      tar xZf nome_arquivo.tar.Z
      
    • Com gzip:
      tar xzf nome_arquivo.tar.gz
      
    • Com bzip2:
      tar xjf nome_arquivo.tar.bz2
      

Roteiro desta aula:

30/08: Revisão para avaliação SOP

02/09: Avaliação SOP

Recuperação SOP

Lógica de Programação

Segundo módulo da disciplina de Sitemas Operacionais. Baseado no material Lógica de Programação, de Paulo Sérgio de Moraes - uma das referências bibliográficas da disciplina.

06/09: Introdução

  • Revisão da avaliação de SOP 1
  • Tópicos: instrução, sequência, problemas do dia a dia.
  • Páginas da apostila: 4 a 7.

09/09: Resolução de exercícios

  • Aula cedida ao Prof. Wolney
  • Resolução de exercícios propostos aos alunos na aula do dia 06/09

13/09: Desenvolvendo algoritmos

  • Tópicos: resolvendo problemas, linguagens e instrução disponíveis (vocabulário).
  • Páginas da apostila: 8 a 11.

Exemplificando com shell scripts:

#!/bin/bash

# Cada linha no script abaixo corresponde a uma instrução ...
# O conjunto de instruções na ordem apresentada forma uma sequência lógica ...

echo Iniciando o script ...
echo Vou procurar todos os arquivos de texto existentes neste diretório

find . -type f -name "*.doc" > .tmp
find . -type f -name "*.txt" >> .tmp
find . -type f -name "*.rtf" >> .tmp
find . -type f -name "*.odt" >> .tmp

echo Os arquivos são:

cat .tmp

rm -f .tmp

Problemas exemplo

Problema dos três recipientes

Há três recipientes com tamanhos distintos: um com 8 litros, outro com 5 litros e o terceiro com 3 litros. O recipiente com 8 litros está completamente cheio. Deseja-se colocar 4 litros em dois recipientes. Considere que os recipientes não são graduados.


Problema da travessia

Um barqueiro precisa levar um saco de milho, uma galinha e uma raposa para o outro lado do rio. Porém o barco somente é capaz de levar uma coisa de cada vez (além do barqueiro). Qual a sequência de travessias necessário para atravessar o milho, a galinha e a raposa ?

Torres de Hanoi

Há três hastes. Uma das hastes serve de suporte para três discos de tamanhos diferentes. Um disco menor sempre é colocado sobre um disco maior. A figura abaixo ilustra as hastes e os discos:

Hanoi.png

Desejam-se mover os três discos para a haste da direita. Porém só pode se mover um disco por vez, e um disco maior nunca pode ficar sobre um disco menor.

Operação possível: Move disco para haste

Qual a sequência de operações para mover os discos de uma haste para outra ?

Atividade extra

  • O jogo LightBot mostra de uma forma divertida como criar pequenos algoritmos. Até que fase desse jogo você consegue chegar ?

Exercícios: desenho de figuras geométricas

  • Usando apenas as instruções:
    limpa
    avança X
    giraDireita angulo
    giraEsquerda angulo
    
    escreva algoritmos para desenhar as seguintes figuras:
    • triângulo equilátero
    • triângulo isósceles
    • triângulo escaleno
    • quadrado
    • hexágono
    • octógono
    • 7 hexágonos interligados (um central e seis periféricos).
  • kturtle é um software educacional para ajudar no ensino de matemática, geometria e introdução à programação. Ele possibilita fazer desenhos facilmente, seguindo um programa com instruções de desenho. Usando as instruções:
    reset
    forward X
    turnright angulo
    turnleft angulo
    
    ... escreva programas para os algoritmos criados no ítem anterior.

16/09: Pseudocódigo e diagrama de blocos (fluxograma)

  • Adoção do Portugol IDE como ferramenta didática.
  • Páginas da apostila: 12 a 14.

Portugol

As aulas de Lógica de Programação usarão um software de auxílio ao ensino de algoritmos chamado Portugol, desenvolvido na Escola Superior de Engenharia do Instituto Politécnico de Tomar, em Portugal.

Guia rápido de instalação e utilização do Portugol

Abaixo segue uma breve ajuda de como obtê-lo, instalá-lo e usá-lo. Esse guia assume que você esteja usando o Ubuntu Linux 9.04 ou superior.

  1. Faça o download do Portugol.
  2. Descompacte-o com o seguinte comando:
    tar xzf portugol23.tar.gz
    
  3. Repare que existe agora um subdiretório portugol no diretório onde você o descompactou. Execute o Portugol com o seguinte comando:
    java -jar portugol/Portugol.jar
    
    Obs: você precisará ter Java instalado. Caso não o tenha, execute o comando:
    sudo apt-get install openjdk-6-jre
    
  4. Copie esse arquivo para poder ver fluxogramas coloridos, e grave-o no memso diretório onde está o Portugol.
  5. Veja a ajuda do Portugol, e use-a sempre que tiver dúvidas !


A tela inicial do Portugol segue abaixo, junto com um programa demonstrativo.

Editor-Portugol.png

Exemplos de programas iniciais em Portugol:

  1. Lendo um número e mostrando-o na tela em seguida:
    Inicio
      inteiro x
    
      Escrever "Digite um numero: ",
      Ler X
      Escrever "Numero digitado: ", x
    Fim
    
  2. Lendo dois números, somando-os e mostrando o resultado na tela:
    Inicio
      inteiro x, y
    
      Escrever "Digite um numero: ",
      Ler x
      Escrever "Digite outro numero: ",
      Ler y
      Escrever "Soma = ", x+y
    Fim
    
    O programa abaixo é equivalente:
    Inicio
      inteiro x, y, z
    
      Escrever "Digite um numero: ",
      Ler x
      Escrever "Digite outro numero: ",
      Ler y
      z <- x + y
      Escrever "Soma = ", z
    Fim
    

Atividades

  1. Média de três números: escreva um programa para calcular a média de três números.
    Inicio
      Inteiro n1, n2, n3, r
    
      Escrever "Primeiro numero: "
      ler n1
      Escrever "Segundo numero: "
      ler n2
      Escrever "Terceiro numero: "
      ler n3
    
      r <- (n1 + n2 + n3) /3
    
      Escrever "Media=", r
    Fim
    
  2. Sequência de Fibonacci: em matemática corresponde aos números:
    1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
    
    ... que pode ser descrita pela relação de recorrência



    ... com valores iniciais e .

    Numerosas formas na natureza apresentam essa sequência, como neste girassol (cujas flores se dispõem em uma espiral):

    Sunflower.jpg Espiral fibonacci.png FibonacciBlocks.png

    Usando o Portugol escreva um programa que mostre os 10 primeiros números dessa sequência.

20/09: Fluxogramas, constantes e Variáveis

  • Diagrama de blocos (fluxograma)
  • Variáveis e constantes

Fluxogramas

Diagramas de bloco para auxiliar a descrição de algoritmos. Ajudam na compreensão do algoritmo, por poder visualizar o fluxo de execução.


Fluxograma-soma.png Fluxograma para o algoritmo da média de trẽs números.


Blocos de uso mais comum

Bloco Descrição Exemplo
Inicio.png Inicio do fluxograma
Processamento.png Processamento
Entrada.png Entrada de dados (ler do teclado)
Saida.png Saída de dados (mostrar na tela)
Decisao.png Decisão (testar uma condição e bifurcar) Ex-decisao.png
Conector.png Conector (juntar dos ou mais ramos do fluxograma) Ex-conector.png
Fim.png Fim

Obs: Arquivo de configuração das cores do fluxograma do Portugol.

Variáveis e constantes

  • Variável: capaz de guardar um dado a ser usado no algoritmo. Pode ser entendida como uma caixa, onde se coloca um dado e se pode consultá-lo quantas vezes for necessário. O dado pode ser modificado (substituído por outro). Exemplo em Portugol:
    Inicio
      inteiro anos, dias
    
      Escrever "Quantos anos se passaram ? "
      Ler anos
      dias <- anos * 365
      Escrever "... então se passaram ", dias, " dias"
    Fim
    
    Nesse exemplo há duas variáveis: dias e anos
  • Constante: semelhante à variável, porém o dado armazenado não pode ser modificado. Exemplo em Portugol:
    Inicio
      constante inteiro diasPorAno <- 365
      inteiro anos, dias
    
      Escrever "Quantos anos se passaram ? "
      Ler anos
      dias <- anos * diasPorAno
      Escrever "... então se passaram ", dias, " dias"
    Fim
    
    Nesse exemplo há uma constante: diasPorAno


Variáveis e constantes devem ser declaradas antes de serem usadas (algumas poucas linguagens, como Python e Perl, não exigem isto). A declaração consiste do tipo e identificador da variável. O tipo corresponde ao tipo de valor que pode ser guardado, e o identificador é o nome da variável. No exemplo abaixo:

  constante inteiro diasPorAno <- 365
  inteiro anos, dias
Fim

Há duas variáveis do tipo inteiro, e seus identificadores são dias e anos. O tipo inteiro indica que essas variáveis podem guardar somente números inteiros.

Tipos de variáveis e constantes no Portugol:


Tipo Descrição Exemplo
Inteiro Número inteiro entre -2 147 483 648 e 2 147 483 647 begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting              2 147 483 647      end_of_the_skype_highlighting begin_of_the_skype_highlighting 2 147 483 647 end_of_the_skype_highlighting Inteiro x <- 10
Real Número real entre -1.7 E 308 e 1.7 E 308 Real y <- 10.789
Lógico Valor booleano, com valores "Verdadeiro" e "Falso" Logico ok <- Falso
Caracter Um caractere da tabela ASCII Caracter letra <- "A"
Texto Uma sequência de caracteres (ou string) Texto palavra <- "um teste"

A declaração de constantes é semelhante à de variáveis, bastanto prefixá-las com a palavra-chave constante.

Atividade

Para os exercícios abaixo, desenhe o fluxograma e escreva o algoritmo no Portugol.

  1. Faça um algoritmo que calcule a média de quatro números, porém mostrando as casas decimais (caso existam).
  2. Escreva um algoritmo que mostre, em sequência: 9, 9^2 (ao quadrado), 9^3 (ao cubo) e a soma desses 3 números.
  3. Escreva um algoritmo que leia o nome, sobrenome e idade de uma pessoa, e escreva na tela:
    sobrenome, nome
    idade anos
    

23/09: Algoritmos

  • Resolução de exercícios
  • Exemplo de um algoritmo simples, onde após calculado os valores de entrada de um usuário, apresenta-se os valores na tele. Observe a declaração de variáveis e constantes, além dos comentários e identação do código portugol:

inicio

   //declaração das variáveis
   texto nome<-"", sobrenome<-"", endereco<-""
   inteiro ano<-0, idade<-0
   constante inteiro ano_atual <- 2010
   caracter sexo<-"X"
   //área de leitura de valores
   escrever "Informe o Nome: "
   ler nome
   escrever "Informe o Sobrenome: "
   ler sobrenome
   escrever "Informa o endereço: "
   ler endereco
   escrever "Informe o ano de nascimento: "
   ler ano
   escrever "Informe o sexo (M ou F): "
   ler sexo
   //calcula idade
   idade <- (ano_atual - ano)


   //Mostra valores
   escrever "\n ****** Dados Pessoais ******"
   escrever "\nNome Completo: ", nome, " ",sobrenome
   escrever "\nEndereço: ", endereco
   escrever "\nAno de Nascimento: ", ano
   escrever "\nIdade: ", idade
   escrever "\nSexo: ", sexo

fim </syntaxhighlight>

  • Solução do exercício das poltronas no cinema, proposta pelo Ismael:

inicio

   // variaveis
   inteiro ncadeira <- 0 , fila <- 0 , cadeira <- 0 , calculo <- 0
   // area de leitura
   escrever "informe o número de sua cadeira:\n"
   ler ncadeira
   // area de calculo
   fila <- ( ncadeira / 20 ) + 1
   cadeira <- ( ncadeira % 20 )
   // mostrar valores
   escrever "Fila: " , fila
   escrever "\nCadeira: " , cadeira

fim </syntaxhighlight>

27/09: Expressões lógicas e aritméticas

Expressão aritmética: um conjunto de operações sobre variáveis, constantes e funções numéricas, e que gera um determinado resultado numérico.

Exemplos de expressões aritméticas:

# Uma expressão que calcula quantos segundos existem em um horário do tipo horas, minutos e segundos
3600*horas + 60*minutos + segundos

# Uma expressão que calcula a velocidade instantânea, segundo um MRV
vel_inicial + aceleracao*tempo;

# Uma expressão que calcula o módulo de um vetor bidimensional, que possui coordenadas x e y
raiz(x^2 + y^2)

Os resultados de expressões podem ser mostrados na tela, ou armazenados em variáveis:

# Uma expressão que calcula quantos segundos existem em um horário do tipo horas, minutos e segundos
segundos <- 3600*horas + 60*minutos + segundos

# Uma expressão que calcula a velocidade instantânea, segundo um MRV
escrever 'Velocidade no instante ', tempo, ' = ', vel_inicial + aceleracao*tempo;

# Uma expressão que calcula o módulo de um vetor bidimensional, que possui coordenadas x e y
modulo <- raiz(x^2 + y^2)

Repare que uma expressão fica sempre do lado direito, quando atribuída a uma variável. A expressão é primeiro calculada, e em seguida seu resultado é armazenado na variável:

segundos <- 3600*horas + 60*minutos + segundos

Operadores aritméticos

Expressões aritméticas sao compostas por números e operadores aritméticos:

Obs: para os exemplos abaixo são usadas estas variáveis:

Real x, area, lado
inteiro dias, horas
Operador Descrição Exemplo
+ Adição x <- x + 1
- Subtração x <- x - 1
* Multiplicação x <- x*x*x
/ Divisão dias <- horas / 24
% Módulo (resto de divisão) horas <- horas % 24
^ Potenciação area <- lado^2

Precedência dos operadores (nesta ordem): ^, *, /, %, + e -

A precedência pode ser modificada com o uso de parênteses. Ex:

escrever 1 + 2 * 3
escrever (1 + 2)*3

No Portugol, existem também algumas funções úteis, como a função raiz:

r <- raiz(x^2 + y^2)

O resultado de expressões aritméticas depende dos tipos numéricos das variáveis e constantes:

inicio
  real x
  inteiro y
  inteiro resultadoInteiro
  real resultadoReal
  
  x <- 9
  y <- 9
  
  escrever "O resultado de uma expressão aritmética depende dos tipos das variá¡veis e constantes\n"
  escrever "usadas na expressão. Se forem todas inteiras, então o resultado será inteiro.\n"
  escrever "Veja este exemplo: \n"
  escrever "Variável inteira y=", y
  escrever "\nExpressão: y/2=", y/2
  
  escrever "\n\nNeste segundo exemplo, repete-se a mesma expressão, porém usando-se uma\n"
  escrever "variável real:\n"
  escrever "variável real x=", x
  escrever "\nExpressão: x/2=", x/2
  
  x <- 4
  y <- 5
  escrever "\n\nSe as variáveis de diferentes tipos forem combinadas, o resultado da\n"
  escrever "expressão será real:\n"
  escrever "Variável real x=", x, " e inteira y=", y
  escrever "\nExpressão: (x+y)/2=", (x+y)/2

  escrever "\n\nNo entanto, se uma expressão tiver um resultado real, mas este for\n"
  escrever "atribuí­do a uma variável inteira, então apenas a parte inteira será guardada:\n"
  escrever "Variável real x=", x, " e inteira y=", y
  y <- (x+y)/2
  escrever "\nExpressão: y <- (x+y)/2 ... após executada, y=", y
  
fim

Atividades

  1. Escreva um algoritmo que calcule a raiz de uma equação de 1o grau.
  2. Escreva um algoritmo que calcule as raízes de uma equação de 2o grau. Assuma que existam duas raízes reais
  3. Um equipamento conta o tempo desde que foi ligado. No entanto, essa contagem é feita em segundos. Faça um algoritmo que converta o valor desse contador para horas, minutos e segundos.
  4. Faça um algoritmo que converta um número decimal para sua representação binária. Assuma que o número decimal tenha até dois dígitos.
  • Resolução do ecercício 2, proposta pelo Giovanni e Francisco:
inicio
    real va , vb , vc , x1,delta,x2 <- 0.0
    escrever "Digite um valor para A: "
     ler va
    escrever "Digite um valor para B: "
    Ler vb
    escrever "Digite um valor para C: "
    Ler vc
    
    escrever "Sua equação é: " ,va,"x^2+",vb,"x+",vc, "=0\n"
    delta <- (vb ^ 2) - (4*va*vc)
    escrever delta ,"\n"
     x1 <- ((-vb) + (raiz(delta))) / (2*va)
    Escrever " x ' = " , x1
    x2 <- ((-vb) - (raiz(delta))) / (2*va)
    Escrever "\n x '' = " , x2
fim

30/09: Estruturas de decisão

Páginas da apostila: 26 a 31.

Estruturas de decisão possibilitam que se executem diferentes sequências de instruções de um programa, dependendo de uma condição a ser avaliada. Por exemplo, um jogo poderia armazenar a maior pontuação já obtida, e verificar se foi ultrapassada ao final de cada partida:

  Se pontuacao > recorde então 
    recorde <- pontuação
  FimSe

O exemplo acima mostra a estrutura de decisão Se condição entao comandos Fimse. Veja o próximo exemplo:

  Se conceito > 70 entao
    escrever 'Voce esta aprovado'
  senao
    escrever 'Desta vez não deu ... tente de novo !'
  Fimse

O uso de Se condição entao comandos Senao comandos Fimse possibilita que se execute uma sequência de comandos se a condição for verdadeira, e outra sequência se for falsa.

Para fazer um bom uso de estruturas de decisão deve-se primeiro conseguir identificar as condições a serem avaliadas. Condições são escritas com expressões lógicas, e estas são compostas de operadores lógicos e relacionais aplicados a variáveis e constantes.

Condições

Obs: para os exemplos abaixo são usadas estas variáveis:

Logico correto, multa, aprovado, barato, bombear_agua
Logico descartar, baixo, reprovado, erro, enviado, recebido
inteiro erros, pontuacao, preco, endereco, velocidade
Real faltas, nivel_agua, altura

Operadores relacionais

Operador Descrição Exemplo
= Igualdade correto <- (erros = 0)
> Maior multa <- (velocidade > 80)
>= Maior ou igual aprovado <- (pontuacao >= 70)
< Menor barato <- (preco < 100)
<= Menor ou igual bombear_agua <- (nivel_agua <= 0.7)
=/= Diferente descartar <- (endereco =/= 12345)


Operadores lógicos

Operador Descrição Exemplo
NAO Negação baixo <- NOT (altura > 1.8)
E Conjunção aprovado <- NOT (conceito = "D") E (faltas <= 0.25)
OU Disjunção reprovado <- (conceito = "D") OU (faltas > 0.25)
XOU Disjunção exclusiva erro <- enviado XOU recebido

Precedência dos operadores (nesta ordem): NAO, E, OU e XOU

Lembre que a precedência pode ser modificada com o uso de parênteses.

03/10: Exercícios estruturas de decisão

  • Prof. Tiago ausente, participação na 10 ERRC =)
  • Resolvam os exercícios, aproveitem o tempo em sala. Os exercícios serão cobrados e vistos na próxima aula.

Atividades para serem desenvolvidas em sala no dia 04/10:

  1. Faça um programa que leia um número e então informe se ele é par ou ímpar.
  2. Um radar de trânsito faz a medição de velocidade de veículos e, dependendo do valor, calcula a multa a ser aplicada. Em uma determinada via esse radar foi configurado da seguinte forma:
    • Se a velocidade for maior que 80 km/h, a multa é de R$ 360.
    • Se a velocidade for maior que 60 km/h, a multa é de R$ 180.
    • Se a velocidade for menor ou igual a 60 km/h, não há multa.

      Escreva um algoritmo que calcule a multa de acordo com a velocidade de um veículo.
  3. Faça um algoritmo que leia três números do teclado, e mostre o maior e menor números.
  4. O objetivo de um estudo médico feito entre os anos 70 e 80 foi o desenvolvimento de um método para identificar pacientes de alto risco (que não sobreviverão ao menos 30 dias) com base nos dados obtidos nas primeiras 24 horas. O diagrama abaixo mostra uma regra de classificação que foi produzida nesse estudo. A letra F significa que não há um risco alto, e a letra G quer dizer paciente de alto risco.Crt-decisao.png

Essa regra classifica os pacientes como F ou G dependendo de respostas do tipo sim/não a no máximo três perguntas. Como seria um algoritmo que a implementasse ? Escreva um algoritmo que faça o teste de risco de paciente cardíaco de um paciente, conforme descrito acima.

  1. Um estudo sobre sensibilidade de pessoas a temperaturas da água identificou que a maioria das pessoas considera fria a água com temperaturas abaixo de 25 graus, morna entre 25 e 30 graus, e quente acima de 30 graus. Escreva um algoritmo que mostre as palavras "fria", "morna" ou "quente" dependendo da temperatura da água que for informada.
  2. Em uma rede de computadores, o firewall restringe o acesso a Internet dependendo do horário e do tipo de usuário que faz o acesso. Os tipos de usuário abaixo têm as seguintes restrições:
    • Funcionário: apenas entre 0:00 e 7:30, entre 18:30 e 0:00, e entre 12:00 e 13:30
    • Financeiro: qualquer horário
    • Diretoria: qualquer horário
      Escreva um algoritmo que informe se um acesso foi permitido, em função do horário e do tipo de usuário.
  3. Modifique o algoritmo acima para adicionar a seguinte restrição:
    • Funcionário: não pode acessar sites de jornal (ex: www.rbs.com.br)
    • Financeiro: não pode acessar sites de jornal durante o expediente
    • Diretoria: sem restrições a sites
  4. Faça um algoritmo para fazer a divisão de dois números reais. Antes de dividi-los deve ser feito um teste de validade. Caso não seja possível dividi-los, deve ser mostrada uma mensagem de erro. Se for possível, deve-se mostrar o resultado da divisão.
  5. Faça um jogo de par ou ímpar, em que o jogador aposta contra o computador. O jogador deve digitar um número entre 0 e 5 e optar entre par ou ímpar. O computador deve sortear um número também entre 0 e 5. Se a paridade da soma dos números do jogador e do computador for a mesma que o jogador optou, então ele ganha a partida, senão o computador vence.
  6. Escreva um algoritmo para identificar se há, dentre três palavras lidas do teclado, ao menos duas palavras distintas que pertençam ao conjunto {azul, preto, vermelho}. Exemplos:
    • Se o usuário digitar verde, preto, vermelho, o programa deve mostrar na tela verdadeiro
    • Se o usuário digitar verde, preto, preto, o programa deve mostrar na tela falso
    • Se o usuário digitar azul, preto, azul, o programa deve mostrar na tela verdadeiro

Solução Exercício 3 proposto:

inicio
    inteiro num<-0,maior<-0,menor<-0, i<-0
    constante inteiro valores<-2 //declaração da constante
    
    escrever "Digite um valor: \n"
    ler num
    maior <- num
    menor <- num
    para i de 1 até valores passo 1
        ler num
        se (num > maior) então
            maior <- num
        fimse
        se (num < menor) então 
            menor <- num
        fimse
    proximo
    escrever "O maior valor digitado é: ", maior
    escrever "\n"
    escrever "O menor valor digitado é: ", menor
fim

07/10: Estruturas de decisão

Há situações em que se precisa fazer um conjunto de comparações, como mostrado abaixo:

// Lê a data no formato numérico dia, mes, ano, e mostra a data no formato
// dia, nome do mês, ano.
Inicio
  inteiro dia, mes, ano
  texto nome_mes

  escrever "Dia: "
  ler dia
  escrever "Mes: "
  ler mes
  escrever "Ano: "
  ler ano

  se mes = 1 entao
    nome_mes <- "Janeiro"
  senao
    se mes = 2 entao
      nome_mes <- "Fevereiro"
    senao
      se mes = 3 entao
        nome_mes <- "Março"
      senao
        se mes = 4 entao
          nome_mes <- "Abril"
        senao
          se mes = 5 entao
            nome_mes <- "Maio"
          senao
            se mes = 6 entao
              nome_mes <- "Junho"
            senao
              se mes = 7 entao
                nome_mes <- "Julho"
              senao
                se mes = 8 entao
                  nome_mes <- "Agosto"
               senao
                  se mes = 9 entao
                    nome_mes <- "Setembro"
                  senao
                    se mes = 10 entao
                      nome_mes <- "Outubro"
                    senao
                      se mes = 11 entao
                        nome_mes <- "Novembro"
                      senao
                        se mes = 12 entao
                            nome_mes <- "Dezembro"
                        fimSe
                    fimSe
                  fimSe
                fimSe
              fimSe
            fimSe
          fimSe
        fimSe
      fimSe
    fimSe
  fimSe

  escrever dia, " de ", nome_mes, " de ", ano
fim

Além de ser trabalhoso esse encadeamento de Se ... entao ... senao, o algoritmo resultante fica pouco legível. Quer dizer, ele fica feio e difícil de entender.

Existe uma estrutura de decisão criada justamente para casos como esse, e que resulta em um algoritmo mais limpo e compreensível:

// Lê a data no formato numérico dia, mes, ano, e mostra a data no formato
// dia, nome do mês, ano.
Inicio
  inteiro dia, mes, ano
  texto nome_mes

  escrever "Dia: "
  ler dia
  escrever "Mes: "
  ler mes
  escrever "Ano: "
  ler ano

  Escolhe mes
    caso 1: 
      nome_mes <- "Janeiro"
    caso 2: 
      nome_mes <- "Fevereiro"
    caso 3: 
      nome_mes <- "Março"
    caso 4: 
      nome_mes <- "Abril"
    caso 5: 
      nome_mes <- "Maio"
    caso 6: 
      nome_mes <- "Junho"
    caso 7: 
      nome_mes <- "Julho"
    caso 8: 
      nome_mes <- "Agosto"
    caso 9: 
      nome_mes <- "Setembro"
    caso 10: 
      nome_mes <- "Outubro"
    caso 11: 
      nome_mes <- "Novembro"
    Defeito: 
      nome_mes <- "Dezembro"
  fimEscolhe

  escrever dia, " de ", nome_mes, " de ", ano
fim

A estrutura de decisão escolhe ... caso tem uma certa flexibilidade. No exemplo abaixo, mostra-se a possibilidade de testar mais de um valor no mesmo caso:

inicio     
  caracter sexo     

  escrever "Qual o seu sexo (f/m):"     
  ler sexo     

  escrever "Olá "     

  escolhe sexo         
    caso "m", "M" :             
      escrever "senhor"         
    caso "f","F" :             
      escrever "senhorita"         
    defeito :             
      escrever "Sexo indefinido"     
  fimescolhe     

  escrever ", benvindo ao portugol" 
fim

Atividades

  1. Faça um algoritmo que converta um número de 1 a 7 para o respectivo dia da semana (ex: 1 = domingo, 2 = 2a feira, e assim por diante).
  2. Faça uma calculadora com as quatro operações aritméticas. Sua calculadora deve ler (nesta ordem) o primeiro número, a operação aritmética (que deve ser informada usando o símbolo da respectiva operação: +, -, * ou /), e depois o segundo número. Ao final, seu algoritmo deve mostrar o resultado, ou uma mensagem de erro se a operação não for possível de realizar (ex: divisão por zero).
  3. A previsão do tempo na costa brasileira pode ser feita de forma aproximada usando-se um barômetro e um termômetro. Uma estimativa com boa chance de acerto se baseia na tabela abaixo:
    Previsao-barometro.png

    Faça um algoritmo que forneça uma estimativa da previsão do tempo, usando essa tabela.
  4. Faça um algoritmo que mostre qual o último dia de um determinado mês informado pelo teclado. Caso seja informado o mês 2 (fevereiro), seu algoritmo deve identificar se é ano bissexto (assim o mês tem 29 dias), ou não (mês tem 28 dias). Obs: anos bissextos são dados pelas regras (segundo o calendário Gregoriano):
    1. De 4 em 4 anos é ano bissexto.
    2. De 100 em 100 anos não é ano bissexto.
    3. De 400 em 400 anos é ano bissexto.
    4. Prevalecem as últimas regras sobre as primeiras.

12/10: Feriado Nacional

  • Feriado Nacional

14/10: Estruturas de repetição

Páginas da apostila: 32 a 35.

Alguns algoritmos vistos anteriormente possuem sequências repetitivas de instruções. Por exemplo, o algoritmo da média de quatro avaliações:

Inicio
  real m1, m2, m3, m4
  real media

  escrever 'Avaliação 1:'
  Ler m1
  escrever 'Avaliação 2:'
  Ler m2
  escrever 'Avaliação 3:'
  Ler m3
  escrever 'Avaliação 4:'
  Ler m4

  media <- (m1 + m2 + m3 + m4) / 4

  escrever 'Média: ', media
Fim

O algoritmo acima repete quatro vezes a sequência que lê uma nota do teclado. Porém há uma forma de expressar a repetição de sequências de instruções, usando-se o que se chama de estrutura de repetição. A estrutura de repetição enquanto condição faz repete todas as instruções enquanto a condição for verdadeira. A condição é escrita como uma expressão lógica, da mesma forma que na estrutura de decisão se condição então ... senão. Veja como fica o algoritmo acima ao ser reescrito para usar essa estrutura de repetição:

Inicio
  constante inteiro NUMEROS <- 4
  real m
  real media
  inteiro contador <- 0

  enquanto contador < NUMEROS faz  
    escrever 'Avaliação ', contador, ':'
    ler m
    media <- media + m
    contador <- contador + 1
  fimEnquanto

  escrever 'Média: ', media/NUMEROS
Fim

Esse algoritmo funciona somente para médias de quatro números. Porém calcular a média de qualquer quantidade de números usa a mesma lógica: ler os números, somá-los e dividir o total pela quantidade de números lidos. Por exemplo, para fazer com que ele calcule a média de 7 números é necessário escrevê-lo assim:

Inicio
  constante inteiro NUMEROS <- 7
  real m
  real media
  inteiro contador <- 0

  enquanto contador < NUMEROS faz  
    escrever 'Avaliação ', contador, ':'
    ler m
    media <- media + m
    contador <- contador + 1
  fimEnquanto

  escrever 'Média: ', media/NUMEROS
Fim

Note que o algoritmo praticamente não foi modificado, pois somente se alterou o valor da constante NUMEROS.

A estrutura de repetição junto com a sequência de instruções a ser repetida é comumente chamada de 'laço. Assim, no algoritmo acima o laço aparece em:

  enquanto contador < NUMEROS faz  
    escrever 'Avaliação ', contador, ':'
    ler m
    media <- media + m
    contador <- contador + 1
  fimEnquanto

Um outro exemplo ainda mais simples é mostrar na tela uma contagem numérica:

inicio
    inteiro contador
    contador <- 0

    enquanto contador < 10 faz
        escrever contador , " "
        contador <- contador + 1
    fimenquanto
fim

Ao executar esse algoritmo, tem-se como resultado:

0 1 2 3 4 5 6 7 8 9

Repare no uso de uma variável auxiliar contador para controlar a quantidade de repetições. Essa é uma técnica comum para controlar a estrutura de repetição, e já foi usada no exemplo da média. Ela pode também ser combinada com outras condições, como mostrado abaixo:

inicio
    inteiro contador <- 1
    caracter opcao <- "s"
        
    enquanto ((opcao = "s") ou (opcao = "S")) e contador < 11 faz
        escrever contador, "\n"
        contador <- contador + 1
        
        escrever "\nContinuar (S/N) ? "
        ler opcao
    fimenquanto
    
    escrever "Terminou com contador = " , contador
fim

Nesse exemplo se usa um laço para mostrar uma contagem de 1 a 10. Porém há a possibilidade de encerrar o algoritmo. Observe a condição para continuidade do laço: ela é verdadeira somente se contador < 11 e se a variável opcao for igual a "s" ou "S".

Finalmente, apesar de ser comum o uso de contadores para controle do laço, pode-se usar qualquer condição para essa finalidade. Então podem existir laços que não usam contadores para controlar a quantidade de repetições, como no próximo exemplo:

inicio
    constante texto segredo <- "secreto"
    texto senha
    
    ler senha
    enquanto senha =/= segredo faz
        escrever "Voce continua preso ! Digite a senha correta: "
        ler senha
    fimenquanto
    escrever "Voce foi liberado ..."
fim

Solução do problema proposto em sala)

inicio

   inteiro opcao <- 0
   real numero1 <- 0 , numero2 <- 0 , resultado <- 0
   enquanto opcao =/= 5 faz
       escrever "\n Entre com a opção desejada: 1- Adição; 2- Subtração; 3- Multiplicação; 4- Divisão , 5- Sair."
       ler opcao
       se opcao = 5 entao
           escrever "\n Você saiu com sucesso!"
       senao
           escrever "\n Lembre-se: Na subtração e na divisão a ordem dos números é importante!"
           escrever "\n Entre com o primeiro número: "
           ler numero1
           escrever "\n Entre com o segundo número: "
           ler numero2
           se opcao = 1 entao
               resultado <- ( numero1 + numero2 )
               escrever "\n A soma dos dois números é: " , resultado
           fimse
           se opcao = 2 entao
               resultado <- ( numero1 - numero2 )
               escrever "\n A subtração dos dois números é: " , resultado
           fimse
           se opcao = 3 entao
               resultado <- ( numero1 * numero2 )
               escrever "\n O produto dos dois números é: " , resultado
           fimse
           se opcao = 4 entao
               se numero2 = 0 entao
                   escrever "\n Não existe divisão por 0 (zero)."
               senao
                   resultado <- ( numero1 / numero2 )
                   escrever "\n A divisão dos dois números é: " , resultado
               fimse
           fimse
           se ( opcao =/= 1 e opcao =/= 2 ) e ( opcao =/= 3 e opcao =/= 4 ) entao
               escrever "\n Esta operação não está definida."
           fimse
       fimse
   fimenquanto
fim

</syntaxhighlight>

Atividades

  1. Escreva um algoritmo que mostre a tabuada de um número fornecido pelo teclado. Esse número deve estar entre 1 e 10.
  2. Modifique o exemplo da média para que a quantidade de números a serem lidos seja previamente informada pelo teclado.
  3. Modifique novamente o exemplo da média para que ela funcione para um quantidade de números desconhecida de antemão. Quer dizer, o algoritmo deve ler os números para calcular a média, mas não sabe quantos números existem (e isto não pode ser informado pelo teclado).
  4. Modifique o exemplo da senha para que o usuário tenha somente três tentativas permitidas para digitar a senha correta. caso ao final as três senhas estejam erradas, o algoritmo deve informar que a conta foi bloqueada.
  5. Escreva um algoritmo que leia até 10 números do teclado, e informe ao final qual o maior e o menor deles.
  6. Escreva um algoritmo que teste se um número informado pelo teclado é primo.

18/10: Estruturas de repetição

  • Resolução de exercícios
  • Introdução a variáveis multidimencionais

21/10: Estruturas de repetição

Variáveis multidimensionais

Em matemática existem matrizes e vetores, que são variáveis multidimensionais. Por exemplo, uma matriz 3 x 3 (3 linhas e 3 colunas) pode ser:

Vetores são matrizes unidimensionais, portanto possuem somente uma linha ou uma coluna:

Cada elemento em uma matriz ou vetor é identificado pela sua posição. Por exemplo, na posição 1, 2 da matriz A acima está o valor 6, e na posição 4 do vetor v está o valor 18. Assim, a matriz A do exemplo pode ser entendida da seguinte forma:

... e o vetor v do exemplo:

Nas linguagens de programação em geral existe um conceito muito parecido, chamado de variáveis multidimensionais ou simplesmente matrizes (arrays em inglẽs). Para exemplificar, no Portugol se poderiam definir a matriz A e o vetor v:

inicio
  inteiro A[2][2] <- {{1, 6}, {3, 5}}
  inteiro M[3][2];
  inteiro v[5] <- {1, 6, 2, 18, 5}
  inteiro i, j

  escrever "Valor de A[0][0]: ", A[0][0], "\n"
  escrever "Valor de A[0][1]: ", A[0][1], "\n"
  escrever "Valor de A[1][0]: ", A[1][0], "\n"
  escrever "Valor de A[1][1]: ", A[1][1], "\n"

  escrever "Valor de v[0]: ", v[0], "\n"
  escrever "Valor de v[1]: ", v[1], "\n"
  escrever "Valor de v[2]: ", v[2], "\n"
  escrever "Valor de v[3]: ", v[3], "\n"
  escrever "Valor de v[4]: ", v[4], "\n"

fim

A declaração da matriz se faz como uma variável comum, porém indicando-se suas dimensões:

  inteiro A[2][2] <- {{1, 6}, {3, 5}}
  inteiro M[3][2];

Exemplo de preenchimento e impressão de matrizes não quadradas

inicio
	inteiro i,j, mat[2][4]
    
      //leitura (preenchimento da matriz)
      para i de 0 ate 1 passo 1
          para j de 0 ate 3 passo 1
              ler mat[i][j]
          proximo
      proximo
      
      //impressão da matriz
      para i de 0 ate 1 passo 1
          para j de 0 ate 3 passo 1
              escrever "O valor na linha: ",i, "Coluna: ", j, "eh: ", mat[i][j]
              escrever "\n"
          proximo
      proximo
fim

Veja que a matriz M foi declarada sem valores iniciais, porém a matriz A foi inicializada na declaração.

O acesso aos elementos da matriz se faz usando-se índices, que funcionam como coordenadas dos elementos que se quer acessar. Os índices iniciam em 0:

  # índice 0,0
  escrever "Valor de A[0][0]: ", A[0][0], "\n"

O exemplo acima pode ser reescrito usando-se estruturas de repetição:

inicio
  inteiro A[2][2] <- {{1, 6}, {3, 5}}
  inteiro v[5] <- {1, 6, 2, 18, 5}
  inteiro i, j

  enquanto i < 2 faz
    j <- 0
    enquanto j < 2 faz
       escrever "Valor do elemento de A na posição ", i, ", ", j, ": ", A[i][j], "\n"
       j <- j + 1
    fimenquanto
    i <- i + 1
  fimenquanto

  i <- 0
  enquanto i < 5 faz
    escrever "valor de v na posição ", i, ": ", v[i], "\n"
    i <- i + 1
  fimenquanto

fim

Como se vê, matrizes e vetores casam perfeitamente com estruturas de repetição, e são úteis para a resolução de inúmeros problemas. Por exemplo, o problema de mostrar o nome do mês a partir do número do mês, feito anteriormente com escolhe ... caso pode ser feito assim com um vetor:

inicio
  texto nome_mes[12] <- {"Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", 
                         "Outubro", "Novembro, "Dezembro"}
  inteiro dia, mes, ano

  escrever "Dia: "
  ler dia
  escrever "Mes: "
  ler mes
  escrever "Ano: "
  ler ano

  escrever dia, " de ", nome_mes[mes], " de ", ano
fim

Outro problema comum é precisar guardar um conjunto de valores, e depois ordená-los:

inicio
  inteiro v[10]
  inteiro i
  inteiro quantidade

  escrever "Quantos valores serão digitados (máximo = 10) ? "
  ler quantidade

  i <- 0
  enquanto i < quantidade faz
    escrever "valor ", i, ": "
    ler v[i]
    i <- i + 1
  fimenquanto

  // ordena os valores ...

  escrever "valores ordenados: "
  i <- 0
  enquanto i < quantidade
    escrever v[i], " "
    i <- i + 1
  fimenquanto
fim

Atividades

  1. Escreva um algoritmo que leia 5 números do teclado, e depois mostre-os em ordem inversa à que foi digitada.
  2. Escreva um algoritmo que leia dois vetores de 5 números, e depois mostre se os vetores são iguais.
  3. Escreva um algoritmo que leia um palavra do teclado e depois procure-a numa lista de palavras preexistente. Essa lista deve ser implementada usando um vetor.
  4. Escreva um algoritmo que leia 5 números, e mostre-os em ordem crescente.
  5. Modifique o algoritmo anterior para mostrá-los em ordem decrescente.
  6. Em um jogo de bingo devem-se contar quantos números de uma aposta foram sorteados no bingo. Faça um algoritmo que, dados os números sorteados e uma aposta, conta quantos números apostados forma sorteados.

Solução exercício 4 e 6 propostos pelo Luiz Gustavo

inicio

   //declaração da variáveis
   inteiro v [ 5 ] , i , j , troca
   //entrada de dados
   para i de 0 ate 4 passo 1
       ler v [ i ]
   proximo
   //organizar em ordem crescente
   para i de 0 ate 4 passo 1
       para j de 0 ate 4 passo 1
           se v [ i ] > v [ j ] entao
               troca <- v [ i ]
               v [ i ] <- v [ j ]
               v [ j ] <- troca
           fimse
       proximo
   proximo
   //impressão dos dados
   para i de 0 ate 4 passo 1
       escrever "\n" , v [ i ]
   proximo

fim </syntaxhighlight>

inicio

   //declaração das variáveis
   inteiro lista_num [5][5] <- {{10, 5, 20, 31, 33}, {51, 12, 13, 15, 29}, {25, 28, 22, 26, 36},

{11, 24, 34, 54, 44}, {1, 2, 55, 3, 5}}

   inteiro numero [5][5],i,j,cont
   //entrada de dados
   escrever "Informe os números do Bingo: "
   enquanto i < 5 faz
       j <- 0
       enquanto j < 5 faz
           ler numero [ i ] [ j ]
           j <- j + 1
       fimenquanto
       i <- i + 1
   fimenquanto
   //verificando quantos números são iguais
   i <- 0
   enquanto i < 5 faz
       j <- 0
       enquanto j < 5 faz
           se (numero [i][j] = lista_num [i][j]) entao
               cont <- cont + 1
           fimse
           j <- j + 1
       fimenquanto
       i <- i + 1
   fimenquanto
   //Imprimindo os dados
   escrever "A quantidade de números sorteados nesta aposta foi: " , cont

fim </syntaxhighlight>

25/10: Revisão para avaliação de Lógica de Programação

1. Crie um programa que lê três inteiros e informa VERDADEIRO se apenas o maior deles é par ou se o menor deles é ímpar ou informa FALSO em caso contrário.

2. Desenvolva um programa que recebe do usuário o placar de um jogo de futebol (os gols de cada time) e informa se o resultado foi um empate, a vitória do primeiro time ou do segundo time.

3. Elabore um programa que recebe do usuário três cadeias de caracteres e informa VERDADEIRO se há pelo menos duas diferentes cadeias iguais aos valores 'azul', 'preto'ou 'vermelho' ou FALSO em caso contrário. Exemplos: {'azul', 'preto', 'branco'} é VERDADEIRO; {'azul', 'roxo', 'azul'} é FALSO; {'preto', vermelho', 'vermelho'} é VERDADEIRO.

4. Tendo-se como dados de entrada a altura e o sexo de uma pessoa, construa um algoritmo que calcule seu peso ideal, utilizando as seguintes fórmulas:

    • para homens: (72,7 * h) – 58;
    • para mulheres: (62,1 * h) – 44,7.

5. Escrever um algoritmo, que leia um conjunto de 23 dados, cada um, contendo o peso e o código do sexo ("F" ou "M") dos alunos de uma classe, calcule e imprima:

    • Maior e o menor peso da turma;
    • A média de peso dos homens;
    • A média de peso da turma;

Solução proposta pelo Manfred Ex. 1

inicio

   inteiro n1 <- 0 , n2 <- 0 , n3 <- 0 , maior <- 0 , menor <- 0
   escrever "Digite o primeiro número: "
   ler n1
   escrever "Digite o segundo número: "
   ler n2
   escrever "Digite o terceiro número: "
   ler n3
   maior <- n1
   se ( n2 > maior ) entao
       maior <- n2
   fimse
   se ( n3 > maior ) entao
       maior <- n3
   fimse
   menor <- n1
   se ( n2 < menor ) entao
       menor <- n2
   fimse
   se ( n3 < menor ) entao
       menor <- n3
   fimse
   se ( maior % 2 ) = 0 ou ( menor % 2 ) =/= 0 entao
       escrever "Verdadeiro"
   senao
       escrever "Falso"
   fimse

fim


</syntaxhighlight>

Proposta do Luiz para exercício 5

inicio
    //declaração das variaveis
    real peso [ 5 ] <- 0 , menor <- 0 , maior <- 0 , pesom <- 0 , pesot <- 0
    inteiro i , cont <- 0
    caracter sexo [ 5 ]
    //entrada de dados
    para i de 0 ate 4 passo 1
        escrever "Informe o peso do " , ( i + 1 ) , "º aluno: "
        ler peso [ i ]
        escrever "Informe o código do sexo do " , ( i + 1 ) , "º aluno (Masculino= M; Feminino= F): "
        ler sexo [ i ]
        escrever "\n"
    proximo
    //testando o maior e menor peso
    maior <- peso [ 1 ]
    menor <- peso [ 1 ]
    para i de 0 ate 4 passo 1
        se ( peso [ i ] > maior ) entao
            maior <- peso [ i ]
        fimse
        se ( peso [ i ] < menor ) entao
            menor <- peso [ i ]
        fimse
    proximo
    //calculando a media de peso dos homens
    para i de 0 ate 4 passo 1
        se ( sexo [ i ] = "M" ) ou ( sexo [ i ] = "m" ) entao
            pesom <- ( pesom + peso [ i ] )
            cont <- ( cont + 1 )
        fimse
    proximo
    //calculando a media de peso da turma
    para i de 0 ate 4 passo 1
        pesot <- ( peso [ i ] + pesot )
    proximo
    //impressão dos dados
    escrever "\nO maior peso é: " , maior , "\nO menor peso é: " , menor
    escrever "\nA média de peso dos homens é: " , ( pesom / cont )
    escrever "\nA média de peso da turma é: " , ( pesot / 5 )
fim

25/10: Revisão Lógica de Programação, com respostas :)

1. Desenvolver um programa que efetue a leitura de 5 elementos de uma matriz A do tipo vetor. Construir uma matriz B de mesmo tipo, observando a seguinte lei de formação: Se o valor do índice for par, o valor deverá ser multiplicado por 5, sendo ímpar deverá ser somado por 5. Ao final mostrar os conteúdos das duas matrizes.


inicio

     //declaração dos vetores A e B

inteiro i,a[5],b[5]

     //formação do vetor A
     para i de 0 ate 4 passo 1
         ler a[i]
     proximo
     
     //guarda valor na posição par
     para i de 0 ate 4 passo 2
         b[i]<-a[i]*5
     proximo
     
     //guarda valor na posição ímpar
     para i de 1 ate 4 passo 2
         b[i]<-a[i]+5
     proximo
     
     //apresenta valor B resposta
     escrever "Formação do vetor B (vetor respota):"
     escrever "\n"
     
     para i de 0 ate 4 passo 1
         escrever "O valor da posição ",i, " é: ", b[i]
         escrever "\n"
     proximo

fim </syntaxhighlight>

Solução para o exercício 1 desenvolvida pelo Thiarlles e Manfred:

inicio real matrizA[10], matrizB[10]

          inteiro i<-0
          escrever "\n Construa a matriz A."
          enquanto i <= 9 faz 
              escrever  "\n Entre com a posição ", i
              ler matrizA[i]
              i <- i+1
          fimEnquanto
          i <- 0 
          enquanto i <= 9 faz 
              escrever matrizA[i], " "
              i <- i+1   
          fimEnquanto  
          escrever "\n "
          i <- 0
          enquanto i <= 9 faz
              matrizB[i] <- ((matrizA[i])*5)
              matrizB[i+1] <- ((matrizA[i+1])+5)
              i <- i+2
          fimEnquanto
          i <- 0
          escrever "\n A matriz B será: "
          enquanto i <= 9 faz 
              escrever matrizB[i], "   " 
              i <- i+1
          fimenquanto 

fim </syntaxhighlight>

2. Desenvolver um programa que efetue a leitura de 5 elementos de uma matriz A do tipo vetor. No final, apresente o total da soma de todos os elementos que sejam ímpares.

inicio

   //declaração das variáveis
   inteiro a [5] , i , soma <- 0
   //entrada de dados
   para i de 0 ate 4 passo 1
       ler a [i]
   proximo
   //construindo a matriz "B"
   para i de 0 ate 4 passo 1
       se ( a [i] % 2 =/= 0 ) entao
           soma <- soma + a [ i ]
       fimse
   proximo
   //impressão dos dados
   escrever "O valor da soma dos numero ímpares é: " , soma

fim </syntaxhighlight>

3. Ler 15 elementos de uma matriz A do tipo vetor. Construir uma matriz B de mesmo tipo. Observando a seguinte lei de formação: “Todo elemento de B deverá ser o quadrado do elemento de A correspondente”.

inicio

   //declaração das variáveis
   inteiro a[15] ,b[15] ,i
   //entrada de dados
   para i de 0 ate 14 passo 1
       ler a[i]
   proximo
   //construindo a matriz "B"
   para i de 0 ate 14 passo 1
       b[i] <- a[i] * a[i]
   proximo
   //impressão dos dados
   escrever "\nMatriz A:"
   para i de 0 ate 14 passo 1
       escrever "" , a[i]
   proximo
   escrever "\nMatriz B:"
   para i de 0 ate 14 passo 1
       escrever "" , b [i]
   proximo

fim </syntaxhighlight>

4. Escreva um algoritmo que:

    • Leia uma matriz 5 x 5 de elementos reais;
    • Divida cada elemento de uma linha da matriz pelo elemento da diagonal principal desta linha;
    • Imprima a matriz assim modificada.

inicio

   //declaração das variáveis
   real a [5] [5] , b [5] [5]
   inteiro i , j
   //entrada de dados
   para i de 0 ate 4 passo 1
       para j de 0 ate 4 passo 1
           ler a [i] [j]
       proximo
   proximo
   //dividindo a linha da matriz por sua diagonal principal
   para i de 0 ate 4 passo 1
       para j de 0 ate 4 passo 1
           b [i] [j] <- ( a [i] [j] / a [i] [i] )
       proximo
   proximo
   //impressão dos dados
   escrever "\nMatriz: "
   escrever "\n"
   para i de 0 ate 4 passo 1
       escrever "\n" , a [i] [0] , " " , a [i] [1] , " " , a [i] [2] , " " , a [i] [3] , " " , a [i] [4]
   proximo
   escrever "\n\nMatriz modificada: "
   escrever "\n"
   para i de 0 ate 4 passo 1
       escrever "\n" , b [i] [0] , " " , b [i] [1] , " " , b [i] [2] , " " , b [i] [3] , " " , b [i] [4]
   proximo

fim </syntaxhighlight>

5. Elabore um algoritmo para corrigir provas de múltipla escolha. Assuma que em cada prova encontraremos os seguintes dados: RM, NOME DO ALUNO, MATÉRIA e BIMESTRE, além de 10 questões numeradas de 1 até 10 e que cada questão possui 5 alternativas identificadas pelas letras de “a” até “e”. Primeiramente, o algoritmo deve ler o gabarito e o número de provas a serem corrigidas . A seguir, os dados das provas a serem corrigidas devem ser lidas. Ainda, o algoritmo deverá calcular e escrever:

    • O RM, NOME DO ALUNO, MATÉRIA, BIMESTRE e a NOTA de cada aluno (assumindo que cada questão correta vale 1 ponto).
    • A porcentagem de aprovação, assumindo que a nota mínima para aprovação é 6.

inicio

   //declaração das variáveis
   caracter gab [10] , resp [10]
   inteiro i , qtdprova , cont <- 0 , aprovados <- 0
   real nota <- 0
   texto rm <- "" , aluno <- "" , mat <- "" , bimestre <- ""
   
   //entrada de dados
   para i de 0 ate 9 passo 1
       escrever "Informe o gabarito da " , (i + 1) , "ª questão:"
       ler gab [i]
   proximo
   
   escrever "Informe a quantidade de provas: "
   ler qtdprova
   
   //dados das provas
   enquanto cont < qtdprova faz
       escrever "**************************************************"
       escrever "\nInforme RM: "
       ler rm
       escrever "Informe o nome do aluno: "
       ler aluno
       escrever "Informe a matéria: "
       ler mat
       escrever "Informe o bimestre: "
       ler bimestre
       //informando as respostas
       para i de 0 ate 9 passo 1
           escrever "Informe a resposta da " , (i + 1) , "ª questão:"
           ler resp [i]
       proximo
       
       //corrigindo a prova
       nota <- 0
       para i de 0 ate 9 passo 1
           se ( gab [i] = resp [i] ) entao
               nota <- nota + 1
           fimse
       proximo
       
       //informando a nota
       escrever "A nota do(a) " , aluno , " é: " , nota , "\n\n"
       
       //verificando aprovação do aluno
       se ( nota >= 6 ) entao
           aprovados <- ( aprovados + 1 )
       fimse
       cont <- ( cont + 1 )
   fimenquanto
   
   //imprimindo valores
   escrever "\n**************************************************"
   escrever "\nA quantidade de aprovados é: " , aprovados

fim </syntaxhighlight>

28/10: Avaliação de Lógica de Programação

Dicas para a avaliação (vale a pena revisar conceitos):

    • Números primos
    • Fatorial
    • MDC: Máximo Divisor Comum
    • MMC: Mínimo Múltiplo Comum
    • Cálculo para série de Fibonacci

Conceitos Avaliação de Lógica:

  • Conceitos avaliação de Lógica de Programação clique aqui

02/11: Feriado Nacional

  • Finados (sem atividades).

04/11: Linguagem C

    • Introdução a linguagem C
    • Primeiros Programas
    • Compilador Gcc

Obs: durante as aulas usaremos o NetBeans, um Ambiente Integrado de Desenvolvimento (IDE - Integrated Development Environment). Um IDE é um programa que auxilia o programador. Ele integra um editor de programas, um gerenciador de projetos, compilador e um depurador (debugger).

Para instalar o Netbeans:

  1. Faça o download do instalador. Salve-o em algum subdiretório.
  2. Abrindo um terminal, entre no subdiretório onde está o instalador e execute esse comando:
    bash netbeans-6.8-ml-cpp-linux.sh
    
    • Caso o instalador falhe porque não encontrou a JVM (Máquina Virtual Java), instale-a com esse comando:
      sudo apt-get install -y sun-java6-jdk
      
  3. Aceite as opções de instalação sugeridas pelo instalador.
  4. Ao final da instalação, o Netbeans 6.8 estará acessível pelo menu Aplicativos -> Programação.
  5. Sempre que for escrever um novo programa com o Netbeans, crie um novo projeto (ver menu Arquivo->Novo Projeto). Selecione um projeto do tipo "Aplicativo C/C++".

Compilando o primeiro programa

  • O clássico Hello World!
#include <stdio.h>

int main(int argc, char *argv[])
{
	printf("Alô mundo!\n");
}
  • Mostrando mensagens de na tela: puts e printf:
    #include <stdio.h>
    
    int main() {
      int n;
    
      n = 5;
      
      puts("Demonstração de puts e printf");
    
      printf("Valor de n: %d\n", n);
    
      n = n + 1;
    
      printf("Novo valor de n: %d\n", n);
    
      return 0;
    }
    
  • Lendo dados do teclado: scanf
    #include <stdio.h>
    
    int main() {
      int n;
    
      printf("Digite um número inteiro: ");
    
      scanf("%d", &n);
    
      printf("Valor digitado foi %d\n", n);
    
      return 0;
    }
    

Tipos de dados

Portugol C Exemplo
inteiro int int x;
caracter char char letra;
real float ou double float pi = 3.1416;
texto char * ou vetor de char char * mensagem = "Hello world";
char palavra[16];
logico qualquer tipo (valor 0 = Falso, qualquer outro valor = Verdadeiro) int ok = 1;
char teste = 0;


Comandos/funções e Estruturas de controle

Portugol C Exemplo
inteiro n, m

escrever "Ola, mundo!\n"
escrever "valor de n: ", n, "\n"
escrever "valor de n: ", n, ", e valor de x: ", x, "\n"
int n, m;

printf("Ola, mundo!\n");
printf("valor de n: %d\n", n);
printf("valor de n: %d, e valor de x: %d\n", n, x);
inteiro n

ler n
int n;

scanf("%d", &n);
se condição então
//comandos
fimse
if (condição) {
//comandos
}
se condição então
  //comandos
senão
  //comandos
fimse
if (condição) {
 //comandos
} else {
 //comandos
}
escolhe expressão
  caso valor1:  
    //comandos
  caso valor2:
    //comandos
  defeito:
    //comandos
fimescolhe
switch (expressão) {
  case valor1:
    //comandos
  case valor2:
    //comandos
  default:
    //comandos
}
enquanto condição faz
//comandos
fimenquanto
while (condição) {
  //comandos
}
para variavel de inicio ate fim passo incremento
//comandos
proximo
for (variavel=inicio; variavel <= fim; variavel++) {
//comandos
}

Atividades

  • Traduza para C os seguintes algoritmos Portugol:
    1. Inicio
        inteiro x, y
       
        Escrever "Digite um numero: ",
        Ler x
        Escrever "Digite outro numero: ",
        Ler y
        Escrever "Soma = ", x+y
      Fim
      
    2. Inicio
        inteiro x, y, z
       
        Escrever "Digite um numero: ",
        Ler x
        Escrever "Digite outro numero: ",
        Ler y
        z <- x + y
        Escrever "Soma = ", z
      Fim
      
    3. Inicio
        Inteiro n1, n2, n3, r
       
        Escrever "Primeiro numero: "
        ler n1
        Escrever "Segundo numero: "
        ler n2
        Escrever "Terceiro numero: "
        ler n3
       
        r <- (n1 + n2 + n3) /3
       
        Escrever "Media=", r
      Fim
      
    4. Inicio
        inteiro anos, dias
       
        Escrever "Quantos anos se passaram ? "
        Ler anos
        dias <- anos * 365
        Escrever "... então se passaram ", dias, " dias"
      Fim
      
    5. Inicio
        constante inteiro diasPorAno <- 365
        inteiro anos, dias
       
        Escrever "Quantos anos se passaram ? "
        Ler anos
        dias <- anos * diasPorAno
        Escrever "... então se passaram ", dias, " dias"
      Fim
      
    6. inicio
        real massa
        real forca
        real aceleracao
        constante real g <- 9.8
        constante real ac <- 0.01
        
        escrever "força: "
        ler forca
        
        escrever "massa: "
        ler massa
        
        aceleracao <- forca/massa - ac*massa*g
        
        escrever "aceleracao=", aceleracao, " m/s2"
        
      fim
      
    7. inicio
        real a, b, c
        real delta
        real x1, x2
        
        escrever "Forneça os coeficientes da equação de 2o grau (formato: ax^2 + bx + c):\n"
        escrever "a="
        ler a
        escrever "b="
        ler b
        escrever "c="
        ler c
        
        delta <- b^2 - 4*a*c
        x1 <- (-b + delta^0.5)/(2*a)
        x2 <- (-b - delta^0.5)/(2*a)
        
        escrever "1a raiz=", x1
        escrever "\n2a raiz=", x2  
      fim
      
    8. inicio
            real x1, x2, x3, x4, x5
            real media
            real desvioPadrao
            constante inteiro N <- 5
            
            // Ler os cinco valores pelo teclado
            ler x1
            ler x2
            ler x3
            ler x4
            ler x5
            
            // Calcular a media
            media <- (x1 + x2 + x3 + x4 + x5) / N
            
            // Calcular o desvio padrao
            desvioPadrao <- (x1 - media)^2 + (x2 - media)^2 + (x3 - media)^2 + (x4 - media)^2 + (x5 - media)^2
            desvioPadrao <- (desvioPadrao / (N-1))^0.5
            
            escrever "Media=", media
            escrever "\nDesvio padrao=", desvioPadrao
      fim
      
    9. inicio
            real renda
            real irpf
            
            escrever "Informe sua renda: "
            ler renda
            
            se renda < 1372.81 entao
              irpf <- 0
            senao 
              se renda < 2743.25 entao
                irpf <- (renda - 205.92)*0.15 
              senao
                irpf <- (renda - 548.82)*0.275
              fimSe
            fimSe
            
            escrever "Imposto devido: ", irpf  
      fim
      
    10. inicio
          inteiro dividendo
          inteiro divisor
          inteiro resto , quociente
      
          escrever "Dividendo: "
          ler dividendo
          escrever "Divisor: "
          ler divisor
      
          se divisor = 0 entao
              escrever "Nao pode dividir: divisor = 0 !!!"
          senao
              resto <- dividendo % divisor
              se resto = 0 entao
                  quociente <- dividendo / divisor
                  escrever dividendo , " / " , divisor , " = " , quociente
              senao
                  escrever "Nao pode fazer divisao inteira"
                  escrever " (resto = " , resto , ")"
              fimse
          fimse
      fim
      
    11. inicio
          inteiro termometro , barometro , tempo
      
          escrever "Qual a condição do termômetro: \n"
          escrever "Digite 1 para baixando , 2 para estacionário e 3 para subindo. \n"
          ler termometro
      
          escrever "Informe a condição do barômetro: \n"
          escrever "Digite 1 para baixando , 2 para estacionário e 3 para subindo. \n"
          ler barometro
      
          tempo <- termometro*10 + barometro
      
          escolhe tempo
              caso 11:
                  escrever "Chuvas abundantes e ventos de sul a sudoeste fortes"
              caso 12:
                  escrever "Chuva Provavel , ventos de sul a sudeste"
              caso 13:
                  escrever "Tempos Bons , ventos de sul a sudeste"
              caso 21:
                  escrever "Frente quente com chuva provavel"
              caso 22:
                  escrever "Tempo Incerto , ventos variaveis"
              caso 23:
                  escrever "Tempos Bons , ventos do leste frescos"
              caso 31:
                  escrever " Tempo instavel , aproximaçao de frente"
              caso 32:
                  escrever "Tempo Mudando para bom , ventos de leste"
              caso 33:
                  escrever "Tempos Bons , ventos quentes e secos"
              defeito:
                  escrever "Utilize somente os algorismos de 1 a 3 para indicar as condiçoes do equipamentos"
          fimescolhe
      fim
      
    12. inicio
          // coeficientes do polinomio  [ax^2 + bx + c = 0 ]
          real a , b , c
          
          escrever "Forneça os coeficientes da equação de 2o grau:\n"
          escrever "a="
          ler a
          escrever "b="
          ler b
          escrever "c="
          ler c
          
          // equação do tipo [ bx + c = 0 ]
          se a = 0 entao
              escrever " não é uma equação de 2o grau !!!"
          senao
              // calcular o delta => interior da raiz
              real delta
              
              delta <- b ^ 2 - 4 * a * c
              
              // não existem raizes  reais de números negativos
              se delta < 0 entao
                  escrever " não tem raizes reais"
              senao
                  // -----------  raiz dupla  ----------------
                  se delta = 0 entao
                      real x1
                      x1 <- -b / 2 * a
                      escrever "\nraiz dupla : " , x1
                  senao
                      // - ---------- duas raizes ---------------
                      real x1 , x2
                      x1 <- ( -b + raiz ( delta ) ) / 2 * a
                      x2 <- ( -b - raiz ( delta ) ) / 2 * a
                      escrever "\nraiz x1 : " , x1
                      escrever "\nraiz x2 : " , x2
                  fimse//raiz dupla
              fimse// delta >0
          fimse// a <> 0
      fim
      
    13. inicio
          inteiro num, bit
          inteiro base
          
          escrever "Este algoritmo converte um número inteiro para sua representação binária.\n"
          Escrever "O número deve estar entre 0 e 131071, e a representação binária\n"
          escrever "terá 17 bits\n\n"
          escrever "Digite o numero a ser convertido para binário: "
          ler num
      
          base <- 65536
          enquanto base > 0 faz
              bit <- ( num / base ) % 2
              escrever bit, " " 
              base <- base / 2
          fimenquanto
      fim
      
    14. inicio
          inteiro n , fat
          ler n
          fat <- 1
          enquanto n > 1 faz
             fat <- fat * n
             n <- n - 1         
          fimenquanto
          
          escrever "Fatorial=" , fat
      fim
      
    15. inicio
          inteiro valor , menor , contador
          ler menor
          contador <- 9
          enquanto contador > 0 faz
              ler valor
              se valor < menor entao
                  menor <- valor
              fimse
              contador <- contador - 1
          fimenquanto
          escrever "menor valor = ", menor
      fim
      
    16. inicio
          inteiro numero , n , resto <- 1
          escrever "Forneçaa um número: "
          ler numero
          n <- 2
          enquanto n <= numero / 2 e resto =/= 0 faz
              resto <- numero % n
              escrever "n=" , n , ": resto=" , resto , "\n"
              n <- n + 1
          fimenquanto
          
          se resto = 0 entao
              escrever "nao primo: divisivel por " , n - 1
          senao
              escrever "primo"
          fimse
      fim
      
    17. // Le 5 valores e identifica os dois maiores.
      inicio
          inteiro valor , maior1 , maior2 , contador
          
          ler valor
          maior1 <- valor
          
          ler valor
          se valor > maior1 entao
            maior2 <- maior1
            maior1 <- valor
          senao
            maior2 <- valor
          fimse
      
          contador <- 3
          enquanto contador > 0 faz
              ler valor
              se valor > maior1 entao
                  maior2 <- maior1
                  maior1 <- valor
              senao
                  se valor > maior2 entao
                      maior2 <- valor
                  fimse
              fimse
              contador <- contador - 1
          fimenquanto
      
          escrever "maior valor = " , maior1
          escrever "\nsegundo maior valor = " , maior2
      fim
      

08/11: Linguagem C

  • Vista de prova (Lógica de programação)
  • Refaça a avaliação completa em linguagem C
  • Utilize a IDE NetBeans.

11/11: Projeto Final da Disciplina

O jogo: Campo Minado

O Campo Minado é um jogo clássico disponível em diferentes sistemas operacionais. Basicamente devem-se procurar as minas existentes em um campo quadriculado, perdendo-se o jogo se pisar em uma mina, e vencendo se descobrir todas as minas. O jogo oferece pistas sobre a localização das minas, e usando-se um pouco de lógica podem-se encontrá-las. Uma versão desse jogo para Linux aparece na figura a seguir .

Minas-linux.png

A cada jogada deve-se escolher uma casa do tabuleiro, optando-se por pisá-la (revelando-a) ou marcá-la como uma provável mina. Ao pisar numa casa, três ações podem ocorrer:

  1. A casa contém uma mina, o que revela todas as demais minas e encerra o jogo com derrota.
  2. A casa é vizinha a uma ou mais minas, e assim em seu lugar aparece o número de minas em casas vizinhas.
  3. Nenhuma mina existe em casas vizinhas, então a casa aparece vazia. Além disso, todas as casas vizinhas que também não possuam minas são reveladas.

Ao final do jogo, a pontuação é dada pelo tempo que se levou para se descobrirem as minas. O jogo contabiliza uma lista de melhores jogadas, contendo o nome do jogador e o tempo de jogo. Melhores jogadas são aquelas com menores tempos de jogo.

A versão do jogo a ser desenvolvida será baseada em texto (mas quem quiser fazer uma versão gráfica fique à vontade !). Basicamente deve ser apresentado o tabuleiro, mostrando-se apenas as casas já reveladas e o tempo de jogo decorrido, e um prompt pedindo as coordenadas da próxima casa assim como o tipo de ação (se pisar na casa ou marcar a provável existência de uma mina).

Etapas de desenvolvimento

  • Proposta de código que contempla:
    • Bibliotecas e definições
    • Declaração de constantes e variáveis
      • Uso de variáveis com mesmo nome e diferentes escopos
      • Vetor e matriz
    • Operadores lógicos e matemáticos
    • Expressões
      • E/S
      • Estruturas de decisão e repetição
    • Funções
      • Passagem de parâmetro por valor e por referência
    • Acesso a uma matriz através de um vetor linear (função iniciaJogo)
    • Ponteiros

O laço principal do jogo ...

O jogo funciona com um laço principal, que lê as coordenadas da pŕoxima casa e a ação a ser feita, e atualiza o tabuleiro apropriadamente:

Fluxo-Campo-Minado.png

Note que nesse laço devem-se contabilizar quantas minas fora descobertas. Esse valor é necessário para decidir se o jogo já acabou.

O tabuleiro

Representar o tabuleiro: etapas X a Y.

O tabuleiro do campo minado deve ser representado em formato de texto conforme a figura abaixo. Nesta figura, o tabuleiro está completamente revelado.

Tabuleiro-Minado.png

As colunas são identificadas por letras maiúsculas, e as linhas por números. Cada casa do tabuleiro pode conter uma mina ou um número que conta quantas minas existem em casas vizinhas. Casas já reveladas devem mostrar essa contagem de minas vizinhas, sendo que se não houver minas a casa deve ser mostrada vazia (preenchida com espaço). Casa em que se marcou a existência de uma mina deve mostrar a letra M. Por fim, casas ainda não reveladas devem ser preenchidas com o caractere ?. Um tabuleiro parcialmente revelado apareceria como a figura abaixo.

Tabuleiro-Minado2.png

Etapa 1: Modelando o tabuleiro

Conteúdos abordados:

Deve-se nessa etapa escolher uma forma de representar o tabuleiro dentro do programa. Devem-se pensar também em como representar as casas do campo minado:

  • Como definir que uma casa possui uma mina ?
  • Como definir que uma casa está vazia ? Nesse caso, como informar a quantidade de minas em casas vizinhas ?
  • Como definir se uma casa já foi pisada ?

Ponto de partida para mostrar um tabuleiro na tela. O tabuleiro foi modelado como uma matriz de inteiros bidimensional.

#include <stdio.h>

int main(int argc, char** argv) {
    int tabuleiro[5][5] = { {0,0,1,1,0}, {1,1,2,0,0}, {10,1,0,0,0},
                           {1,1,1,0,0}, {0,0,0,0,10} };
    int i, j;

    //i indica a linha, j a coluna

    for (i=0;i<5;i++){
        printf("\n");
        for (j=0;j<5;j++){
            printf("%d ", tabuleiro[i][j]);

        }
    }
    return (EXIT_SUCCESS);
}

Cada casa dessa matriz contém um número inteiro. Para representar o estado de cada casa do tabuleiro sugeriu-se um código numérico:

  • Casa com mina: algum número > 8
  • Casa sem mina: um número que conte quantas minas existem em casas vizinhas. Tal número estará entre 0 e 8.

18/11: Montando o tabuleiro completo

Conteúdos abordados:

Desenhando o tabuleiro completo

Dando continuidade à visualização do tabuleiro, agora deve-se desenhá-lo por completo na tela. Mostrar um tabuleiro com 10 linhas e 10 colunas, seguindo a abordagem da aula anterior.

Explorando printf para mostrar dados na tela

A função printf mostra dados na tela de acordo com um formato (daí seu nome: printf = print formatted, ou imprima formatado). O exemplo mais simples de uso do printf faz com que seja mostrada somente uma constante de texto, como a seguir:

printf("Apenas uma constante de texto ...\n");

O resultado na tela é:

Apenas uma constante de texto ...

Porém printf faz muito mais do que isso. Um segundo uso envolve mostrar dados que misturam constantes de texto e valores numéricos:

int voltas = 15;
float pi = 3.1416;

printf("Contador de voltas = %d\n", voltas);
printf("Angulo da volta atual = %f radianos\n", pi);

Na tela será mostrado o seguinte:

Contador  de voltas = 15
Angulo da volta atual = 3.1416 radianos

Esse segundo exemplo mostra como especificar o formato do que deve aparecer na tela. O formato é o primeiro argumento da função printf, e ele contém uma especificação do texto que deve aparecer na tela. Nesse texto podem-se indicar valores a serem substituídos (eles aparecem prefixados com %), os quais devem ser fornecidos nos demais argumentos da função. No primeiro printf do exemplo acima, o formato é:

"Contador de voltas = %d\n"

Nesse texto, toda sequência de caracteres que iniciar com % indica que ali deve-se substituir por um valor. Dependendo da letra que vier depois de %, o tipo de valor será int (inteiro), float (real), double (real com mais casas), char (caractere), string (texto). A tabela abaixo exemplifica os diferentes tipos de valores que podem ser especificados no formato da função printf:

Tipo de dados Formato Exemplo O que aparece na tela
int %d
int horas=2;

printf("Já se passaram %d horas ...\n", horas);
Já se passaram 2 horas ...
char %c
char letra = 'S';

printf("Você digitou a letra %c !\n", letra);
Você digitou a letra S !
float %f
float media = 4.5;

printf("Média calculada=%f\n", media);
Média calculada=4.5
double %g
double angulo = 0.1122333;

printf("Angulo=%g\n", angulo);
Angulo=0.111222333
char * (string) %s
char * nome = "Filomena";

printf("Cara sra. %s ...",  nome);
Cara sra. Filomena ...

Para substituir mais de um valor, basta especificar no formato e fornecer os valores nos demais argumentos:

int hora = 10, minuto = 5, segundo = 0;

printf("Horario: %d:%d:%d\n", hora, minuto, segundo);

... o que faz aparecer na tela:

Horario: 10:5:0

Esse último exemplo poderia ser melhorado, pois o horário ficou esquisito de ler ... normalmente costumamos ver horas, minutos e segundos com dois algarismos, como a seguir:

Horario: 10:05:00

É possível fazer com que printf faça isso automaticamente, bastando especificar o seguinte no formato:

int hora = 10, minuto = 5, segundo = 0;

printf("Horario: %02d:%02d:%02d\n", hora, minuto, segundo);

Note que ao invés de %d se especificou %02d. Esse formato faz com que se mostre um número inteiro com no mínimo dois algarismos. Caso o número tenha somente um algarismo, printf automaticamente adiciona um 0 à esquerda. Isso funciona somente para formatos numéricos.

Além de acrescentar zeros à esquerda de valores numéricos, é possível tabular os valores mostrados de forma que ocupem uma certa quantidade de colunas. Por exemplo, caso se deseje mostrar o seguinte:

Nome         Idade        Sexo
Marcelo      39           M
Marina       9            F
Luis         11           M

... pode-se fazer assim:

printf("%-12s %-12s %s\n", "Nome", "Idade", "Sexo");
printf("%-12s %-12d %c\n", "Marcelo", 39, 'M');
printf("%-12s %-12d %c\n", "Marina", 9, 'F');
printf("%-12s %-12d %c\n", "Luis", 11, 'M');

Note que desta vez adicionou-se após % a sequência -12. Isso indica que o valor a ser mostrado deve ocupar no mínimo 12 posições, preenchendo-se com espaços caso necessário. Veja que os valores foram alinhados à esquerda. Caso se deseje que sejam alinhados à direita, basta fazer assim:

printf("%12s %12s %s\n", "Nome", "Idade", "Sexo");
printf("%12s %12d %c\n", "Marcelo", 39, 'M');
printf("%12s %12d %c\n", "Marina", 9, 'F');
printf("%12s %12d %c\n", "Luis", 11, 'M');

... e assim aparecerá o seguinte na tela:

       Nome        Idade Sexo
    Marcelo           39 M
     Marina            9 F
       Luis           11 M

Colocando as minas

No tabuleiro devem ser colocadas 10 minas aleatoriamente. Isso significa que para cada uma dessas minas, devem-se gerar aleatoriamente suas coordenadas no tabuleiro. A geração de números aleatórios pode ser feita usando-se a função random(). Essa função gera um número inteiro entre 0 e 2147483647. Para usá-la no tabuleiro, pode-se fazer o seguinte:

#include <stdlib.h>

int main() {
  int x, y;

  // gera dois números aleatórios entre 0 e 9, e guarda-os nas variáveis x e y
  x = random() % 10;
  y = random() % 10;
  
}

Mais sobre a função random()

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

int main() {
  int x,y,z;
  time_t t;

  // Lê o valor do relógio
  t = time(NULL);

  // Usa o valor do relógio como semente do gerador de números
  // pseudo-aleatórios.
  srandom(t);

  // Sorteia três números pseudo-aleatórios
  x = random() % 10;
  y = random() % 10;
  z = random() % 10;

  printf("x=%d, y=%d, z=%d\n", x, y, z);
}

A versão atual do jogo está assim:

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

#define MINAS 10
#define LINHAS 10
#define COLUNAS 10

#define TEM_MINA 10

/*
 * 
 */
int main(int argc, char** argv) {
    int tabuleiro[LINHAS][COLUNAS];
    int i, j;

    // Zerar todas as posições do tabuleiro !
    i = 0;
    while ( i < LINHAS) {
        j = 0;
        while (j < COLUNAS) {
            tabuleiro[i][j] = 0;
            j++;
        }
        i++;
    }
    
    // Colocar as minas aqui !!!

    //Agora mostrar o tabuleiro que foi gerado

    //i indica a linha, j a coluna
    i = 0;
    while (i < LINHAS) {
        // O while abaixo mostra todas as colunas da linha "i"
        j = 0;
        while (j < COLUNAS) {
            if (tabuleiro[i][j] == TEM_MINA) {
                printf("* ");
            } else {
                if (tabuleiro[i][j] == 0) {
                    printf("  ");
                } else {
                    if ((tabuleiro[i][j] >= 1) && (tabuleiro[i][j] <= 8)) {
                        printf("%d ", tabuleiro[i][j]);
                    }
                }
            }
            j++;
        }

        printf("\n");
        i++;
    }

    return (EXIT_SUCCESS);
}

Meta desta semana

Nesta semana o seu programa deve ser capaz de:

  1. Representar o tabuleiro com uma matriz de inteiros bidimensional.
  2. Mostrar o tabuleiro na tela, indicando o que existe em cada casa. O tabuleiro deve ser apresentado enfeitado, o que significa que deve mostrar uma grade para separar as casas e a identificação de linhas e colunas. Linhas devem ser identificadas numericamente, e colunas devem ser identificadas por letras (ex: primeira coluna=A, segunda coluna=B, ...).
  3. Colocar minas aleatoriamente no tabuleiro.

O seu programa cumprindo as metas acima deve ser apresentado ao professor na próxima aula (22/11), já sendo parte da avaliação desta unidade.


Funções

Escopo de variáveis

Por escopo de uma variável entende-se o bloco de código onde esta variável é válida. Com base nisto, temos as seguintes afirmações:

  • As variáveis valem no bloco que são definidas;
  • As variáveis definidas dentro de uma função recebem o nome de variáveis locais
  • As variáveis declaradas fora de qualquer função são chamadas de variáveis globais
  • Os parâmetros formais de uma função (também conhecidos como argumentos da função) valem também somente dentro da função;
  • Uma variável definida dentro de uma função não é acessível em outras funções, MESMO QUE ESSAS VARIÁVEIS TENHAM NOMES IDÊNTICOS.
Variáveis locais

No trecho de código a seguir tem-se um exemplo com funções e variáveis com nomes iguais.

#include <stdio.h>

void FUNC1() {
   int B;

   B = -100;
   printf("Valor de B dentro da função FUNC1: %d\n", B);
}

void FUNC2() {
   int B;

   B = -200;
   printf("Valor de B dentro da função FUNC2: %d\n", B);
}

void main() {
   int B;

   B = 10;
   printf("Valor de B: %d\n", B);
   B = 20;
   FUNC1();
   printf("Valor de B: %d\n", B);
   B = 30;
   FUNC2();
   printf("Valor de B: %d\n", B);
}

O resultado de sua execução deve ser:

Valor de B: 10
Valor de B dentro da função FUNC1: -100
Valor de B: 20
Valor de B dentro da função FUNC2: -200
Valor de B: 30
Variáveis globais

O seguinte exemplo mostra o mesmo programa, porém fazendo com que a variável B seja global:

#include <stdio.h>

// Declaração da variável global B
int B;

void FUNC1() {
   B = -100;
   printf("Valor de B dentro da função FUNC1: %d\n", B);
}

void FUNC2() {
   B = -200;
   printf("Valor de B dentro da função FUNC2: %d\n", B);
}

void main() {
   B = 10;
   printf("Valor de B: %d\n", B);
   B = 20;
   FUNC1();
   printf("Valor de B: %d\n", B);
   B = 30;
   FUNC2();
   printf("Valor de B: %d\n", B);
}

O resultado de sua execução deve ser:

Valor de B: 10
Valor de B dentro da função FUNC1: -100
Valor de B: -100
Valor de B dentro da função FUNC2: -200
Valor de B: -200

E se existir um variável local com mesmo nome que uma global ? nesse caso, a variável local vai esconder a sua homônima global:

#include <stdio.h>

// Declaração da variável global B
int B;

void FUNC1() {
   //  no escopo desta função, esta variável local vai esconder a variável global B! 
   int B; 

   B = -100;
   printf("Valor de B dentro da função FUNC1: %d\n", B);
}

void FUNC2() {
   B = -200;
   printf("Valor de B dentro da função FUNC2: %d\n", B);
}

void main() {
   B = 10;
   printf("Valor de B: %d\n", B);
   B = 20;
   FUNC1();
   printf("Valor de B: %d\n", B);
   B = 30;
   FUNC2();
   printf("Valor de B: %d\n", B);
}

O resultado de sua execução deve ser:

Valor de B: 10
Valor de B dentro da função FUNC1: -100
Valor de B: 20
Valor de B dentro da função FUNC2: -200
Valor de B: -200

Para fixar

  1. Escreva o programa para mostrar a tabuada de um número lido do teclado.
    #include <stdlib.h>
    #include <stdio.h>
    
    /*
     * 
     */
    int main(int argc, char** argv) {
    
        int numero, c;
    
        printf("Numero: ");
        scanf("%d", &numero);
    
        c = 1;
        while (c < 11) {
            printf("%d X %d = %d\n", numero, c, numero*c);
            c++;
        }
    
        return (EXIT_SUCCESS);
    }
    
  2. Reescreva o programa anterior, mas usando uma função para mostrar a tabuada.
    #include <stdio.h>
    
    int tabuada(int num) {
        int c = 1;
        while (c < 11) {
            printf("%d X %d = %d\n", num, c, num*c);
            c++;
        }
    
    }
    int main(int argc, char** argv) {
    
        int numero, c;
    
        printf("Numero: ");
        scanf("%d", &numero);
    
        tabuada(numero);
        
        return (EXIT_SUCCESS);
    }
    
  3. Modifique o programa anterior para mostrar a tabuada de todos os números entre 1 e 10. Obs: não modifique a função tabuada!
  4. Escreva um programa para ler 10 números do teclado, e em seguida mostrar o maior e o menor número.
  5. Reescreva o programa anterior, mas criando as função "maior" e "menor", que retornam o maior e menor número de um vetor de tamanho arbitrário.

22/11: Campo Minado

Para referência: apostila online sobre linguagem C.

  • Tópico sobre linguagem C: continuando funções
    • ... mais especificamente: passagem de parâmetros por valor e por referência

Escondendo as casas não pisadas

No momento você deve já conseguir mostrar todo o tabuleiro, porém no jogo apenas as casas já pisadas devem ser reveladas. Pense em como modelar o seu tabuleiro de forma a esconder as casas ainda não pisadas.

Retomando o laço principal do jogo ...

O jogo funciona com um laço principal, que lê as coordenadas da casa a ser pisada ou marcada e atualiza o tabuleiro apropriadamente:

Note que nesse laço devem-se contabilizar quantas minas foram realmente descobertas - o que não corresponde necessariamente a quantas minas foram marcadas ... A quantidade de minas descobertas é necessária para decidir se o jogo já acabou.

Fluxo-Campo-Minado.png

25/11: Campo Minado

Ponteiros em linguagem C

Ponteiros é uma característica poderosa oferecida pela linguagem C. A linguagem de programação C depende muito dos ponteiros, assim, um bom programador em C precisa dominar bem ponteiros.

Ponteiro é visto pela maior parte dos programadores iniciantes como uma das partes mais difíceis na linguagem C, pois o conceito de ponteiros pode ser novo ou um mesmo símbolo usado para certa finalidade e usado para outra diferente, tornando mais difícil o entendimento.

Entendendo o que é um ponteiro

Um ponteiro é uma variável que guarda um endereço de memória de outra variável. Os ponteiros da linguagem C proporcionam uma forma fácil de acesso ao valor de variáveis sem referenciá-las diretamente. Um ponteiro possui tipo, por exemplo, inteiros, ponto flutuante e caracteres. O tipo do ponteiro indica que tipo é a variável para qual ele aponta.

Um ponteiro é declarado a seguinte forma:

tipo_do_ponteiro *nome_do_ponteiro

Exemplo:

int *p, *a;
char *pt, *ponteiro;

No exemplo acima foram criados quatro ponteiros, dois de tipo inteiro e dois de tipo caractere. É importante não confundir o asterisco (*), que indica que a variável é um ponteiro, com o mesmo sinal indicando uma multiplicação.

Conhecendo os operadores

Sempre é importante iniciar o ponteiro. Um ponteiro sempre é iniciado com o local na memória onde se localiza o valor da variável. Para iniciar a variável desejada como o endereço de memória, segue o exemplo:

int variavel_apontada=2;
int *ponteiro;
ponteiro=&variavel_apontada;

No exemplo foi criada uma variável e iniciada com valor 2, foi criado também um ponteiro que logo abaixo foi iniciado com o endereço da variável chamada variável_apontada.

A linguagem de programação C oferece dois operadores unitários, o operador de endereço (&) e o operador indireto (*). O operador de endereço retorna o endereço de memória onde fica localizado a variável, como foi mostrado no exemplo acima. O operador indireto retorna o valor da variável para qual o ponteiro aponta. Por exemplo:

main() {
   int var, *p;
   var=10;
   p=&var;
   printf("O valor da variavel eh: %d \n", *p);
   printf("O endereco de memoria da variavel eh: %p \n", p);
   printf("O endereco de memoria do ponteiro eh: %p \n", &p);
   *p=15;
   printf("O novo valor da variavel e': %d \n", var);
   return (0);    
}

A saída será:

O valor da variavel eh: 10
O endereco de memoria da variavel eh: 00AE4F6
O endereco de memoria do ponteiro eh: 00AE4F8
O novo valor da variavel eh: 15

No exemplo, usam-se os operadores para imprimir e aterá o valor da variável. Onde o endereço de memória varia de cada computador.

O ponteiro é usado em situações em que a passagem de valores é complicada, por isso é muito importante seu aprendizado. O conceito de ponteiro e seu uso podem, aparentemente, ser complicado, porém, não é muito difícil. O uso indevido e insensato de ponteiros pode causar sérios bugs em um programa e até comprometer todo o sistema, assim, é necessário cuidado quando se usa eles.

Outro exemplo

Considere a declaração do ponteiro abaixo:

int *pa

A instrução acima indica que pa é um ponteiro do tipo int. Agora veremos como atribuir valor ao ponteiro declarado. Para isto é necessário saber que existem dois operadores unitários que são utilizados com os ponteiros. O primeiro é o operador (*) através dele é possível retornar o valor da variável que está localizada no ponteiro. E o segundo é o operador (&) que retorna o endereço de memória que está localizado o valor da variável contida no ponteiro. Portanto para atribuirmos um valor para o ponteiro é necessário referencia o valor da variável que se encontra no ponteiro utilizando o operador (*), como será demonstrado a seguir.

*pa=25

Desta forma estamos atribuindo o valor 24 para a variável que está contida no ponteiro. Para entender melhor quando e como utilizar os operadores (*) e (&), veja o programa mostrado abaixo.

#include<stdio.h>

int main (){
    int a, b;
    int *pa, *pb; //declaração  de ponteiros

    /*inicializando variáveis*/
    a=25;
    b=12;

    /*fazendo os ponteiros pa e pb apontarem para os endereços de
    memórias das bariáves a e b, respectivamente*/
    pa=&a;
    pb=&b;

    /*Imprimindo os dados na tela*/
    printf("\n O endereco do ponteiro pa: %d", pa);
    printf("\n O endereco da variavel contida no ponteiro pa: %d", &pa);
    printf("\n O valor da variavel contida no ponteiro pa: %d", *pa);

    printf("\n\n");

    printf("\n O endereco do ponteiro pb: %d", pb);
    printf("\n O endereco da variavel contida no ponteiro pb: %d", &pb);
    printf("\n O valor da variavel contida no ponteiro pb: %d\n", *pb);

}

Quando os ponteiros são declarados, eles são inicializados com um endereço não valido, portanto antes de usa-los é necessário atribuir um endereço e isso é feito através do operador (&) como demonstra a instrução pa=&a e pb=&b que atribui aos ponteiros pa e pb o endereço das varieis a e b.

Uma outra novidade do programa anterior é quando queremos imprimir o endereço do próprio ponteiro isto é feito referenciando pa normalmente. Porém para imprimir o endereço contido no ponteiro é usado &pa e por ultimo para imprimir o valor do endereço contido no ponteiro usamos *pa.

Através do programa abaixo é possível verificar que se pode fazer comparações entre ponteiros.

#include<stdio.h>

int main (){
    int x1=34, x2=78;
    int *px1, *px2;

    /*Iniciando os ponteiros com os endereços das variáveis
    x1 e x2*/
    px1=&x1;
    px2=&x2;

    printf("\n px1= %d", px1);
    printf("\n px2= %d", px2);

    if(px1 > px2){
        printf("\n\n px1-px2=%d\n", px1-px2);
    }else{
        printf("\n\n px2-px1=%d\n", px2-px1);
        }
}

A comparação entre ponteiros em uma expressão relacional (>=,<=,> e <) é possível quando os dois ponteiros são do mesmo tipo. Isso é feito no programa mostrado através da linha “if (px1>px2)”, Caso a instrução seja verdadeira será feita a diferença entre os dois ponteiros “px1-px2”. E caso seja falso será feito ao contrario “px2-px1”. É importante dizer que os dados de saída deste programa não são iguais em todos os computadores, depende muito da memória disponível. Mas como pode-se observar em nosso exemplo, se px1=1245064 e px2=1245060 então px1-px2 será igual a um. Isso ocorre, pois a diferença depende da unidade tipo apontado.

29/11: Campo Minado

A contagem de minas

Para ajudar a visualizar o algoritmo de contagem de minas vizinhas, segue o fluxograma abaixo. As coordenadas (x,y) correspondem à casa cujas minas vizinhas se desejam contar. Veja sua semelhança com o algoritmo para zerar o tabuleiro.

Conta-minas.png

A sugestão é por o algoritmo de contagem em uma função, e dentro do programa chamá-lo para cada casa do tabuleiro:

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

#define MINAS 10
#define LINHAS 10
#define COLUNAS 10

#define TEM_MINA 10

// O tabuleiro como variável global: necessário para poder ser usado e modificado por outras funções
int tabuleiro[LINHAS][COLUNAS];


// Função para contar as minas vizinhas da casa x, y
void conta(int x, int y) {

  
}

/*
 * 
 */
int main(int argc, char** argv) {
    int i, j;

    // Zerar todas as posições do tabuleiro !
    i = 0;
    while ( i < LINHAS) {
        j = 0;
        while (j < COLUNAS) {
            tabuleiro[i][j] = 0;
            j++;
        }
        i++;
    }
    
    // Colocar as minas aqui !!!

    // contar as minas vizinhas de cada casa do tabuleiro
    i = 0;
    while ( i < LINHAS) {
        j = 0;
        while (j < COLUNAS) {
            // chama a função de contagem de minas, para contar as minas
            // vizinhas da casa com coordenadas i,j
            conta(i, j);
            j++;
        }
        i++;
    }

    //Agora mostrar o tabuleiro que foi gerado

Obs: cuidado com o seguinte ao fazer o algoritmo de contagem de minas:

  • Casas na borda do tabuleiro possuem menos casas vizinhas (casas fora do tabuleiro devem ser ignoradas).
  • O algoritmo não pode ser aplicado em casas que contêm minas. Quer dizer, não faz sentido calcular as minas vizinhas de uma casa que tem uma mina.

Levando em conta as restrições acima, o algoritmo deve ficar parecido com o seguinte:

Conta-minas2.png

  • Desenvolvimento do projeto
  • Arquivos em linguagem C
  • Armazenar pontuação dos jogadores em arquivo modo texto

02/12: Campo Minado

  • Desenvolvimento do projeto
  • O código abaixo faz uso da biblioteca <time.h>, necessário para cálculo do tempo transcorrido pelo jogador
#include <stdio.h>
#include <time.h>
#include <string.h>


void calcula(){ //função calcula tempo transcorrido para executar uma operação.
    
  time_t inicio, fim;
  char nome[51];

  inicio= time(NULL);
  printf("Digite seu nome: ");
  scanf("%s",nome);
  //fgets(nome, 51, stdin);
  fim= time(NULL);

  printf("%s, voce demorou %.2f segundos para digitar seu nome.\n", nome, difftime(inicio,fim)*(-1));

}

void tempo()
{
  time_t segundos, inicio;

  inicio = time(NULL); //captura tempo nesse instante
  printf("O valor lido neste instante eh %ld \n", inicio);

  segundos= time(NULL); //captura e apresenta o tempo em segundos
  printf("%ld horas desde 1 de Janeiro de 1970.\n", segundos/3600);

}

int main() {

    tempo();
    calcula();

    return 0;
}

06/12: Campo Minado

  • Desenvolvimento do projeto

Expansões propostas para o projeto

  • Cada jogo implementado deve apresentar ao menos uma das espansões propostas abaixo:
    • Ao término do jogo, com a descoberta de todas as minas pelo jogador, o programa desenvolvido deve informar o tempo de jogo transcorrido.
    • Ao término do jogo, o programa deve armazenar o nome do jogador juntamente com o tempo de jogo em um arquivo.
    • Antes do início do jogo, na fase de inicialização deve-se solicitar ao jogador o grau de dificuldade do jogo. O grau de dificuldade do jogo refere-se a quantidade de bombas no tabuleiro. Sugere-se três níveis possíveis:
      • 1) Iniciante, 2) Intermediário, 3) Avançado.

Exemplo de utilização de funções no programa

#include<stdio.h>

//define as dimensões da matriz
#define LIN 10
#define COL 10

//declaração das funções do programa
void inicia_tabela(int tab[LIN][COL]);
void imprime_tabela(int tab[LIN][COL]);

//função que inicia a tabela com zeros
void inicia_tabela(int tab[LIN][COL]){
    int i=0,j=0;

    for(i=0; i<LIN; i++){
        for (j=0; j<COL;j++){
            tab[i][j]=0;
        }
    }
}

//função para impressão da tabela
void imprime_tabela(int tab[LIN][COL]){
    int i=0,j=0;

    for(i=0; i<LIN; i++){
        printf("\n");
        for (j=0; j<COL;j++){
            printf("| %d ", tab[i][j]);
        }
    }
    printf("\n \n");
}

//função principal
int main (){
    int tabela[10][10];

    inicia_tabela(tabela);
    imprime_tabela(tabela);
}
  • O código acima apresenta o uso de funções para atividades básicas como zerar a matriz e apresentar o tabuleiro.
  • A passagem de parâmetro da matriz é sempre realizada por referencia.
  • Não é possível utilizar tamanhos variáveis (informada pelo usuário), pois a matriz deve conter ao menos as dimensões das colunas na passagem dos parâmetro na função (delimitado aqui pelas constantes LIN e COL). No projeto pode-se adotar uma solução desse tipo =)

09/12: Campo Minado

Arquivos na linguagem C

Para um programador, arquivos são repositórios permanentes de dados, os quais usualmente ficam em midia não volátil (disco rígido, CD ou DVD, pendrive, e outros). Arquivos servem para guardar informações que devem continuar a existir mesmo que termine o processo que as criou. Um exemplo é a agenda, cujo conteúdo deve ser preservado para futuras consultas e modificações. Mas além de serem depósitos de dados, arquivos possuem características bem definidas do ponto de vista de programação.

Um arquivo é uma sequência de bytes, que pode ser acessada, lida e modificada por meio de funções específicas existentes na biblioteca padrão da linguagem C. Essas funções servem para abrir e fechar um arquivo, ler e escrever uma certa quantidade de bytes, e mudar a posição da próxima leitura ou escrita.

Escrevendo em um arquivo

Abaixo segue um exemplo de um programa para escrever uma linha em um arquivo:

#include<stdio.h>

int main() {
  char linha[256];
  FILE * arquivo;

  printf("Digite uma linha: ");
  scanf("%[^\n]", linha);
  
  printf("Vou gravar isto no arquivo teste.txt\n");
  arquivo = fopen("teste.txt", "w");
  if (arquivo == NULL) {
    perror("Nao conseguiu abrir o arquivo");
    return 1;
  }
  fprintf(arquivo, "%s\n", linha);
  fclose(arquivo);

  printf("Pronto ... veja o arquivo teste.txt !\n");
}

Esse pequeno programa evidencia que trabalhar com arquivos é muito parecido a trabalhar com escrita na tela e leitura do teclado. Mas primeiro deve-se focar nas linhas do programa que têm relação direta com arquivos. Para começar, um arquivo é referenciado por uma variável do tipo FILE *:

  FILE * arquivo;

Em seguida, o arquivo a ser lido ou escrito deve ser aberto, usando-se a função FILE * fopen(char * nome_arquivo, char * modo):

  arquivo = fopen("teste.txt", "w");

Como se pode ver, a função fopen precisa de dois parâmetros do tipo char * (quer dizer, dois parâmetros string). O primeiro é o caminho do arquivo a ser aberto, e o segundo é o modo de abertura (o que se pretende fazer com ele: ler, escrever, adicionar dados ao final, ler e escrever). No exemplo acima, vai-se abrir o arquivo teste.txt para escrita (modo "w", de write). O valor de retorno de fopen é do tipo FILE *, e corresponde a uma descrição do arquivo que foi aberto. Caso aconteça algum erro (ex: não há permissão para criar o arquivo), fopen retorna o valor NULL. O exemplo testa se isto acontece da seguinte forma:

  if (arquivo == NULL) {
    perror("Nao conseguiu abrir o arquivo");
    return 1;
  }

Uma vez o arquivo estando aberto para escrita, pode-se escrever nele usando-se a função fprintf. Essa função é idêntica à função printf que se usa para escrever na tela. Porém fprintf precisa de um parâmetro adicional, deve ser a variável que corresponde ao arquivo aberto (primeiro parâmetro da função):

  fprintf(arquivo, "%s\n", linha);

Finalmente, quando não se quer mais escrever no arquivo deve-se chamar a função fclose para fechá-lo:

  fclose(arquivo);

Lendo uma linha de um arquivo

A leitura de um arquivo é parecida, com algumas pequenas modificações em sua abertura (deve-se indicar que o mode de operação será "r", de "read"), e usando-se a função fscanf para ler dados do arquivo. O exemplo abaixo mostra um programa para ler a primeira linha de um arquivo:

#include<stdio.h>

int main() {
  char linha[1024];
  char nome[256];
  FILE * arquivo;

  printf("Digite o nome de um arquivo: ");
  scanf("%s", nome);
  
  printf("Vou mostrar a primeira linha do arquivo %s\n", nome);

  arquivo = fopen(nome, "r");
  if (arquivo == NULL) {
    perror("Ops ... erro ao acessar esse arquivo: ");
    return 1;
  }

  fgets(linha, 1024, arquivo);
  fclose(arquivo);

  printf("Eis a primeira linha do arquivo: \n\n%s\n\n", linha);

}

Como adiantado, na abertura com fopen deve-se usar o valor "r" para o modo:

  arquivo = fopen(nome, "r");

Já a leitura de uma linha pode ser feita mais facilmente com a função fgets:

  fgets(linha, 1024, arquivo);

A função char * fgets(char * resultado, int max_caracteres, FILE * arquivo) lê uma linha de um arquivo com até max_caracteres e a guarda na variável passada no parâmetro resultado. No exemplo acima, fgets lê uma linha com até 1024 caracteres e a guarda na variável linha.

Lendo todas as linhas de um arquivo

Nesse próximo exemplo, abre-se um arquivo para leitura e lêem-se todas suas linhas, mostrando-as na tela:

#include<stdio.h>

int main() {
  char linha[1024];
  char nome[256];
  char * ok;
  FILE * arquivo;

  printf("Digite o nome de um arquivo: ");
  scanf("%s", nome);
  
  printf("\nVou mostrar todas as linhas do arquivo %s\n\n", nome);

  arquivo = fopen(nome, "r");
  if (arquivo == NULL) {
    perror("Ops ... erro ao acessar esse arquivo: ");
    return 1;
  }

  do {
    ok = fgets(linha, 1024, arquivo);
    if (ok != NULL) printf("%s", linha);
  } while (! feof(arquivo));

  fclose(arquivo);

}

A diferença em relação ao exemplo anterior está na sequência que lê as linhas do arquivo:

 do {
    ok = fgets(linha, 1024, arquivo); // Lê a próxima linha do arquivo
    if (ok != NULL) printf("%s", linha); // se conseguiu ler algo, mostra na tela
  } while (! feof(arquivo)); // para se chegou ao fim de arquivo

Há algumas novidades aqui:

  1. O valor de retorno de fgets é testado quanto a sua validade: a função fgets retorna o valor NULL se não conseguiu ler algo do arquivo. Isto pode ter ocorrido por um erro de leitura (ex: disco com defeito) ou porque se chegou ao fim do arquivo, e assim nada mais existe para ser lido. Esse teste aparece na linha:
    if (ok != NULL) printf("%s", linha)
    
    .
  2. A leitura continua enquanto não se chegar ao fim de arquivo: o teste de fim de arquivo se faz com a função int feof(FILE * arquivo), que retorna 0 se ainda não se chegou ao final do arquivo, ou 1 caso contrário. A chamada de feof se faz ao final do laço:
      } while (! feof(arquivo));
    
  • Desenvolvimento do projeto final da disciplina
  • Preparação para apresentação

13/12: Entrega projeto da disciplina

  • Entrega do projeto final da disciplina

ATENÇÃO

  • Avaliação realizada individualmente
  • Entrega de avaliações e conceitos.

Conceitos Projeto Final disciplina

  • Conceitos projeto final disciplina: conceitos projeto
  • Critério: código clonado, soluções apresentadas sem explicação ou integração entre os membros considerou-se conceito insuficiente.

16/12: Recuperação Lógica e Programação em linguagem C

  • Recuperação Lógica de Programação em Linguagem C
  • Recuperação realizada utilizando linguagem C

20/12: Encerramento disciplina

  • Aproveito para desejar à todos Feliz Natal e que 2011 seja repleto de boas surpresas =)

Conceitos Finais: