Sistemas Operacionais e Introdução a Programação (diário 2010-1) - Prof. Ederson Torresini

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar

Sistemas Operacionais

18/02: Apresentação da disciplina

  • Tópicos: plano de ensino, abordagem pedagógica.

24/02: História dos Sistemas Operacionais e das Linguagens de Programação

25/02: Arquitetura de Sistemas Computacionais

  • As linguagens de programação, sistemas operacionais e protocolos em rede mais comuns (C, UNIX e TCP/IP) existem desde os anos 1970. Àquela época, era comum organizar a informação em estruturas de dados simples: fila e árvore.
  • Sistemas Operacionais modernos são desenvolvidos em linguagens de programação de alto nível (na maior parte do seu código). Esses sistemas transmitem e recebem dados através das redes de computadores.

<graphviz> digraph Triade { "Linguagens de Programação" -> "Sistemas Operacionais" "Sistemas Operacionais" -> "Redes de Computadores" "Linguagens de Programação" -> "Redes de Computadores" } </graphviz>

  • Multiusuário, multiprocesso e multidados: usuários utilizam processos para manipular dados. Toda ação e arquivo deve possuir, portanto, um responsável ou dono para garantir o devido controle de acesso.

<graphviz> digraph SO { Usuários -> Kernel [label=1] Kernel -> Processos [label=2] Processos -> Kernel [label=3] Kernel -> Dados [label=4] } </graphviz>

03/03: Sistema de arquivos

  • Tópicos: Estrutura de diretórios e arquivos organizados em árvore, visualização em modo gráfico e texto.
  • Visualização em modo gráfico: no Linux, há vários programas que realizam uma mesma tarefa. Em aula, foi escolhido o sistema operacional Ubuntu Linux 9.10, que adota o navegador Nautilus (menu Locais -> Pasta Pessoal)para visualizar diretórios e arquivos - o equivalente ao Windows Explorer para o Windows.
  • Visualização em modo texto: cada comando possui uma função. Cabe reforçar que no Linux as operações em modo gráfico possuem um equivalente em modo texto - sendo esse um instrumento bastante poderoso pela sua flexibilidade e agilidade para o administrador BEM acostumado :-)
    • Alguns comandos utilizados: ls, cd, pwd, find, mkdir, mv e cp.

Atividades-problema

  1. Crie o diretório /var/tmp/0303, depois mova-o para o diretório /tmp.
  2. Copie o arquivo /etc/passwd para o diretório /tmp/a/b/c.
  3. Copie o arquivo /etc/shadow para o mesmo diretório do exercício anterior.
  4. Copie o diretório /tmp para /var/tmp (incluindo subdiretórios).
  5. O diretório /usr/../local/ existe? Por quê?

04/03: Gerência de memória e processos

  • Tópicos: árvore de processos, filas de processos, comandos de manipulação dos processos.
  • Alguns comandos utilizados para visualizar e operar sobre processos: ps, pstree, top e kill.

10/03: Processos, Usuários e Controle de acesso

  • Tópicos: a relação entre comandos, arquivos executáveis e processos, usuários e permissões e propriedades, números binários. Comandos novos: whoami, w, id, touch, rmdir (veja a lista completa).
    • Usuários são agrupados para facilitar a sua organização e manutenção. Assim pode-se utilizar grupos para ampliar ou restringir permissões de acesso a recursos do sistema, como CD-ROM, impressoras e outros.
    • Todo arquivo está associado a um usuário (dono, responsável) e um grupo. As permissões, com isso, ficam estruturadas em 3 níveis:
      • O próprio dono ou usuário do arquivo.
      • Todos os usuários associados ao grupo do arquivo.
      • Demais usuários do sistema.
    • Cada usuário pode ler, modificar (escrever) e executar um arquivo (programa). Tem-se, assim, a combinação entre níveis de usuários e permissões:
Usuário Grupo Outros
Ler Escrever Executar Ler Escrever Executar Ler Escrever Executar
4 2 1 4 2 1 4 2 1
Código da permissão (octal)

O comando

$ ls -l /etc/shadow

vai apresentar o seguinte resultado:

-rw-r----- 1 root shadow 796 Mar 13 20:27 /etc/shadow

Faz-se a seguinte leitura:

  • -: O arquivo é regular (simples)
  • rw-: o dono, root, pode ler e escrever no arquivo.
  • r--: todos os usuários associados ao grupo shadow podem apenas ler o conteúdo do arquivo.
  • ---: os demais usuários não têm qualquer acesso ao arquivo.

11/03: Controle de acesso e usuários

  • Tópicos: usuários e grupos.
  • Em um interpretador de comandos, ou shell, é comum digitarmos uma série de comandos para resolver um único problema, como por exemplo criar um arquivo e depois atribuir permissões ao mesmo. Essa série de comandos podem ser organizados em um único arquivo, o qual poderá ser executado - realizando todos os comandos (uma por por, linha por linha) em sequência. A isso chama-se um roteiro de comandos interpretados, ou script shell. A estrutura é relativamente simples do arquivo: deve-se começar informando que o conteúdo é uma série de comandos a serem interpretados (#!) e, em seguida, o interpretador escolhido (no nosso caso, o /bin/bash, já trabalhado em sala):
#!/bin/bash
...
...
...

Assim, as atividades-problema abaixo, por necessitarem de uma série de comandos, pode ser criado um script shell que os resolvam. Lógico, o arquivo a ser executado deve permitir, para tal, permissão de execução a quem for executá-lo. Exemplo: se o usuário aluno quer executar o arquivo /home/aluno/Desktop/meuPrimeiroPrograma.txt, ele deve ativar a permissão de execução para, em seguida, fazê-lo:

$ chmod 744 /home/aluno/Desktop/meuPrimeiroPrograma.txt
$ /home/aluno/Desktop/meuPrimeiroPrograma.txt

Atividades-problema

  • Crie o arquivo /tmp/a/d/j/arquivo.txt. Apenas o dono poderá ler e escrever nesse arquivo - os demais não deverão possuir qualquer acesso. Quanto ao diretório /tmp/a, aplique as permissões 751 - e diga o que representam tais permissões (quem pode o quê).
  • Crie a seguinte estrutura de arquivos e diretórios:
<graphviz>

graph Dir { splines=false root [shape=Mrecord,label="/"] tmp [shape=Mrecord,label="tmp/"] l [shape=Mrecord,label="permissões: 755|grupo: aluno|<0>l/"] m [shape=Mrecord,label="<0>m/|grupo: vboxusers|permissões: 755"] n [shape=Mrecord,label="<0>n/|grupo: xboxusers|permissões: 570"] arq1 [shape=record,label="grupo: aluno|<0>arq1"] arq2 [shape=record,label="<0>arq2|grupo: xboxusers"]

root -- tmp tmp -- l:0 l:0 -- arq1:0 tmp -- m:0 m:0 -- n:0 n:0 -- arq2:0 }

</graphviz>

Os arquivos devem possuir as seguintes permissões: leitura e escrita para o dono, leitura para o grupo e nenhuma permissão aos demais.

17/03: Atividades pré-prova

  • A partir do diretório /usr/local/src, mova-se até o diretório /usr/src e depois ao diretório /var/tmp usando:
    • Endereço relativo:
      • 1 salto
      • 2 saltos
      • 3 saltos.
    • Endereço absoluto

Dicas:

  1. movimentar-se para o diretório acima: cd ..
  2. movimentar-se o diretório atual (para fins de entendimento): cd .
  • Crie a estrutura de diretório /home/aluno/a/b/c/d/e/f. Copie o diretório recém-criado c (e tudo que está abaixo dele) para o diretório /tmp. Tente remover o diretório /tmp/d - é possível?
  • Quantos e quais processos contêm a palavra gdm? Há alguma relação entre eles? Que usuário(s) executou(aram) cada um deles?
  • Quais usuários estão executando o processo chamado bash? Finalize todos os processos bash do usuário aluno:
    • Processo a processo: kill
    • Todos de uma só vez: killall
  • Na estrutura /home/aluno/a/b/c/d/e/f, apenas o usuário aluno pode modificar o diretório d e diretórios/arquivos-filhos (e/f), o grupo vboxusers pode ler e demais não têm acesso algum.

18/03: Prova prática

Lógica de Programação

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

24/03: Introdução

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

25/03: Desenvolvendo algoritmos

  • Tópicos: resolvendo problemas, linguagens e instruções disponíveis (vocabulário).
  • Páginas da apostila: 8 a 11.
  • Primeira semana das atividades extraclasse.

31/03: Pseudocódigo e diagrama de blocos

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

07/04: Constantes e variáveis

  • Página da apostila: 15 a 18.
  • Solução do Luiz Henrique para o problema da sequência de Fibonacci utilizando apenas 2 variáveis:
inicio
    
   inteiro var1, var2
   var1 <- 1
   escrever var1
   escrever "\n"
   escrever var1
   escrever "\n"

   var2 <- var1 + var1
   escrever var2
   escrever "\n"
   escrever var1 + var2

   var1 <- var1 + var2
   escrever "\n"
   escrever var1 + var2

   var2 <- var1 + var2
   escrever "\n"
   escrever var2 + var1
   var1 <- var2 + var1

fim
  • Solução vista em sala para o problema do conversor decimal-binário:
inicio

    inteiro dividendo <- 9
    constante inteiro divisor <- 2
    inteiro quociente
    inteiro resto
    inteiro segundoResto
    inteiro terceiroResto

    quociente    <- dividendo / divisor
    resto        <- dividendo % divisor

    dividendo    <- quociente
    quociente    <- dividendo / divisor
    segundoResto <- dividendo % divisor

    dividendo    <- quociente
    quociente    <- dividendo / divisor
    terceiroResto <- dividendo % divisor
    
    escrever quociente, terceiroResto, segundoResto, resto

fim

08/04: Expressões lógicas e matemáticas e operadores

  • Páginas da apostila: 19 a 25.
  • Segunda semana das atividades extraclasse.
  • Visão do algoritmo como pseudocódigo e como diagrama de blocos.

Um problema, uma solução, várias linguagens

Problema: apresentar os números 9, 9 ^ 2, 9 ^ 3 e a soma dos mesmos.

  • Solução em shell script:
#!/bin/bash

elemento1="9"
elemento2=`expr $elemento1 \* 9`
elemento3=`expr $elemento2 \* 9`
soma=`expr $elemento1 + $elemento2 + $elemento3`

echo $elemento1
echo $elemento2
echo $elemento3
echo $soma
  • Solução em pseudocódigo:
inicio
	inteiro elemento1
	inteiro elemento2
	inteiro elemento3
	inteiro soma

	elemento1 <- 9
	elemento2 <- elemento1 * 9
	elemento3 <- elemento2 * 9
	soma <- elemento1 + elemento2 + elemento3

	escrever elemento1, "\n"
	escrever elemento2, "\n"
	escrever elemento3, "\n"
	escrever soma

fim
#!/usr/bin/python

elemento1 = 9
elemento2 = elemento1 * 9
elemento3 = elemento2 * 9
soma = elemento1 + elemento2 + elemento3

print elemento1
print elemento2
print elemento3
print soma
  • Solução em C:
#include <stdio.h>

void main()
{
	int elemento1;	
	int elemento2;
	int elemento3;
	int soma;

	elemento1 = 9;
	elemento2 = elemento1 * 9;
	elemento3 = elemento2 * 9;
	soma = elemento1 + elemento2 + elemento3;

	printf("%d\n", elemento1);
	printf("%d\n", elemento2);
	printf("%d\n", elemento3);
	printf("%d\n", soma);
}

14/04: Estruturas de decisão

  • Páginas da apostila: 26 a 31.

15/04: Estruturas de repetição

21/04: "Cola da prova prática"

  • Espirais podem ser quadradas.
  • Exceto o 1, números perfeitos não são primos.
  • Alguém se lembra de MDC e MMC?
  • Conhece soma cabalística?

22/04: Prova prática

Sobre a prova

  • Deve ser entregue impreterivelmente até a próxima aula de quarta-feira, 28/04, seja em papel ou mídia digital (horário da aula). Não serão aceitas entregas após esse prazo.
  • Para quem não entregar a prova em tempo, haverá a recuperação na quinta-feira, dia 29/04, recuperação esta a ser realizada durante a aula.
  • Definições matemáticas:
    • Números amigáveis: diz-se que dois números A e B são ditos amigáveis quando a soma dos divisores de um é igual ao outro número. Ex.: os números 220 e 284 são amigáveis, pois a soma dos divisores de 220 soma 284, enquanto que a soma dos divisores de 284 alcança 220.
    • Soma cabalística: soma dos algarismos de um número até obter, recursivamente, um único algarismo. Ex.: assumindo o número 465 inicialmente, serão somados os seus algarismos (4+6+5), atingindo 15 que, por sua vez (1+5), resultará 6.
    • MDC: máximo divisor comum. É o maior número que divide dois ou mais números.
    • MMC: mínimo múltiplo comum. É o menor número que é múltiplo de dois ou mais números. O MMC é facilmente obtido pela fórmula:

A Prova

  1. Desenhe uma espiral quadrada no programa Kturtle. Utilize a sequência de Fibonacci para definir o comprimento dos segmentos de reta. Consultem o "vocabulário" do programa, em particular atribuição de valores a variáveis e estruturas de repetição - e algum tradutor :-)
    • O que entregar: o código do Kturtle que desenha uma espiral quadrada fibonacciana com pelo menos 15 segmentos de reta.
  2. Dados dois números naturais, calcule se os mesmos são amigáveis.
    • O que entregar: o código em Portugol ou diagrama de blocos do programa que resolve o problema para quaisquer números naturais até 1000.
  3. Dados dois números naturais, calcule o MDC e o MMC desses números.
    • O que entregar: o código em Portugol ou diagrama de blocos do programa que resolve o problema para quaisquer números naturais até 1000.
  4. Dado um número natural até 999, realiza a soma cabalística.
    • O que entregar: o código em Portugol ou diagrama de blocos do programa que resolve o problema para quaisquer número natural até 9999.

Dúvidas? Entrem em contato com o professor.

28/04: Correção da prova prática de Lógica de Programação

29/04: Recuperação da prova prática de Lógica de Programação

  • Para quem entregou a prova em tempo: entrevista.
    • 13:30: Bruno
    • 13:50: Luiz Henrique
    • 14:10: Ana Paula
    • 14:30: Rodrigo
  • Para quem não entregou em tempo: recuperação da prova prática.

Linguagem de Programação C

05/05: Compilando o primeiro programa

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

int main(int argc, char *argv[])
{
	printf("Alô mundo!\n");
}

06/05: Projeto Final da Disciplina

O jogo: Batalha Naval

  • Etapas de desenvolvimento:
  1. Desenha 1 onda
  2. Desenha 1 linha de ondas
  3. Desenha 1 matriz de tamanho fixo de ondas
  4. Desenha 1 matriz de tamanho variável de ondas (o usuário informa as dimensões)
  5. Mapeia 1 barco: latitude e longitude (vetor)
  6. Desenha o mar com 1 barco
  7. Mapeia 10 barcos: latitude e longitude (matriz)
  8. Desenha os 10 barcos
  9. Mapeia 10 barcos: latitude, longitude e se já foi atingido
  10. Pede ao usuário atirar
  11. Se o barco foi atingido, desenhar um X
  12. Ao final (todo os barcos atingidos): informar o usuário que venceu em 'n' movimentos
  • 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
#include <stdio.h>

#define QTDE_BARCOS 2


int iniciaJogo(int *barcos, int *tiros, int *atingidos)
{
	int barco;
	for(barco=0; barco<QTDE_BARCOS; barco++)
	{
		printf("\nBarco número %d:\n", barco + 1); // O primeiro barco é o de no. zero :-)
		printf("Informe a latitude do barco: ");
		scanf("%d", barcos + 3*barco);	// end. inicial (barcos)
										// + qtde. objetos por linha
										// * linhas
										// + coluna (1o. elemento)
		printf("Informe a longitude do barco: ");
		scanf("%d", barcos + 3*barco + 1);	// end. inicial (barcos)
											// + qtde. objetos por linha
											// * linhas
											// + coluna (2o. elemento)
		*(barcos + 3*barco + 2) = 0;	// endereço inicial (barcos)
										// + qtde. objetos por linha
										// * linhas
										// + coluna (3o. elemento)
	}
	*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;
	
	for (linha=1; linha<linhas+1; linha++)
	{
		for (coluna=1; coluna<colunas+1; 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++;
		}
	}
}

Ou o mesmo código, agora em modo interativo:

#include <stdio.h>

#define QTDE_BARCOS 2


int iniciaJogo(int *barcos, int *tiros, int *atingidos)
{
	int barco;
	for(barco=0; barco<QTDE_BARCOS; barco++)
	{
		printf("\nBarco número %d:\n", barco + 1); // O primeiro barco é o de no. zero :-)
		printf("Informe a latitude do barco: ");
		scanf("%d", barcos + 3*barco);	// end. inicial (barcos)
										// + qtde. objetos por linha
										// * linhas
										// + coluna (1o. elemento)
		printf("Informe a longitude do barco: ");
		scanf("%d", barcos + 3*barco + 1);	// end. inicial (barcos)
											// + qtde. objetos por linha
											// * linhas
											// + coluna (2o. elemento)
		*(barcos + 3*barco + 2) = 0;	// endereço inicial (barcos)
										// + qtde. objetos por linha
										// * linhas
										// + coluna (3o. elemento)
	}
	*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;
	
	for (linha=1; linha<linhas+1; linha++)
	{
		for (coluna=1; coluna<colunas+1; 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;
	int altura, largura;
	printf("Por favor, digite a altura do tabuleiro (qtde. de linhas): ");
	scanf("%d", &altura);
	printf("Agora, igite a largura do tabuleiro (qtde. de colunas): ");
	scanf("%d", &largura);
	
	// 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(altura, largura, 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++;
		}
	}
}

12/05: Constantes e Variáveis

13/05: Entrada e Saída de Dados

19-20/05: Vetores e Matrizes

  • A sequência de Fibonacci, agora em C. O programa apresentará os 30 primeiros números da sequência e, ao lado dos números pares, a letra "p":
#include <stdio.h>

void main(void)
 {
    // Declaração de variáveis
    int numeros[30];
    int contador;

    // Atribuição inicial de valores
    numeros[0] = 1;
    numeros[1] = 1;

    // Processamento
    contador = 2;
    while (contador < 30) {
        numeros[contador] = numeros[contador - 1]
                + numeros[contador - 2];
        contador = contador + 1;

    }

    // Saída de dados
    for (contador = 29; contador >= 0; contador--){
        printf("%d:%d",contador + 1,numeros[contador]);
        if (numeros[contador] % 2 == 0){
            printf("p");
        }
        printf("\n");
    }
}

Projeto Final: Matriz 2x3

  • Desenhando o tabuleiro (mar) com dimensões 2x3:
#include <stdio.h>

void main(void) {
    char mar[2][3]; // 2 linhas e 3 colunas
    int linha, coluna; // variáveis auxiliares

    // Desenha as 2 linhas (de 0 a 1)
    for(linha=0; linha <=1; linha++) {

        // Desenha as 3 colunas (de 0 a 2)
        for(coluna=0; coluna <=2; coluna++) {
            // Armazena na matriz
            mar[linha][coluna] = '~';
            //Escreve na tela
            printf("%c", mar[linha][coluna]);
        }

        // Avança para a próxima linha
        printf("\n");
    }
}

26/05: Estruturas de decisão

#include <stdio.h>

void main(void) {
    int tabuleiroLinhas, tabuleiroColunas;
    printf("Por favor, digite quantas linhas para o mar: ");
    scanf("%d", &tabuleiroLinhas);
    printf("Agora, digite quantas colunas para o mar: ");
    scanf("%d", &tabuleiroColunas);
    char mar[tabuleiroLinhas][tabuleiroColunas];

    int barcoLinha, barcoColuna;
    printf("Informe a linha do barco: ");
    scanf("%d", &barcoLinha);
    printf("E a coluna (do barco): ");
    scanf("%d", &barcoColuna);

    int linha, coluna;
    for (linha = 0; linha < tabuleiroLinhas; linha++) {
        for (coluna = 0; coluna < tabuleiroColunas; coluna++) {
            mar[linha][coluna] = '~';
            if (linha == barcoLinha-1 && coluna == barcoColuna-1) {
                printf("*");
            } else {
                printf("%c", mar[linha][coluna]);
            }
        }
        printf("\n");
    }
}

27/05: Estruturas de repetição

#include <stdio.h>

void main(void) {
    int tabuleiroLinhas, tabuleiroColunas;
    printf("Por favor, digite quantas linhas para o mar: ");
    scanf("%d", &tabuleiroLinhas);
    printf("Agora, digite quantas colunas para o mar: ");
    scanf("%d", &tabuleiroColunas);
    char mar[tabuleiroLinhas][tabuleiroColunas];

    int qtdeBarcos, auxiliar;
    printf("Quantos barcos? ");
    scanf("%d", &qtdeBarcos);
    int barcos[qtdeBarcos][2];
    for(auxiliar=0; auxiliar < qtdeBarcos; auxiliar++) {
        printf("Informe a linha do %do. barco: ", auxiliar+1);
        scanf("%d", &barcos[auxiliar][0]);
        barcos[auxiliar][0]--;
        printf("Informe a coluna do %do. barco: ", auxiliar+1);
        scanf("%d", &barcos[auxiliar][1]);
        barcos[auxiliar][1]--;
    }

    int linha, coluna, existe;
    for (linha = 0; linha < tabuleiroLinhas; linha++) {
        for (coluna = 0; coluna < tabuleiroColunas; coluna++) {
            mar[linha][coluna] = '~';

            existe = 0;
            for(auxiliar=0; auxiliar < qtdeBarcos; auxiliar++){
                if (linha == barcos[auxiliar][0] &&
                    coluna == barcos[auxiliar][1]) {
                    existe = existe + 1;
                }
            }
            if(existe >= 1) {
                printf("*");
            } else {
                printf("%c", mar[linha][coluna]);
            }
        }
        printf("\n");
    }
}

02/06: Avaliação intermediária

Com base no código da aula anterior, responda:

  • Nas linha 25 e 26, troque um for por um while.
  • Faça o mesmo, agora com o outro for (inverta a sequência da questão anterior).
  • O que acontece, na prática, se retirar as linhas 18 e 21?
  • Modifique o código para evitar que o tabuleiro tenha alguma dimensão igual a zero.
  • Se trocar (linha 9):
char mar[tabuleiroLinhas][tabuleiroColunas];

por:

int mar[tabuleiroLinhas][tabuleiroColunas];

o que é preciso mudar no restante do código? Além disso, que impacto trará no programa em execução?

  • Quantas vezes rodará esse laço (estrutura de repetição):
for(auxiliar=0; auxiliar < qtdeBarcos; auxiliar++) { .. }

09/06: Funções e passagem de parâmetro por valor e referência

#include <stdio.h>

void main(void)
{
    int quantosCaracteres(char* Frase)
    {
        int indice = 0;
        int contador = 0;
        while(Frase[indice] != '\000')
        {
            if(Frase[indice] != ' ')
                contador++;
            indice++;
        }
        return contador;
    }

    char frase[30];
    printf("Digite uma frase: ");
    scanf(" %[^\n]", frase);

    printf("A frase digitada contém %d caracteres (ignorando espaços).\n",
           quantosCaracteres(frase));
}

10/06: Strings e ponteiros

Leitura

Leia o material sobre funções e strings (e poteiros) descritos no Guia Básico de C:

Exercícios Genéricos

Construa um programa que:

  • Lê uma frase e conta as letras em maiúsculo.
  • Lê uma frase e conta os espaços e as vogais.

Desenvolvendo o Projeto Final

Em relação ao projeto do jogo Batalha Naval, avance no código (relembrando: ele já desenha o tabuleiro e define os barcos) para que:

  1. Leia n tiros do jogador (latitude, longitude). Não há limite de tiros.
  2. Verifique, a cada tiro, se o mesmo acertou um dos barcos.
  3. Atualize o tabuleiro com um X no local do barco atingido.
  4. Quando todo os barcos forem atingidos, mostrar uma frase informando o fim do jogo.

Obs.: consulte o código de exemplo.

Proposta de Expansão

Além disso, envie a sua proposta de expansão do jogo para o professor analisar a sua viabilidade técnica e grau de dificuldade.

Atenção! Propostas não entregues até amanhã (11/06/2010) serão desconsideradas e caberá ao professor, exclusivamente, definir a expansão para o aluno.

16/06: Desenvolvimento do Projeto Final

Sugestões de Expansões

  • Limitar a quantidade de tiros e, caso o usuário não atinja todos os barcos, deve-se mostrá-los na tela.
  • Tratar exceções de E/S, incluindo números fora dos limites - como por exemplo um barco fora do "mar".
  • 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".
  • Os barcos podem ser desenhados tanto na horizontal como na vertical.
  • Utilizar apenas um vetor unidimensional ao invés de uma matriz em todo o código.
  • MEGADESAFIO: utilizar a biblioteca ncurses, Tcl/Tk ou outra biblioteca gráfica para uma interface melhorada.

Dicas

  • Entenda o problema, modele-o: utilize sempre que possível pseudocódigo / diagrama de bloco.
  • Defina entradas, processamento e saídas do programa.
  • Primeiro declare as variáveis, depois realize as expressões lógicas e matemáticas.
  • Deixe claro (documente) 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).

Escolha de cada Aluno/Equipe

Alexandre

  • Tratamento de exceção de E/S: falha na leitura/escrita (tipo conflitante ou informação nula) e valores fora do limite.
  • 4 tamanhos de barco, na horizontal ou vertical: 1, 2 ou 3 casas em série e o hidroavião, esse último de forma triangular:
^
[ ]

Ana e Kelly

  • Limite da quantidade de tiros.
  • barcos em 4 tamanhos na horizontal ou na vertical: 1, 2, 3 e 4 casas.
  • Pontuação, onde os tiros mais próximos do centro do barco valem mais.

Carlos Eduardo

  • Limite da quantidade de tiros.
  • 3 tamanhos de barco na horizontal: 1, 2 e 4 casas.
  • Pontuação dos tiros.
  • "Hall of fame" com armazenamento em arquivo.

Jean

  • Informação das linhas por números e das colunas por letras. Ex.: casa "A1".
  • Uso de vetores unidimensionais em todo o código - ao invés de matrizes.

José

  • Limite da quantidade de tiros.
  • Tratamento de exceção de E/S: falha na leitura/escrita (tipo conflitante ou informação nula) e valores fora do limite.
  • Interface no estilo tradicional: letra para linha e número para coluna.
  • Barcos em 3 tamanhos na horizontal: 1, 2 ou 3 casas.

Belmiro e Vinicius

  • 4 tamanhos: barco com 1 casa, cruzador com duas casas, porta-aviões com 4 casas e avião com 1 casa. O avião (>), diferente dos demais, se move a cada tiro em um "círculo" perpendicular ao porta-aviões - lembrando os antigos jogos de videogame:

Após o primeiro tiro:

   ^      
| >   
|      
|      

e após o segundo:

   ^      
|    >
|      
|      

Bruno

  • Barcos e submarino em tamanhos diferentes:
    • 2 barcos que ocupam 1 casas;
    • 1 submarino que ocupar 2 casas;
    • 1 encouraçado que ocupa 3 casas;
    • 1 porta-aviões que ocupa 4 casas.
  • Tiro (1 casa) ou bomba (5 casa em formato de cruz), ambos com número limitado de tiros.
  • Tratamento de exceção de E/S: falha na leitura/escrita (tipo conflitante ou informação nula) e valores fora do limite.

Davi e Rodrigo

  • Limite da quantidade de tiros.
  • Se um alvo for atingido, o usuário ganha x tiros.
  • Os barcos podem ter 1, 3 ou 4 casas, na horizontal ou na vertical.
  • Vai haver sons de tiros durante o jogo.

Luiz

  • 3 tamanhos de barco na horizontal: 1, 2 ou 3 casas.
  • A cada tiro certo em um alvo, ganha-se um tiro extra; a cada errado, perde-se um.
  • Tratamento de exceção de E/S quanto aos tiros (repetidos em mesma casa ou fora do tabuleiro).

Matheus e Pamella

  • Tratamento de exceção de E/S: falha na leitura/escrita (tipo conflitante ou informação nula) e valores fora do limite.
  • Informação das linhas por números e das colunas por letras. Ex.: casa "A1".
  • O posicionamento dos barcos pode ser aleatório. Além disso, o usuário, quando estiver jogando, pode usar o comando "chute", que é um tiro aleatório no tabuleiro.
  • Barcos em 3 tamanhos na horizontal: 1, 2 ou 3 casas.

17-30/06: Desenvolvimento do Projeto Final

  • Desenvolvimento em aula do o=projeto final da disciplina.

01/07: Entrega do Projeto Final

A entrega do projeto final consiste em três atividades complementares:

  1. Avaliação oral - máximo 10 minutos
    • 13:30 - Alexandre
    • 13:40 - Ana
    • 13:50 - Kelly
    • 14:00 - Belmiro
    • 14:10 - Vinicius
    • 14:20 - Bruno
    • 14:30 - Carlos Eduardo
    • 14:40 - Jean
    • 14:50 - José
    • 15:00 - Davi
    • 15:10 - Rodrigo
    • 15:20 - Luiz
    • 15:30 - Matheus
    • 15:40 - Pamella
    • 15:50 - Raphael
  2. Avaliação prática - máximo 30 minutos
    • Pode ser realizada em qualquer horário da aula.
  3. Avaliação supresa - máximo 5 minutos
    • Pode ser realizada em qualquer horário da aula, desde que seja após as outras duas avaliações.

07/07: Recuperação

A seguir, a lista de alunos que deverão comparecer à aula para realizar a recuperação. Ao lado de cada nome, estão marcados com um X os assuntos da disciplina a serem recuperados.

Aluno Sistemas Operacionais Lógica de Programação Linguagem C
Alexandre X X
Carlos Eduardo X
Jean X X X
José X
Matheus X
Pamella X X
Vinicius X

08/07: O futuro das linguagens de programação



Voltar para página principal da disciplina