• Nenhum resultado encontrado

Variáveis unidimensionais (vetores) e multidimensionais matrizes

No documento Livro Logica Programacao b (páginas 131-140)

Estruturas de Dados

10.1 Variáveis unidimensionais (vetores) e multidimensionais matrizes

Esse tipo de variável contém vários valores do mesmo tipo básico. Assim é possível utilizar um vetor ou matriz de inteiros, por exemplo.

Na verdade, um vetor é uma coleção de elementos do tipo específico e com tamanho pré-definido (o número de elementos do vetor deve ser defi- nido pelo programador na declaração dessa estrutura).

O vetor é uma coleção unidimensional e o acesso a cada elemento é dado por um índice que representa a posição do elemento no vetor. Na maioria das representações de vetores, o acesso é representado pelo nome da variável do tipo vetor seguido de um valor inteiro entre colchetes, representando o índice.

 A sintaxe para declaração desse tipo de variável depende da linguagem de programação que a implementa. No caso da linguagem Pascal, a declaração

notas: array[1..10] of integeré usada para definir a variável notas como sendo

do tipo vetor de inteiros, contendo 10 elementos desse tipo. Já na linguagem C, essa mesma variável é definida a partir da declaração int notas[10]. No caso do

Pascal, a declaração notas[1] permite acessar o valor do primeiro elemento do

vetor, enquanto notas[10], o último. Já na linguagem C, um vetor é indexado

a partir do índice zero. Com isso, para acessar o primeiro elemento de um vetor em C, é usada a declaração notas[0]e notas[9] para o último.

 Ao indexar um vetor, estamos tratando de um item individual, como se fosse uma variável isolada.

 Já uma variável do tipo matriz pode ser vista como um vetor de vetores, em que cada vetor representa uma dimensão. Por isso essa estrutura é dita multidimensional.

O tipo de matriz mais utilizado é o bidimensional, em que são decla- radas apenas duas dimensões. Porém a maioria das linguagens não impõem qualquer tipo de restrição à quantidade de dimensões. Assim é possível criar matrizes tridimensionais ou até n-dimensionais.

Um exemplo de declaração de matriz em C seria int notas[2][5]. Nesse

caso, é declarada uma matriz bidimensional, em que a primeira dimensão pos- sui dois elementos, e a segunda possui cinco elementos. No total, serão reser- vados em memória espaço suficiente para representar 2x5=10 valores inteiros.

De forma similar aos vetores, o acesso a cada elemento da matriz deve ser realizado a partir do nome da variável seguida de um valor inteiro para servir de índice para cada dimensão.

10.2 Registros

São estruturas heterogêneas – compostas de elementos de tipos diferentes. Cada elemento que faz parte do registro é chamado de campo. Inclusive, cada campo pode ser do tipo registro também.

Esse tipo de estrutura permite organizar melhor os dados a serem mani- pulados, principalmente por permitir agregar dados de uma mesma natureza. Para entendermos melhor isso, imaginemos um programa que manipule os seguintes dados sobre os alunos de um curso: o nome do aluno, a idade e o número do seu CPF. Sem o uso de registros, normalmente, cada um desses dados sobre o aluno seria manipulado em variáveis diferentes. Mesmo utili- zando o conceito de vetor, ainda assim seria necessário manipular três vetores diferentes. Isso torna a atividade de programação bastante complexa.

Com o uso de registro é possível agregar esses dados em uma estrutura do tipo registro e declarar um único vetor desse tipo. Para exemplificar, pode- mos examinar o seguinte trecho de código na linguagem C:

struct TAluno {

char nome[80]; int idade;

char cpf[11]; } ;

struct TAluno alunos[10];

 Aqui usaremos uma notação mais genérica, independente da linguagem de programação a ser usada. Usando essa notação, teríamos a seguinte decla- ração do mesmo registro:

TIPO TAluno = REGISTRO nome: CARACTERE;

idade: INTEIRO; cpf: CARACTERE; FIM REGISTRO

Nesse trecho de código é definida a estrutura do tipo registro chamada

TAluno. Essa estrutura agrega os campos char nome[80] usados para repre-

sentar um literal com até 80 caracteres que armazena o nome do aluno, int idade usado para armazenar a idade do aluno, e  char cpf[11]  usado para

representar um literal de até 11 caracteres que armazena o CPF do aluno. Em seguida, é declarado um vetor com 10 elementos do tipo TAluno.

 A vantagem dessa abordagem é que o acesso ao elemento alunos[0],

por exemplo, retorna um registro do tipo TAluno contendo todos os seus campos de uma única vez. Assim cada campo pode ser facilmente acessado individualmente por sua descrição como alunos[0].nome, alunos[0].idade

ou alunos[0].cpf .

Um bom programador deve dominar o uso dessas estruturas a fim de diminuir a complexidade na manipulação dos dados em um programa.

Síntese da aula 

Nesta aula discutimos estruturas de dados compostas - vetores, matrizes e registros. Estes conceitos serão de grande importância para solucionar pro- blemas mais complexos do dia-a-dia da programação de computadores.

Cada uma destas estruturas tem sua própria forma de declaração e acesso permitindo facilidades para o programador quando propõem a solução algo- rítmica para o problema a ser resolvido usando o computador.

Atividades

1. Sobre o uso de variáveis e constantes em um algoritmo é incorreto

afirmar que:

a) toda informação manipulada diretamente pelo computador é arma- zenada na memória principal (RAM) e as variáveis representam

b) o valor de uma variável não pode ser alterado ao longo do programa, mantendo o mesmo valor até o encerramento do programa;

c) o tipo de dado implica na forma como os dados são representados na memória;

d) os vetores e matrizes só podem manipular dados de um mesmo tipo de dado;

e) um dado constante não sofre alteração no seu valor durante a execução do programa.

2. Com base no que foi estudado nesta aula, escolha a alternativa que apre- senta, respectivamente, os tipos de dados mais adequados para variáveis que deverão armazenar os seguintes conteúdos: idade, temperatura, nome da cidade, número da carteira de identidade, notas de um aluno. a) Inteiro, real, caractere, caractere, vetor de real.

b) Inteiro, inteiro, caractere, caractere, vetor de inteiro. c) Inteiro, real, inteiro, caractere, vetor de real.

d) Inteiro, real, real, caractere, vetor de inteiro. e) Inteiro, real, caractere, real, vetor de real.

3. Comente o uso de variáveis e constantes em um algoritmo. 4. Comente as vantagens do uso do tipo de dados Registro.

Comentário das atividades

Na atividade 1, de acordo com o que você estudou sobre variáveis e constantes, deve reconhecer a opção (b) como a opção incorreta. Essa opção apresenta o conceito contrário de variável. Você deveria saber que o valor de uma variável pode ser alterado a qualquer momento da execução de um. pro- grama. E é exatamente essa “variação” de seu valor que dá nome a esse tipo de dado. A opção (a) está correta, pois as variáveis servem de apontador para as posições da memória RAM, onde estão os dados a serem manipulados pelo programa. A opção (c) também apresenta um conceito correto sobre tipo de dado, pois é baseado no tipo do dado que o computador saberá como tratar a posição de memória apontada pela variável. A opção (d) está correta, inclu- sive é por esse motivo que vetores e matrizes são considerados estruturas de

dados homogêneos – por tratar de dados do mesmo tipo. Por fim, a opção (e) também está correta ao trazer a definição de um dado constante.

Na atividade 2, após analisar os conteúdos a serem armazenados você

deve ter concluído que a opção correta é a opção (a), pois ela apresenta para

o conteúdo idade o tipo inteiro (afinal costumamos utilizar valores inteiros positivos para a contar a passagem dos anos – não usamos “3,4 anos de idade”); para o conteúdo temperatura devemos usar casas decimais, logo o tipo mais indicado é o real; para o nome da cidade precisamos de um literal ou caractere; para o número da carteira de identidade, na verdade, pode- ríamos usar um tipo caractere (isso permitiria armazenar os caracteres de formatação, como ponto e hífen) ou como inteiro (sem formatação); já para as notas de um aluno, uma nota normalmente é expressa como um valor real e como será mais de uma nota (notas), o tipo de dado mais adequado a esse caso é um vetor de real, o que permitiria manipular todas as notas de um aluno a partir de uma mesma variável. Tomando como base essas jus- tificativas, você deveria considerar as demais opções como incorretas, pelos seguintes motivos: a opção (b) apresenta inadequação para o conteúdo tem-

peratura e para as notas do aluno; a opção (c) apresenta inadequação para o

nome da cidade; a opção (d)apresenta inadequações para o nome da cidade

e as notas do aluno; e a opção (e) apresenta inadequações para o número da

carteira de identidade.

Para solucionar a atividade 3, você já deve saber que o uso de variáveis

permite ao programador manipular de forma mais fácil os dados que estão armazenados na memória. Sem o auxílio de variáveis, toda vez que fosse necessário algum dado da memória seria necessário endereçar a posição de memória usando seu endereço físico em notação hexadecimal. As variáveis levam esse nome em função do seu comportamento, em que o valor de uma variável (na verdade, o conteúdo da posição de memória por ela referen- ciada) pode ser alterado várias vezes ao longo da execução de um programa.  Já um dado do tipo constante não tem o seu valor alterado do início ao fim

do programa.

 Ao realizar as atividades propostas com sucesso, você alcançou os obje- tivos desta aula de entender os conceitos de variável e de constante e suas utilizações e de utilizar adequadamente cada tipo de dado disponível.

Na próxima aula 

Estudaremos a Técnica de Modularização, que permite dividir um pro- blema complexo em problemas menores e, com isso, diminuir o tempo de criação do algoritmo e otimizar a sua solução. Nessa aula, será apresentado o conceito de função e procedimento e como essas instruções especiais devem ser utilizadas.

11

Modularização

Introdução

 Até aqui temos discutido a construção de algoritmos como uma solução linear que aborda um problema na sua forma geral e define um conjunto de instruções a serem executadas para alcançar uma solução. Todavia, até o momento, não consideramos a comple- xidade do problema ou o tamanho (quantidade de instruções) que um algoritmo pode ter.

Nos vários exemplos mostrados nesse caderno, abordamos, por motivos didáticos, algoritmos e problemas simples. Porém, na vida prática, encontramos problemas de complexidade muito mais elevada e que exigem soluções algorítmicas mais robustas e, conse- qüentemente, maiores.

No cotidiano de um programador, é comum a construção de algoritmos que envolvam centenas ou milhares de instruções. Fica óbvio, para esses casos, que a representação de um algoritmo nessa

escala usando fluxograma fica inviável e, mesmo usando pseudocódigo, tere- mos dificuldade em gerenciar um conjunto tão grande de instruções.

Nesta aula, é fundamental que você já domine a criação de algoritmos e como representá-los na forma de pseudocódigo, pois nesta aula são apre- sentados e comentados exemplos nessa forma. Além disso, é necessário que você tenha apreendido o conceito de variáveis. Portanto retome o conteúdo  já estudado nas aulas anteriores se ainda houver dúvidas!

Esperamos que, ao final desta aula, você seja capaz de:

2 entender os principais conceitos relacionados ao uso de funções e

procedimentos;

2 criar de forma correta funções em seus algoritmos, utilizando-as; 2 criar de forma correta procedimentos em seus algoritmos, utili-

zando-os.

11.1 Modularização

Uma solução para problemas complexos é a sua divisão sucessiva em problemas menores a fim de obter uma solução de custo mínimo. Essa idéia conhecida como “Dividir para Conquistar” é o princípio básico da técnica de

análise estruturada, chamada de Modularização. Nessa técnica, o problema

maior é dividido em problemas menores, chamados de módulos.

O segredo de uma boa modularização está em identificarmos claramente que módulos devem existir no sistema. Devemos atribuir uma única função bem definida a cada módulo, minimizar as ligações entre os módulos e maxi- mizar a coesão interna de cada módulo.

Essa técnica apresenta inúmeras vantagens para a programação. Vejamos. 1. Facilita a verificação de erros: pois é, em princípio, simples identi-

ficar o módulo responsável pelo erro, reduzindo-se assim o tempo gasto na identificação de erros.

2. Permite testar os módulos individualmente, em vez de se testar ape- nas o programa completo, o que reduz a complexidade do teste e permite começar a testar antes de se ter completado o programa.

3. Permite fazer a manutenção do programa (correção de erros, melhoramentos etc.) módulo a módulo e não no programa todo, o que reduz a probabilidade de essa manutenção ter conseqüências imprevistas em outras partes do programa.

4. Permite o desenvolvimento independente dos módulos, o que simplifica o trabalho em equipe, pois cada elemento ou cada sub- -equipe tem a seu encargo apenas alguns módulos do programa. 5. Permite a reutilização do código desenvolvido, ou seja, que módu-

los individuais sejam utilizados para formar outro programa.

Um programador assume, ao longo do desenvolvimento de um pro- grama, dois papéis distintos: por um lado é fabricante, pois é sua responsa-

bilidade desenvolver módulos; por outro é utilizador , pois fará com certeza

uso de outros módulos, desenvolvidos por outros programadores ou por ele próprio no passado.

 A modularização em um algoritmo é expressa por meio das unidades atômicas: funções e procedimentos. Uma função representa um conjunto de instruções, com interface bem definida, que efetua um dado cálculo e, na maioria dos casos, devolve um valor. Já um procedimento também representa um conjunto de instruções, com interface bem definida, que faz qualquer coisa, porém sem devolver valor algum. Algumas linguagens de programação, como a linguagem C ou Java, não fazem distinção entre procedimento e função e trata todo o processo de modularização somente com o uso de funções.

No documento Livro Logica Programacao b (páginas 131-140)