Capítulo 2 – parte 3

Share

2.4.4 – Os tipos vetor e matriz

Nem sempre os tipos básicos são suficientemente práticos para se guardar todos os tipos de dados presentes em algoritmos. A fim de deixarmos nossos algoritmos mais descritivos, usaremos tipos de dados definidos por nós mesmos.

2.4.4.1 – Vetor

Quando precisamos trabalhar com um grande conjunto de variáveis do mesmo tipo e significado, usamos um vetor. O tipo vetor pode ser criado da seguuinte forma:

	tipo <identificador> = vetor[<inicio>:<fim>] <tipo>;

Após sua criação, podemos definir variáveis com nosso novo tipo. Por exemplo:

	tipo TReais = vetor[1:40] real;
	TReais: notas;
	
	tipo TTextos = vetor[1:40] caracter;
	TTextos: nomes;
	

Cada elemento do vetor é como uma variável comum. É acessado pelo identificador do vetor e um índice entre colchetes.

	tipo n = vetor[1:40] caracter;
	n: nomes;

	nomes[1] ← "Abel";
	nomes[2] ← "Kafka";
	nomes[3] ← "Francis";
			...
	imprima(nomes[23]);

Exemplo: Construa um algoritmo que leia 5 nomes pelo teclado e os guarde em um vetor.

algoritmo leiaNomes;
início
	tipo TNomes = vetor[1:5] caracter;
	TNomes: nomes;
	inteiro: I;
	para I de 1 até 5 faça
		leia(nomes[I]);
	fim-para;
fim.

Exemplo: Construa um algoritmo que leia 10 números inteiros pelo teclado e os guarde em um vetor. Em seguida os imprima na ordem de digitação.

algoritmo imprimaNumeros;
início
	tipo TNumeros = vetor[1:10] real;
	TNumeros: numeros;
	inteiro: I;
	
	{Ler os números}
	para I de 1 até 10 faça
		leia(numeros[I]);
	fim-para;
	
	{Imprimir}
	para I de 1 até 10 faça
		imprima(numeros[I]);
	fim-para;
fim.

Exemplo: Construa um algoritmo que monte um vetor de caracter com os seguintes valores nesta ordem: “!”,”O”,”T”,”E”,”R”,”R”,”O”,”C”. E inverta seguida, construa um estrutura de repetição para inverter a ordem dos elementos no vetor.

algoritmo inverte;
início
	tipo TLetras = vetor[1:8] caracter;
	TLetras: palavra;
	inteiro: I;
	caracter: AUX;
	palavra[1] = "!";	
	palavra[2] = "O";	
	palavra[3] = "T";	
	palavra[4] = "E";	
	palavra[5] = "R";	
	palavra[6] = "R";	
	palavra[7] = "O";	
	palavra[8] = "C";	
	
	{Imprimir}
	para I de 1 até 4 faça
		AUX ← palavra[I];
		palavra[I] ← palavra[8-I+1];
		palavra[8-I+1] ← AUX; 
	fim-para;
fim.

Exemplo: Construa um algoritmo que leia o preço de mercadorias e guarde em um vetor de real, leia a quantidade vendida e guarde em um vetor de inteiros e imprima o faturamento por mercadoria e o total. Assuma inicialmente que existem 6 mercadorias com códigos de 1 a 6.

algoritmo faturamento;
início
	tipo TPrecos = vetor[1:6] real;
	TPrecos: preco;
	tipo TQuantidades = vetor[1:6] inteiro;
	TQuantidades: quantidade;
	inteiro: I;
	real: faturamento,faturamentoTotal;
	
	faturamento ← 0;
	faturamentoTotal ← 0;

	{Ler os valores}
	para I de 1 até 6 faça
		imprima("Preço da mercadoria ",I,": ");
		leia(preco[I]);
		imprima("Qtd vendida de ",I,": ");
		leia(quantidade[I]);
	fim-para;
	
	{Imprimir}
	para I de 1 até 6 faça
		imprima("Mercadoria: ",I);
		imprima(" preço:",preco[I]);
		imprima(" qtd:",quantidade[I]);
		faturamento ← preco[I]*quantidade[I]; 
		imprima(" fat:",faturamento);
		faturamentoTotal ← faturamentoTotal + faturamento; 
	fim-para;
	imprima("Faturamento total: ",faturamentoTotal);
fim.

Exemplo: Construa um algoritmo que leia 10 números reais pelo teclado e os guarde em um vetor. Em seguida os imprima na ordem inversa de digitação.

algoritmo leiaNumeros;
início
	tipo TNumeros = vetor[1:10] real;
	TNumeros: numeros;
	inteiro: I;
	
	{Ler os números}
	para I de 1 até 10 faça
		leia(numeros[I]);
	fim-para;
	
	{Imprimir na ordem inversa}
	para I de 10 até 1 passo -1 faça
		imprima(numeros[I]);
	fim-para;
fim.

Exemplo: Construa um algoritmo que leia 10 números reais pelo teclado e os guarde em um vetor. Em seguida calcule e imprima a média destes números.

algoritmo mediaNumeros;
início
	tipo TNumeros = vetor[1:10] real;
	TNumeros: numeros;
	inteiro: I;
	real: soma;
		
	{Ler os números}
	para I de 1 até 10 faça
		leia(numeros[I]);
	fim-para;
	
	{Calcular a média}
	soma ← 0;
	para I de 1 até 10 faça
		soma ← soma +  numeros[I];
	fim-para;
	imprima(soma/10);
fim.

Exemplo: Construa um algoritmo que leia 10 números reais pelo teclado e os guarde em um vetor. Em seguida calcule e imprima o desvio padrão destes números.

algoritmo mediaNumeros;
início
	tipo TNumeros = vetor[1:10] real;
	TNumeros: numeros;
	inteiro: I;
	real: média, soma, desvioPadrão;
		
	{Ler os números}
	para I de 1 até 10 faça
		leia(numeros[I]);
	fim-para;
	
	{Calcular a média}
	soma ← 0;
	para I de 1 até 10 faça
		soma ← soma +  numeros[I];
	fim-para;
	média ← soma/10;
	imprima(média);
	
	
	{Calcular o  desvio padrão}
	soma ← 0;
	para I de 1 até 10 faça
		soma ← soma + (numeros[I] - média)**2;
	fim-para;
	desvioPadrão ← raiz(soma/N);
	imprima(desvioPadrão);
fim.

Exemplo: Construa um algoritmo que leia 6 números inteiros pelo teclado e os guarde em um vetor. Em seguida classifique e imprima os elementos em ordem crescente.

algoritmo MetodoDaBolha;
início
	tipo TNumeros = vetor[1:6] inteiro;
	TNumeros: numeros;
	inteiro: BOLHA, {Elemento mais alto fora de ordem}
				    AUX,	  {Auxiliar para troca}
				    TAMANHO,  {Quantidade de elementos a ordenar}
				    I;	  	  {Conador para varrer o vetor}
		
	{Ler os números}
	para I de 1 até 6 faça
		leia(numeros[I]);
	fim-para;
	
	{Bolha}
	TAMANHO ← 6;
	enquanto TAMANHO >1 faça
		BOLHA ← 0;
		para I de 1 até TAMANHO-1 faça
			se numeros[I] > numeros[I+1] então
				AUX ← numeros[I+1];
				numeros[I+1] ← numeros[I];
				numeros[I] ← AUX;
				BOLHA ← I;
			fim-se;
		fim-para;
		TAMANHO ← BOLHA;
	fim-enquanto;

	{Imprimir os números}
	para I de 1 até 6 faça
		imprima(numeros[I]);
	fim-para;
	
fim.

2.4.4.2 – Matriz

O Portugol nos permite definir o tipo matriz para os casos onde for necessário usar vetores de mais de uma dimensão. A sintaxe para a definição do tipo é:

	tipo <identificador> = matriz[d1i:d1f, d2i:d2f, ...] <tipo>;

A definição de variáveis e acesso aos elementos da matriz são feitos da mesma forma que no vetor, com a única diferença que é usado um índice por dimensão.

	tipo TReais = matriz[1:40, 1:3] real;
	TReais: notas;
	
	notas[1,1] ← 8.0;
	notas[1,2] ← 9.0;
	notas[1,3] ← 10.0;
	
	notas[2,1] ← 8.0;
	notas[2,2] ← 9.0;
	notas[2,3] ← 10.0;
	
	tipo TTabuleiro = vetor[1:8, 1:8] inteiro;
	TTabuleiro: tabuleiro;
	
	tabuleiro[1,1] = 1;
	tabuleiro[2,2] = 2;
	tabuleiro[3,3] = 3;
	tabuleiro[4,4] = 4;

Exemplo: Contrua um algoritmo usando laços para guardar os dados no formato dado a seguir em uma matriz.

		1	2	3	4	5
		6	7	8	9	10
		11	12	13	14	15

algoritmo matriz1;
início
	tipo TMatriz = matriz[1:3, 1:5] inteiro;
	
	TMatriz: matriz;
	inteiro: linha, coluna;
	
	contador ← 1;
	para linha de 1 até 3 faça
		para coluna de 1 até 5 faça
			matriz[linha,coluna] ← contador;
			contador ← contador+1;
		fim-para;
	fim-para;
fim. 

Exemplo: Construa um algoritmo usando laços para guardar os dados no formato dado a seguir em uma matriz.

	1	4	7	10
	2	5	8	11
	3	6	9	12

algoritmo matriz2;
início
	tipo TMatriz = matriz[1:3, 1:4] inteiro;
	
	TMatriz: matriz;
	inteiro: linha, coluna;
	
	contador ← 1;
	para coluna de 1 até 4 faça
		para linha de 1 até 3 faça
			matriz[linha,coluna] ← contador;
			contador ← contador+1;
		fim-para;
	fim-para;
fim.

Exemplo: Construa um algoritmo usando laços para realizar a soma de duas matrizes 3×3 de reais.

algoritmo matriz2;
início
	tipo TMatriz = matriz[1:3, 1:3] real;
	
	TMatriz: matriz1, matriz2, soma;
	inteiro: l, c;
	
	leia(matriz1); {Comando conciso}
	leia(matriz2); {Comando conciso}
	soma ← 0; {Comando conciso}
	
	para l de 1 até 3 faça
		para c de 1 até 3 faça
			soma[l,c] ← matriz1[l,c]+matriz2[l,c];
		fim-para;
	fim-para;
	
	imprima(matriz1); {Comando conciso}
	imprima(matriz2); {Comando conciso}
	imprima(soma); {Comando conciso}
	
fim.

2.4.5 – O comando abandone

Podemos interromper estruturas de repetição(enquanto, repita e para) a qualquer momento utilizando o comando abandone. Assim, quando encontrado, o comando abandone desloca a execução do algoritmo para o primeiro comando após a estrutura de repetição.

Exemplo: Construa um algoritmo que dado um valor inteiro, retorne o índice da primeira posição que este valor ocupa em um vetor. Caso não exista o valor, deve-se retornar -1 como índice.

algoritmo exAbandone;
início
	tipo TNumeros = vetor[1:60] inteiro;
	TNumeros: numeros;
	inteiro: indice,   {índice encontrado}
				    valor,	  {valor procurado}
				    I;	  	  {Contador para varrer o vetor}
		
	{Ler os números}
	para I de 1 até 60 faça
		leia(numeros[I]);
	fim-para;

	indice ← -1;
	leia(valor);
	
	{Procura pelo valor}
	para I de 1 até 60 faça
		se numeros[I]=valor então
			indice = I;
			abandone;			
		fim-se;
	fim-para;
	imprima("O valor ",valor," está na posição ",indice);

2.5 – Algoritmos baseados em estruturas de dados não homogêneas

Até agora os tipos que definimos eram estruturas homogêneas, compostas apenas por um tipo básico. A estrutura de dados a a seguir nos permite agrupar um conjunto de dados de tipos diferentes em um conjunto de dados mais abstrato, permitindo representação mais próxima da realidade.

2.5.1 – O tipo de Registro

Para usarmos uma estrutura heterogênea, vamos definir nosso novos tipos como um registro.

tipo <identificador> = registro
                             <tipo1>: atributo1;
                             <tipo2>: atributo2;
                             <tipo3>: atributo3;
                             	...
                       fim-registro;

Desta forma, temos como exemplos de registros:

tipo TPessoa = registro
                 caracter: nome;
                 inteiro: idade;
                 lógico: sexo;
                 real: peso;
               fim-registro;

tipo TAluno = registro
                 caracter: nome;
                 inteiro: faltas;
                 real: tvc1,tvc2,trb1,trb2,tvco;
               fim-registro;

tipo TEndereço = registro
                 caracter: rua,bairro;
                 inteiro: numero,cep;
               fim-registro;

tipo TImovel = registro
                 real: preço;
                 inteiro: quartos;
                 lógico: garagem;
                 TEndereço: endereço;
               fim-registro;

A definição de variáveis é normal, mas o acesso aos atributos de um registro é feita pelo identificador seguido de um ponto “.”. Veja os exemplos usando os tipos definidos acima:

	TPessoa: usuario1, usuario2;
	usuario1.nome ← "Fulano";
	usuario1.idade ← 18;
	leia(usuario1.sexo);
	leia(usuario1.peso);

	usuario2.nome ← "Ciclano";
	usuario2.idade ← 23;
	leia(usuario2.sexo);
	leia(usuario2.peso);
	
	se usuario1.idade > usuario2.idade então
		imprima(usuario1.nome, "é mais velho que ", usuario2.nome);
	fim-se;
	
	tipo TTurma = vetor[1:40] TAluno;
	TTurma:turma;
	turma[1].nome ← "Fulano";
	leia(turma[12].tvc1);
	
	tipo TPredio = matriz[1:4,1:2,1:10] TImovel;
	TPredio:predio;
	predio[1,2,10].preço ← 100000.00;
	predio[2,1,1].garagem ← falso;

2.6 – Programação modular

2.6.1 – Introdução

A programação modular permite agrupar comandos e variáveis que executam a mesma função repetidamente em pontos diferentes do algoritmo a fim melhorar o controle de memória e reduzir a quantidade de código e erros gerados.

2.6.2 – Blocos

Um bloco em PORTUGOL é um conjunto de comandos entre início e fim. Cada bloco pode definir suas próprias variáveis e elas são liberadas quando o bloco termina. Estas variáveis são chamadas de variáveis locais ao bloco.

Os blocos podem ser agrupados uns dentro dos outros. As variáveis declaradas em um bloco são visíveis para todos os blocos mais internos. Estas variáveis são consideradas globais para os blocos internos. Caso um bloco interno redefina uma variável global como local, somente somente a local esta passa a ser visível dentro dele.

2.6.3 – Procedimentos

Um procedimento é um bloco precedido por um identificador que podemos referenciar em qualquer ponto do algoritmo. Sua sintaxe é:

procedimento <identificador>(<parâmetros>);
<declaraçao de parâmetros>
início
	C1;
	C2;
	...
	Cn;
fim;

Procedimentos em PORTUGOL devem ser declarados antes dos blocos que serão utilizados.

Os parâmetros podem ser passados por cópia ou por referência. Os parâmetros por cópia copiam os valores passados em variáveis locais. Assim se os valores forem alterados dentro do procedimento estes não mudam externamente. Parâmetros por referência alteram os valores das variáveis passadas como parâmetros e podem servir como retorno de valores do procedimento. Para marcarmos uma parâmetro como referência colocamos a palavara var antes do identificador do parâmetro.

2.6.4 – Funções

Uma função é um procedimento que retorna um único valor sem ser via parâmetros. A sintaxe é:

função <identificador>(<parâmetros>):<tipo>;
<declaraçao de parâmetros>
início
	C1;
	C2;
	...
	<identificador> ← <valor>;
	...
	Cn;
fim;

2.6.5 – Recursividade

Recursividade é quando um procedimento ou função chama a si mesmo.

    Share

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

*