Baixe o app para aproveitar ainda mais
Prévia do material em texto
Algoritmos Estruturados Algoritmo - é a descrição de um conjunto de ações que obedecidas, resultam uma sucessão finita de passos, atingindo um objetivo. Linguagem de Programação - é o conjunto de símbolos e regras que associamos semânticas utilizadas para programar computadores. Tipo de Dados - Numeral (inteiro e real) - Literal (caracter) - Lógico (verdadeiro ou falso) Bloco - conjunto de ações com uma função definida - para delimitar utilizamos os delimitadores: Início e Fim. Estrutura de um Programa Constante - é um determinado valor fixo que não se modifica ao longo do tempo, durante a execução de um programa. Conforme o seu tipo, a constante é classificada como sendo numérica, lógica e literal. Variável - é a representação simbólica dos elementos de um certo conjunto. Cada variável corresponde um posição de memória, cujo o conteúdo pode variar ao longo do tempo durante a execução de um programa. Embora uma variável possa assumir diferentes valores, ela só pode armazenar um valor a cada instante. Identificador - é formado por um ou mais caracter, sendo que o primeiro caracter deve, obrigatoriamente, ser uma letra e os caracteres seguintes, letras ou dígitos, não sendo permitido o uso de caracteres especiais. Indicadores Permitidos: A; Nota; Matrícula Indicadores Não Permitidos: 5B; E(13); X-Y Declaração de Variáveis - as variáveis só podem armazenar valores de um mesmo tipo, de maneira que também são classificadas como sendo numéricas, lógicas e literais. Toda variável é declarada da seguinte forma: Declare Lista-de-Identificadores Nome-do-Tipo Onde: Declare: é uma palavra-chave do algoritmo; Lista-de-Identificadores: são os nomes escolhidos para as variáveis, que devem estar separados por virgulas; Nome-do-Tipo: é uma das três palavras-chaves - numérico, lógico ou literal, que indicam o tipo associado às variáveis. Comentários - são mensagens colocadas no algoritmo entre chaves, a fim que as pessoas possam entender facilmente o que um determinado trecho ou variável representa. Expressões Aritméticas - são operadores aritméticos e cujos os operandos são constantes e/ou variáveis do tipo numérico (adição, subtração, multiplicação, divisão, potenciação e radiciação). Funções - além das operações básicas, podem-se usar nas expressões aritméticas algumas funções muito comuns na matemática. Expressões Lógicas - denomina-se expressão lógica a expressão cujos operadores são lógicos e cujos os operandos são relações constantes e/ou variáveis do tipo lógico. Relações - é uma comparação realizada entre valores do mesmos tipo básico ( =, <, >, <>, ) Operadores Lógicos - são definidos três conectivos usados na formação de novas proposições a partir de outras já conhecidas. e - para conjunção ou - para a disjunção não - para a negação A conjunção de duas proposições é verdadeira se e somente se ambas a proposições são verdadeiras. p q p ^ q V V V V F F F V F F F F A disjunção de duas proposições é verdadeira se e somente se, pelo menos, uma delas for verdadeira. p q p v q V V V V F V F V V F F F Prioridade das Operações: Prioridade Operador 1 Aritmético 2 Relacional 3 Não (negação) 4 E (conjunção) 5 OU (disjunção) Comando de Atribuição - permite que se forneça um valor a uma certa variável, onde a natureza deste valor tem de ser compatível na qual está sendo armazenado. Identificados <= Expressão Onde: Identificador é o nome da variável à qual está sendo atribuído o valor; <= é o símbolo de atribuição; A expressão pode ser aritmética, lógica ou literal de cuja avaliação é obtido o valor a ser atribuído à variável. Estrutura Seqüencial - é o conjunto de ações primitivas que serão executadas numa seqüência linear de cima para baixo e da esquerda para a direita, isto é, da mesma ordem que foram escritas. Todas ações devem ser seguidas por um ponto-e-virgula (;), que objetiva separar uma ação de outra e auxiliar a organização seqüencial das ações. Exemplo: Início {começo do algoritmo} Comando A; Comando B; Comando C; Comando n; Fim. {fim do algoritmo} Calcular a média aritmética entre 4 números Algoritmo Real : N1, N2, N3, N4, MA; Leia (N1, N2, N3, N4); MA <= (N1, N2, N3, N4) / 4; Escreva (MA) Fim Algoritmo. Estrutura de Seleção - é a seleção que permite a escolha de um grupo de ações e estruturas a ser executado por determinadas condições, representada por expressões lógicas, são ou não satisfeitas. Seleção Simples - é uma expressão lógica que quando inspecionada, pode gerar um resultado falso ou verdadeiro. Exemplo: Se (condição) Então C: {comando único} Fim Se Algoritmo Real : N1, N2, N3, N4, MA; Leia (N1, N2, N3, N4); MA <= (N1, N2, N3, N4) / 4; Escreva (MA); Se MA > 6 Então Escreva ("Aluno Aprovado") Fim Se Fim Algoritmo. Seleção Composta - é uma expressão lógica que quando inspecionada, pode gerar um resultado falso ou verdadeiro, executando uma nova seleção. Se (condição) Então Início Comando 1; Comando 2; Fim; Senão C; Fim Se Estrutura de Repetição - permite que uma seqüência de comandos seja executada repentinamente até que uma determinada condição de interrupção seja satisfeita. Interrupção no Início: Repita Se (condição) Então Interrompa Fim Se Seqüência A de Comandos Fim Repita Interrupção no Interior: Repita Seqüência A de Comandos Se (condição) Então Interrompa Fim Se Seqüência B de Comandos Fim Repita Interrupção no Final: Repita Seqüência A de Comandos Se (condição) Então Interrompa Fim Se Fim Repita Como solucionar problemas utilizando o computador? 1. Criação de uma seqüência de passos (operações) que, quando executados, produz o resultado do problema (Algoritmo). 2. Execução da seqüência de passos mencionada acima. Cuidados devem ser tomados no desenvolvimento de algoritmos: algoritmo errado --> resultado errado. Representação de Algoritmos: Pseudo-Linguagem Algoritmos podem ser representados de duas maneiras: a) uma mais próxima (entendida) pelas pessoas b) uma entendida pelo computador Uma pseudo-linguagem possui as seguintes características: utilização de certas palavras-chave, que indicam a natureza da operação a ser efetuada em certos passos do algoritmo utilização de espaços no começo das linhas do algoritmo para ressaltar a estrutura do algoritmo numeração do passos do algoritmo utilização ponto-e-vírgula (;) para separar os passos consecutivos do algoritmo. Exemplo: algoritmo para somar dois números. Algoritmo 1. pegar o primeiro número 2. pegar o segundo número 3. somar o primeiro número com o segundo 4. mostrar o resultado da soma Fim-algoritmo. Em um algoritmo, os passos podem pertencer a uma das três naturezas: 1. um operação elementar 2. uma operação de controle especificando uma seleção entre seqüência de passos 3. uma operação de controle especificando a repetição de uma seqüência de passos Seleções 1. com um ramo se condição então seqüência de passos 2. com dois ramos se condição então seqüência de passos 1 senão seqüência de passos 2 Repetições 1. teste do início enquanto condição repetir: seqüência de passos 2. teste no fim repetir: seqüência de passos até condição 3. repetir um número conhecido de vezes repetir especificação de vezes seqüência de passos Representação de Algoritmos: Linguagens de Programação A representação de algoritmos em uma pseudo-linguagem mais próxima às pessoas é bastante útil principalmente quando o problema a ser tratado envolve um grande número de passos. No entanto, para que esses passos possam ser entendidos pelo computador é necessário representar tal algoritmo em uma linguagem de programação. Pascal Fortran C C++ As linguagens de programação obrigam o uso de formas rígidas na especificação de seus passos, ou seja, obrigam as pessoas a detalharem as operações que deverão ser executadas. Uma dica aquié refinar a solução do problema de um nível mais abstrato até chegar ao nível de detalhamento que deve ser representado em uma linguagem de programação. Essa prática, além de prover um tipo de documentação, também ajuda muito no tratamento dos erros que eventualmente possam surgir. Convencionamos aqui que um algoritmo representado em uma linguagem de programação é um programa. Ex.: programa em Pascal para somar dois números. program somadoisnum; { esse programa soma dois números e exibe o resultado na tela } var n1, n2, result : integer; begin readln(n1); readln(n2); result := n1 + n2; writeln(result); end. Os algoritmos descritos em pseudo-linguagem não podem ser executados (entendidos) por computadores. É necessário ainda uma fase de tradução da linguagem de programação para a linguagem que a máquina entenda. Essa fase é conhecida por compilação, e é realizada pelo Compilador. Compilador traduz o programa escrito em uma linguagem de programação para linguagem de máquina. verifica se as formas rígidas na especificação dos passos foi seguida corretamente. compiladores são relacionados diretamente com a máquina para a qual será feita a tradução. gera um arquivo executável do programa descrito. Programação Pascal Abordaremos aqui, a utilização dos conceitos de programação pascal por meio de exemplos. 1. Estrutura principal A estrutura principal de um programa em pascal se apresenta da seguinte forma: program cabeçalho; declarações begin comandos end. As palavras em negrito são palavras reservadas ou palavras chave da linguagem, que não podem ser declaradas como identificadores. Elas definem o tipo de dados ou estrutura que se deseja utilizar. 2. Palavras Chaves (reservadas): and, array, begin, case, const, div, do, downto, else, end, file, for, function, goto, if, in, label, mod, nil, not, of, or, packed, procedure, program, record, repeat, set, then, to, type, until, var, while, with 3. Identificador Um identificador é formado por uma única letra, ou então por uma letra seguida de letras ou dígitos, em qualquer número. Considera-se dois identificadores como distintos quando considerados seus oito primeiros caracteres. 1. Comentários Os comentários são identificados por estarem delimitados pelos caracteres { e }, ou pelo caracteres (* e *). Comentários são ignorados pelo compilador na fase de tradução do programa. Comentários são úteis no sentido de destacar ou documentar o programa, para torná-lo mais legível e fácil de entender o seu objetivo, quando retomado para correção ou alteração após determinado tempo. Declarações A parte de declarações em um programa está relacionada a alocação de memória para os dados que serão utilizados no decorrer do programa. O montante do memória alocada está relacionada ao tipo de dado a ser utilizado. Podem ser declarados aqui regiões de memória que podem ter seu conteúdo alterado (variáveis), regiões de memória que não são permitidos a alteração de seu conteúdo, e também outros tipos além dos pré-definidos pela linguagem. 1. Tipos pré-definidos da linguagem Pascal: integer char boolean (TRUE, FALSE) string 1. Variáveis Variáveis são entidades que são representadas por identificadores. Sintaxe: var Lista-de-Identificadores : tipo; Lista-de-Identificadores : tipo; Exemplo: var nota, A12 : real; i, codigo : integer; flag, Sim : boolean; letra1, letra2: char; 1. Constantes Define identificadores que não se alteram durante a execução do algoritmo. Exemplo: const pi = 3,1415 2. Declaração de outros Tipos Além dos tipos pré-definidos pela linguagem Pascal, há a possibilidade de se definir outros tipos. Exemplo: type LETRASMA = ´A´ .. ´Z´; INDICES = 0 .. 100; DIAS = (dom, seg, ter, qua, qui, sex, sab); var diasemana : DIAS; 1. Expressões Aritméticas A tabela seguinte mostra as operações aritméticas básicas da linguagem com sua prioridade de execução quando agrupadas em um expressão aritmética. Prioridade Operadores 1 2 * / div mod + - div(a,b) retorna o valor inteiro do quociente de a/b. a/b retorna o valor real do quociente de a/b mod(a,b) retorna o valor do resto da divisão a/b. Pode-se definir a prioridade de execução das operações com a utilização de parênteses. Exemplos: a =1, b = 2, c = 3 a + b * c = 9 c / b * a = 0.5 c div b = 1 c mod b 1 2. Funções Numéricas Predefinidas Em Pascal há algumas funções numéricas pré-definidas. Veja a tabela a seguir. ln(ea) logaritmo neperiano exp(ea) número e elevado a ea abs(ea) valor absoluto trunc(ea) valor truncado round(ea) valor arredondado sqr(ea) quadrado sqrt(ea) raíz quadrada sin(ea) seno cos(ea) coseno arctan(ea) arco tangente Exemplos: exp(y*(b+2)-6) ln(sqrt(a+2*b)-b) Expressões Lógicas Expressão lógica é uma expressão cujos operadores são os operadores lógicos e cujos operandos são relações e/ou variáveis. Uma relação é uma comparação realizada entre valores do mesmo tipo. Estes valores são representados na relação por constantes, variáveis ou expressões do tipo correspondente. A natureza da comparação é indicada por um operador relacional que pode ser: = igual <> diferente <= menor ou igual < menor >= maior ou igual > maior IN contido em (conjunto) O resultado de uma relação é sempre um valor lógico: TRUE ou FALSE Exemplos: a <> b nome = ´Maria´ x * y + 5 * b > 0 x = 10 Operadores Lógicos and conjunção or disjunção not negação Exemplos: (a + b = 0) and (c <> d) sim or (a * b > c) not verdade and cor = ´verde´ Prioridades Pascal permite a construção de expressões compostas de várias pequenas expressões, desde que os tipos de dados das expressões sejam os mesmos, a ordem em que a expressão é escrita também é levada em consideração. Veja o exemplo: x * y * z Neste exemplo em particular, a ordem em que a expressão foi escrita é irrelevante, numa multiplicação, não importa a ordem, o resultado é sempre o mesmo. Mas isto não é verdade para todas as operações, algumas expressões dão resultados diferentes, dependendo de qual operação é realizada primeiro. Veja o exemplo x + y / 100 Usando parênteses ( ), você pode direcionar o compilador Pascal para executar uma operação primeiro. Por exemplo, para a expressão do exemplo anterior deixar de ser ambígua, você deveria escrever ( x + y ) / 100. Sem parênteses, o compilador vai efetuar as operações na ordem em que aparecem e seguindo uma certa prioridade, operações com maior prioridade são efetuadas primeiro. é equivalente a: x + ( y / 100) Para tornar seu código mais fácil de ler e manter, é recomendável, deixar explícito e indicado com parênteses qual a operação que deve ser realizada primeiro. Segue abaixo uma tabela de prioridades. Prioridade Operadores 1 2 3 4 not *, /, div, mod, and +, -, or =, <> , <, <=, >, >=, in Comando de Atribuição Um comando de atribuição altera o conteúdo de um identificador (lado esquerdo) pelo valor resultante da expressão (lado direito). A variável e a expressão devem ser do mesmo tipo, exceto no caso em que a variável é do tipo real e o resultado da expressão é do tipo inteiro, quando o valor inteiro da expressão é transformado em real. identificador := expressão Exemplos: var a, c, n, soma, x , y : integer; k, media, total: real; cod, sim,teste : boolean; cor : string; k := 1; cor := ´verde´; teste := FALSE; a := b; media := soma/n; cod := sqr(n) + 1 >= 5; sim := (x=0) and (y <> 2); total := sqrt(n) + sqr(x) + y; n := x/y; {não válida} Comandos de Entrada e Saída read(lista-de-identificadores) readln(lista-de-identificadores) write(lista-de-identificadores e/ou constantes e/ou expressões) writeln(lista-de-identificadores e/ou constantes e/ou expressões) READ e READLN são os comandos de entrada usados em Pascal. lista-de- identificadores são os nomes das variáveis do tipo STRING, INTEGER, CHAR, ou REAL, cujos valores serão lidos na unidade de entrada. Os identificadores contidos na lista, devem estar separados por vírgula. A diferença entre estes dois comandos de entrada é que o comando READ lê os valores das variáveis da lista deixandoo valor seguinte desta linha, se houver, disponível para o próximo comando de entrada. Ao contrário, o comando READLN lê os valores das variáveis da lista e salta, se houver, os valores restantes da linha. Assim o próximo comando de entrada não receberá esses valores adicionais contidos na linha. Os valores de entrada deverão estar separados por espaço(s) ou por fim de linha. WRITE e WRITELN são os comandos de saída usados em Pascal. lista-de- identificadores são os nomes das variáveis do tipo STRING, INTEGER, CHAR, REAL ou BOOLEAN, cujos valores serão lidos na unidade de entrada. Os identificadores contidos na lista, devem estar separados por vírgula. Constantes e expressões de mesmo tipo podem aparecer nos comandos de saída. A diferença entre estes dois comandos é que o comando WRITE escreve os valores numa ou mais linhas, deixando que o próximo comando de saída continue escrevendo na última linha, se ainda houver espaço. Ao contrário, o comando WRITELN escreve os valores em uma ou mais linhas, de modo que o próximo comandos de saída comece a escrever após a última linha. Exemplos: read(x); readln(nome, n ,y); write(k, soma); writeln(21, ´Nome´, n); write(´Tabela de Preços´); writeln(n, sqrt(n)); Formatação Podemos generalizar as comandos de saída do Pascal da seguinte forma: write(p1, ...,pn) writeln(p1, ...,pn) onde pi é um parâmetro com uma das formas: - e - e : e1 - e : e1 : e2 sendo e, e1, e2 expressões. e representa o valor a ser escrito e pode ser do tipo INTEGER, REALM, CHAR, STRING ou BOOLEAN, podendo ser uma constante ou uma expressão. e1 representa um valor inteiro positivo e indica o número mínimo de caracteres a ser escrito. Se e1 for insuficiente para representar o valor escrito, então será alocado mais espaço. Se e1 for excessivo, o espaço excedente será preenchido com brancos. e2 só se aplica de e for do tipo REAL. e2 é um valor inteiro positivo e especifica o número de dígitos que devem ser escritos após o ponto decimal. Se e2 for omitido, então o valor real será escrito no formato exponencial. Exemplo: program exe1; var a, b : real; k : char; begin a := 3.2; b := 5.81; k := ´*´; writeln('resultado: ', a:5, ' + ', b:5, ' = ', a+b:5, k); writeln('resultado: ',a:5:1, ' + ', b:5:1, ' = ', a+b:5:1, k:1); writeln('resultado: ',a:5:2, ' + ', b:5:2, ' = ', a+b:5:2, k:2); writeln('resultado: ',a:5:3, ' + ', b:5:3, ' = ', a+b:5:3, k:3); end. Saída: resultado: 3.2e+00 + 5.8e+00 = 9.0e+00* resultado: 3.2 + 5.8 = 9.0* resultado: 3.20 + 5.81 = 9.01 * resultado: 3.200 + 5.810 = 9.010 * Estrutura Condicional if condição then comando1 Neste caso, comando1 só será executado se a condição for verdadeira. A condição deve ser uma expressão lógica. O comando pode ser um comando simples ou um comando composto. Um comando composto é formado por diversos comandos (simples ou compostos), delimitados pelas palavras BEGIN e END, além das estruturas de controle (condicional e de repetição). if condição then comando1 else comando2 Neste caso, se a condição for verdadeira, será executado o comando1. Caso contrário será executado o comando2. Exemplos: program condicional; var i, j: integer; begin i := 1; j := 3; if i < j then writeln('i maior do que j'); else writeln('j maior do que i'); if (i+j) > 0 then writeln('soma de i com j é maior do que 0'); end. Estrutura de repetição 1. Condição no Início while condição do comando Essa estrutura significa que enquanto a condição for verdadeira, o comando será executado repetidamente. Se a condição for falsa, então a repetição será interrompida. Comando pode ser simples ou composto e condição é uma expressão lógica. Exemplo: program repeticaoinicio; var i, soma : integer; begin i := 1; soma := 0; while (soma < 100) do begin i := i * 2; soma := soma + i; end; writeln(soma); end. 1. Condição no Fim repeat comando until condição Nessa estrutura o comando é executada, e em seguida é verificado a condição. Se a condição for falsa, então repete-se a execução do comando. Se for verdadeira, então o laço é interrompido. Comando pode ser simples ou composto e condição é uma expressão lógica. Nesta estrutura o comando é executado pelo menos uma vez. Um ponto interessante para colocarmos aqui é a questão da condição. Exemplo: program repeticaofim; var i, soma : integer; begin i := 1; soma := 0; repeat i := i * 2; soma := soma + i; until (soma >= 100); writeln(soma); end. 1. Número de Repetições Conhecido for var-controle := valor-inicial to valor-final do comando for var-controle := valor-inicial downto valor-final do comando O significado dessas repetições é: a var-controle recebe o valor- inicial; verifica-se se o valor de var-controle ultrapassa o valor-final; se não ultrapassa, o comando será executado; a seguir, var- controle recebe o valor seguinte (no caso do for-to) ou valor anterior (no caso for-downto); verifica-se se ultrapassa o valor-final; se não ultrapassar, o comando será executado; e assim sucessivamente. Exemplo: program repeticaofor; { Esse programa calcula 2 elevado n } var i, n, s : integer; begin s := 0; read(n); for i:= 1 to n do s := s * 2; writeln(s); end. Estrutura de Dados Vimos anteriormente como um identificador referencia um tipo, como inteiro, real, char, boolean e string. A linguagem Pascal também dispõe meios para que um mesmo identificador referencie vários dados, do mesmo tipo ou de tipos diferentes. Isso é conhecido em Pascal como variável estruturada. Há dois tipos dessas variáveis: Variáveis Compostas Homogêneas Variáveis Compostas Heterogêneas Variáveis Compostas Homogêneas São variáveis conhecidas em Pascal como arrays (vetores), e correspondem a um conjunto de dados de um mesmo tipo. Essas variáveis podem ser unidimensionais ou multidimensionais, ou seja, dependem da quantidade de índices necessários para individualização de cada elemento do conjunto. Variáveis Compostas Homogêneas Unidimensionais São variáveis compostas que necessitam de somente um índice para individualizar um elemento do conjunto. A criação desse tipo de variável é feita com a seguinte declaração: lista-de-identificadores : ARRAY[k] OF t; lista-de-identificadores são nomes associados às variáveis que se deseja declarar. k é da forma k1..k2, em que l1 é o índice inferior do intervalo de variação do índice e l2 é o limite superior. t é o tipo dos componentes da variável. Para se declarar uma variável nota do tipo real com 10 elementos basta escrever nota : array[1..10] of real; Os índices para a variável nota estão no intervalo 1,2,3,...,10. Para acessar um elemento i dessa variável basta referenciá-lo como nota[i]. Por exemplo, nota[1], nota[10], que referenciam respectivamente o valor do primeiro e o valor do décimo elemento da variável nota. Utilizando-se, por exemplo um variável i do tipo inteiro, tem-se a possibilidade de acesso a qualquer um dos elementos. Seja nota[i] uma referência em um programa. Antes da variável nota ser consultada, a variável i seria substituída pelo seu conteúdo no dado instante. Se i=2, então o elemento da acessado seria nota[2]. Os elementos da variável nota podem ser referenciados por expressões como por exemplo nota[i+1] e nota[i+j+1]. Exemplo 4.1: nota 80 70 75 100 85 92 68 80 90 75 1 2 3 4 5 6 7 8 9 10 nota[1] = 80 nota[2] = 70 . . . nota[10] = 75 program array_uni; { Lê dez notas e calcular a média} var nota : array[1..10] of real; soma, media : real; i : integer; begin soma := 0; writeln('Digite os valores das 10 notas:'); for i:= 1 to 10 do read(nota[i]); for i:= 1 to 10 do soma := soma + nota[i]; media := soma/10; writeln('Média das notas: ',media:2:2); end. Saída: Digite os valores das 10 notas: 80 70 75 100 85 92 68 80 90 75 Média das notas: 81.50 Variáveis Compostas Homogêneas Multidimensionais São variáveis compostas que necessitam de mais de um índice para individualização de seus elementos. A criação desse tipo de variável é feita com a seguinte declaração: lista-de-identificadores : ARRAY[k] OFt; lista-de-identificadores são os nome que serão associados às variáveis multidimensionais. k é da forma l11..l12,l21..l22, ... ,ln1..ln2, que são limites do intervalo de variação de cada um dos n índices da variável. t é o tipo a que pertencem os componentes do conjunto. Por exemplo, para criar uma variável notas2, contendo as notas de alunos em cada disciplina, onde as linhas representam os alunos e as colunas representam as disciplinas, faz-se o seguinte notas2 : array[1..10,1..5] of real; Isso indica que temos 10 alunos e 5 disciplinas, ou o contrário, conforme a convenção que se adotar para linha e para coluna. Para acessar a nota do aluno 3 na disciplina 5 basta referenciá-lo por nota2[3,5] ou nota[3][5]. Outros exemplos de acesso aos elementos neste tipo de variável são: notas2[3,4], notas2[5,5], notas2[i,j] ou notas2[3][4], notas2[5][5], notas2[i][j] Exemplo 4.2: program matrizes; { Calcular a média das notas de cada aluno e as médias das notas em cada disciplina } var notas2 : array[1..10,1..5] of real; media_aluno : array[1..10] of real; media_disc : array[1..5] of real; i, j : integer; soma, media : real; begin { preenche a matriz notas2, linha a linha (aluno) } for i:= 1 to 10 do for j:= 1 to 5 do read(notas2[i,j]); { calculando as médias das notas dos alunos} for i:= 1 to 10 do begin soma := 0; for j:= 1 to 5 do soma := soma + notas2[i,j]; media := soma/5; media_aluno[i] := media; end; { calculando as médias das notas em cada disciplina } for j:= 1 to 5 do begin soma := 0; for i:= 1 to 10 do soma := soma + notas2[i,j]; media := soma/10; media_disc[j] := media; end; { Imprimindo os resultados } writeln('Média das notas dos alunos:'); for i:= 1 to 10 do writeln('Aluno[', i:2, '] = ', media_aluno[i]:3:2); writeln('Média das notas em cada disciplina:'); for j:= 1 to 5 do writeln('Disciplina[', j:2, '] = ', media_disc[j]:3:2); end. Variáveis Compostas Heterogêneas I. Registros São conjuntos de dados logicamente relacionados, mas de tipos diferentes (inteiro, real, literal, ...). Para se utilizar estruturas desse tipo, deve-se declará-las da seguinte forma: lista-de-identificadores : record componentes end; lista-de-identificadores são os nomes que estão sendo associados aos registros que se deseja declarar. componentes são declarações de variáveis, separadas por ponto-e-vírgula. Exemplo 4.3: Para se declarar um registro com os campos abaixo, faz-se o seguinte: Cadastro -------------------------------------------------- |Nome | -------------------------------------------------- |Rua | Número | CEP | -------------------------------------------------- |RG |CPF |Nascimento |Sexo | -------------------------------------------------- Var cadastro : record nome : string[30]; rua : string[40]; numero: integer; cep: real; rg : real; cpf:real; nascimento: string[10]; sexo : char; end; É possível também, declarar um registro como um tipo. No exemplo abaixo o registro endereço é declarado como um tipo. Na declaração das variáveis a variável cadastro (que é um registro) tem como um dos seus componentes a variável do tipo endereço, referenciado pela variável ender. Type endereço = record rua : string[40]; numero : integer; CEP : real; end; Var ... cadastro : record nome : string[30]; ender : endereço; CPF: real; Sexo : char; nascimento : real; rg : real; end; Para se referencia a cada campo (ou componente) de um registro utiliza-se a seguinte notação: identificador.variável Por exemplo, do registro cadastro acima, imprimimos os valores de cada campo da seguinte forma: writeln(cadastro.nome); writeln(cadastro.ender.rua); writeln(cadastro.ender.numero); writeln(cadastro.ender.CEP); writeln(cadastro.CPF); writeln(cadastro.Sexo); writeln(cadastro.nascimento); writeln(cadastro.rg); Conjunto de Registros Assim como pode ter conjuntos de dados de mesmo um tipo referenciados por um mesmo identificador, e individualizados por índices, temos a possibilidade de fazer isso com registros. Nos exemplos abaixo exibimos duas formas de declarar estes tipos de estruturas em Pascal. A primeira como a declaração do registro junto com a declaração do vetor(array), e a segunda como declaração do tipo cadastro (que é um registro) e a sua utilização em um vetor do tipo cadastro. Exemplo 4.4: bd : array[1..10] of record nome : string[30]; ender : endereço; CPF: real; Sexo : char; nascimento : real; rg : real; end; ---------------------------------------- Type cadastro = record nome : string[30]; ender : endereço; CPF: real; Sexo : char; nascimento : real; rg : real; end; . . . var bd : array[1..10] of cadastro; Embora a tenham o mesmo sentido quanto a utilização, nesses dois tipos de declaração com vetores de índices as variáveis são referenciados de maneira diferente. Por exemplo, no primeiro caso basta acrescentar um ponto e o nome da variável para referenciar o devido campo. No segundo caso deve-se colocar o nome do tipo do vetor. A seguir, são mostrados os exemplos desses dois casos, quando imprimindo-se os valores do registro do vetor da posição i. Exemplo 4.5: Caso 1 writeln(bd[i].nome); writeln(bd[i].ender.rua); writeln(bd[i].ender.numero); writeln(bd[i].ender.CEP); writeln(bd[i].CPF); writeln(bd[i].Sexo); writeln(bd[i].nascimento); writeln(bd[i].rg); Caso 2 writeln(bd[i].cadastro.nome); writeln(bd[i].cadastro.ender.rua); writeln(bd[i].cadastro.ender.numero); writeln(bd[i].cadastro.ender.CEP); writeln(bd[i].cadastro.CPF); writeln(bd[i].cadastro.Sexo); writeln(bd[i].cadastro.nascimento); writeln(bd[i].cadastro.rg); Arquivos Em Pascal estruturas de dados manipuladas fora do ambiente do programa são conhecidas como arquivos. Considera-se como ambiente do programa a memória principal, onde nem sempre é possível ou conveniente manter certas estruturas de dados. Um arquivo, armazenado num dispositivo de memória secundária, como discos e disquetes, pode ser lido ou escrito por um programa através de registros. Antes de se declarar arquivos em um programa, deve ser declarar primeiramente o seu tipo. As formas das declarações é a seguinte: type identificador-do-tipo = file of tipo; lista-de-identificadores : identificador-do-arquivo; type é uma palavra-chave; identificador-de-tipo é o identificador associado ao novo tipo; file of são palavras reservadas; tipo é o tipo a que pertencem os registros do arquivo; lista-de-identificadores são nomes associados aos arquivos. Exemplo 4.6: Aproveitando a declaração do tipo cadastro acima, abaixo seguem exemplos de sua utilização com arquivos. Type cadastro = record . . . . end; arqcad = file of cadastro; var arquivo : arqcad; arquivo2 : file of cadastro; Operações com Arquivos As operações básicas realizadas sobre um arquivo são abertura, leitura, escrita e fechamento. A abertura de arquivos corresponde à ação de se associar o arquivo declarado no programa com o arquivo físico. O primeiro registro do arquivo fica disponível para leitura através do seguinte comando: reset(nome-do-arquivo); Caso o arquivo já exista, para começar a escrever novamente no arquivo, ignorando-se os registros anteriores, utiliza-se o seguinte comando: rewrite(nome-do-arquivo); O nome-do-arquivo é o identificador do arquivo no programa. Para se fazer uma associação desta identificação interna com a identificação externa, usa-se o comando assign, cuja forma é: assign(nome-do-arquivo,'nome-externo'); nome-externo é o nome pelo qual o arquivo é conhecido externamente ao programa. O comando assign deve anteceder a abertura do arquivo e nunca deve ser utilizado quando o arquivo já estiver sendo manipulado. O fechamento do arquivo desvincula o arquivo do programa, atualizando as informações do arquivo no ambiente do sistema operacional. Para se fechar um arquivo, usa-se o comando: close(nome-do-arquivo); Para ler um arquivo, ou seja ler o seu conteúdo, é utilizado o seguinte comando: read(nome-do-arquivo,registro);Esse comando lê o conteúdo do registro corrente do arquivo associado à nome-do-arquivo e armazena-o em na variável registro, que deve ser do mesmo tipo do arquivo. Após a execução desse comando, o registro corrente é lido, e o próximo passa a ser o registro corrente. Para escrever em um arquivo, é utilizado o seguinte comando: write(nome-do-arquivo,registro); Esse comando, quando executado, grava no registro corrente do arquivo associado à nome- do-arquivo o conteúdo da variável registro. Usando somente os comandos read e write, os registros estão acessíveis somente seqüencialmente, ou seja, um registro será acessado somente após todos os seus anteriores sejam acessados. É possível acessar um registro qualquer do arquivo diretamente, desde que se saiba a sua posição física no arquivo. Esse tipo de acesso é conseguido pelo comando: seek(nome-do-arquivo,n); Com esse comando é possível acessar o n-ésimo registro do arquivo associado à nome-do- arquivo, caso n seja menor que o número de registros do arquivo. O primeiro registro é o de número 0 (zero). Para se obter o número de registros de um arquivo, utiliza-se o comando: filesize(nome-do-arquivo); Com a utilização dos comandos seek e filesize temos um outro tipo de organização ou acesso aos arquivos: a organização direta. Neste caso temos que escolher uma chave para indexar os registros, ou seja, essa chave será utilizada para indicar em que posição no arquivo um registro será armazenado. Exemplo 4.7: program sequencial; type endereço = record rua : string[40]; numero : integer; CEP : real; end; cadastro = record nome : string[30]; ender : endereço; CPF: real; Sexo : char; nascimento : real; rg : real; end; arqcad = file of cadastro; var arq_in, arq_out : arqcad; reg: cadastro; begin assign(arq_out,'sample.dat'); {associando nome interno com nome externo} rewrite(arq_out); {abrindo arquivo para gravação} write('Nome: '); readln(reg.nome); while (reg.nome <> 'fim') do begin write('Rua: '); readln(reg.ender.rua); write('Numero: '); readln(reg.ender.numero); write('CEP: '); readln(reg.ender.CEP); write('CPF: '); readln(reg.CPF); write('Sexo(M/F): '); readln(reg.Sexo); write('Data de Nascimento(dd/mm/aaaa): '); readln(reg.nascimento); write('RG: '); readln(reg.rg); write(arq_out,reg); {grava registro após o último registro do arquivo} readln(reg.nome); end; close(arq_out); assign(arq_in,'sample.dat'); {associando nome interno com nome externo} reset(arq_in); {abrindo arquivo para leitura} read(arq_in,reg); while (not EOF(arq_in)) do begin write(reg.ender,rua,' '); write(reg.ender.numero,' '); write(reg.ender.CEP,' '); write(reg.CPF,' '); write(reg.Sexo,' '); write(reg.nascimento,' '); writeln(reg.rg,' '); end; writeln('O número de registros do arquivo é: ',filesize(arq_in)); end. Este programa a seguir exemplifica a utilização dos comando seek. Neste caso assumimos que as chaves estão no intervalo entre 1 e 100. program acesso_direto; type endereço = record rua : string[40]; numero : integer; CEP : real; end; cadastro = record chave : integer; nome : string[30]; ender : endereço; CPF: real; Sexo : char; nascimento : real; rg : real; end; arqcad = file of cadastro; tammax = 100; var arq_out : arqcad; reg : cadastro; begin assign(arq_out,'sample.dat'); {associando nome interno com nome externo} rewrite(arq_out); {abrindo arquivo para gravação} write('Chave: '); readln(reg.chave); while (reg.chave <> 0) do begin if (reg.chave >= 1) and (reg.chave <= 100) then begin write('Nome: '); readln(reg.nome); write('Rua: '); readln(reg.ender.rua); write('Numero: '); readln(reg.ender.numero); write('CEP: '); readln(reg.ender.CEP); write('CPF: '); readln(reg.CPF); write('Sexo(M/F): '); readln(reg.Sexo); write('Data de Nascimento(dd/mm/aaaa): '); readln(reg.nascimento); write('RG: '); readln(reg.rg); seek(arq_out,chave-1); write(arq_out,reg); { grava registro após o último registro do arquivo} end else begin writeln('Chave deve estar no intervalo [1,100].'); end; write('Chave: '); readln(reg.chave); end; close(arq_out); end. Arquivos texto Os arquivos gerados pelo programa exemplo 4.7 são arquivos binários. Esse tipo de arquivo não legível às pessoas, embora seja útil para fins de armazenamento de informações, visto que os dados são armazenados de forma comprimida, que diminui o tamanho do arquivo, e também restringe o acesso às informações contidas no arquivo. A linguagem Pascal também provê meios para lidar com um arquivo texto. A seguir mostramos como tratar arquivos em Pascal. As operações de abertura, de associação entre o nome interno e externo, de fechamento, de leitura, de escrita de um arquivo texto são as mesmas que dos arquivos binários. No entanto, para se declarar um arquivo texto utiliza-se uma outra notação: lista-de-identificadores:text lista-de-identificadores são nomes associados aos arquivos declarados como texto. Outra diferença com relação às operações é a possibilidade de utilização dos comandos readln e writeln sobre arquivos texto, o que não é possível sobre arquivos binários, visto que estes não possuem marca de final de linha. A diferença entre os comandos read e readln, write e writeln é basicamente a mesma quando utilizados como comandos de entrada e saída. Os comandos read e write operam sobre campos, enquanto que os comandos readln e writeln operam sobre linhas. Exemplos Esse programa lê um arquivo texto, exibe o seu conteúdo na tela e o número de linhas do arquivo. program le_arquivo_texto; var entrada : text; linha : string[100]; nlinhas : integer; begin nlinhas = 0; assign(entrada,'arq1.txt'); reset(entrada); readln(entrada,linha); {lê cada linha do arquivo} while (not EOF(entrada)) do begin writeln(linha); readln(entrada,linha); nlinhas := nlinhas + 1; end; writeln('Número de linhas do arquivo: ',nlinhas); close(entrada); end. O próximo programa lê 10 linhas contendo três campos do tipo inteiro, lê 10 linhas contendo três campos do tipo real, somando os valores de cada linha e colocando o resuldato em um arquivo de saída. O programa assume que o arquivo de entrada já esteja no formato correto. program le_valores_inteiro_real; var arq_in, arq_out : text; vi1, vi2, vi3, somai : integer; vr1, vr2, vr3, somar : real; i : integer; begin assign(arq_in,'dados.txt'); assign(arq_out,'saida.txt'); reset(arq_in); rewrite(arq_out); for i:= 1 to 10 do begin readln(arq_in,vi1,vi1,vi3); somai := vi1 + vi2 + vi3; writeln(arq_out,'linha ',i ,' - soma = ',somai); end; for i:= 1 to 10 do begin readln(arq_in,vr1,vr1,vr3); somar := vr1 + vr2 + vr3; writeln(arq_out, 'linha ',i+10 ,' - soma = ',somar:10:4); end; close(arq_in); close(arq_out); end. Exemplo do conteúdo do arquivo dados.txt: 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 50.00 51.10 52.20 53.30 54.40 55.50 56.60 57.70 58.80 59.90 60.00 61.10 62.20 63.30 64.40 65.50 66.60 67.70 68.80 69.90 70.00 71.10 72.20 73.30 74.40 75.50 76.60 77.70 78.80 79.90 Modularização A linguagem Pascal oferece facilidades necessárias no tocante a modularização de programas, por meio de procedimentos e funções, que permitem a confecção de programas modulares e bem estruturados. A idéia principal do conceito de modularização, informalmente falando, é dividir o programa em sub-programas, o que torna o trabalho de desenvolvimento e manutenção menos desgastante. Em Pascal o conceito de modularização é implementado por meio de sub-rotinas. Um módulo em Pascal é definido como sendo uma procedure ou uma function. Esses módulos podem ter variáveis próprias ou utilizar as variáveis declaradas no programa principal. E possível a declaração de variáveis com o mesmo identificador em módulos diferentes no mesmo nível ou em módulos aninhados (um módulo dentro do outro). Conforme o contexto em está inserido, uma variável pode ser considerada uma variável local ou um variável global. Por exemplo: as variáveis declaradas em um módulo A são consideradas locaisà A, porém são consideradas variáveis globais aos sub-módulos contidos em A. Dessa forma, todas as variáveis declaradas no programa principal são consideradas globais as procedimentos. Variáveis locais com o mesmo identificador declaradas em módulos diferentes e no mesmo nível são invisíveis umas para o outras, ou seja, não causam conflito. Quando os módulos estão aninhados, as variáveis declaradas em cada módulo, podem ser vistas e/ou utilizadas pelos respectivos sub-módulos. Porém, não serão utilizadas se forem declaradas variáveis com o mesmo identificador em seus sub-módulos, onde valerá somente as variáveis locais. Ou seja, se forem declaradas variáveis locais em um módulo A com o mesmo identificador que as variáveis globais à A, valerá as variáveis locais. Isso define as regras de escopo das variáveis, ou seja, até onde as variáveis podem ser utilizadas e/ou visíveis à outros módulos. No caso de existirem variáveis locais e globais com o mesmo nome, alterações feitas nas variáveis locais não afetam as globais. Já no caso onde um variável global é modificada, o próximo instrução que acessá-la irá encontrar o valor dessa última atualização. Exemplo: program A; { declaração de variáveis } var m, n : real; procedure B; { declaração de variáveis } var i, j : integer; begin { corpo do procedimento B } end; procedure C; { declaração de variáveis } var i, j : integer; k, l : real; procedure D; { declaração de variáveis } var k, l : integer; begin { corpo do procedimento D } end; begin { corpo do procedimento C } end; begin { corpo do programa principal } end. As variáveis i e j declaradas nos procedimentos A e B são invisíveis entre si, portanto não causam conflito. As variáveis k e l são válidas como inteiros em C. Apesar de serem globais, são invisíveis a D, pois foram redeclaradas como tipo real. É como se k e l fossem declaradas com outros identificadores. As variáveis i e j declaradas em C são globais a D, assim como as variáveis m e n são globais à todos os procedimentos. Procedimentos Convencionamos aqui que módulos do Pascal como procedimentos do Pascal. Procedimento é um trecho do programa que possui seus objetos (variáves, arquivos, etc.) e comandos próprios e que para ser executado deve ser ativado por um programa principal ou por outro procedimento. A criação de um procedimento em Pascal é feita através de sua declaração em um programa, ou seja, o procedimento é um objeto da linguagem que deve ser declarado, como os demais objetos, no início do programa ou de outro procedimento. Um procedimento em Pascal pode, por sua vez, conter outros procedimentos, que só serão conhecidos dentro do mesmo. A declaração de um procedimento em Pascal é constituída de um cabeçalho e de um corpo. O cabeçalho identifica o procedimento através de um nome, e o corpo contém as declarações dos objetos locais, além de comandos e estruturas do procedimento. A ativação de um procedimento, atendidas às condições de escopo, é feita através da referência ao seu nome em algum ponto do programa. Em Pascal existem dois tipos de procedimentos: procedure e function. Não confunda procedimento com a tradução de procedure, pois esta última é uma palavra reservada do Pascal, que define um tipo de procedimento. Procedimentos - Procedure O objetivo de se declarar uma procedure é associá-la a um identificador para que a mesma possa ser ativada por um comando do programa. A sua declaração é feita da seguinte forma: procedure nome; declaração dos objetos locais à procedure BEGIN comandos da procedure END; A chamada ou ativação de uma procedure é feita referenciando-se o seu nome no local do programa onde a mesma deve ser ativada, ou seja, onde a sua execução deve ser iniciada. Ao terminar a execução dos comandos de um procedure, a seqüência do programa retorna sempre à instrução seguinte que provocou a sua chamada. A nível de execução, a chamada de uma procedure valeria como se fosse feita uma cópia dos comandos do procedimento no local do programa onde foi ativada, ajustando-se os objetos locais para atender as regras de escopo. Exemplo: program procedimentos; var { declaração das variáveis do programa principal } procedure entrada_de_dados; var { declaração das variáveis do procedimento entrad_de_dados } begin { comandos do procedimento entrada_de_dados } end; procedure processa_dados; var { declaração das variáveis do procedimento processa_dados } begin { comandos do procedimento processa_dados } end; procedure imprime_resultados; var { declaração das variáveis do procedimento imprime_resultados } begin { comandos do procedimento imprime_resultados } end; begin { corpo programa principal } entrada_de_dados; processa_dados; imprime_resultados; end. Este exemplo ilustra como procedimentos podem facilitar o entendimento do programa. Neste caso, o corpo do programa principal se constitui apenas de três chamadas à procedimentos. Funções - Functions As functions são como procedimentos. No entanto, são distintas pela característica de retornar um valor. Isso caracteriza o fato de uma function ser ativada na avaliação de expressões, como as funções matemáticas. Como vimos, a linguagem Pascal possui algumas funções pré-definidas, o que faz com que o programador não tenha que implementá-las. A declaração de uma function tem como objetivo associá-la a um identificador para que possa se ativada em uma expressão do programa. A declaração de uma function é feita da seguinte forma: function nome: t declararão dos objetos locais à function BEGIN comandos da function . . . nome := X; END; t é tipo que a função irá retornar. X é o valor do mesmo tipo t que será retornado pela função. Vemos aqui que o corpo da função precisa necessariamente conter um comando de atribuição no qual o nome da function aparece à esquerda do sinal de atribuição. A ativação de uma function é feita posicionando-se o nome da mesma em uma expressão de mesmo tipo. Exemplo: program exemplo_function; { program que calcula o fatorial de N com a utilização de uma função } var N : integer; function fatorial : integer; var i, acumul : integer; begin acumul := 1; i := 1; while (i <= N) do begin acumul := acumul * i; i := i + 1; end; fatorial := acumul; end; begin write('Digite o valor de N: '); readln(N); writeln('O valor do Fatorial de ',N , ' é = ', fatorial); end. Vimos que as procedures e functions utilizam objetos (variáveis, arquivos, etc) locais (declarados em seu corpo) e objetos globais (declarados nos níveis mais externos). Variáveis globais servem para implementar um mecanismo de transmissão de informações de um nível mais externo para um nível mais interno, como o exemplo do fatorial acima. Analogamente, o mesmo mecanismo pode ser usado inversamente para transmitir informações de dentro para fora dos procedimentos, ou seja, quando se altera o conteúdo de uma variável global dentro de um procedimento, a próxima instrução após o término do procedimento terá disponível o valor da última atualização dentro do procedimento. A utilização de variáveis globais, no entanto, não constitui uma boa prática de programação, visto que podem amarrar os procedimentos (tornando-os dependentes) e quebrar a questão de modularidade. Em um procedimento, as suas variáveis locais tem vida somente durante a sua execução. ou seja, são criadas e alocadas quando no momento da ativação, e liberadas quando de seu término. Além do mais, essas variáveis não podem ser acessadas pelos níveis externos ao procedimento. Então, para transmissão de informações de dentro para fora dos procedimentos a linguagem Pascal utiliza o mecanismo de parâmetros. Por meio dos parâmetros faz-se a comunicação de fora para dentro e de dentro para fora de um procedimento, o que torna o módulos independentes e reutilizáveis em outros programas. Os parâmetros são objetos utilizados dentro do procedimento e representam os objetos do nível mais externo (parâmetros de definição). Para declarar procedures e functions que utilizam parâmetros bastaacrescentar ao cabeçalho a lista de parâmetros a ser utilizada, que deverá estar entre parênteses. Isso é feito da seguinte forma: procedure nome(lista-de-parametros); function nome(lista-de-parametros); lista-de-parametros é da forma: parâmetro1 : tipo, parâmetro2 : tipo, ..., parâmetron: tipo. A ativação de um procedimento se faz por meio de uma referência a seu nome seguido pela lista de parâmetros envolvida por parênteses. Esses parâmetros são conhecidos por parâmetros de chamada, e podem ser constantes, variáveis ou expressões dos módulos externos cujos valores serão transmitidos para os parâmetros de definição do procedimento e após a sua execução receberão de volta, ou não, os valores contidos no parâmetros de definição. Dependendo de como são declarados os parâmetros de definição no procedimento, é determinado se os parâmetros de chamada conterão ou não os valores contidos nos parâmetros de definição. Isso define o modo de passagem dos parâmetros: passagem por referência e passagem por valor. Quando se declara um parâmetro como sendo de referência, as atribuições à ele são refletidas no parâmetro de chamada correspondente, após a execução do procedimento o parâmetro de chamada conterá o mesmo valor que o parâmetro de definição correspondente. Para especificar se um parâmetro terá passagem por referência, a sua declaração deverá ser precedida pela palavra-chave var. Caso a declaração não seja precedida por var, então o parâmetro possui passagem por valor. Neste caso, os parâmetros de definição conterão os mesmos valores de seus parâmetros de chamada correspondente no momento da ativação, mas alterações nos parâmetros de definição não serão refletidas nos parâmetros de chamada correspondente. Pode-se dizer também que um parâmetro com passagem por referência é um parâmetro de entrada e saída, enquanto que um parâmetro com passagem por valor é um parâmetro de entrada. Exemplo: program exemplo_function_2; { program que calcula o fatorial de N com a utilização de uma função com passagem de parâmetros } var N : integer; function fatorial(fat : integer): integer; var i, acumul : integer; begin acumul := 1; i := 1; while (i <= fat) do begin acumul := acumul * i; i := i + 1; end; fatorial := acumul; end; begin write('Digite o valor de N: '); readln(N); writeln('O valor do Fatorial de ',N , ' é = ', fatorial(N)); end. program exemplo_procedure_2; { programa que utiliza uma procedure para ler os valores em uma matriz N x M e uma procedure que imprime os valores de uma matriz M x N } const M = 10; N = 10; type matriz = array[1..M,1..N] of integer; var a : matriz; numlin, numcol : integer; procedure le_matriz(var mat : matriz; lin, col : integer); var i, j : integer; begin for i:= 1 to lin do for j := 1 to col do read(mat[i,j]); end; procedure imprime_matriz(mat : matriz; lin, col : integer); var i, j : integer; begin for i:= 1 to lin do begin for j := 1 to col do write(mat[i,j]:10,' '); writeln; end; end; begin { programa principal } write('Entre com o número de linhas da matriz (<',M, '): '); readln(num_lin); write('Entre com o número de colunas da matriz (<',N, '): '); readln(num_col); le_matriz(a,num_lin,num_col); imprime_matriz(a,num_lin, num_col); end. https://track.lottery.com/visit/?bta=35111&nci=5446 https://www.angelfire.lycos.com/ https://track.lottery.com/visit/?bta=35111&nci=5440 https://www.angelfire.lycos.com/ https://track.lottery.com/visit/?bta=35111&nci=5440
Compartilhar