Você está na página 1de 81

UNIVERSIDADE REGIONAL INTEGRADA URUGUAI E DAS MISSES

DEPARTAMENTO
DE

DO

ALTO

CAMPUS FREDERICO WESTPHALEN


ENGENHARIAS E CINCIA DA COMPUTAO

Linguagem de Programao II
C, Pascal e Delphi

Cincia da Computao III

Prof. Evandro Preuss preuss@fw.uri.br http://www.uri.br/~preuss

2009

SUMRIO 1. 2. INTRODUO .................................................................................................................... 5 DADOS .................................................................................................................................. 6

5.2.2 Argumentos das funes .............................................................................................. 38 5.2.3 Tipos de funes........................................................................................................... 40 5.3 ARGUMENTOS PASSADOS A PROGRAMAS ........................................................................... 42 5.3.1 Argumentos passados a programas em PASCAL ........................................................ 42 5.3.2 Argumentos passados a programas em C.................................................................... 42 6. 6.1 6.2 6.3 6.4 7. MATRIZES......................................................................................................................... 44 MATRIZES EM PASCAL....................................................................................................... 44 MATRIZES EM C ................................................................................................................ 45 STRINGS ............................................................................................................................ 46 MATRIZES E VETORES COMO PARMETROS DE FUNES ................................................... 47 DELPHI............................................................................................................................... 50

2.1 ELEMENTOS DA LINGUAGEM ............................................................................................... 6 2.1.1 Elementos definidos pela linguagem: ............................................................................ 6 2.1.2 Elementos definidos pelo Usurio ................................................................................. 8 2.2 TIPOS DE DADOS ................................................................................................................. 8 2.2.1 Tipos predefinidos pela linguagem................................................................................ 8 2.2.2 Tipos definidos pelo usurio........................................................................................ 10 2.3 CONVERSES DE TIPOS DE DADOS ..................................................................................... 10 2.4 CONSTANTES E VARIVEIS ................................................................................................ 11 2.4.1 Constantes.................................................................................................................... 11 2.4.2 Variveis ...................................................................................................................... 12 2.4.3 Classes de armazenamento .......................................................................................... 12 2.5 OPERADORES..................................................................................................................... 13 2.5.1 Operadores aritmticos ............................................................................................... 13 2.5.2 Operadores de atribuio ............................................................................................ 13 2.5.3 Operadores relacionais e lgicos ................................................................................ 13 2.5.4 Operadores bit a bit ..................................................................................................... 14 2.5.5 Operadores de incremento e decremento .................................................................... 15 2.5.6 Operador Condicional ................................................................................................. 15 2.5.7 Operador Vrgula......................................................................................................... 16 3. ESTRUTURA DO PROGRAMA...................................................................................... 17 3.1 ESTRUTURA DE UM PROGRAMA EM PASCAL ..................................................................... 17 3.1.1 Identificao do programa .......................................................................................... 17 3.1.2 Bloco de Declaraes .................................................................................................. 17 3.1.3 Bloco de Comandos ..................................................................................................... 18 3.2 ESTRUTURA DE UM PROGRAMA EM C ............................................................................... 18 3.2.1 Bloco de Diretivas de Compilao .............................................................................. 18 3.2.2 Bloco de Declaraes: ................................................................................................. 19 3.2.3 Bloco de Implementao:............................................................................................. 19 4. COMANDOS ...................................................................................................................... 20 4.1 COMANDOS SIMPLES ......................................................................................................... 20 4.1.1 Comandos de Entrada e Sada..................................................................................... 20 4.1.2 Comandos de Desvio Incondicional ............................................................................ 25 4.2 ESTRUTURAS DE CONTROLE .............................................................................................. 26 4.2.1 Seqncia ..................................................................................................................... 26 4.2.2 Comandos condicionais ............................................................................................... 26 4.2.3 Comandos de Repetio............................................................................................... 31 5. FUNES E PROCEDIMENTOS................................................................................... 37 5.1 PROCEDIMENTOS ............................................................................................................... 37 5.1.1 Passagem de parmetros ............................................................................................. 37 5.2 FUNES ........................................................................................................................... 38 5.2.1 Estilos e prottipos das funes................................................................................... 38

7.1 CONCEITOS BSICOS.......................................................................................................... 51 7.1.1 Programao em Windows: Janelas e eventos............................................................ 51 7.2 PROGRAMAO ORIENTADA A OBJETO (POO) ................................................................. 51 7.3 O AMBIENTE DO DELPHI .................................................................................................... 52 7.3.1 Arquivos que Compem um Aplicao ........................................................................ 52 7.3.2 Arquivos Gerados pela Compilao ............................................................................ 53 7.4 CDIGO FONTE DO ARQUIVO PROJECT(.DPR).................................................................... 53 7.5 CDIGO FONTE DO ARQUIVO UNIT (.PAS) ......................................................................... 53 7.5.1 Seo Unit.................................................................................................................... 53 7.5.2 Seo Uses ................................................................................................................... 54 7.5.3 Seo Interface............................................................................................................ 54 7.5.4 Seo Type ................................................................................................................... 54 7.5.5 Seo Var ..................................................................................................................... 54 7.5.6 Seo Implementation .................................................................................................. 54 7.5.7 Seo uses adicional .................................................................................................... 55 7.5.8 Inicialization ................................................................................................................ 55 7.5.9 Exemplo........................................................................................................................ 55 7.6 CODE EDITOR (EDITOR DE CDIGO).................................................................................. 56 7.7 FORM (FORMULRIO)........................................................................................................ 56 7.8 OBJECT INSPECTOR (INSPETOR DE OBJETOS) ..................................................................... 57 7.9 COMPONENT PALETTE( PALHETA DE COMPONENTES) ....................................................... 58 7.10 COMPONENTES .................................................................................................................. 58 7.10.1 Nomenclatura .......................................................................................................... 58 7.10.2 Propriedades ........................................................................................................... 58 7.10.3 Eventos..................................................................................................................... 59 7.10.4 Mtodos ................................................................................................................... 60 7.10.5 Forms (janelas)........................................................................................................ 60 7.10.6 TMainMenu ............................................................................................................. 61 7.10.7 TPopUpMenu........................................................................................................... 62 7.10.8 TLabel...................................................................................................................... 62 7.10.9 TEdit ........................................................................................................................ 62 7.10.10 TMemo ..................................................................................................................... 62 7.10.11 TButton .................................................................................................................... 63 7.10.12 TCheckBox............................................................................................................... 63 7.10.13 TRadioButton........................................................................................................... 63 7.10.14 TListBox................................................................................................................... 63 7.10.15 TComboBox ............................................................................................................. 64

7.10.16 TScrollBox ............................................................................................................... 64 7.10.17 TGroupBox .............................................................................................................. 64 7.10.18 TRadioGroup ........................................................................................................... 64 7.10.19 TPanel...................................................................................................................... 64 7.10.20 TActionList .............................................................................................................. 65 7.10.21 TBitBtn..................................................................................................................... 65 7.10.22 TMaskEdit................................................................................................................ 65 7.10.23 TBevel ...................................................................................................................... 66 7.10.24 TShape ..................................................................................................................... 66 7.10.25 TImage ..................................................................................................................... 66 7.10.26 TPageControl .......................................................................................................... 66 7.10.27 TTabSheet ................................................................................................................ 66 7.10.28 TTimer ..................................................................................................................... 66 7.10.29 TStatusBar ............................................................................................................... 67 7.10.30 TStatusPanels .......................................................................................................... 67 7.10.31 TStatusPanel............................................................................................................ 67 7.10.32 TStringGrid.............................................................................................................. 67 7.11 CAIXAS DE MENSAGEM ..................................................................................................... 68 7.11.1 ShowMessage........................................................................................................... 68 7.11.2 MessageBox ............................................................................................................. 68 7.11.3 InputBox................................................................................................................... 69 7.12 DICAS ................................................................................................................................ 70 7.13 EXEMPLOS DE PROGRAMAS EM DELPHI ............................................................................. 73 8. ESTRUTURAS, UNIES E ITENS DIVERSOS............................................................ 78 8.1 ESTRUTURAS ..................................................................................................................... 78 8.1.1 Passando uma estrutura para uma funo .................................................................. 79 8.1.2 Matriz de Estruturas .................................................................................................... 79 8.1.3 Estruturas dentro de estruturas ................................................................................... 80 8.1.4 Ponteiros para estruturas ............................................................................................ 81 8.1.5 Estruturas em Pascal e Delphi .................................................................................... 82 8.2 UNIES .............................................................................................................................. 84 8.3 ITENS DIVERSOS................................................................................................................. 85 8.3.1 typedef .......................................................................................................................... 85 8.3.2 enum............................................................................................................................. 86 9. ARQUIVOS......................................................................................................................... 87 9.1 ARQUIVO TIPADO EM DELPHI E PASCAL ............................................................................ 87 9.1.1 Declarao de arquivos ............................................................................................... 87 9.1.2 Funes de abertura e fechamento de arquivos .......................................................... 88 9.1.3 Funes de escrita e gravao..................................................................................... 90 9.2 ARQUIVOS TEXTO EM PASCAL E DELPHI ........................................................................... 95 9.2.1 Funes para manipulao de arquivos texto ............................................................. 97 9.3 ARQUIVOS SEM TIPOS EM PASCAL E DELPHI ....................................................... 99 9.3.1 Funes para manipulao de arquivos sem tipos...................................................... 99 9.3.2 Arquivos com diversas estruturas em Pascal e Delphi.............................................. 100 9.4 ARQUIVOS EM C .............................................................................................................. 103 9.4.1 Declarao de arquivos ............................................................................................. 105 9.4.2 Funes de abertura e fechamento de arquivos ........................................................ 105 9.4.3 Funes de escrita e gravao................................................................................... 106

9.4.4 Funes de Escrita e Gravao em Arquivos Texto .................................................. 108 9.4.5 Funes "fseek" , "ftell" e "rewind"........................................................................... 111 9.4.6 Arquivos com diversas estruturas .............................................................................. 112 9.5 RESUMO DO USO DE ARQUIVOS TIPADOS EM PASCAL ..................................................... 114 9.6 MANIPULAO DE ARQUIVOS COM DELPHI..................................................................... 121 10. PONTEIROS..................................................................................................................... 129 10.1 DEFINIO DE PONTEIROS ............................................................................................... 129 10.1.1 Declarao de variveis tipo ponteiro .................................................................. 130 10.1.2 Usando variveis tipo ponteiro ............................................................................. 131 10.1.3 Inicializando variveis do tipo ponteiro................................................................ 132 10.1.4 Limitaes no operador de endereos................................................................... 133 10.1.5 Ponteiros para matrizes......................................................................................... 133 10.1.6 Ponteiros para ponteiros ....................................................................................... 134 10.1.7 Aritmtica com ponteiros....................................................................................... 135 10.2 PONTEIROS PARA FUNES .............................................................................................. 135 10.3 PONTEIROS EM PASCAL ................................................................................................... 137 11. ALOCAO DINMICA DE MEMRIA .................................................................. 140 11.1 11.2 LISTA ENCADEADA COM ALOCAO DINMICA DE MEMRIA:......................................... 143 EXEMPLO DE UTILIZAO DE ALOCAO DINMICA DE MEMRIA COM DELPHI .............. 150

12. EXERCCIOS................................................................................................................... 157

1. INTRODUO
C uma linguagem de programao que foi desenvolvida por Dennis Ritchie durante o comeo dos anos 70 para ser usada na implementao de sistemas operacionais e outras tarefas de programao de baixo nvel. Em 1960 um comit de cientistas europeus definiu a linguagem Algol. Em meados dos anos 60 pesquisadores da Universidade de Cambridge desenvolveram a linguagem BCPL na tentativa de terem um Algol simplificado. Ainda nos anos 60, Dennis Ritchie desenvolveu a linguagem B a partir da BCPL. Em 1971 ritchie e thompson escreveram a primeira verso da linguagem C. O desenvolvimento inicial de C ocorreu entre 1969 e 1973 (de acordo com Ritchie, o perodo mais criativo foi durante 1972). Em 1973 ela tornou-se poderosa o suficiente para reimplementar o kernel do sistema operacional Unix. Em 1978, Brian Kernighan e Dennis Ritchie publicaram o agora bastante conhecido "C Programming Language" (tambm conhecido como "o livro branco", K&R). C tornou-se imensamente popular fora do Bell Labs depois de 1980 e foi por um tempo a linguagem dominante em programao de sistemas e de aplicaes de micro-computadores. Ela se consagrou como a linguagem de programao de sistemas, e a mais importante da comunidade Open Source. Bjarne Stroustrup e outros no Bell Labs trabalharam no final dos anos 80 para adicionar a orientao a objetos ao C, criando uma linguagem chamada C++. C++ agora a linguagem mais comum para aplicaes comerciais nos sistemas Microsoft Windows, embora C permanea mais popular no mundo Unix. Implementaes de C no checam erros tais como buffer overflow ou acesso a memria no alocada em tempo de execuo. Ferramentas tm sido criadas para ajudar programadores a evitar esses erros. Foi chamada "C" porque apresenta muitas caractersticas derivadas de uma linguagem anterior chamada B, em homenagem ao seu parente, BCPL. BCPL, por sua vez, descendeu de uma linguagem derivada do Algol, CPL. A linguagem de programao C foi padronizada na forma de um padro ISO, ISO 9899. A primeira edio do ISO deste documento foi publicado em 1990 (ISO 9899:1990) e foi uma pequena modificao de um padro ANSI um pouco anterior, ANSI X3.159-1989 "Programming Language C". Edies seguintes tm sido feitas, algumas das quais tm sido amplamente ignoradas.

2. DADOS
2.1 Elementos da Linguagem
Normalmente uma linguagem de programao possui dois tipos de elementos: os elementos definidos pela linguagem e os elementos definidos pelo prprio usurio:

2.1.1 Elementos definidos pela linguagem:


2.1.1.1 Letras (alfanumricas) - PASCAL e C: A at Z a at z 2.1.1.2 Dgitos (numricos) - PASCAL e C: 0 at 9 2.1.1.3 Smbolos Especiais Todas as linguagens possuem smbolos especiais que so diferentes em cada linguagem, mas que tem a mesma finalidade: Pascal + * / = > < >= <= <> := ( ) { ou (* } ou *) ; ' C + * / == > < >= <= != = ( ) /* */ ; " ou ' Significado adio subtrao multiplicao diviso comp. igualdade maior que menor que maior ou igual menor ou igual diferente atribuio parnteses incio de comentrio final de comentrio separador demarca strings ou caracteres

Linguagem de Programao II - URI Campus de Frederico Westphalen

Linguagem de Programao II - URI Campus de Frederico Westphalen

2.1.1.4 Palavras Reservadas ou Palavras Chave Palavras Reservadas so smbolos que possuem significado definido na linguagem, no podendo ser redefinidos ou usado como nome de identificador. PASCAL array const downto file goto label not packed record then until with C break const do enum for int return sizeof switch unsigned while

2.1.2 Elementos definidos pelo Usurio


2.1.2.1 Identificadores Um identificador um smbolo definido pelo usurio que pode ser um rtulo (label), uma constante, um tipo, uma varivel, um nome de programa ou subprograma (procedimento ou funo). Os identificadores normalmente devem comear com um caractere alfabtico e no pode conter espaos em branco. O nmero mximo de caracteres que podem format o identificador varia de compilador para compilador. No PASCAL padro somente os 8 primeiros caracteres so vlidos; no TURBO PASCAL pode-se usar identificadores de at 127 caracteres sendo todos significativos e no h distino entre maisculas e minsculas. No C somente os 32 primeiros caracteres so significativos e h diferena entre maisculas e minsculas. Em C Cont diferente de cont que diferente de CONT. 2.1.2.2 Comentrios Os comentrios no tem funo nenhuma para o compilador e serve apenas para aumentar a legibilidade e clareza do programa. 2.1.2.3 Endentao A endentao tambm no tem nenhuma funo para o compilador e serve para tornar a listagem do programa mais clara dando hierarquia e estrutura ao programa.

and case do end function in nil or program set type while

begin div else for if mod of procedure repeat to var

auto char default else float if register signed struct union volatile

case continue double extern goto long short static typedef void

Na linguagem C, o restante dos comandos so todos funes (da biblioteca padro ou no). Todas as palavras reservadas devem ser escritas em minsculo. A linguagem Pascal tem ainda alguns identificadores predefinidos pela linguagem conhecidos como Identificadores Padro. Podem ser constantes, tipos, variveis ou subprogramas (procedimentos ou funes) e podem ser escritos tanto em minsculo como em maisculo: abs eof ln read sin true arqtan eoln maxint readln sqr trunc boolean exp odd real sqrt write char false ord reset str writeln chr input output rewrite succ cos integer pred run text

2.2 Tipos de Dados


Um Tipo de Dado define o conjunto de valores que uma varivel pode assumir e as operaes que podem ser feitas sobre ela. Toda varivel em um programa deve ser associada a um e somente um tipo de dado. Esta associao feita quando a varivel declarada na parte de declarao de variveis do programa.

2.1.1.5 Delimitadores Os elementos da linguagem (identificadores, nmeros e smbolos especiais) devem ser separados por pelo menos um dos seguintes delimitadores: branco, final de linha ou comentrio.

2.2.1 Tipos predefinidos pela linguagem


PASCAL tipo shortint byte integer word intervalo de representao -128 a 127 0 a 255 -32.768 a 32.767 0 a 65.535 tamanho 1 byte 1 byte 2 bytes 2 bytes 8

Linguagem de Programao II - URI Campus de Frederico Westphalen

Linguagem de Programao II - URI Campus de Frederico Westphalen

-2.147.483.648 a 2.147.483.647 4 bytes 2.9 x 10 39 a 1.7 x 10 38 6 bytes 1.5 x 10 45 a 3.4 x 10 38 4 bytes 5.0 x 10 324 a 1.7 x 10 308 8 bytes 1.9 x 10 4951 a 1.1 x 10 4932 10 bytes -9.2 x 10 18 a 9.2 x 10 18 8 bytes os caracteres da tabela ASCII 1 byte TRUE ou FALSE 1 byte tipo estruturado composto por um quantidade de caracteres x 1 byte conjunto de elementos tipo char * os tipos assinalados somente podem ser utilizados em mquinas com co-processador matemtico (8087, 80287, 80387, 80487) ou com chip processador 80486 DX ou superior. DELPHI tipo shortint byte smallint word integer ou longint cardinal ou longword int64 real * single double extended comp ** char boolean string intervalo de representao -128 a 127 0 a 255 -32.768 a 32.767 0 a 65535 -2.147.483.648 a 2.147.483.647 0 a 4294967295 tamanho 1 byte 1 byte 2 bytes 2 bytes 4 bytes 4 bytes

longint real single * double * extended * comp * char boolean string

tipo long int long double tipo unsigned char unsigned int unsigned long int

Modificadores de Tipo Modificador Long intervalo de representao -2.147.483.647 a 2.147.483.647 4 bytes 1.2 E-4932 a 1.2 E4932 10 bytes Modificador Unsigned intervalo de representao 0 a 255 1 byte 0 a 65.535 2 bytes 0 a 4.294.967.295 4 bytes

tamanho

tamanho

2.2.2 Tipos definidos pelo usurio


Os tipos definidos pelo usurio so aqueles que usam um grupo de tipos predefinidos ou um subgrupo de algum tipo. Este tipo chamado de tipo enumerado de dados e representa uma escolha dentre um pequeno nmero de alternativas. 2.2.2.1 Tipo enumerado discreto Em Pascal temos o comando TYPE para definir o tipo de dados que queremos:
TYPE tpdias = (segunda, tera, quarta, quinta, sexta, sbado, domingo); VAR diasem: tpdias; diasem:= segunda; if (diasem = tera) then ...

-2 63 a 2 63 8 bytes 2.9 x 10 39 a 1.7 x 10 38 6 bytes 1.5 x 10 45 a 3.4 x 10 38 4 bytes 5.0 x 10 324 a 1.7 x 10 308 8 bytes 1.9 x 10 4932 a 1.1 x 10 4932 10 bytes -2 63 a 2 63 8 bytes os caracteres da tabela ASCII 1 byte TRUE ou FALSE 1 byte tipo estruturado composto por um quantidade de caracteres x 1 byte conjunto de elementos tipo char * Apenas para manter compatibilidade com Pascal. Este tipo no nativo para processadores Intel e as operaes com este tipo so mais lentas que os demais. ** O mesmo que um inteiro de 64 bits (int64) C tipo char int float double void intervalo de representao -128 a 127 -32.768 a -32767 3.4 E-38 a 3.4 E38 1.7 E-308 a 1.7 E308 tamanho 1 byte 2 bytes 4 bytes 8 bytes 9

Em C e C++ temos o comando enum


enum tpdias { segunda, tera, quarta, quinta, sexta, sbado, domingo } diasem

2.2.2.2 Tipo enumerado contnuo O tipo enumerado contnuo pode ser definido como um intervalo de um tipo enumerado discreto j definido ou de um tipo padro.
TYPE tpdias = (segunda, tera, quarta, quinta, sexta, sbado, domingo); TYPE tpfimsem = sbado..domingo; TYPE tpdiautil = segunda..sexta; VAR fimsem: tpfimsem; fimsem:= sbado; if (fimsem = domingo) then ...

2.3 Converses de tipos de dados


As operaes que usam comandos que envolvem variveis de diferentes tipos so chamadas de operaes de modo misto.
Linguagem de Programao II - URI Campus de Frederico Westphalen

Linguagem de Programao II - URI Campus de Frederico Westphalen

10

Ao contrrio das outras linguagens, C e C++ executam converses automticas de dados para um tipo maior ou trunca o valor para um tipo menor. Devemos ter cuidado quando usamos operaes de modo misto em C ou C++, pois os valores podem ser truncados, enquanto que no Pascal devemos prever exatamente o tipo da varivel que necessitamos, por exemplo: PASCAL:
a, b:integer; c: real; a:=5; b:=3; c:=a/b; c = 1,66666667

2.4.2 Variveis
Uma declarao de varivel consiste do nome do tipo seguido do nome da varivel (em C e C++) ou do nome da varivel seguido do nome do tipo (em Pascal). Todas as variveis devem ser declaradas antes de serem usadas. As variveis devem ser declaradas no incio de cada funo, procedimento ou incio do programa. No podem ocorrer declaraes de variveis aps a primeira sentena executvel de uma rotina. As variveis podem ser globais ou locais. Variveis globais so declaradas fora de qualquer funo, valem em qualquer ponto do cdigo, so inicializadas com zero automaticamente e uma nica vez, so armazenadas na memria. Variveis locais so declaradas dentro das funes, existem apenas enquanto a funo na qual foi declarada est ativa. Dentro de funes variveis locais com mesmo nome de variveis globais tem preferncia, no so inicializadas automaticamente, ou seja, deve-se informar um valor inicial, so alocadas na pilha ("stack"). Os parmetros das funes so tratados como se fossem variveis locais, so inicializados com o valor passado na chamada, so declarados na lista de parmetros, so passados por valor, somente tipos escalares de dados podem ser parmetros.

C:
int a, b; float c; c=a/b; c=1,000000

C:
float a, b; int c; a=5; b=3; c=a/b; c=1

C:
int a; float b,c; a=5; a=5; b=3; b=3; c=a/b; c=1,666667

A linguagem C e C++ permitem a converso temporria dos tipos de variveis atravs do operador de converso. Sempre que voc necessitar a mudar o formato de uma varivel temporariamente, simplesmente preceda o identificador da varivel com o tipo entre parnteses para aquele que quiser converter. Se utilizarmos o primeiro exemplo de C acima podemos obter o resultado esperado usando um operador de converso ou cast:
int a, b; float c; a=5; b=3; c=(float)a/b; c=1,666667

2.4.3 Classes de armazenamento


Em C e C++ as variveis tem diferente classes de armazenamento: auto: varivel automtica. criada quando uma rotina chamada e destruda quando a rotina termina. a classe default para variveis locais a funes. register: pede ao compilador para colocar uma varivel em registrador. O compilador pode, ou no, seguir a "dica" dada pelo programador. muito comum seu uso em variveis de controle de laos "for". O operador endereo (&) no pode ser aplicada a uma varivel de classe register. static: o contrrio da varivel "auto". Uma varivel "static" alocada na rea de dados e sempre existe, mantendo seu contedo entre as chamadas de uma rotina.
ex: void teste() { static int x=0; x++; }

2.4 Constantes e Variveis


2.4.1 Constantes
Constantes so valores declarados no incio do programa e que no se alteram na execuo do programa. Podem ser expessas em qualquer base, desde que seguidas algumas regras simples: 1. Constantes em octal na linguagem C devem sempre iniciar com um 0, como em mem = 01777 2. Constantes em hexa na linguagem C devem sempre iniciar com 0x ou 0X, como em mem = 0x1FA 3. Constantes em hexa na linguagem Pascal devem sempre iniciar com $, como em mem = $1FA 4. Constantes em decimal so escritas de modo convencional sem se inicarem com 0

Neste caso a inicializao somente ser feita na primeira evocao da rotina. O valor de "x" sobreviver de uma chamada para outra da rotina (cada vez que for chamada, "x" aumentar de valor).

Linguagem de Programao II - URI Campus de Frederico Westphalen

11

Linguagem de Programao II - URI Campus de Frederico Westphalen

12

Se uma varivel global possui o atributo "static" significa que ela somente poder ser usada no arquivo onde est declarada, sendo invisvel a outros arquivos que componham o sistema. extern: significa que a varivel est declarada em outro arquivo, onde sua rea alocada. utilizada para variveis globais a diferentes arquivos componentes de um mesmo projeto (programa). volatile: informa ao compilador para no otimizar o uso de uma varivel colocando-a em registrador. utilizado quando uma varivel pode ser atualizada concorrentemente por mais de um processo.

> < >= <= = <>

maior que menor que maior ou igual menor ou igual igual diferente

> < >= <= == !=

maior que menor que maior ou igual menor ou igual igual diferente

Os operadores lgicos so usados para combinar expresses relacionais. Tambm devolvem como resultado valores lgicos verdadeiro ou falso. PASCAL e DELPHI and or not xor e ou no ou exclusivo && || ! ^ C e ou no ou exclusivo

2.5 Operadores
2.5.1 Operadores aritmticos
PASCAL e DELPHI + * / MOD DIV soma subtrao multiplicao diviso resto da diviso inteira inteiro da diviso + * / % C soma subtrao multiplicao diviso resto da diviso inteira

Uma expresso relacional ou lgica em C ou C++, retornar zero para o valor lgico falso e um para o valor lgico verdade. No entanto, qualquer valor diferente de zero ser considerado um valor verdade quando inserido em uma expresso lgica.

2.5.4 Operadores bit a bit


Em C e C++ temos os operadores bit a bit. So operadores capazes de alterar os valores dos bits de uma varivel. Funcionam apenas com os tipos char e int.

2.5.2 Operadores de atribuio


Em Pascal e Delphi temos o operador de atribuio: := Em C e C++ temos os seguintes operadores de atribuio: =
Ex: i=2; i+=4; x *= y+1; p %= 5;

PASCAL e DELPHI and or not xor SHR SHL Exemplos:


C

C & | ~ ^ >> <<

OPERAO e ou no ou exclusivo shift para direita (diviso por 2) shift para esquerda (multiplicao por 2)

+=

*=

/=

%=

> atribui o nmero 2 varivel i > i=i+4; > x=x*(y+1); > p = p % 5;

2.5.3 Operadores relacionais e lgicos


Os operadores relacionais so operadores binrios que devolvem os valores lgicos verdadeiro e falso. PASCAL e DELPHI
Linguagem de Programao II - URI Campus de Frederico Westphalen

Pascal

char a, b, c;
a=1; b=3;

a, b, c: byte
a:=1; b:=3

C 13
Linguagem de Programao II - URI Campus de Frederico Westphalen

14

(C) c = a & b

00000001 & 00000011 00000001 (Pascal) c:= a and b (C) c = ~a ~ 00000001 11111110 (Pascal) c:= not a (C) c = b >> 1 00000011 00000001 (Pascal) c:= b shr 1

(C) c = a | b (Pascal) c:= a or b (C) c = a ^ b

00000001 | 00000011 00000011

2.5.7 Operador Vrgula


Em C e C++ o operador vrgula avalia duas expresses onde a sintaxe permite somente uma. O valor do operador vrgula o valor da expresso direita. comumente utilizado no lao for, onde mais de uma varivel utilizada. Por exemplo:
for(min=0, max=compr-1; min < max; min++, max--) { ... }

00000001 ^ 00000011 00000010 (Pascal) c:= a xor b (C) c = b << 1 00000011 00000110 (Pascal) c:= b shl 1

2.5.5 Operadores de incremento e decremento


Em C e C++ tambm temos os operadores de incremento e decremento: ++ -incremento de um decremento de um

Escrever "m++" ou "++m" quando estes se encontram isolados em uma linha no faz diferena. Quando estiverem sendo usados em conjunto com uma atribuio, entretanto: Ex:
int m, n; m = 5; n = 4; m = n++; Res: m = 4 n = 5 m = ++n; m = 5 n = 5

Obs.: A declarao:

printf("%d %d %d",n,n++,n+1);

est correta, porm o resultado pode variar de acordo com o compilador dependendo da ordem em que os parmetros so retirados da pilha (stack).

2.5.6 Operador Condicional


O operador condicional ternrio pode ser utilizado em C e C++ quando o valor de uma atribuio depende de uma condio. O operador ternrio sibolizado pelo operador: ? Exemplo:
if (x>3) k = k + 1; else k = s - 5;

pode ser substitudo por:


k=(x>3)? k+1: s-5; Linguagem de Programao II - URI Campus de Frederico Westphalen

15

Linguagem de Programao II - URI Campus de Frederico Westphalen

16

Serve para o programadore criar seus prprios tipos de dados.

3. ESTRUTURA DO PROGRAMA
3.1 Estrutura de um Programa em Pascal
Normalmente um programa Pascal possui trs partes distintas: Identificao do programa, Bloco de declaraes e Bloco de comandos.

A declarao dos tipos iniciadas pela palavra reservada TYPE, seguida de um ou mais identificadores separados por vrgula, um sinal de igual, um tipo e um ponto e vrgula: TYPE <tipoident1> , ... , <tipoidentn> = <tipo> ; 3.1.2.4 Parte de Declaraes de Variveis: Quando declaramos uma varivel temos que definir, alm do nome, seu tipo. O tipo especifica os valores que podero ser atribudos a esta varivel. O tipo pode ser algum dos tipos predefinidos pela linguagem ou um tipo definido pelo usurio. A declarao das variveis iniciada pela palavra reservada VAR, seguida de um ou mais identificadores, separados por vrgula, um tipo um ponto e vrgula: VAR < ident1> , ... , <identn> : <tipo> ; 3.1.2.5 Parte de Declaraes de Subprogramas: Nesta parte so declarados e implementados os subprogramas (funes e procedimentos) e devem estar declarados e implementados antes da sua chamada em qualquer parte do programa principal ou de subprogramas.

3.1.1 Identificao do programa


A identificao ou cabealho do programa em Pascal d um nome ao programa e lista seus parmetros. a primeira linha do programa. PROGRAM <identificao> ( <lista de parmetros> );

3.1.2 Bloco de Declaraes


Todo identificador definido pelo usurio em um programa deve ser declarado antes de referenciado (usado), caso contrrio o compilador acusar um erro na fase de compilao por desconhecer o identificador. O Bloco de Declaraes define todos os identificadores utilizados pelo Bloco de Comandos, sendo todos opcionais. Quando o Bloco de Delaraes existir sempre estar antes do Bloco de Comandos. Em Pascal o Bloco de Declaraes formado por cinco partes: 3.1.2.1 Parte de Declaraes de Rtulos: Rtulos (labels) existem para possibilitar o uso do comando de desvio incondicional GOTO. Este comando comando gera a desestruturao do programa e no aconselhado seu uso. LABEL <rotulo1>, ... , <rotulon>; 3.1.2.2 Parte de Declaraes de Constantes: Define os identificadores que tero valores constantes dureante toda a esxecuo do programa, podendo ser nmeros, seqncias de caracteres (strings) ou mesmo outras constantes. A declarao de constantes inicia pela palavra reservada CONST, seguida po uma seqncia de: identificador, um sinal de igual, o valor da constante e um ponto e vrgula: CONST <identificador> = <valor> ; 3.1.2.3 Parte de Declaraes de Tipos:
Linguagem de Programao II - URI Campus de Frederico Westphalen

3.1.3 Bloco de Comandos


O Bloco de Comandos a ltima parte que compe um programa em Pascal e especifica as aes a serem executadas sobre os objetos definidos no Bloco de Declaraes. O Bloco de Comandos tambm conhecido como programa principal e iniciado pela palavra reservada BEGIN seguida de por uma seqncia de comandos e finalizada pela palavra reservada END seguida um ponto.

3.2 Estrutura de um Programa em C


Normalmente um programa em C possui trs partes distintas: Bloco de Diretivas de Compilao, Bloco de declaraes e Bloco de Implementao

3.2.1 Bloco de Diretivas de Compilao


Como a linguagem C no possui nenhum comando de entrada e sada incorporado linguagem, todas essas operaes so realizadas atravs de funes que encontram-se nas bibliotecas da linguagem. Para utilizar essas funes dentro do programa necessrio incluir o cabealho das funes no incio do programa atravs da diretiva de compilao #include:

17

Linguagem de Programao II - URI Campus de Frederico Westphalen

18

#include <stdio.h> /* inclui a biblioteca padro de comandos de entrada e sada que se encontra no diretrio padro*/ #include outros.h /*inclui uma outra bliblioteca criada pelo usurio que se encontra no diretrio corrente */ Tambm nesse bloco podemos definir as macros para o nosso programa. Uma macro pode ser simplesmente a substituio de um texto como a implementao de uma pequena funo, por exemplo: #define MAXINT 32767 #define triplo(x) ((x)*3) #define pqt Pressione Qualquer Tecla Para Continuar...

4. COMANDOS
4.1 Comandos Simples
Os comandos simples ou no estruturados, caracterizam-se por no possurem outros comandos relacionados.

4.1.1 Comandos de Entrada e Sada


4.1.1.1 Comandos de E/S em Pascal A linguagem Pascal tem definido os comandos de entrada e sada na prpria linguagem. 4.1.1.1.1 Read e Readln Os comandos de Leitura (entrada) associam valores lidos do teclado ou de arquivos para as variveis. So eles: READ ( <var1>, ... , <varn> ); READLN ( <var1>, ... , <varn> ); 4.1.1.1.2 Write e Writeln Os comandos de gravao (sada) transferem para os dispositivos de sada (disco, video ou impressora) os valores das variveis. Para mostrar valores no video temos os seguintes comandos: WRITE ( <var1> , <texto1> , ... , < texto n>, <varn>); WRITELN ( <var1> , <texto1> , ... , < texto n>, <varn>); Para imprimir valores na impressora temos os seguintes comandos: WRITE (LST, <var1> , <texto1> , ... , < texto n>, <varn>); WRITELN (LST, <var1> , <texto1> , ... , < texto n>, <varn>); Para gravar valores em arquivos temos os seguintes comandos: WRITE (<arq>, <var1> , <texto1> , ... , < texto n>, <varn>); WRITELN (<arq>, <var1> , <texto1> , ... , < texto n>, <varn>);

3.2.2 Bloco de Declaraes:


No bloco das declaraes so declaradas todas as variveis globais, tipos definidos pelo usurio, estruturas, unies e declaradas todas as funes (exceto a main) que esto implementadas no programa, atravs de um prottipo (cabealho) da mesma. int soma(int x, int y); int num, quant; char nome[50];

3.2.3 Bloco de Implementao:


No bloco de implementaes so implementadas todas as funes que compem o programa. Inicialmente se implementa a funo principal, que a primeira a ser executada e logo abaixo todas as demais funes.
void main() { printf(Ol mundo!); }

Linguagem de Programao II - URI Campus de Frederico Westphalen

19

Linguagem de Programao II - URI Campus de Frederico Westphalen

20

char c; double d;

4.1.1.1.3 Readkey O comando READKEY l um caracter do teclado e associa a uma varivel do tipo char. 4.1.1.2 Comandos de E/S em C A linguagem C no possui nenhum comando de entrada e sada predefinido na linguagem. Todas as operaes de E/S so realizadas por funes que encontram-se nas mais diversas bibliotecas. As principais funes so: 4.1.1.2.1 A funo printf() A funo printf a funo para sada formatada de dados e funciona da seguinte forma: o primeiro argumento uma string entre aspas (chamada de string de controle) que pode conter tanto caracteres normais como cdigos de formato que comeam pelo caracter de porcentagem. Caracteres normais so apresentados na tela na ordem em que so encontrados. Um cdigo de formato informa a funo printf que um item no caracter deve ser mostrado. Os valores correspondentes encontram-se no segundo argumento (lista de argumentos). SINTAXE: printf(<string de controle>,<lista de argumentos>);

printf(%d %f %c %lf,a,b,c,d);

Sintaxe completa de um cdigo de formato: %[flags][largura][.preciso][tamanho]<tipo> <tipo> indica o tipo do valor a ser exibido. Listados acima. [flags]: - + indica alinhamento pela esquerda fora os nmeros a comearem por + ou -

os negativos ficam com o sinal de - e os positivos com um espao em branco no lugar do sinal. [largura]: n indica o nmero mximo de casas a ocupar.

Obs.: Alm de cdigos de formato e caracteres normais a string de controle pode conter ainda caracteres especiais iniciados pelo smbolo \. Exemplos:
printf(O preo R$ %d,00,preco); printf(So %d horas e %d minutos., hora, minuto); printf(O nome %s.,nome); printf(%d dividido por %d igual a %f, n1, n2, (float)n1/n2); printf(O cdigo de %c %d, letra, letra);

0n idntico ao anterior, apenas com a diferena de que as casas no ocupadas sero preenchidas com zeros. [preciso]: n [tamanho]: l long indica o nmero de casas aps a vrgula.

Cdigos de formato: Normalmente os cdigos de formato so utilizados na sua forma mais simples: %c %ld %o %x caracter simples inteiro longo octal hexadecima %d %f %s %lf decimal ponto flutuante cadeia de caracteres double

Caracteres especiais: Alguns caracteres, como o de tabulao, no possuem representao grfica na tela. Por razes de compatibilidade, a linguagem C fornece constantes iniciadas pelo caracter \ para indicar esses caracteres. \n \r \t \b \ \\ \0 \a nova linha retorno do carro tabulao retrocesso (backspace) aspas barra nulo sinal sonoro 22

Obs.: Deve haver uma varivel ou constante para cada cdigo de formato! O tipo das variveis ou constantes tambm deve coincidir com os cdigos de formato.
int a; float b; Linguagem de Programao II - URI Campus de Frederico Westphalen

21

Linguagem de Programao II - URI Campus de Frederico Westphalen

\xn Exemplos:

caracter de cdigo n (em hexadecimal)

Toda entrada correspondente <ENTER>. Ex.:

um comando scanf deve sempre ser finalizado por

printf(Ol!\n); printf(Linha1\nLinha2\n); printf(\tPargrafo\nHoje %d/%d/%d\n,dia,mes,ano); printf(Este o \\\\ backslach\n); printf(\xB3\n); printf(Ateno!!!\a\a\a Erro!!!\a\n);

void main() { float anos, dias; printf(Digite sua idade em anos: ); scanf(%f,&anos); dias=anos*365; printf(Voc j viveu %f dias\n,dias); }

4.1.1.2.2 A funo scanf() a funo de entrada formatada de dados pelo teclado. Sua sintaxe similar da funo printf. scanf(<expr. de controle>, <lista de argumentos>); A expresso de controle pode conter tanto cdigos de formatao precedidos pelo sinal %, que indicam o tipo dos dados a serem lidos, como caracteres de espaamento. a) Cdigos de formato: %c %d %e %f %s %u %l %lf Sintaxe: l um caracter l um inteiro decimal l um nmero em notao cientfica l um nmero de ponto flutuante l uma string l um decimal sem sinal l um inteiro longo l um double [largura][cdigo de formato]

Obs.: Por enquanto vamos assumir que todas as variveis da lista de argumentos, com exceo das variveis string, devero ser antecedidas do operador &. Mais adiante vamos entender a razo do operador & e quando o mesmo deve ser utilizado.

c) Search set possvel ainda, no caso de entradas de strings determinar o conjunto de caracteres vlidos (todos os caracteres que no aparecerem nesse conjunto sero considerados separadores). Sintaxe: Exemplos: %[A-Z] %[abc] %[^abc] %[A-Z0-9a-z] todos os caracteres de A at Z apenas os caracteres a, b ou c todos os caracteres menos a, b, c maisculas + minsculas + dgitos %[search set]

4.1.1.2.3 As funes getche() e getch() So funes que lem caracteres do teclado sem esperar a tecla <ENTER>. Ambas no recebem argumentos e devolvem o caracter lido para a funo que os chamou. A diferena entre as duas reside no fato de que getche ecoa o caracter lido no vdeo. Exemplo:
void main() { char ch; printf(Digite algum caracter: ); ch=getch(); printf(\nA tecla digitada foi %c e seu valor na tabela ASCII %d.,ch,ch); }

b) Caracteres de Espaamento: So considerados caracteres de espaamento o espao em branco, o caracter \t e o \n. Sempre que um destes surgir na string de controle de um comando scanf ele indicar que o mesmo deve ser considerado como separador dos valores a serem entrados Esses caracteres sero ento lidos pelo scanf, porm, no armazenados. Normalmente quando o usurio est entrando com valores atendendo a um scanf, quando o mesmo digita um destes caracteres de espaamento, o mesmo lido e no armazenado. A diferena que se o caracter de espaamento aparece na string de controle, ento o scanf n encerrado enquanto o mesmo no for digitado.

Linguagem de Programao II - URI Campus de Frederico Westphalen

23

Linguagem de Programao II - URI Campus de Frederico Westphalen

24

Obs.: Devido maneira diferenciada como tratam o buffer de teclado, o uso das rotinas getch e scanf no mesmo programa pode trazer problemas. Para contorn-los, a funo fflush(stdin) garante que o buffer do teclado (stdin - entrada padro) esteja vazio.

#include <ctype.h> char x; void main() { clrscr(); inicio: printf("R-Repetir, F-finalizar por bem, Outra tecla- Finalizar de qualquer maneira\n"); x=toupper(getch()); if (x=='R') goto inicio; if (x=='F') goto fim_ok; goto fim_qm; fim_ok: printf("Finalizando por bem"); goto fim; fim_qm: printf("Finalizando de qualquer maneira"); fim: getch(); }

4.1.2 Comandos de Desvio Incondicional


Comandos de desvio incondicional so comandos que alteram a seqncia normal de execuo em um bloco de comandos, transferindo o processamento para um ponto no programa fonte marcado com o rtulo especificado no comando GOTO.

Em Pascal: label <rtulo>; begin GOTO <rtulo>; ... <rtulo> : <comandos>; end.

Em C: { GOTO <rtulo>; ... <rtulo> : <comandos>; }

4.2 Estruturas de Controle


4.2.1 Seqncia
Seqncia finita de instrues so agrupamentos de comandos, onde cada comando executado um aps o outro e sem desvios. Em Pascal a seqncia delimitada pelas palavras reservadas BEGIN no incio e END no final e seus comando so separados pelo delimitador ; (ponto e vrgula). Em C a seqncia delimitada pelos smbolos { no incio e } no final e seus comando tambm so separados pelo delimitador ; (ponto e vrgula).

Devemos evitar sempre que possvel o uso de comandos desse tipo. Exemplo em Pascal:
uses crt; label inicio, fim_ok, fim_qm, fim; var x:char; begin clrscr; inicio: writeln('R-Repetir, F-finalizar por bem, Outra tecla- Finalizar de qualquer maneira'); x:=upcase(readkey); if (x='R') then goto inicio; if (x='F') then goto fim_ok; goto fim_qm; fim_ok: writeln('Finalizando por bem'); goto fim; fim_qm: writeln('Finalizando de qualquer maneira'); fim: readkey; end.

4.2.2 Comandos condicionais


4.2.2.1 IF O comando if usado para executar um segmento de cdigo condicionalmente. A forma mais simples do comando if :
if (expresso) ao;

Neste caso a ao somente ser executada se a expresso ou o conjunto de expresses lgicas for verdadeira. No caso do comando if-else o programa pode ter duas aes distintas. Se a expresso for verdadeira, ser executado o conjunto de aes do comando1. Se for falsa ser executado o conjunto de aes do comando2. Em Pascal a implementao do comando if : 25
Linguagem de Programao II - URI Campus de Frederico Westphalen

Exemplo em C:
#include <stdio.h> #include <conio.h> Linguagem de Programao II - URI Campus de Frederico Westphalen

26

IF condio THEN <comando>;

IF condio THEN <comando1> ELSE <comando2>;

O comando if no necessita de uma expresso lgica no lugar do teste. Em C, qualquer expresso que resultar ZERO ser considerada como FALSA e qualquer outro valor considerado VERDADEIRO. Em Pascal somente aceito os valores booleanos TRUE ou FALSE. Em C tambm temos o comando if else if - else que freqentemente utilizado para executar mltiplas comparaes sucessiva. Sua forma geral : if (expresso1) ao1; else if (expresso2) ao2; else if (expresso3) ao3;

Exemplos em Pascal
uses crt; var x: integer; begin x:=10; if x>15 then begin writeln(X maior que 15); end; end. uses crt; var x, y: integer; begin x:=10; if (x>15) and (y>15) then begin writeln(X e Y so maiores que 15); end else begin writeln(X e Y no so maiores que 15); end; end.

Em C a implementao do comando if : if (expresso) { <comando>; } else if (expresso) { <comando1>; } { <comando2>; } Exemplos em C:


#include <stdio.h> #include <conio.h> int x; void main() { x = 10; if (x>15) { printf("X maior que 15\n"); } } #include <stdio.h> #include <conio.h> int x, y; void main() { x = 10; y = 20; if (x>15 && y>15) { printf("X e Y so maiores que 15\n"); } else { printf("X e Y no so maiores que 15\n"); } }

Logicamente, cada ao poderia ser um bloco composto exigindo seu prprio conjunto de chaves. Este tipo de controle de fluxo lgico avalia a expresso at que encontre uma que VERDADEIRA. Quando isto ocorre, todos os testes condicionais restantes sero desviados. No exemplo anterior, nenhuma ao seria tomada se nenhuma das expresses fosse avaliada como VERDADEIRA. Para executar uma ao padro no caso de no satisfazer nenhuma das expresses declaradas pode-se colocar um else sem expresso de teste para realizar a ao pretendida, por exemplo: if (expresso1) ao1; else if (expresso2) ao2; else if (expresso3) ao3; else ao_padro; Exemplo:
#include <stdio.h> #include <conio.h> int x; void main() { x = 16; if (x == 5) { printf("X vale 5\n"); } else if (x == 10) Linguagem de Programao II - URI Campus de Frederico Westphalen

Obs.: Deve-se tomar cuidado com os comando if-else aninhados. O else sempre est associado ao if mais prximo dentro do mesmo nvel de comandos. Blocos mais internos no so considerados.
Linguagem de Programao II - URI Campus de Frederico Westphalen

27

28

{ printf("X vale 10\n"); } else if (x == 15) { printf("X vale 15\n"); } else { printf("X no vale 5, 10 ou 15\n"); } }

end.

end;

Em C o comando de seleo mltipla o comando SWITCH: Em C devemos tomar um pouco de cuidado, pois o comando switch possui algumas peculiaridades. Sua sintaxe :
switch (expresso) { case <valor1>: <comandos1>;

4.2.2.2 Comando de Seleo mltipla: SWITCH ou CASE Quando se deseja testar uma varivel ou uma expresso em relao a diversos valores usamos o comando de seleo mltipla. O valor da expresso seletora comparado com cada elemento da lista de valores. Se existir um valor igual ser executada somente a seqncia relacionada ao valor. Caso contrrio, ou nenhuma seqncia ser executada, ou a seqncia relacionada clusula padro ser executada se ela existir.

break; case <valor2>: <comandos2>; break; ... case <valor n>: <comandos n>; break; default: <comandos_padro>; }

Em Pascal o comando de seleo mltipla o comando CASE: CASE <seletor> OF <valor1> : <comandos1>; <valor2> : <comandos2>; ... <valorn> : <comandosn>; ELSE : <comandos_padro>; END; Exemplo:
uses crt; var x:integer; begin x := 15; case x of 5: begin writeln('X vale 5'); end; 10: begin writeln('X vale 10'); end; 15: begin writeln('X vale 15'); end; else begin writeln('X nao vale 5, 10 ou 15'); end; Linguagem de Programao II - URI Campus de Frederico Westphalen

Exemplo:
#include <stdio.h> #include <conio.h> int x; void main() { x = 15; switch(x) { case 5: { printf("X vale 5\n"); break; } case 10: { printf("X vale 10\n"); break; } case 15: { printf("X vale 15\n"); break; } default: { printf("X nao vale 5, 10 ou 15\n"); } Linguagem de Programao II - URI Campus de Frederico Westphalen

29

30

} getch(); }

for (i=10; i>=1; i--) { printf(%d x 7 = %d \n, i, i*7); }

Devemos tomar bastante cuidado com o comando obrigatrio break, que faz a poro restante do comando switch ser pulada. Caso ele seja removido do segmento de cdigo, seriam executados todos os comandos abaixo dele.

4.2.3 Comandos de Repetio


Os comandos de repetio so caracterizados por permitir que uam seqncia de comandos seja executada um nmero repetido de vezes. 4.2.3.1 For O comando for utilizado para executar uma seqncia de comandos repetidamente e com um nmero conhecido de vezes. Em Pascal a sintaxe do comando :
FOR <var> := <limite_inferior> TO <lim_superior> do <comando> ou FOR <var> := <limite_superior> DOWNTO <limite_inferior> do <comando>

Quando o comando de lao for encontrado, a expr_inicializao executada primeiro, no incio do lao, e nunca mais ser executada. Geralmente esse comando fornece a inicializao da varivel de controle do lao. Aps isso testada a expr_teste, que chamada de cndio de trmino do lao. Quando expr_teste avaliada como VERDADEIRA, o comando ou comandos dentro do lao sero executados. Se o lao foi iniciado, expr_incremento executada aps todos os comandos dentro do lao serem executados. Contudo, se exp_teste avaliada como FALSA, os comandos dentro do lao sero ignorados, junto com expr_incremento, e a execuo continua no comando que segue o final do lao. O esquema de endentao para os laos for com diversos comandos a serem repetidos assim:
for (expr_inicializao; expr_teste; expr_incremento) { comando_a; comando_b; comando_c; }

As variveis de controle de um lao de for podem ter seu valor alterado em qualquer ponto do lao. Qualqur uma das expresses de controle do lao de for pode ser omitida desde que sejam mantidos os ;. As variveis utilizadas nas trs expresses de controle no precisam ter relao entre si. Ex.:
void main() { char c; int x,y; for(c=9;c>0;c--) { printf(%d,c); } for(c=9;c>0; ) { printf(%d,c); c--; } for(x=0,y=0; x+y<100; x=x+4, y++) { printf(%d+%d=%d\n,x,y,x+y); } for(;;) { printf(no saio deste lao nunca!!!!\n);

Exemplos:
for i:= 1 to 10 do begin writeln(i, x, 7, =, i*7); end; for i:= 10 downto 1 do begin writeln(i, x, 7, =, i*7); end;

Em C a sintaxe do comando :
for (expr_inicializao; expr_teste; expr_incremento) <comando>;

Exemplos:
for (i=1; i<=10; i++) { printf(%d x 7 = %d \n, i, i*7); } Linguagem de Programao II - URI Campus de Frederico Westphalen

31

Linguagem de Programao II - URI Campus de Frederico Westphalen

32

4.2.3.3 Do While ou Repeat Estes comandos, assim como o comando WHILE, so usados quando no conhecido o nmero de vezes que uma seqncia de comandos dever ser executada. Porm a seqncia ser executada pelo menos uma vez.

4.2.3.2 While Assim como o lao for, while um lao com teste no inco. Isto significa que a expresso teste avaliada antes dos comandos dentro do corpo do lao serem executados. Por causa disto, os laos com teste no incio podem ser executados de zero a mais vezes. Geralmente estas estruturas so usadas quando um nmero indefinido de repeties esperado. Em Pascal a sintaxe :
WHILE <condio> do <comandos>;

Em Pascal a sintaxe do comando :


REPEAT <comandos>; UNTIL <cond_teste>;

Exemplo:
var a:char; Begin repeat clrscr; writeln(1 - Executar); writeln(2 - Sair); a := readkey; if a = 1 then executar; until a =2; end.

Exemplo:
uses crt; var a,b,ano: integer; begin a:=1500; b:=2000; ano:=0; while a < b do begin a := a * 1.05; b := b * 1.02; ano++; end; writeln(ano, anos); end.

Em C a sintaxe do comando :
do <comandos> while(cond_teste);

Em C a sintaxe :
while (expr_teste) <comandos>;

Exemplo.:
void main() { char a; do { clrscr(); printf(1 - Executar\n); printf(2 - Sair\n); a = getche(); if (a == 1) executar(); } while (a != 2); }

Exemplo.:
void main() { int a, b,ano; a=1500; b=2000; ano=0; while(a<b) { a=a*1.05; b=b*1.02; ano++; } printf(%d anos,ano); }

Observe que em Pascal usamos o comando repeat e until fazendo com que o lao repita at que a condio seja satisfeita e em C usamos o comando do e while fazendo com que o lao repita enquanto a condio esteja sendo satisfeita.

Linguagem de Programao II - URI Campus de Frederico Westphalen

33

Linguagem de Programao II - URI Campus de Frederico Westphalen

34

4.2.3.4 Comandos de desvio Nas linguagem C e Pascal temos os comandos de desvio que interrompem a execuo de um lao. 4.2.3.4.1 Comando break O comando break pode ser usado para sair de um lao for, while ou do-while (repeat) mais interno, desde que no mesmo subprograma, passando a seqncia da execuo para a primeira linha aps o lao. Exemplo em Pascal:
uses crt; var x: char; i: integer; begin for i:= 1 to 100 do begin write('Digite um numero entre 0 e 9: '); x:=readkey; if (x < #48) or (x > #57) then break; writeln(x, ' foi digitado!'); end; end.

end.

Exemplo em C:
void main() { int i; for(i=1;i<=10;i++) { if ( i % 2 != 0) continue; printf(O nmero %d par!,i); } }

4.2.3.4.3 Funo Exit A funo exit causa a imediata interrupo do programa e o retorno ao sistema operacional. Em C, o valor do parmetro retornado ao processo que o chamou que geralmente o sistema operacional. O valor 0 ( exit(0);) geralmente indica que o processo terminou sem problemas. Exemplo em Pascal:
uses crt; begin while true do begin write('Xx '); if keypressed then exit; end; end.

Exemplo em C:
void main() { char x, i; for(x=1;x<=100;x++) { printf(Digite um nmero de 0 a 9:); x = getch(); if (y < 48 || y > 57) break; printf(%d foi digitado \n,x); } }

Exemplo em C:
#include <stdio.h> #include <conio.h> #include <stdlib.h> void main() { while(1) { printf("Xx "); if ( kbhit()) exit(0); } }

4.2.3.4.2 Comando continue O comando continue causa o fim de um dos laos de uma repetio e o retorno imediato ao teste. Exemplo em Pascal:
uses crt; var i: integer; begin for i:= 1 to 10 do begin if (i mod 2 <> 0) then continue; writeln(i, ' e par!'); end; Linguagem de Programao II - URI Campus de Frederico Westphalen

4.2.3.4.4 Comando return O comando return causa uma interrupo no fluxo de comandos de uma funo e o retorno a funo chamadora. Pode ser usado com ou sem argumento dependento do tipo de funo em que utilizado, porm no possvel em uma nica funo seu uso com e sem argumentos.

35

Linguagem de Programao II - URI Campus de Frederico Westphalen

36

5.2 Funes

5. FUNES E PROCEDIMENTOS
As funes formam o alicerce da programao em C e C++. Conforme vamos aumentando a prtica em programao, os programas comeam a tomar uma aparncia modular quando programamos com funes. Podemos fazer toda a programao em C e C++ dentro de uma funo. Isto porque todos os programas devem incluir main, que uma funo. As funes so similares aos mdulos de outras linguagens. Pascal utiliza procedimentos e funes. Fortran utiliza somente funes, e a linguagem Assembly utiliza somente procedimentos. O modo como as funes trabalham determina o alto grau de eficincia, legibilidade e portabilidade do cdigo do programa em C.

Em Pascal as funes podem ser vistas como um procedimento que retorna um nico valor. Ex.:
PROGRAM FUNCAO; VAR pr, imp: REAL; FUNCTION calc_imposto(preco: REAL):REAL; BEGIN calc_imposto = preco * 0.17; END; BEGIN READLN(pr); imp = calc_imposto(pr); WRITELN('Preo: ',pr,' Imposto: ',imp); END.

5.1 Procedimentos
Um procedimento um tipo de subprograma utilizado na linguagem Pascal, que se assemelha em muito com um programa em Pascal. Possui um cabealho de identificao com o nome do procedimento, uma lista opcional de parmetros de comunicao, um bloco de declaraes e um bloco de comandos. Em C uma funo void ou que retorna um valor nulo, pode ser comparada com um procedimento utilizado na linguagem Pascal, porm todas os subprogramas em C so funes e devem retornar um valor (ou retornar void, vazio).

5.2.1 Estilos e prottipos das funes


As declaraes de funo comeam com o prottipo da funo C e C++. O prottipo de funo simples e includo no incio do cdigo do programa para notificar o compilador do tipo e do nmero de argumentos que uma funo utilizar. Embora outras variaes sejam legais, sempre que possvel voc deve utilizar a forma do prottipo de funo que uma rplica da linha de declarao da funo. Por exemplo: tipo_de_retorno nome_da_funo ( tipo(s)_argumento nome(s)_argumento);

5.1.1 Passagem de parmetros


Quando a varivel que se quer trabalhar no visvel dentro do procedimento ela deve ser passada como parmetro: 5.1.1.1 Passagem de parmetros por valor Quando uma varivel passada por valor para um prodedimento, seu valor original no alterado. Declarao: procedure <nome>(<variveis>:<tipo>) 5.1.1.2 Passagem de parmetros por referncia Quando uma varivel passada por referncia para um prodedimento, seu valor original alterado na execuo do procedimento. Declarao: procedure <nome>(var <variveis>:<tipo>)

5.2.2 Argumentos das funes


Os argumentos, ou parmetros, passados s funes so opcionais; algumas funes podem no receber argumentos enquanto outras podem receber diversos. Os argumentos podem ser misturados, sendo possvel o uso de qualquer um dos tipos de dados escalares padronizados, podendo ser int, float, double, char e ponteiros. Existem situaes onde necessrio que as sub-rotinas retornem valores calculados internamente. A linguagem C apresenta dois mecanismos para tanto: 5.2.2.1 Passagem de parmetros por valor As funes recebem parmetros por valor quando na lista de argumentos existem valores ou variveis com valores. Esses argumentos so criados na pilha no momento em que a funo chamada. 37
Linguagem de Programao II - URI Campus de Frederico Westphalen

Linguagem de Programao II - URI Campus de Frederico Westphalen

38

O comando return permite que uma funo retorne um nico valor. Esse valor obtido na rotina chamadora na medida em que a chamada na funo feita atravs de uma atribuio (Ex. 2). Ex. 1:
... int v; v=30; func1(v,25);

printf("%d",a); } void func1(int *p) { int x; scanf("%d",&x); *p = x * 2; }

...

void func1(int a, int b) { int x; a = a + 10; b = b - 10; x = a + b; printf("%d\n",x); } Ex. 2: void main() { float pr, imp; scanf("%f",&pr); imp=calc_imposto(pr); printf("Preo: %f, Imposto: %f\n",pr,imp); } float calc_imposto(float preco); { float imposto; imposto=preco * 0.17; return(imposto); }

Observe que o argumento da funo func1 um ponteiro para inteiro. O que se passa na chamada dessa funo, no o valor da varivel a, mas sim seu endereo (at porque nesse momento a nem ao menos foi inicializado). Dentro da funo func1, o valor digitado pelo usurio multiplicado por 2 e armazenado, no na varivel p que contm o endereo de a, mas na prpria varivel a. Desta forma, quando a funo acaba e o controle volta rotina chamadora, o valor correto j est armazenado em a. Note-se, ento, que o uso de um * antes de uma varivel ponteiro em uma expresso significa que no estamos nos referindo ao valor do ponteiro, mas sim ao valor para o qual aponta. Resumindo, podemos dizer que: &a *p o endereo de a o contedo da varivel apontada por p

5.2.3 Tipos de funes


As funes podem ser: Funes do tipo void: As funes so do tipo void quando indicam explicitamente a ausncia de argumentos na funo. EX.:
#include <stdio.h> #include <math.h> void impressao(void); main() { printf("Este programa extrai uma raiz quadrada\n"); impressao(); return(0); } void impressao(void) { double z=5678.0; double x; x=sqrt(z); printf("A raiz quadrada de %lf %lf\n",z,x); }

No exemplo 1 acima, o valor da varivel v e o valor 25 so passados respectivamente para os argumentos a e b da funo func1. Apesar do valor de a e b ser alterado dentro da funo, essa mudana no se refletir no valor da varivel v pois o que passado para a funo apenas uma cpia do valor da varivel. 5.2.2.2 Passagem de parmetros por referncia A passagem de parmetros por referncia faz com que os valores das variveis passadas por referncia sejam alterados dentro da funo. Em C, quando queremos que isto acontea, ao invs de passarmos o valor como parmetro de uma funo, passamos o endereo dessa varivel (que no deixa de ser um valor). O endereo, no caso, faz as vezes de "referncia" para a varivel e nos permite alterar o contedo da mesma dentro da sub-rotina. Ex:
void main() { int a; func1(&a); Linguagem de Programao II - URI Campus de Frederico Westphalen

39

Linguagem de Programao II - URI Campus de Frederico Westphalen

40

Funes do tipo char: As funes so do tipo char quando recebem um caracter como argumento.

Ex.:
#include <stdio.h> #include <conio.h> void impressao(char c); void main() { char meucaracter; printf("Informe um caracter pelo teclado\n"); meucaracter=getch(); impressao(meucaracter); } void impressao(char c) { int i; for(i=0;i<10;i++) printf("O caracter : %c\n",c); }

Funes do tipo double: As funes que aceitam e retornam um tipo double, ou seja um float com muita preciso so do tipo double. Todas as funes que esto definidas em math.h aceitam e retornam tipo double.

5.3 Argumentos passados a programas


Nomalmente as linguagens de programao permitem que o programa receba parmetros passados na linha de comando no momento da sua ativao. Assim, quando usamos o comando format a: ou scan a: passamos o argumento a: para o programa.

5.3.1 Argumentos passados a programas em PASCAL


Os argumentos passados aos programas em Pascal so verificados atravs de dois comandos (variveis que esto armazenados os parmentros): PARAMCOUNT: armazena o nmero de argumentos passados na linha de comando. Paramcount igual a zero indica que no h argumentos na linha de comando. PARAMSTR: armazena as strings de argumentos da linha de comando. ParamStr(1) o primeiro argumento.

Funes do tipo int: As funes so do tipo int quando aceitam e retornam um inteiro como argumentos. Funes do tipo long: As funes so do tipo long quando aceitam e retornam long int como argumentos. Funes do tipo float: As funes so do tipo float quando aceitam e retornam float como argumentos. Ex.:
#include <stdio.h> #include <math.h> void hipotenusa(float x, float y); main() { float cateto_y, cateto_x; printf("Altura do tringulo retngulo: "); scanf("%f",cateto_y); printf("Base do tringulo retngulo: "); scanf("%f",cateto_x); hipotenusa(cateto_y,cateto_x); return(0); } void hipotenusa(float x, float y) { double minhahipo; minhahipo = hipot((double)x,(double)y); printf("A hipotenusa do tringulo : %f\n",minhahipo); } Linguagem de Programao II - URI Campus de Frederico Westphalen

program parametros; uses crt; var I: integer; begin if ParamCount = 0 then begin Writeln('Este programa no tem argumentos!'); exit; end; for I := 1 to ParamCount do Writeln('O ',I,' parmetro : ',ParamStr(I)); end.

5.3.2 Argumentos passados a programas em C


C e C++ podem aceitar inmeros argumentos da linha de comando. A funo main recebe os parmetros com a seguinte declarao: main(int argc, char *argv[]) O primeiro argumento um inteiro que fornece o nmero de termos da linha de comando. O nome do programa executvel conta como sendo o primeiro, isto , todo programa ter argc com valor 1 se no tiver nenhum parmetro e valor num_parmetros + 1 quando tiver parmetros.

41

Linguagem de Programao II - URI Campus de Frederico Westphalen

42

O segundo argumento um ponteiro para as strings argv. Todos os argumentos so strings de caracteres, de modo que so conhecidos no programa como:
argv[1] argv[2] ... primeiro argumento segundo argumento

6. MATRIZES
Matrizes so variveis indexadas que contm diversos itens de dados do mesmo tipo. Cada matriz possui um nome, e seus elementos so acessados com a associao de um ndice ao nome da matriz. Uma matriz possui quatro propriedades bsicas: a) Os itens de dados individuais na matriz so chamados de elementos. b) Todos os elementos devem ser do mesmo tipo de dados. c) Todos os elementos so armazenados contiguamente na memria do computador, e em linguagem C o ndice do primento elemento sempre ser zero. d) O nome da matriz um valor constante que representa o endereo do primeiro elemento na matriz. Como todos os elementos so do mesmo tamanho, no podemos definir matrizes usando uma mistura de tipos de dados, pois a localizao de um elemento feita com base no endereo do primeiro elemento mais o deslocamento proporcional ao ndice. As matrizes podem ser unidimensionais quando o acesso a um de seus elementos feito atravs de um nico ndice, tambm conhecida como vetores em Pascal, ou multidimensionais quando possuem mais que uma dimenso, sendo necessrio mais de um ndice para acessar um de seus elementos.

Ex.:
#include <stdio.h> #include <stdlib.h> void main(int argc, char *argv[]) { int i; if (argc < 2) { printf("Este programa no tem argumentos!"); exit(1); } for (i=1;i < argc; i++) printf("O %d argumento %s\n",i,argv[i]); }

Os argumentos so recebidos da linha de comando e impressos na tela na mesma ordem. Se nmeros forem informados na linha de comando, eles sero interpretados como strings ASCII e impressos como caracteres. Se desejarmos fazer clculos com esses nmeros devemos convertlos de string para nmero com as funes de converso apropriadas (atoi, atol, atof que encontram-se definidas em stdlib.h)

6.1 Matrizes em Pascal


Uma matriz unidimensional ou vetor em Pascal definido com o uso da palavra reservada array, seguida de seus limites inferior e superior entre colchetes, da palavra reservada of e do tipo de componente do vetor. <nomeVetor> : ARRAY [<lim_inf> .. <lim_sup>] of <TipoComponente> Ex: Alunos: Array[1..40] of integer; Uma matriz multidimensional pode ser comparada a uma tabela de duas ou mais dimenses, sendo necessrios tantos ndices quantas forem as dimenses. Uma matriz multidimensional em Pascal definida com o uso da palavra reservada array, seguida de seus limites inferior e superior para cada dimenso, separada por vrgulas, entre colchetes, da palavra reservada of e do tipo de componente do vetor. Ex:

Linguagem de Programao II - URI Campus de Frederico Westphalen

43

Linguagem de Programao II - URI Campus de Frederico Westphalen

44

Notas: Array[1..40,1..3] of integer; Uma matriz pode ser declarada e inicializada declarando-se no bloco de constantes:
const num1: array [1..5] of integer = (2,4,6,8,10); num2: array [1..2,1..5] of integer = ((10,20,30,40,50),(15,25,35,45,55));

Observe qua no se pode usar uma varivel na definio da matriz para dimensionar o seu tamanho, pois o compilador precisa alocar a memria necessria no momento da compilao.

6.3 Strings
Em Pascal temos o tipo de dado string predefinido na linguagem que nada mais que um vetor de caracteres.

6.2 Matrizes em C
Uma matriz em C definida escrevendo-se o tipo da matriz, seguida de um nome, e um par de colchetes contendo uma expresso constante que define o tamanho da matriz. <tipo> <nomematriz> [<tamanho>] Ex: int alunos[40]; Uma matriz multidimensional definida escrevendo-se o tipo da matriz, seguida de um nome, e tantos pares de colchetes quantas forem a dimenses, contendo uma expresso constante que define o tamanho da matriz em cada dimenso. Ex: int Notas[40][3]; Em C o primeiro elemento sempre ser o elemento de ndice 0. Uma matriz pode ser inicializada explicitamente quando declarada: Ex.:
#include <conio.h> #include <stdio.h> int numeros[3] = {2,4,6}; char vogais[5] = {'a','b','c','d','e'}; int num[2][5]={{2,4,6,8,10},{1,3,5,7,9}}; void main() { int i,j; for (i=0;i<2;i++) { printf("\n"); for (j=0;j<5;j++) { printf(" %d",num[i][j]); } } }

A linguagem C no possui este tipo de dado. Toda a vez que queremos uma string em C devemos declar-la como: char <nome> [<tamanho>]; Quando precisamos de um vetor de string, declaramos como uma matriz de caracteres, por exemplo, se queremos uma lista de 250 nomes com 80 letras cada: char nomes[250][80]; Toda a vez que precisamos fazer operaes com strings em C, como comparao, cpia de valores, concatenao, devemos usar as funes predefinidas em string.h:
Funo strcat strchr strcmp
Sintaxe e Funo char *strcat(char *dest, const char *src); Adiciona uma string a outra strcat adiciona uma cdia da string de origem para o final da string de destino. char *strchr(char *s, int c); Procura numa string a primeira ocorrncia de um caracter. Retorna um ponteiro para a primeira ocorrncia do caracter dentro da string. Se o caracter no for encontrado, strchr retorna NULL.. int strcmp(const char *s1, const char *s2); Compara uma string com outra e retorna: < 0 se s1 for menor que s2 = 0 se s1 for igual s2 > 0 se s1 for maior que s2 char *strcpy(char *dest, const char *src); Copia uma string para outra. Copia string src para dest. Retorna um ponteiro para a string dest. size_t strcspn(const char *s1, const char *s2); Procura em s1 at que qualquer um dos caracteres contidos em s2 encontrado. O nmero de caracteres que so lidos em s1 o valor retornado. int stricmp(const char *s1, const char *s2); Compara uma string com outra sem distino entre maiscula e minscula e retorna: < 0 se s1 for menor que s2 = 0 se s1 for igual s2 > 0 se s1 for maior que s2 size_t strlen(const char *s); Calcula e retorna o tamanho de uma string. char *strlwr(char *s); Converte letras maisculas em minsculas numa string. char *strncat(char *dest, const char *src, size_t n); Adiciona uma poro de uma string a outra. strncat copia n caracteres de src para o final de dest e acrescenta um caractere NULL.

strcpy strcspn stricmp

strlen strlwr strncat

Linguagem de Programao II - URI Campus de Frederico Westphalen

45

Linguagem de Programao II - URI Campus de Frederico Westphalen

46

strncmp

strncpy strnicmp

strnset strrchr strrev strset strspn strstr strupr

int strncmp(const char *s1, const char *s2, size_t n); Compara uma poro de uma string com uma poro de outra string. strncmp faz a mesma comparao que strcmp, mas analisa no mximo os n primeiros caracteres e retorna: < 0 se s1 for menor que s2 = 0 se s1 for igual s2 > 0 se s1 for maior que s2 char *strncpy(char *dest, const char *src, size_t n); Copia um um determinado nmero de bytes (n) de uma string para outra.. int strnicmp(const char *s1, const char *s2, size_t n); Compara uma poro de uma string com uma poro de outra string sem distino de maisculas com minsculas. strncmp faz a mesma comparao que stricmp, mas analisa no mximo os n primeiros caracteres. Retorna: < 0 se s1 for menor que s2 = 0 se s1 for igual s2 > 0 se s1 for maior que s2 char *strnset(char *s, int ch, size_t n); Altera os n primeiros caracters de uma string para um caractere especfico (ch). char *strrchr(const char *s, int c); Procura numa string pela ltima ocorrncia de um caracter (c). char *strrev(char *s); Reverte uma string. strrev muda todos os caracteres numa string para a ordem reversa, com exeo do caracter nulo de terminao. char *strset(char *s, int ch); Altera todos os caracteres numa string para um determinado caracter (ch). size_t strspn(const char *s1, const char *s2); Procura numa string s1 pelo primeiro segmento que difere de s2, retornando a posio onde inicia a diferena. char *strstr(const char *s1, const char *s2); Procura numa string s1 pela ocorrncia de uma dada substring s2. char *strupr(char *s); Converte letras minsculas numa string para maisculas.

for (a=0;a<10;a++) { scanf("%d",&vet[a]); } imprime(vet); getch();

void imprime(int vet2[10]) { int a; for (a=0;a<10;a++) printf("%d ",vet2[a]); }

Exemplo de passagem de parmetro por referncia de um vetor :


#include <stdio.h> #include <conio.h> void imprime(int *vet2, int n); void main() { int a, vet[10]; clrscr(); for (a=0;a<10;a++) { scanf("%d",&vet[a]); } imprime(vet,10); getch();

6.4 Matrizes e vetores como parmetros de funes


Como j se viu anteriormente, uma funo em C s aceita parmetros por valor. No possvel, portanto, passar um vetor ou matriz (tipos de dados estruturados) como parmetro. A soluo utilizada quando da necessidade de se trabalhar com os dados contidos em um vetor no global dentro de uma funo passar um ponteiro para este vetor como parmetro. Para trabalhar com os elementos do vetor dentro da funo procede-se de forma normal j que sempre que estamos trabalhando com vetores estamos usando um ponteiro para a primeira posio da rea de memria alocada para o mesmo. Exemplo de passagem de parmetro por valor de um vetor :
#include <stdio.h> #include <conio.h> void imprime(int vet2[10]); void main() { int a, vet[10]; clrscr(); Linguagem de Programao II - URI Campus de Frederico Westphalen

void imprime(int *vet2, int n) { int a; for (a=0;a<n;a++) printf("%d ",vet2[a]); }

Exemplo de passagem de passagem de parmetro por valor de uma matriz:


#include <stdio.h> #include <conio.h> void imprime(int mat2[3][3]); void main() { int i, j, mat[3][3]; clrscr(); for (i=0;i<3;i++) for (j=0;j<3;j++) scanf("%d",&mat[i][j]); imprime(mat); getch();

void imprime(int mat2[3][3])

47

Linguagem de Programao II - URI Campus de Frederico Westphalen

48

int a, b; for (a=0;a<3;a++) { printf("\n"); for (b=0;b<3;b++) { printf("%d ",mat2[a][b]); } }

7. DELPHI
O que o Delphi ? O Delphi nada mais que um simples IDE, IDE um ambiente integrado para desenvolvimento composto por compilador, editor de texto, ferramenta de depurao e alguns recursos a mais. Um IDE nem sempre um ambiente grafico. A diferena entre o IDE DELPHI para os outros IDE's por ai, que o DELPHI um IDE RAD. Sim o DELPHI RAD, isto , a medida em que os componentes vo sendo selecionados, o DELPHI escreve o cdigo fonte para voc. Os componentes em geral, incluem classes e propriedades muito utilizadas e que se relacionam com outros objetos. Tudo que nele existe foi pensando em Velocidade de Desenvolvimento. Um exemplo tpico para o RAD do DELPHI : Ao colocar um Boto num formulrio, veja o que ocorre: na clausula "uses", acrescenta a lib que contm o objeto TButton. Tambem criado um TButton.Create que cria o objeto para ser usado, mas dessa vez fica no arquivo .DFM. Se o object TButton possuir dependencias de outras classes, o DELPHI se encarrega de encontra-las e inclui-las em sua aplicacao.

Exemplo de passagem de passagem de parmetro por referncia de uma matriz. No caso de matrizes, pelo menos uma das dimenses tem que ser conhecida.
#include <stdio.h> #include <conio.h> void imprime(int mat2[][3], int l); void main() { int i, j, mat[3][3]; clrscr(); for (i=0;i<3;i++) { for (j=0;j<3;j++) { scanf("%d",&mat[i][j]); } } imprime(mat,3); } void imprime(int mat2[][3], int linha) { int a, b; for (a=0;a<linha;a++) { printf("\n"); for (b=0;b<3;b++) { printf("%d ",mat2[a][b]); } } }

Mas o DELPHI uma linguagem ou no ? Pois , se algum lhe perguntar em que linguagem voc cria seus sistemas, no diga "DELPHI" to rapidamente. Voc s deve dizer DELPHI, quando estiver em volta de um meio onde as pessoas conheam o DELPHI, tal como, lista de discusso sobre o assunto, forums relacionados, etc... Talvez voc esteja achando que estou sendo purista demais, no ? Veja bem, se voc for a uma lista, diga-mos de Linux, e falar que voce escreve programas em DELPHI, os programadores Linux que normalmente usam C, C++, etc... que no so usurios de DELPHI, mas entendem o que linguagem, vo entender que voc no entende nada sobre programao, pois voc no respondeu adequadamente. Na certa, vo achar que voc um daqueles que fica arrastando botezinhos, labelzinhos e depois vende um aplicativo quase sem nenhuma programao. Concluso : Se algum lhe perguntar que linguagem voc usa, nunca diga "DELPHI", diga : Object Pascal! ObjectPascal, a liguagem Quando voc est usando o DELPHI, a linguagem gerada por ele o ObjectPascal. Tanto isso verdade que possivel compilar o programa e seu codigo fonte sem a presena do DELPHI. Faa o teste :
dbcc32 [nome-do-dpr] lib [nome-das-libs]

Linguagem de Programao II - URI Campus de Frederico Westphalen

49

O ObjectPascal, a linguagem pascal orientado a objetos, com todo o poder do OOP. Se voc for um timo programador ObjectPascal, talvez nem precise do DELPHI para escrever seus programas. O pessoal do FreePascal (outra linguagem compatvel com ObjectPascal) j faz isso h bastante tempo. Mas convenhamos, o DELPHI quebra um galho, com todos aqueles packages e componentes, a linha de comando para se compilar um projeto ObjectPascal na mo (da at Linguagem de Programao II - URI Campus de Frederico Westphalen 50

medo)... certamente no seria das tarefas mais agradveis. Temos de dar os parabens a Borland, escrever um IDE decente para uma linguagem no nada fcil. Outras linguagens, mesmos as mais complexas tornam-se fceis para o iniciante se tivermos um IDE decente, principalmente se for RAD. O pessoal do KDE (Linux) j vem trabalhando h muito tempo no Kdevelopment, um IDE parecido com o DELPHI para a linguagem C++, no entanto, no um IDE RAD, apenas um IDE. O KDevelopment um bom IDE, mas acho que no existe interesse em transforma-lo em RAD.

Exemplo: Se colocarmos um boto no form, a classe deste form ser modificada para incluir este boto. Os eventos e mtodos deste form, tambm esto na classe. Assim, supondo que o form se chame Form1 (nome default), para por exemplo desativar o boto que inclumos (de nome Buttom1) escreveramos:
Form1.Buttom1.Enabled := false;

Note como o Buttom1 faz parte da estrutura que define o form. Mas se quisermos ativar mtodo RePaint (Repintar) do form faramos:
Form1.Repaint;

7.1 Conceitos bsicos


7.1.1 Programao em Windows: Janelas e eventos
Existem muitas diferenas entre a programao em DOS e a programao em Windows. Vejamos a principal: Quando programamos em DOS, nosso programa responsvel pelo fluxo de processamento. Temos que definir claramente no s que instrues, mas tambm em que ordem devem ser executadas. Em Windows no bem assim. Nosso programa no controla o fluxo de processamento, ele responde e trata eventos que ocorrem no sistema. Existem muitos eventos que podem ocorrer, sendo que os principais so aqueles gerados pelo usurio atravs do mouse e do teclado. A coisa acontece mais ou menos assim: O usurio clica o mouse e o Windows verifica que aplicao estava debaixo do mouse no momento em que foi clicado. Em seguida ele manda uma mensagem para a aplicao informando que ocorreu um clique e as coordenadas do cursor do mouse na tela no momento do clique. A aplicao ento responde mensagem executando uma funo de acordo com a posio do mouse na tela. claro que o Delphi toma conta do servio mais pesado e facilita muito as coisas para o programador. Detalhes como as coordenadas da tela em que ocorreu o clique, embora estejam disponveis, dificilmente so necessrios nos programas.

Veja que Repaint, no uma varivel, tecnicamente uma procedure, mas fazemos referncia a ela como parte da estrutura Form1. Pode parecer confuso no incio, mas facilita muito a programao.

7.3 O ambiente do Delphi


Quando ativamos o Delphi, a tela inicial tem a barra do menu principal do Delphi, esquerda a SpeedBar, com as opes mais comuns e direita a paleta de componentes. Estes componentes so a base da programao visual e onde o designer vai buscar recursos para sua aplicao. Abaixo da SpeedBar, est a janela do Object Inspector, que permite visualizar e modificar as propriedades e eventos de todos os componentes. tambm largamente utilizado pelo designer. Abaixo da paleta ficam a janela de cdigo-fonte e as janelas que esto sendo construdas.

7.3.1 Arquivos que Compem um Aplicao


7.3.1.1 Arquivos Gerados no desenvolvimento
Ext. .DPR Definio Arquivo do Projeto Funo Cdigo fonte em Pascal do arquivo principal do projeto. Lista todos os formulrios e units no projeto, e contm cdigo de inicializao da aplicao. Criado quando o projeto salvo. Um arquivo .PAS gerado por cada formulrio que o projeto contm. Seu projeto pode conter um ou mais arquivos .PAS associados com algum formulrio. Contem todas as declaraes e procedimentos incluindo eventos de um formulrio. Arquivo binrio que contm as propriedades do desenho de um formulrio contido em um projeto. Um .DFM gerado em companhia de um arquivo .PAS para cada formulrio do projeto. Arquivo texto que contm a situao corrente das opes do projeto. Gerado com o primeiro salvamento e atualizado em subsequentes alteraes feitas para as opes do projeto. Arquivo binrio que contm o cone, mensagens da aplicao e outros recursos usados pelo projeto. Este arquivo armazena informaes sobre a situao da rea de trabalho especifica para o projeto em opes de ambiente( Options Environment).

7.2 Programao Orientada a Objeto (POO)


Embora no seja objetivo ensinar POO, uma breve introduo necessria, j que o Delphi essencialmente orientado a objeto. De maneira prtica, podemos pensar no objeto sendo uma estrutura que agrupa dados e funes para manipular estes dados. Como as funes so sempre ntimas dos dados, o sistema todo funciona de maneira mais segura e confivel. Alm disso, a POO utiliza conceitos como encapsulamento e herana que facilitam muito programao e manuteno dos programas. Neste ponto oportuno citar que os dados de um objeto costumam ser chamados de variveis de instncia e as funes de mtodos. As variveis de instncia definem as propriedades (as vezes chamada de atributos) do objeto e os mtodos definem seu comportamento. Para programar no nvel do designer no necessrio um conhecimento profundo de POO. Mas preciso conhecer pelo menos a sintaxe. Todas as aplicaes para Windows, precisam de pelo menos uma janela, que no Delphi chamada de Form. Cada form (assim como todos os objetos visuais) tem um objeto associado a ele e sua representao visual, que vemos na tela. Todos os componentes que inclumos no form, passam a fazer parte do objeto que define o form.
Linguagem de Programao II - URI Campus de Frederico Westphalen

.PAS

Cdigo fonte da Unit( Object Pascal) Arquivo grfico formulrio do

.DFM

.CFG

Arquivo de opes do projeto Arquivo de Recursos do Compilador Situao da rea de Trabalho

.RES .DSK

Obs.: .~DF, .~PA , .~DP so arquivos de backup. Devido a grande quantidade de arquivos de uma aplicao, cada projeto deve ser montado em um diretrio especfico.

51

Linguagem de Programao II - URI Campus de Frederico Westphalen

52

7.3.2 Arquivos Gerados pela Compilao


Ext Definio .EXE Arquivo compilado executvel .DCU Cdigo ob-jeto da Unit Funo Este um arquivo executvel distribuvel de sua aplicao. Este arquivo incorpora todos os arquivos .DCU gerados quando sua aplicao compilada. A compilao cria um arquivo .DCU para cada .PAS no projeto.

7.5.2 Seo Uses


Contm as units acessadas por este arquivo.

7.5.3 Seo Interface


Nesta seo esto as declaraes de constantes, tipos de variveis, funes e procedures gerais da Unit/Form. As declaraes desta seo so visveis por qualquer Unit. Esta seo formada pelo seguinte cdigo: INTERFACE - Palavra que inicia a seo;

Obs.: Estes arquivos podem ser apagados para economizar espao em disco.

7.4 Cdigo fonte do arquivo Project(.DPR)


Neste arquivo est escrito o cdigo de criao da aplicao e seus formulrios. O arquivo Project tem apenas uma seo. Esta seo formada pelo seguinte cdigo:

USES - Clusula que inicia uma lista de outras unidades compiladas (units) em que se basea: SysUtils = utilitrios do sistema (strings, data/hora, gerar arquivos) WinProcs = acesso a GDI, USER e KERNEL do Windows

PROGRAM - Define o Projeto; USES - Clusula que inicia uma lista de outras unidades. Forms = a unidade do Delphi que define a forma e os componentes do aplicativo In = A clausula indica ao compilador onde encontrar o arquivo Unit. Unit1 = A unidade que voc criou {$R *.RES} - Diretiva compiladora que inclui o arquivo de recursos. Abaixo veja como fica o Project quando voc abre um projeto novo:
program Project1; uses Forms, Unit1 in 'UNIT1.PAS' {Form1}; {$R *.RES} begin Application.CreateForm(TForm1, Form1); Application.Run; end.

Wintypes= tipos de dados e valores constantes Messages=constantes com os nmeros das mensagens do Windows e tipos de dados das Mensagens Classes=elementos de baixo nvel do sistema de componentes Graphics=elementos grficos Controls=elementos de nvel mdio do sistema de componentes Forms=componentes de forma e componentes invisveis de aplicativos Dialogs=componentes de dilogo comuns

7.5.4 Seo Type


Declara os tipos definidos pelo usurio. Subsees: Private, declaraes privativas da Unit. Public declaraes publicas da Unit.

7.5 Cdigo fonte do arquivo Unit (.PAS)


Nesta divisria sero escritos os cdigos dos seus respectivos forms (Unit1 = Form1). Aqui sero definidos os cdigos de cada procedimento dos componentes que voc colocar no form.

7.5.5 Seo Var


Declara as variveis privadas utilizadas.

7.5.6 Seo Implementation


Contm os corpos das funes e procedures declaradas nas sees Interface e Type. Nesta seo tambm esto definidos todos os procedimentos dos componentes que esto includos no

7.5.1 Seo Unit


Declara o nome da unit.
Linguagem de Programao II - URI Campus de Frederico Westphalen

53

Linguagem de Programao II - URI Campus de Frederico Westphalen

54

Form. As declaraes desta seo so visveis apenas por ela mesma. Esta seo formada pelo seguinte cdigo: {$R*.DFM} - Diretiva compiladora que inclui toda a interface, propriedades da forma e componentes do arquivo *.DFM {$S+} - Diretiva compiladora que ativa verificao de pilha.

7.6 Code Editor (Editor de Cdigo)

7.5.7 Seo uses adicional


Serve para declarar outras Units usadas.

Barra de Ttulo (Mostra o nome do arquivo)

7.5.8 Inicialization
Nesta seo, que opcional, pode ser definido um cdigo para proceder as tarefas de inicializao da Unit quando o programa comea. Ela consiste na palavra reservada inicialization seguida por uma ou mais declaraes para serem executadas em ordem.

Indicador de Linha e Coluna Indicador de Modificao Indicador de Modo Aba da Pgina

7.5.9 Exemplo
Abaixo veja como fica a unit quando voc abre um projeto novo:
unit Unit1; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} {Uses Adicional} {Initialization} end.

7.7 Form (Formulrio)


Voc usa formulrios para fazer interface com o usurio, nele so inseridos os componentes. O formulrio uma janela, e portanto, possui os atributos de uma janela (menu de controle, botes de maximizar e minimizar), barra de ttulo, bordas redimensionveis). Para alternar entre o Formulrio (Form) e o Editor de Cdigo, deve-se pressionar a tecla F12.

Linguagem de Programao II - URI Campus de Frederico Westphalen

55

Linguagem de Programao II - URI Campus de Frederico Westphalen

56

7.8 Object Inspector (Inspetor de Objetos)


uma ferramenta composta de duas pginas: Properties (Propriedades) e Events (Eventos).

7.9 Component Palette( Palheta de Componentes)


composta de vrias pginas contendo cada uma grupos de componentes. Para mudar de pgina na palheta de componentes, clique sobre a aba da pgina que voc quiser acessar. Seta de rolagem Palheta de Componente (Pgina Stantard visvel; pgina de componentes adicionais disponveis para esquerda selecionando a aba da pgina) Locais para componentes adicionais Seta de rolagem para direita Ponteiro Aba das Pginas

Seletor de Objetos (mostra o nome e o tipo de objeto selecionado)

Coluna de Propriedades

Separador de Colunas Coluna de Valores Propriedades aninhadas ( Duplo clique para visualizar subpropriedades)

7.10 Componentes
Os componentes so os objetos visuais e no visuais que permitem desenvolver uma aplicao com o Delphi. Cada janela, campo de edio, boto ou rtulo um componente.

Pgina de Propriedades

Pgina de Eventos

7.10.1 Nomenclatura
A pgina Properties (Propriedades) permite que voc estabelea parmetros de formulrios e componentes. Estes parmetros especificam os valores iniciais de caractersticas como nome do componente e sua posio no formulrio. A pginas Events (Eventos) permite associar os componentes com aes do usurio. Para ativar o ObectInspector durante a programao deve-se pressionar a tecla F11. Para nomear os componentes podemos usar uma conveno muito usada, onde as primeiras letras, minsculas, identificam o tipo do componente e o restante identifica a funo deste, assim, btnSair, seria o boto de sair. Se a funo do componente for um nome composto esse nome deve ser escrito com os primeiros nomes abreviados e com letras de caso varivel, como em btnRelVendas, que seria o boto do relatrio de vendas ou btnRelVenProduto, que seria o boto do relatrio de vendas por produto.

7.10.2 Propriedades
As propriedades so caractersticas dos componentes, como foi mostrado anteriormente.

7.10.2.1 Propriedades Comuns


Propriedade Align Canvas Caption Color ComponentCount Components Linguagem de Programao II - URI Campus de Frederico Westphalen Descrio Determina o alinhamento do componente Superfcie de desenho, do tipo TCanvas, onde pode se desenhar a imagem do componente Legenda do componente (& indica tecla de atalho para alguns componentes) Cor do componente O nmero de componentes possudos Matriz de componentes possudos

57

Linguagem de Programao II - URI Campus de Frederico Westphalen

58

Ctl3D Enabled Font Height HelpContext Hint Left Name PopupMenu ShowHint TabOrder TabStop Tag Top Visible Width

Define a aparncia 3D do componente Define se o componente est ativo, se pode ser usado Fonte utilizada no componente Altura Nmero utilizado para chamar o Help on-line String utilizada em dicas instantneas Posio esquerda Nome do componente Menu de contexto do componente Define se o Hint ser mostrado A ordem de tabulao do componente, usada quando o usurio tecla TAB Indica se o componente ser selecionado quando o usurio teclar TAB Propriedade no utilizada pelo Delphi, que pode ser usada como propriedade personalizada Posio superior Define se o componente est visvel Largura

7.10.4 Mtodos
Os mtodos realizam aes definidas pelo componente, veja os exemplos abaixo e atente para os parmetros passados. Note que podemos chamar os mtodos de evento como qualquer outro mtodo e que os mtodos de evento pertencem ao Form, no aos componentes.
Edit1.Clear; Form2.Show; Close; ScaleBy(110, 100); Button1.ScrollBy(10, 10); Button1.OnClick(Sender); Button1Click(Self); Form2.Button1Click(Sender);

7.10.4.1 Mtodos Comuns


Mtodo Create Free Show Hide SetFocus Focused BringToFront SendToBack ScrollBy ScaleBy SetBounds Descrio Cria um novo Objeto de uma Classe Destri um Objeto e libera a memria ocupada por ele Torna o componente visvel Torna o componente invisvel Coloca o foco no componente Determina se o componente tem o foco Coloca o componente na frente dos outros Coloca o componente atrs dos outros Move o componente Gradua o componente em determina escala Muda a posio e o tamanho do componente

7.10.3 Eventos
Os Eventos acontecem em resposta a uma ao do usurio ou do prprio sistema, ao programar um mtodo de evento, devemos levar em considerao que este s ser executados quando o evento acontecer. Uma das tarefas mais importantes na programao baseada em eventos determinar quais eventos sero usados e qual a ordem desses eventos, por exemplo, quando o usurio clicar em um boto, qual evento acontecer primeiro, OnEnter, OnMouseDown ou OnClick? Os eventos podem ser compartilhados entre componentes, dessa Forma, voc pode ter um boto na barra de ferramentas que faz a mesma coisa que uma opo de menu. Para isso, basta escolher o evento na lista em vez de clicar duas vezes no Object Inspector. Podemos tambm mudar os mtodos de evento em cdigo, pois os eventos tambm so propriedades e podem ser usados como tal. Voc pode atribuir um evento de outro componente ou diretamente o nome do mtodo, como mostrado abaixo.
Button1.OnClick := Edit1.OnExit; Button2.OnClick := Edit2Click;

7.10.5 Forms (janelas)


Todo aplicativo Windows composto por janelas, que so o elemento bsico no desenvolvimento Delphi, sobre o qual um aplicativo construdo. O tipo TForm usado no Delphi como classe base para todas as janelas, veja abaixo algumas propriedades, eventos e mtodos dessa classe.
Propriedade Descrio Active Indica se o Form est ativo ActiveContro Determina o controle que receber o foco por default l AutoScroll Adiciona barras de rolagem automaticamente, quando necessrio BorderIcons Define quais cones de controle sero visveis, quais botes vo aparecer na barra de ttulo BorderStyle Estilo da borda do Form FormStyle Tipo de Form, normal, MDI pai, MDI filho ou sempre visvel Icon cone do Form Menu Indica qual o menu do Form Position Permite controlar a posio e tamanho do Form na exibio WindowMen Automatiza o item de menu Window (MDI) u WindowState Estado do Form, maximizada, minimizada ou normal Evento Descrio OnCreate Quando o Form instanciado OnDestroy Quando o Form liberado da memria OnShow Exatamente antes de mostrar o Form OnCloseQuer chamada para validar se o Form pode ser fechado y Linguagem de Programao II - URI Campus de Frederico Westphalen

7.10.3.1 Eventos Comuns


Evento OnChange OnClick OnDblClick OnEnter OnExit OnKeyDown OnKeyPress OnKeyUp Descrio O contedo do componente alterado O componente acionado Duplo-clique no componente O componente recebe o foco O componente perde o foco Tecla pressionada Uma tecla pressionada e solta Tecla solta

Linguagem de Programao II - URI Campus de Frederico Westphalen

59

60

OnClose OnActivate OnDeactivate OnResize Mtodo Cascade Tile ArrangeIcons ShowModal Show Close Previous Next

Quando o Form fechado Quando o Form recebe o foco Quando o Form perde o foco Quando o Form muda de tamanho Descrio Organiza as Forms filhos em cascata (MDI) Organiza as Forms filhos lado a lado (MDI) Organiza os cones dos Forms Filhos minimizados (MDI) Ativa o Form modal, que o usurio tem que fechar para poder continuar a usar a aplicao Mostra o Form Fecha o Form Ativa o Form anterior (MDI) Ativa a prximo Form (MDI)

7.10.7 TPopUpMenu
Menu de contexto de um componente. Cada componente tem uma propriedade PopUpMenu, que indica seu menu de contexto.

7.10.8 TLabel
Utilizado para exibir rtulos
Propriedade Alignment AutoSize WordWrap Transparent FocusControl ShowAccelChar Descrio Alinhamento do texto no componente Define se o tamanho do componente ser automaticamente ajustado ao tamanho do Caption Retorno automtico de linha Define se o componente ser transparente Componente que receber o foco quando a tecla de atalho do Caption (&) for pressionada Indica se o caractere & ser usado para definir tecla de atalho

7.10.6 TMainMenu
Menu principal de um Form.
Propriedade Items Descrio Itens de menu, essa propriedade guarda todas as alteraes feitas no Menu Designer

7.10.9 TEdit
Utilizado para entrada de texto em uma nica linha. Este componente permite somente a utilizao de texto (string), portanto qualquer leitura e escrita que envolva nmeros deve ser realizada com a respectiva converso de String para Inteiro (StrToInt ou StrToIntDef), de String para Real (StrToFloat), de Inteiro para String (IntToStr) ou de Real para String (FloatToStr). Exemplo:
Var x: integer; begin Edit1.text := Teste de Sistema; x := StrToInt(Edit2.text) * 2 ; Edit3.text := IntToStr(x); Edit4.clear; Propriedade Text AutoSelect MaxLength CharCase PasswordChar ReadOnly Mtodo Clear ClearSelection Descrio Texto do componente Indica se o texto ser ou no selecionado quando o componente receber o foco Nmero mximo de caracteres permitidos Define se as letras aparecero em maisculo, minsculo ou normal Caractere utilizado para esconder o texto digitado (Senhas) Define se ser permitido alterar o texto Descrio Limpa o contedo do componente Limpa o texto selecionado no componente

Este componente permite a fcil construo de menus. Aps sua colocao no form, basta executar um duplo-click que aparecer o MenuDesigner, colocando na propriedade Caption o contedo do item de menu. Voc pode clicar e arrastar os itens do menu para rearranj-los em seu projeto. No necessrio rodar o projeto para ver os resultados o menu est sempre visvel na janela de formulrio, com a aparncia que ter durante a execuo do programa. Para se criar sub-menus, clique com o boto direito do mouse no item que voc deseja criar o sub-menu, e escolha a opo Create Submenu (Ctrl+Right); o processo de construo igual ao descrito acima. No h limite para os nveis de sub-menu. Pode-se deletar menus selecionan-dos, e pressinando a tecla Del; e inserir menus clicando-se na tecla Insert - estas operaes so igualmente possveis atravs do acionamento de speedmenu do MenuDesigner (acessa-se o speedmenu, clicando-se o boto direito do mouse sob o MenuDesigner). Colocando um & antes de uma letra do menu (capitulao), ela aparece sublinhada. O usurio pode selecionar a opo do menu apenas pressionando a letra quando o menu estiver aberto. Regras para capitulao: 1 primeira letra; 2 se houver duas letras iniciais iguais, pega-se a primeira consoante; se houver a primeira consoante igual; pega-se o Segunda consoante e assim procede-se at esgortar-se as consoantes; 3 caso os passos 1 e 2 se esgotarem, pega-se a primeira vogal e assim sucessivamente; 4 se no for possvel capitular as opes, pode-se diferencia-las com o acrscimo de caracteres extras ou optar-se por no capitul-las

7.10.10 TMemo
Permite entrada de dados texto em mltiplas linhas. Contm propriedades e mtodos do TEdit. Este componente tambm permite somente a utilizao de texto (string), portanto qualquer leitura e escrita que envolva nmeros deve ser realizada com a respectiva converso de String para Inteiro (StrToInt ou StrToIntDef), de String para Real (StrToFloat), de Inteiro para String (IntToStr) ou de Real para String (FloatToStr).

Linguagem de Programao II - URI Campus de Frederico Westphalen

61

Linguagem de Programao II - URI Campus de Frederico Westphalen

62

Exemplo:
Var x: integer; begin memo1.clear; memol.lines.add(Teste de Sistema); x := StrToInt(Edit2.text) * 2 ; memo1.lines.add(IntToStr(x));

ExtendedSelect IntegralHeight Items ItemIndex Selected SelCount Sorted

Define se a seleo poder ser estendida pelo uso das teclas Shift e Ctrl Define se os itens podero aparecer parcialmente ou somente por completo Lista de strings com os itens da lista ndice do item selecionado, comeando em 0 De acordo com o ndice indica se um item em particular esta selecionado Indica quantos itens esto selecionado Define se os itens aparecero ordenados

7.10.15 TComboBox
Propriedade Lines WantReturns WantTabs ScrollBar Descrio Propriedade do tipo TStrings que armazena as linhas de texto do componente Define se a tecla ENTER ser tratada como quebra de linha Define se a tecla TAB ser tratada como espao de tabulao Define as barras de rolagem

Caixa combinada com lista suspensa.


Propriedade Items DropDownCount Style Descrio Lista de strings com os itens da lista Nmero de itens visveis da lista suspensa Estilo do ComboBox, os principais estilos so csDropDown, csDropDownList, csSimple

7.10.11 TButton
Componente boto padro do Windows, utilizado para executar aes.
Propriedade Cancel Default ModalResult Mtodo Click Descrio Dispara o evento OnClick do boto quando a tecla ESC pressionada em qualquer controle Dispara o evento OnClick do boto quando a tecla ENTER pressionada em qualquer controle Associa o boto a opo de fechamento de um Form modal Descrio Ativa o evento OnClick do boto

7.10.16 TScrollBox
Container com barras de rolagem automticas.

7.10.17 TGroupBox
Componente container com um ttulo e borda 3D. Utilizado com RadioButtons.

7.10.12 TCheckBox
Utilizado para obter inFormaes de checagem.
Propriedade AllowGrayed Checked State Descrio Determina se o checkbox ter trs possibilidades de estado Determina se o checkbox est marcado Estado atual do checkbox

7.10.18 TRadioGroup
Componente que agrupa e controla RadioButtons automaticamente.
Propriedade Columns Items ItemIndex Descrio Nmero de colunas de RadioButtons Lista de strings com os itens do RadioGroup, cada item da lista representa um RadioButton Item selecionado, iniciando em 0

A principal propriedade deste componente a Checked, que indica se o CheckBox est marcado ou desmarcado. Tipicamente, este controle mostra dois tipos de escolha (True ou False). Mas podemos configurar para que ele mostre trs estados diferentes. Para isto colocamos a propriedade AllowGrayed para True e passamos a ler o estado do componente pela propriedade State, que pode assumir um dos trs valores seguintes: cbUnchecked, cbGrayed, cbChecked.

Para acessar o ndice do componente selecionado utilize: <nome do componente>.ItemIndex Ex.: showmessage (Selecionada a + IntToStr(RadioGroup1.ItemIndex) + Opo.); showmessage (Selecionada a + IntToStr(ComboBox1.ItemIndex) + Opo.); showmessage (Selecionada a + IntToStr(ListBox1.ItemIndex) + Opo.); Para acessar o texto do componente selecionado utilize: <nome do componente>.Items[<nome do componente>.ItemIndex ] showmessage (Opo escolhida: + ListBox1.Items[ListBox1.ItemIndex]); showmessage (Opo escolhida: + RadioGruop1.Items[RadioGroup1.ItemIndex]); showmessage (Opo escolhida: + ComboBox1.Items[ComboBox1.ItemIndex]); showmessage (Opo escolhida: + ComboBox1.Text);

7.10.13 TRadioButton
Usado em grupo, pode ser utilizado para obter inFormaes lgicas mutuamente exclusivas, mas recomendado usar o RadioGroup em vez de RadioButtons.

7.10.14 TListBox
Utilizado para exibir opes em uma lista.
Propriedade Columns MultiSelect Descrio Nmero de colunas de texto da lista Define se ser permitida a seleo de mltiplos itens

7.10.19 TPanel
Componente Container utilizado para agrupar componentes em um painel. 63
Linguagem de Programao II - URI Campus de Frederico Westphalen

Linguagem de Programao II - URI Campus de Frederico Westphalen

64

Propriedade BevelInner BevelOuter BevelWidth BorderStyle BorderWidth

Descrio Estilo da moldura interna do painel Estilo da moldura externa do painel Largura das molduras Estilo da Borda Largura da borda, distncia entre as molduras interna e externa

7.10.23 TBevel
Moldura ou linha com aparncia 3D.
Propriedade Shape Style Descrio Tipo de moldura a ser desenhada Define alto ou baixo relevo para a linha

7.10.20 TActionList
Usado para criar lista de aes para serem usadas com SpeedButtons e MenuItems.

7.10.24 TShape
Grfico de uma Forma geomtrica.

7.10.21 TBitBtn
Boto especializado, com Bitmap.
Propriedade Glyph LayOut Margin Spacing Kind Descrio Bitmap exibido pelo boto Posio do Bitmap no Boto Indica o espao entre a borda do boto e o Bitmap Indica o espao entre o Bitmap e o texto do boto Seleciona um tipo padro para o boto, mudando vrias propriedades, como Glyph e ModalResult

Propriedade Brush Pen Shape

Descrio Preenchimento da figura, objeto do tipo TBrush Tipo da linha, objeto do tipo TPen Forma geomtrica

7.10.25 TImage
Componente usado para exibir figuras.
Propriedade Center Picture Stretch Descrio Determina de a figura ser centralizada no componente Figura a exibida, pode ser BMP, ICO, WMF ou EMF Define se o tamanho da figura deve ser ajustada ao do componente

7.10.22 TMaskEdit
Permite entrada de dados texto em uma linha, utilizando uma mscara de edio. Possui todas as propriedades do componente TEdit.
Propriedade EditMask Descrio Mscara de edio

7.10.26 TPageControl
Usado para criar controles com mltiplas pginas, que podem ser manipuladas, em tempo de projeto, atravs do menu de contexto. Cada pgina criada um objeto do tipo TTabSheet.
Propriedade ActivePage MultiLine TabHeigth TabWidth Evento OnChange OnChanging Mtodo FindNextPage SelectNextPage Descrio Pgina ativa Define mltiplas linhas de guias de pginas Altura das guias Largura das guias Descrio Aps uma mudana de pgina Permite a validao de uma mudana de pgina Descrio Retorna a prxima pgina Seleciona a prxima pgina

Mscaras Uma mscara composta por trs partes, a primeira parte a mscara propriamente dita, a segunda parte indica se os caracteres literais sero salvos e a terceira parte indica qual o caractere utilizado para representar os espaos a serem digitados no texto. Estes so os caracteres especiais que podem compor a mscara de edio:
Caractere ! > < \ l L a A 9 0 c C # : / Descrio Espaos em branco no sero considerados no texto Todos os caracteres seguintes sero maisculos at que aparea o caractere < Todos os caracteres seguintes sero minsculos at que aparea o caractere > Indica um caractere literal Somente caractere alfabtico Obrigatoriamente um caractere alfabtico Somente caractere alfanumrico Obrigatoriamente caractere alfanumrico Somente caractere numrico Obrigatoriamente caractere numrico Permite um caractere Obrigatoriamente um caractere Permite um caractere numrico ou sinal de mais ou de menos, mas no os requer. Separador de horas, minutos e segundos Separador de dias, meses e anos

7.10.27 TTabSheet
Pgina de um PageControl.
Propriedade PageIndex TabVisible Descrio Ordem da pgina Define se a aba da pgina visvel

7.10.28 TTimer
Permite a execuo de um evento a cada intervalo de tempo. 65
Linguagem de Programao II - URI Campus de Frederico Westphalen

Linguagem de Programao II - URI Campus de Frederico Westphalen

66

Propriedade Interval Evento OnTimer

Descrio Tempo em milissegundos quando o componente ir disparar o evento OnTimer Descrio Chamado a cada ciclo de tempo determinado em Interval

7.11 Caixas de Mensagem


Existem algumas funes que permitem mostrar uma mensagem rapidamente em uma caixa de dilogo. So elas: ShowMessage, MessageDlg e MessageBox.

7.10.29 TStatusBar
Utilizado para criar barras de status para exibir informaes.
Propriedade SimplePanel SimpleText SizeGrip Panels Descrio Indica se haver apenas um panel Texto exibido caso SimplePanel seja True Define se a ala de redimensionamento padro deve ser mostrada Propriedade do tipo TStatusPanels, com os painis do StatusBar. O texto da barra de status definido com a propriedade StatusBarX.panels[X].text

7.11.1 ShowMessage
Esta funo permite colocar uma caixa de dilogo contendo um boto de OK e uma mensagem. No podemos colocar outros botes nem mudar o ttulo, que sempre o nome do programa.
showmessage(Coloque sua mensagem aqui!);

7.10.30 TStatusPanels
Lista de panels de um StatusBar.
Propriedade Count Items Mtodo Add Descrio Nmero de panels Lista de panels, cada panel um objeto do tipo TStatusPanel Descrio Adiciona um novo panel lista

7.11.2 MessageBox
Esta permite que atribuam valores arbitrrios ao ttulo e as mensagens. Existem dois tipos de MessageBox: um da API ( MessageBox ) e um do Delphi ( Application.MessageBox ). Ambos permitem que se atribuam valores tanto ao recheio como para o ttulo; tambm permitem que se acrescentem constantes MB_xxx para mudar o aspecto da caixa de dilogo. MessageBox retorna um valor dependendo do boto pressionado. Sintaxe: MessageBox(<Mensagem da caixa>, <Titulo>, Constantes MB_xxx); <Mensagem da caixa>: string que ser mostrado no interior da caixa. <Titulo>: string que ser mostrado no titulo da caixa. <Constantes MB_xxx>: concatenao de constantes que mudaro o aspecto da caixa. Podem ser:
Valor MB_ABORTRETRYIGNORE MB_APPLMODAL MB_DEFBUTTON1 MB_DEFBUTTON2 MB_DEFBUTTON3 MB_DEFBUTTON4 MB_HELP MB_ICONASTERISK MB_ICONERROR MB_ICONEXCLAMATION MB_ICONHAND MB_ICONINFORMATION MB_ICONQUESTION MB_ICONSTOP MB_ICONWARNING MB_OK Significado A caixa de dilogo conter trs botes: Anular, Repetir e Ignorar A caixa de dilogo ser modal. O primeiro boto da caixa de dilogo fica como default O segundo boto da caixa de dilogo fica como default O terceiro boto da caixa de dilogo fica como default O quarto boto da caixa de dilogo fica como default adicionado um boto de Ajuda na caixa de dilogo, quando for pressionado ou a tecla F1 gerado o evento de Help, vlido somente para Windows 95, Mostra um i azul, minsculo dentro de um balo (MB_ICONINFORMATION) Mostra um X banco, dentro de um circulo vermelho, o mesmo que MB_ICONHAND, somente para windowes 95. Mostra um ponto de exclamao, dentro de um tringulo amarelo O mesmo que MB_ICONSTOP O mesmo que MB_ICONASTERIX Mostra um ponto de interrogao dentro de um balo O mesmo que MB_ICONERROR O mesmo quer MB_ICONEXCLAMATION, vlido somente para windows 95. A caixa de dilogo conter um boto de OK

7.10.31 TStatusPanel
Panel de um StatusBar.
Propriedade Text Width Bevel Alignment Descrio Texto do panel Largura em pixels Moldura do panel Alinhamento do texto de um panel

7.10.32 TStringGrid
Componente para exibio e edio de uma tabela de strings. organizado em linhas e colunas e o elemento bsico a celula.
Propriedade ColCount RowCount DefaultColWidth DefaultRowHeight Cells FixedCols FixedRows Row Col Options LoadFromFile SaveToFile Descrio Quantidade de lolunas Quantidade de linhas Altura padro das colunas Largura padro das linhas Texto das clulas. uma matriz em que deve ser especificado linha e coluna. Exemplo: StringGrid1.cells[2,3] Quantidade de Colunas fixas Quantidade de Linhas fixas Linha Selecionada Coluna selecionada Conjunto de Opes do StringGrid Carrega figura de um arquivo Salva figura para um arquivo

Linguagem de Programao II - URI Campus de Frederico Westphalen

67

Linguagem de Programao II - URI Campus de Frederico Westphalen

68

MB_OKCANCEL MB_RETRYCANCEL MB_YESNO MB_YESNOCANCEL

A caixa de dilogo conter os botes de OK e Cancelar A caixa de dilogo conter botes de Repetir e Cancelar A caixa de dilogo conter botes de Sim e No A caixa de dilogo conter botes de Sim, No e Cancelar

7.12 Dicas
Resumo dos componentes com as principais propriedades e mtodos:

Esta funo pode retornar valores dependendo do pressionamento dos botes.


Valor IDABORT IDCANCEL IDIGNORE IDNO IDOK IDRETRY IDYES Valor numrico 3 2 5 7 1 4 6 Significado O usrio pressionou o boto de Anular O usrio pressionou o boto de Cancelar O usrio pressionou o boto de Ignorar O usrio pressionou o boto de No O usrio pressionou o boto de OK O usrio pressionou o boto de Repetir O usrio pressionou o boto de Sim

Componente Application

Propriedades

Mtodos Initialize; CreateForm Run; Terminate Close Show Showmodal

Form Label Caption Enabled Font Name Enabled Font Maxlength Name PasswordChar ReadOnly Text Caption Enabled Font Name Text Caption Checked Enabled Font Name Caption Checked Enabled Font Name State Enabled Font Lines Maxlength Name ReadOnly ScrollBars Enabled Font Items MultiSelect Name Sorted

Exemplo: O cdigo abaixo:


Application.MessageBox('A terra azul - tricolor', 'Confirmao', MB_APPLMODAL + MB_ICONWARNING + MB_YESNOCANCEL);

Edit

Setfocus Clear

Ter como resultado a seguinte caixa de dilogo:


Button

Setfocus

RadioButton

Setfocus

Exemplo: O cdigo abaixo:


if Application.MessageBox('A terra azul - tricolor','Confirmao', MB_APPLMODAL + MB_ICONWARNING + MB_YESNOCANCEL) = idyes then

begin showmessage('Realmente azul!'); end;

CheckBox

Setfocus

7.11.3 InputBox
Permite que o usurio digite uma string na caixa de dilogo. Possui os botes OK e Cancel. Se o usurio clicar em cancel o texto padro retornado. Sintaxe: InputBox(<Ttulo>, <Mensagem da Caixa>, <texto padro>
var Texto: string; begin Texto:= InputBox('Gerenciador de Aplicativo', 'Informe a Senha', 'Ningum'); showmessage(texto); end; Linguagem de Programao II - URI Campus de Frederico Westphalen

Memo

Clear Lines.Add Lines.Count Setfocus

ListBox

Clear Items.Add Items.Count Setfocus

69

Linguagem de Programao II - URI Campus de Frederico Westphalen

70

ComboBox

RadioGroup

Enabled Font ItemIndex Items Name Sorted Text Enabled Font ItemIndex Items Name

Clear Items.Add Items.Delete Items.Count Setfocus Items.Add Items.Delete Items.Count Setfocus

Para pedir confirmao antes de encerrar o programa, inserir o cdigo abaixo no evento OnCloseQuery do Formulrio:

if application.messagebox('Encerrar o Programa?', 'Confirmao', MB_APPLMODAL+MB_ICONQUESTION+MB_YESNO) = idyes then canclose:= true else canclose:= false;

Converses Todos os componentes de entrada de dados utilizam a propriedade text que string. Para manipulao de nmeros necessrio uma converso do formato.
Funo Date DateToStr DecodeDate DecodeTime Now FloatToStr FormatFloat Descrio retorna a data corrente converte um valor data em string. Separa a data em dia, ms, ano Separa a hora em hora, minutos, segundos, centsimos Retorna a data e hora do sistema converte um nmero float numa string. formata um nmero float e retorna uma string. (#,##.00,10000,2) = 10.000,24 converte um nmero inteiro numa string. converte uma string num nmero inteiro e atribui um valor padro em caso de erro transforma um nmero em string com nmero de casas pr-definido converte uma string em data. converte uma string num nmero float. converte uma string num nmero inteiro converte uma string em hora retorna a hora corrente. converte a hora corrente em string. Transforma uma string num nmero e permite analisar o sucesso desta transformao Exemplo Edit.text := 'Hoje ' + DateToStr(Date); DecodeDate(Date, ano, mes, dia); DecodeTime(Now, Hora, Min, Seg, cent);

procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char); begin


if ((key<'0') or (key>'9')) and (key<>#8) and (key<>#13) then begin Messagebeep(0); key:=#0; end;

Para aceitar somente nmeros em campos Edit e ComboBox, Inserir o cdigo abaixo no evento OnKeyPress do controle de edio:

end;

Para saltar de um campo para outro usando a tecla ENTER, Inserir o cdigo abaixo no evento OnKeyPress do controle de edio de cada componente:
procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char); begin if Key=#13 then begin SelectNext(Sender as TWinControl, True, True); key:=#0; end; end;

Edit1.text:=FloatToStr(x) formatfloat ('#,##.00', strtofloat(Edit1.text))

IntToStr StrToIntDef

Edit1.Text := IntToStr(x); x := StrToIntDef(Edit1.text, 0);

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char); begin if key=#13 then begin key:=#0; PostMessage( handle, WM_KEYDOWN, VK_TAB, 1); end; end;

Para saltar de um campo para outro usando a tecla ENTER de todos os componentes, Inserir o cdigo abaixo no evento OnKeyPress do Formulrio:

Str StrToDate StrToFloat StrToInt StrToTime Time TimeToStr Val

Str(X:0:2, S); CData := StrToDate(Edit1.Text); x:= StrToFloat(edit1.text); i:= x:= StrToInt(edit1.text); ATime := StrToTime(Edit1.Text); Edit1.text := 'A hora ' + TimeToStr(Time)

Atribua true propriedade KeyPreview do Formulrio. Esta rotina no funcionar em formulrios que tenham TMemo ou TDBMemo. Estes componentes precisam da tecla ENTER para gerar novas linhas. Em formulrios assim, a rotina pode ser usada, desde que seja inserido no evento OnEnter do componente Memo o cdigo:
procedure TForm1.Memo1Enter(Sender: TObject); begin Form1.KeyPreview:=false; end; procedure TForm1.Memo1Exit(Sender: TObject); begin Form1.KeyPreview:=true; end;

e no envento OnExit o cdigo

var I, erro: Integer; begin Val(Edit1.Text, I, erro); if erro <> 0 then begin Showmessage('Erro); end;

Linguagem de Programao II - URI Campus de Frederico Westphalen

71

Linguagem de Programao II - URI Campus de Frederico Westphalen

72

7.13 Exemplos de Programas em Delphi


1. Faa um programa em Delphi que leia o nome e o sobrenome e escreva o nome completo. O programa deve ter: - 2 campos de entrada de valor - 1 campo de escrita - 2 botes de ao: OK e Limpar

Edit3.clear; Edit1.setFocus; Observe que o cdigo deve ficar dentro do procedimento que implementa o evento, desta forma: procedure TForm1.Button2Click(Sender: TObject); begin Edit1.clear; Edit2.clear; Edit3.clear; Edit1.setFocus; end;

2. Faa um programa em Delphi que leia 2 nmeros e escreva a soma dos mesmos. O programa deve ter: - 2 campos de entrada de valor - 1 campo de escrita - 2 botes de ao: OK e Limpar

Mude o ttulo da janela do Form (propriedade Caption do Form) para Nome Completo; Mude as propriedades do campo que escreve o Nome Completo para que fique somente leitura (ReadOnly = true) e que no aceite a parada na tabulao (TabStop = false); Implemente o mtodo ao clicar no do boto OK, dando 2 cliques sobre o mesmo ou selecionando o boto e dando 2 cliques sobre o evento OnClick do ObjectInspector, colocando o seguinte cdigo
Edit3.text := Edit1.text + ' ' + Edit2.Text;

Observe que o cdigo deve ficar dentro do procedimento que implementa o evento, desta forma:
procedure TForm1.Button1Click(Sender: TObject); begin Edit3.text := Edit1.text + ' ' + Edit2.Text; end;

Mude o ttulo da janela do Form (propriedade Caption do Form) para Soma de 2 Nmeros; Mude as propriedades do campo que escreve a Soma para que fique somente leitura (ReadOnly = true) e que no aceite a parada na tabulao (TabStop = false); Implemente o mtodo ao clicar no do boto OK, dando 2 cliques sobre o mesmo ou selecionando o boto e dando 2 cliques sobre o evento OnClick do ObjectInspector, criando 3 variveis (a, b, soma) e implementando o seguinte cdigo:

Importante: Quando for apagar um cdigo, apague somente o cdigo que voc escreveu. A estrutura que o Delphi criou para implementar os eventos no pode ser apagada por voc. Se quiser remover, deixe-a sem nenhum cdigo implementado, que na prxima Compilao, o Delphi a remover. Implemente o mtodo ao clicar no do boto Limpar, dando 2 cliques sobre o mesmo ou selecionando o boto e dando 2 cliques sobre o evento OnClick do ObjectInspector, colocando o seguinte cdigo

Edit1.clear; Edit2.clear; Linguagem de Programao II - URI Campus de Frederico Westphalen

procedure TForm1.Button1Click(Sender: TObject); var a, b, soma: integer; begin a:= StrToInt(Edit1.Text); b:= StrToInt(Edit2.Text); soma := a + b; Edit3.text := IntToStr(soma); end; Linguagem de Programao II - URI Campus de Frederico Westphalen

O Delphi cria esta estrutura para implementar os eventos. O programa deve ser implementado dentro dela

73

74

Implemente o mtodo ao clicar no do boto Limpar, dando 2 cliques sobre o mesmo ou selecionando o boto e dando 2 cliques sobre o evento OnClick do ObjectInspector, colocando o seguinte cdigo:
end;

procedure TForm1.Button2Click(Sender: TObject); begin Edit1.clear; Edit2.clear; Edit3.clear; Edit1.setFocus; end;

begin if i mod x = 0 then begin memo1.lines.add(IntToStr(i)); end; end;

end;

Implemente o evento ao clicar no Boto Limpar:

3. Faa um programa em Delphi que leia um nmero e escreva os seus mltiplos entre 1 e 200. O programa deve ter: 1 campos de entrada de valor 1memo para a apresentao do resultado 3 botes de ao: Executar, limpar, sair

procedure TForm1.BtLimparClick(Sender: TObject); begin memo1.clear; edit1.clear; Edit1.SetFocus; end;

Implemente o evento ao clicar no Boto Sair:

procedure TForm1.BtSairClick(Sender: TObject); begin close; end;

4. Faa um programa em Delphi que leia um valor para a escolha e 3 valores para serem ordenados e escreva: - em ordem crescente, se a escolha for o primeiro boto - em ordem decrescente, se i a escolha for o segundo boto - o maior valor entre os dois, se i a escolha for o terceiro boto O programa deve ter: 1RadioGroup com 3 RadioButtons (Opo 1, 2, 3) 3 campos de entrada de valor 1Memo para a apresentao do resultado 3 botes de ao: ordenar, limpar, sair

Renomeie o boto Calcular para BtCalcular Renomeie o boto Limpar para BtLimpar Renomeie o boto Sair BtSair; Implemente o evento ao Clicar no Boto Calcular:

procedure TForm1.BtCalcularClick(Sender: TObject); var x, i: integer; begin memo1.clear; x:=StrToIntDef(Edit1.Text, 0); if x>0 then begin for i:= 1 to 200 do Linguagem de Programao II - URI Campus de Frederico Westphalen

75

Linguagem de Programao II - URI Campus de Frederico Westphalen

76

Implemente o evento do Boto Limpar:

procedure TForm1.BtLimparClick(Sender: TObject); begin Edit1.clear; Edit2.clear; Edit3.clear; Memo1.clear; RadioGroup1.ItemIndex:=-1; Edit1.setfocus; end;

8. ESTRUTURAS, UNIES E ITENS DIVERSOS


8.1 Estruturas
Ns podemos pensar em estruturas como sendo uma matriz ou um vetor de itens intimamente relacionados. Entretanto, ao contrrio da matriz ou vetor, uma estrutura permite que se armazene diferentes tipos de dados. O conceito de estrutura de dados comum no dia-a-dia. Um arquivo de fichas com informaes sobre o cliente uma estrutura de itens relacionados. Ns podemos criar uma estrutura usando a palavra-chave struct e a seguinte sintaxe:
struct tipo { tipo var1; tipo var2; ... tipo varn; } var_tipo,...;

Implemente o evento do Boto Ordenar:

procedure TForm1.BtOrdenarClick(Sender: TObject); var a, b, c, aux: integer; begin Memo1.clear; a:=StrToIntDef(Edit1.text, 0); b:=StrToIntDef(Edit2.text, 0); c:=StrToIntDef(Edit3.text, 0); if a>b then begin aux:=a; a:=b; b:=aux; end; if a>c then begin aux:=a; a:=c; c:=aux; end; if b>c then begin aux:=b; b:=c; c:=aux; end; BtLimpar.setfocus; if RadioGroup1.itemindex=0 then begin memo1.lines.add(IntToStr(a)); memo1.lines.add(IntToStr(b)); memo1.lines.add(IntToStr(c)); end else if RadioGroup1.itemindex=1 then begin memo1.lines.add(IntToStr(c)); memo1.lines.add(IntToStr(b)); memo1.lines.add(IntToStr(a)); end else if RadioGroup1.itemindex=2 then begin memo1.lines.add(IntToStr(a)); memo1.lines.add(IntToStr(c)); memo1.lines.add(IntToStr(b)); end else begin showmessage('Voc deve escolher a ordem de classificao!'); RadioGroup1.setfocus; end end;

Por exemplo se queremos criar uma estrutura (tipo definido pelo usurio) cadastro e definirmos uma varivel cliente que do tipo (estrutura) cadastro:
#include <stdio.h> #include <conio.h> struct cadastro { char nome[30]; char endereco[50]; char cidade[20]; } cliente; void main() { printf(Nome: ); gets(cliente.nome); printf(Endereo: ); gets(cliente.endereco); printf(Cidade: ); gets(cliente.cidade); clrscr(); printf(%s mora na rua %s, na cidade de %s, cliente.nome, cliente.endereco,cliente.cidade); }

Linguagem de Programao II - URI Campus de Frederico Westphalen

77

Linguagem de Programao II - URI Campus de Frederico Westphalen

78

8.1.1 Passando uma estrutura para uma funo


Podem ocorrer situaes que teremos que passar informaes de estruturas para funes. Quando uma estrutura passada para uma funo, as informaes da estrutura so passadas por valor, e assim a funo no altera a estrutura original. Por exemplo se a impresso dos dados do exemplo anterior fosse passada para uma funo:
#include <stdio.h> #include <conio.h> struct cadastro { char nome[30]; char endereco[50]; char cidade[20]; }; void imprime(struct cadastro pessoas); void main() { struct cadastro cliente printf(Nome: ); gets(cliente.nome); printf(Endereo: ); gets(cliente.endereco); printf(Cidade: ); gets(cliente.cidade); imprime(cliente); } void imprime(struct cadastro pessoas) { clrscr(); printf(%s mora na rua %s, na cidade de %s, pessoas.nome, pessoas.endereco, pessoas.cidade); }

printf(Nome: ); gets(cliente[i].nome); printf(Endereo: ); gets(cliente[i].endereco); printf(Cidade: ); gets(cliente[i].cidade); } clrscr(); for(i=0;i<5;i++) { printf(%s mora na rua %s, na cidade de %s \n, cliente[i].nome, cliente[i].endereco, cliente[i].cidade); } }

8.1.3 Estruturas dentro de estruturas


Podemos aninhar estruturas, isto , tornar uma estrutura parte de uma segunda estrutura. Por exemplo:
#include <stdio.h> #include <conio.h> struct data { int dia; int mes; int ano; }; struct cadastro { char nome[30]; char endereco[50]; char cidade[20]; struct data dnasc; }; void main() { int i; cadastro cliente[5]; for(i=0;i<5;i++) { printf("Nome: "); gets(cliente[i].nome); printf("Endereo: "); gets(cliente[i].endereco); printf("Cidade: "); gets(cliente[i].cidade); fflush(stdin); printf("Data de Nascimento: "); scanf("%d%d%d", &cliente[i].dnasc.dia, &cliente[i].dnasc.mes, &cliente[i].dnasc.ano); fflush(stdin); } clrscr(); for(i=0;i<5;i++) { printf("%s mora na rua %s, na cidade de %s\n", cliente[i].nome, cliente[i].endereco,cliente[i].cidade); Linguagem de Programao II - URI Campus de Frederico Westphalen

8.1.2 Matriz de Estruturas


Podemos criar uma matriz de estruturas, o que semelhante a um fichrio que contm diversas fichas de clientes. Por exemplo:
#include <stdio.h> #include <conio.h> struct cadastro { char nome[30]; char endereco[50]; char cidade[20]; } cliente[5]; void main() { int i; for(i=0;i<5;i++) { Linguagem de Programao II - URI Campus de Frederico Westphalen

79

80

printf("E nasceu no dia %d/%d/%d\n", cliente[i].dnasc.dia, cliente[i].dnasc.mes, cliente[i].dnasc.ano); } }

void leprod(produto *ptr); void imprimeprod(produto *ptr); void main() { leprod(&p1); leprod(&p2); clrscr(); imprimeprod(&p1); imprimeprod(&p2); getch(); } void leprod(produto *ptr) { int aux; float aux2; fflush(stdin); printf("Codigo: "); scanf("%d",&aux); ptr->codigo = aux; fflush(stdin); printf("Descricao: "); gets(ptr->descr); printf("Preco: "); scanf("%f",&aux2); ptr->preco = aux2; } void imprimeprod(produto *ptr) { printf("%d\n",ptr->codigo); puts(ptr->descr); printf("%0.2f\n",ptr->preco); }

8.1.4 Ponteiros para estruturas


A utilizao de ponteiros para estruturas uma tcnica to comum que um novo operador, conhecido cmo operador seta pelos programadores de C, foi desenvolvido, e tem este aspecto: -> . Em outras palavras, se definirmos uma estrutura denominada meus_dados que seja semelhante a:
struct grande_estrutura_dados { int chave; int grande_vetor[20]; } meus_dados;

Ento poderemos declarar um ponteiro denominado meu_ponteiro para meus_dados como este:
struct grande_estrutura_dados *meu_ponteiro;

E atribuir um valor a ele desta forma:


meu_ponteiro = &meus_dados;

A partir de agora, podemos nos referir aos campos em meus_dados como meus_dados.chave, como:
meu_ponteiro->chave = 5;

o mesmo que o comando a seguir:


meus_dados.chave = 5;

8.1.5 Estruturas em Pascal e Delphi


A declarao RECORD permite-nos definir um registro: <identificador> = RECORD <campo1> : tipo; <campo2> : tipo; ... <campon> : tipo; END; REGISTRO um grupo de informaes relativas a uma mesma entidade. Estas informaes podem ter caractersticas diferentes, como em um R.G., onde temos diversos campos com nome, nome do pai, nome da me, nmero do registro, etc. O registro tem uma particularidade em relao a uma matriz, enquanto em uma matriz podemos ter vrios elementos de um nico tipo, no registro podemos ter elementos com tipos diferentes. A definio de um registro no Turbo Pascal s pode ser feita na rea de tipos (TYPE) e assim sendo, quando definimos um registro, na verdade, estamos criando um tipo novo. Para podermos utilizar este tipo, temos que declar-lo na rea de variveis (VAR), j a manipulao dos Linguagem de Programao II - URI Campus de Frederico Westphalen 82

Em outras palavras, meu_ponteiro um ponteiro para uma estrutura; para alcanar um campo na estrutura para a qual ele aponta, utilize o operador seta, ->. Essa a razo pela qual o operador -> foi desenvolvido: para permitir escolher campos isolados da estrutura que est sendo apontada. Foram includos os operadores * e & expressamente para aqueles casos em que apontamos para uma estrutura, porque & ou * sozinhos no podem acessar elementos. Ou seja, no existe algo como *meu_ponteiro.chave; temos que utilizar em seu lugar meu_ponteiro>chave. Uma estrutura somente pode ser passada para uma funo por referncia, atravs de um ponteiro para a estrutura. Por exemplo:
#include <stdio.h> #include <conio.h> struct produto { int codigo; char descr[80]; float preco; }p1, p2; Linguagem de Programao II - URI Campus de Frederico Westphalen

81

campos de um arquivo deve ser feita atravs da referncia do nome do registro e o nome do campo unidos por um ponto (.).

Pode-se tambm armazenar os registros em memria, atravs do uso de vetores ou matrizes de estrutras.
Exemplo: Program ExemploRegistroSeletivo; uses crt; type cadastro = record codigo: integer; nome: string[30]; rg: string[15]; end; var cad: Array [1..10] of cadastro; i: integer; begin clrscr; for i:= 1 to 10 do begin write('Codigo: '); readln(cad[i].codigo); write('Nome: '); readln(cad[i].nome); write('RG: '); readln(cad[i].rg); end; clrscr; for i:= 1 to 10 do begin writeln(cad[i].codigo, ' - ', cad[i].nome, ' - ', cad[i].rg); end; readkey;

Exemplos : TYPE registro = RECORD nome : STRING[30]; ende : STRING[25]; fone : STRING[8]; idade : BYTE; END; tela END; = RECORD atributo : BYTE; caracter : CHAR;

Exemplo de referncia de um campo do registro :


PROGRAM teste_reg; TYPE registro = RECORD nome :STRING[30]; ende :STRING[25]; fone :STRING[8]; idade :BYTE; END; VAR reg : registro;

end.

BEGIN reg.nome := Roberto; reg.ende := Rua Annima, 0; reg.fone := 999-9999; reg.idade:= 30; writeln(Nome: , reg.nome); writeln(Endereo: , reg.ende); writeln(Fone: , reg.fone); writeln(Idade: , reg.idade); write(Nome: ); readln(reg.nome); write(Endereo: readln(reg.ende); write(Fone: readln(reg.fone); write(Idade: readln(reg.idade); writeln(Nome: , reg.nome); writeln(Endereo: , reg.ende); writeln(Fone: , reg.fone); writeln(Idade: , reg.idade); END.

8.2 Unies
Uma Unio um tipo de dados muito similar uma estrutura, com a diferena de que todos os membros de uma unio compartilham a mesma rea de armazenamento, enquanto cada membro de uma estrutura possui a sua prpria rea. As unies so teis para economizar memria, em situaes nas quais os campos de uma estrutura so mutuamente exclusivos. Ex.:
union algum { int i; char c; } u;

Neste caso, a varivel u somente poder conter o valor do campo i ou do campo c, mas no de ambos. O compilador reservar rea suficiente para o maior tipo contido na unio. Em Pascal e Delphi, podemos ter uma estrutura de registro seletivo :

Linguagem de Programao II - URI Campus de Frederico Westphalen

83

Linguagem de Programao II - URI Campus de Frederico Westphalen

84

Exemplo: Program ExemploRegistroSeletivo; uses crt; type Classe = (Num, Str);

uniao = record Nome: string[30]; case campo: Classe of Num: (N: real); Str: (S: string); end; var un: uniao; op: char; begin clrscr; write('Nome: '); readln(un.nome); writeln('O que voce quer armazenar: [N] Numero - [S] - String?'); op:=readkey; if upcase(op)='N' then begin write('Digite um numero: '); readln(un.N); writeln(un.nome); writeln(un.N:0:6); end else begin write('Digite uma string: '); readln(un.S); writeln(un.nome); writeln(un.S); end; readkey; end.

real a, divisao; int b; a = 7; b = 4; divisao = a/b; printf(%f,divisao); }

8.3.2 enum
O tipo de dado enum permite que criemos um tipo de dado com uma escolha de itens. enum til quando a informao pode ser melhor representada por uma lista de valores inteiros,

Neste tipo de registro, temos a possibilidade de variar a estrutura. dependendo da condio encontrada no decorrer do programa para um campo-sinal previamente declarado como tipo escalar, esta estrutura de seleo chamada de unio discriminada, cabendo desta forma ao programador manter vlida.

8.3 Itens diversos


8.3.1 typedef
Podemos associar novos tipos de dados com os tipos de dados existentes, usando typedef. Por exemplo, podemos definir um tipo de dado chamado real que do tipo float:
#include <stdio.h> typedef float real; void main() { Linguagem de Programao II - URI Campus de Frederico Westphalen

85

Linguagem de Programao II - URI Campus de Frederico Westphalen

86

9. ARQUIVOS
Para comearmos a manipular arquivos, necessitamos lembrar alguns conceitos bsicos a respeito dos mesmos. Quando pensamos em arquivos, a primeira coisa que nos vem memria a idia de um arquivo fsico igual aos arquivos encontrados nos escritrios. De forma geral um arquivo serve para armazenar informaes atravs de fichas. Em informtica, estes conceitos so perfeitamente vlidos, pois para o armazenamento de informaes em um arquivo, temos que dar uma forma ao arquivo e dar forma s informaes que estaro contidas nele.

semelhantes, como por exemplo abrir uma gaveta, retirar ou colocar uma ficha, fechar uma gaveta, identificar o arquivo atravs de uma etiqueta qualquer, organizar as informaes, etc. Veremos ento os comandos para fazermos tais tarefas: O primeiro comando que veremos o que nos permite associar a varivel do tipo arquivo ao nome externo deste arquivo, ou seja, o nome local que este deve estar.

ASSIGN Este procedimento permite que associemos o nome externo de um arquivo a uma varivel do tipo arquivo. O nome externo aquele utilizado pelo sistema operacional, portanto deve ser vlido para o mesmo. So possveis todas as formas de referncia usadas no PATH, e quando a unidade ou subdiretrios forem omitidos, estes assumiro o default. Aps o uso do ASSIGN, este continuar valendo at que seja dado um novo ASSIGN. O tamanho mximo do nome do arquivo de 79 bytes. Este procedimento nunca deve ser usado em um arquivo j aberto, pois caso o nome do arquivo tenha tamanho zero, o arquivo ser associado ao dispositivo padro de saida. Sua sintaxe: ASSIGN(VAR <arq>, <nomearq> : STRING); arq, deve ser uma varivel do tipo arquivo. por exemplo:
Exemplo: PROGRAM teste_assign; VAR arq1, arq2 : FILE OF BYTE; BEGIN ASSIGN(arq2,teste.dat); ASSIGN(arq1,''); {o nome externo do arquivo omitido} END. {determina que o dispositivo de saida } {ser o standart }

9.1 Arquivo tipado em Delphi e Pascal


9.1.1 Declarao de arquivos
A primeira preocupao com relao ao contedo de um arquivo. Em um arquivo fsico, este contedo feito normalmente atravs de fichas que tm informaes de uma mesma forma. Para ns, esta ficha um registro e como j vimos anteriormente, o registro uma estrutura que deve ser definido, na rea de tipos, porm s a definio de um registro no implica na formao de um arquivo. Para form-lo devemos ter um conjunto destas fichas, no nosso caso, devemos declarar uma varivel do tipo arquivo e esta varivel pode ser declarada de duas formas bsicas :

FILE Esta declarao define uma varivel como sendo arquivo. Sua sintaxe : identificador : FILE OF tipo; ou identificador : FILE; Vejamos um exemplo de definio de um tipo arquivo:
TYPE registro = RECORD nome : STRING[30]; cep : LONGINT; rg : STRING[8]; cic : STRING[11]; END; VAR arquivo_pessoal : FILE OF registro; arquivo_numerico : FILE OF BYTE; arquivo_sem_tipo : FILE;

9.1.2 Funes de abertura e fechamento de arquivos


Com a definio de uma varivel do tipo arquivo e a sua associao a um nome de arquivo externo, j temos um bom caminho andado, porm ainda nos faltam alguns comandos bsicos para, efetivamente, podermos manipular os arquivos. Voltando analogia com um arquivo de ao, veremos que a primeira coisa que faremos para dar incio a manipulao deste arquivo abri-lo. Pois bem, no nosso arquivo, tambm deveremos ter esta atividade, ou seja, abrir o arquivo e para isto temos dois comandos bsicos:

RESET Este procedimento permite-nos abrir um arquivo j existente. No caso do uso deste, para a tentativa de abertura de um arquivo no existente, ocorrer um erro de execuo. Para que o

Porm, somente a declarao de uma varivel do tipo arquivo no quer dizer que j podemos manipular o arquivo, assim como no arquivo fsico, aquele de ao, aqui teremos tarefas
Linguagem de Programao II - URI Campus de Frederico Westphalen

87

Linguagem de Programao II - URI Campus de Frederico Westphalen

88

procedimento tenha sucesso necessrio que antes de execut-lo, tenhamos utilizado o procedimento ASSIGN. Sua sintaxe : RESET(VAR <arquivo> [:FILE; <tamanho> : WORD]);
Exemplo: PROGRAM teste_reset; Uses CRT; VAR arquivo : FILE OF BYTE; nomearq : STRING[67]; BEGIN WRITE('Entre com o nome do arquivo que quer abrir ') ; READLN(nomearq); ASSIGN(arquivo,nomearq); RESET(arquivo); END.

Pascal chamada IORESULT. Para no abortar um programa quando ocorre um erro de I/O, usa-se a diretiva {$I}. Para voltar ao padro, usa-se a diretiva {$I+}. Por exemplo:
PROGRAM teste_rewrite_ou_close; Uses Crt; VAR arquivo : FILE OF BYTE; nomearq: STRING[67]; BEGIN WRITE('Entre com o nome do arquivo que quer abrir '); READLN(nomearq); ASSIGN(arquivo,nomearq); {$I-} RESET(arquivo); {$I+} if IORESULT <> 0 then REWRITE(arquivo); END.

Este comando apenas permite-nos abrir um arquivo j existente. para que possamos abrir um arquivo novo, temos um outro comando:

REWRITE Este comando permite criar e abrir um novo arquivo. Caso o arquivo j exista, ter seu contedo eliminado e ser gerado um novo arquivo. Antes de executarmos este procedimento, devemos usar o ASSIGN, e caso a varivel do tipo arquivo no seja tipada, o tamanho de cada registro ser de 128 bytes, isto se no for especificado o tamanho do registro. Sua sintaxe: REWRITE(VAR <arquivo> [: FILE ; <tamanho> : WORD]); Vejamos um exemplo, usando o comando REWRITE :
PROGRAM teste_rewrite; Uses Crt; VAR arquivo : FILE OF BYTE; nomearq: STRING[67]; BEGIN WRITE('Entre com o nome do arquivo que quer abrir '); READLN(nomearq); ASSIGN(arquivo,nomearq); REWRITE(arquivo); END.

A segunda tarefa que devemos nos preocupar o fato do arquivo permanecer aberto, ou abrirmos o mesmo arquivo mais de uma vez. Para termos um uso adequado de um arquivo, devemos abri-lo e depois de utilizado fech-lo.

RESET Este procedimento permite gue se feche um arquivo anteriormente aberto, s sendo permitido o fechamento de um arquivo por vez. Sua sintaxe: CLOSE (VAR <arq>); Exemplo :
PROGRAM teste_close; VAR arquivo : FILE OF BYTE; nomearq: STRING[67]; BEGIN WRITE('Entre com o nome do arquivo que quer abrir'); READLN(nomearq); ASSIGN(arquivo,nomearq); REWRITE(arquivo); CLOSE(arquivo); END.

Em ambos os exemplos anteriores, vemos uma deficincia. Enquanto um comando apenas nos permite a abertura de arquivos j existentes, o outro apenas abre arquivos novos ou destri um possvel contedo anterior. Para resolver esse problema podemos usar as diretivas de compilao para checagem de erros de entrada/sada {$I }. Esta diretiva retorna um cdigo de erro em uma funo do Turbo

9.1.3 Funes de escrita e gravao


Porm para manipularmos um arquivo no basta apenas abr-lo e fech-lo, temos, na maioria das vezes, que ler uma informao contida nele, outras vezes registrar informaes novas,

Linguagem de Programao II - URI Campus de Frederico Westphalen

89

Linguagem de Programao II - URI Campus de Frederico Westphalen

90

ou ainda, fazer manuteno em informaes j existentes. Vejamos ento, como so os comandos que nos permitem tais tarefas:

PROGRAM teste_read_arq; Uses Crt; CONST nomearq = TESTE.DAT; max = 10; TYPE registro = RECORD nome : STRING[30]; ender : STRING[25]; END; VAR arquivo: FILE OF registro; reg: registro; ind: BYTE; BEGIN ASSIGN(arquivo,nomearq); RESET(arquivo); FOR ind := 1 TO MAX DO BEGIN READ(arquivo,reg); WRITELN ( 'Este o ', ind, '. Nome ', reg.nome) ; WRITELN('Este ' o ',ind,'. Endereco ',reg.ender); END; CLOSE(arquivo); END.

9.1.3.1 WRITE Este procedimento alm de ser usado para exibir mensagens e variveis no dispositivo padro de sada (video), pode ser usado para gravar informaes em outros dispositivos, como um arquivo. Sua sintaxe: WRITE(<arq>, <reg1>[,<reg2>,..., <regn>] ;

Exemplo: PROGRAM teste_write_arq; CONST nomearq = 'TESTE.DAT'; max = 10; TYPE registro = RECORD nome : STRING[30]; ender: STRING[25]; END; VAR arquivo : FILE OF registro; reg : registro; ind : BYTE; BEGIN ASSIGN(arquivo,nomearq); REWRITE(arquivo); FOR ind := 1 TO MAX DO BEGIN WRITE('Digite o ',ind,'o Nome '); READLN(reg.nome); WRITE('Digite o ',ind,'o Endereco '); READLN(reg.ender); WRITE(arquivo,reg); END; CLOSE(arquivo); END.

No exemplo anterior, no temos problema algum ao executar a leitura no arquivo, pois este havia sido gravado anteriormente por ns mesmos e com uma quantidade de registros predefinidos. Porm, na maioria das vezes, no temos idia da quantidade de registros contidos em um arquivo e para esta situao,devemos saber quando chegamos ao final de um arquivo. O Turbo nos fornece tal funo : 9.1.3.3 EOF Esta funo nos retorna o valor TRUE quando for encontrada a marca de fim de arquivo. Sua sintaxe : EOF(VAR <arq>) : BOOLEAN; Utilizando o exemplo anterior, com uma pequena variao :

9.1.3.2 READ Como j vimos anteriormente, este procedimento permite que atribuamos a uma varivel, um valor obtido por um dispositivo associado. Este dispositivo pode ser tambm um arquivo, e se no caso da leitura em arquivo, for detectado o fim do mesmo, ser gerado um erro. Sua sintaxe: READ(<arq>, <reg>); Vejamos um exemplo simples de uma leitura em arquivos:
Linguagem de Programao II - URI Campus de Frederico Westphalen

PROGRAM teste_eof; Uses crt; CONST nomearq = 'TESTE.DAT'; TYPE registro = RECORD nome : STRING[30]; ender: STRING[25]; END; VAR

91

Linguagem de Programao II - URI Campus de Frederico Westphalen

92

arquivo: FILE OF registro; reg: registro; ind: BYTE; BEGIN ASSIGN(arquivo,nomearq); RESET(arquivo); ind := 1; WHILE NOT EOF(arquivo) DO BEGIN READ(arquivo,reg); WRITELN ( 'Este o ,ind,'. Nome ',reg.nome) ; WRITELN('Este o ',ind,'. Endereco ', reg.ender); ind := ind + 1; END; CLOSE(arquivo); END.

FOR ind := 1 TO MAX DO BEGIN WRITE('Digite o ',ind,'o Nome '); READLN(reg.nome); WRITE('Digite o ',ind,'o Endereco '); READLN(reg.ender); WRITE(arquivo,reg); END; SEEK(arquivo,4); READ(arquivo,reg); WRITELN ('Este o 5 Nome ',reg.nome) ; WRITELN ('Este o 5 Endereco ', reg.ender); CLOSE(arquivo); END.

9.1.3.5 FILEPOS Esta funo nos retoma a posio atual do ponteiro do arquivo. Assim que abrimos um arquivo, com RESET ou REWRITE, a posio do ponteiro zero, ou seja, o primeiro registro, no pode ser usado em arquivos do tipo TEXTO. Sua sintaxe : FILEPOS(VAR <arq>) : LONGINT;

O lao repetido at que seja encontrada a marca de fim de arquivo. Porm, para a manuteno de alguns registros de um determinado arquivo, temos que saber qual a posio deste registro no arquivo e tambm qual a posio do ltimo registro. Quando estamos manipulando um arquivo, existe a todo momento um ponteiro que fica deslocando-se de acordo com as leituras e gravaes, ou seja, quando abrimos um arquivo,este ponteiro indica a posio zero, ou que o primeiro registro fisico do arquivo. A cada leitura ou gravao este ponteiro avana uma posio, mas existem algumas funes e procedimentos que permitem a manipulao deste ponteiro. 9.1.3.4 SEEK Este procedimento permite que movamos o ponteiro do arquivo para uma posio preestabelecida, podendo ser usado em arquivos de qualquer tipo exceto os de tipo TEXTO. S pode ser usado em arquivos previamente abertos. Sua sintaxe : SEEK(VAR <arq>; <posicao> : LONGINT);
Exemplo: PROGRAM teste_seek; CONST max = 10; TYPE registro = RECORD nome : STRING[30]; ender: STRING[25]; END; VAR arquivo : FILE OF registro; reg : registro; ind : BYTE; BEGIN ASSIGN(arquivo,TESTE.DAT); REWRITE(arquivo); Linguagem de Programao II - URI Campus de Frederico Westphalen

9.1.3.6 FILESIZE Esta funo retorna o tamanho de um arquivo em nmero de registros. Caso o arquivo esteja vazio, a funo retornar 0. No pode ser usada, em arquivos do tipo TEXTO. Sua sintaxe: FILESIZE(VAR <arq>) : LONGINT;

Vejamos agora, um exemplo englobando estes ltimos comandos:


PROGRAM teste_ponteiro; Uses Crt; VAR nomearq: STRING[67]; arquivo: FILE OF BYTE; tamanho: LONGINT; BEGIN WRITE('Entre com o nome do arquivo '); READLN(nomearq); ASSIGN(arquivo,nomearq); RESET(arquivo); TAMANHO := FILESIZE(arquivo); WRITELN('O tamanho do arquivo ',nomearq, em bytes ',tamanho); WRITELN('Posicionando no meio do arquivo... '); SEEK(arquivo,tamanho DIV 2); WRITELN ('A posicao atual ', FILEPOS (arquivo) ) ; CLOSE(arquivo); READLN; END.

93

Linguagem de Programao II - URI Campus de Frederico Westphalen

94

identificado pela sequncia CR LF, Carriage Retum, e Line Feed, correspondentes aos caracteres ASCII $0D e $0A. O identificador TEXT define uma varivel como sendo arquivo do tipo texto. 9.1.3.7 WITH Este comando permite que a referncia a uma varivel do tipo registro seja simplificada. Podemos encadear at sete registros em um comando WITH. A referncia aos campos dos registros pode ser efetuada com o uso deste comando sem a utilizao do ponto, ligando o nome do registro ao nome do campo. Sua sintaxe: WITH <registro1>, [<registron>...] DO BLOCO;
Exemplo PROGRAM teste_with; CONST max = 10; TYPE registro = RECORD nome : STRING[30]; ender: STRING[25]; END; VAR arquivo : FILE OF registro; reg : registro; ind : BYTE; BEGIN ASSIGN(arquivo,'TESTE.DAT'); REWRITE(arquivo); WITH reg DO BEGIN FOR ind := 1 TO MAX DO BEGIN WRITE('Digite o ',ind,' Nome '); READLN(nome); WRITE('Digite o ',ind,' Endereco '); READLN(ender); WRITE(arquivo,reg); END; SEEK(arquivo,0); WHILE NOT EOF(arquivo) DO BEGIN READ(arquivo,reg); WRITELN ('Este o ',filepos(arquivo),' Nome ',nome) ; WRITELN ('Este o ',filepos(arquivo),' Endereco ', ender); END; END; CLOSE(arquivo); END.

Exemplo:
PROGRAM teste_text; USES CRT; VAR arq : TEXT; ch : CHAR; BEGIN WRITELN('Escolha onde deseja que seja impressa a frase WRITELN(' Impressora, Disco, ou Video, (I, D,V) ' ) ; REPEAT ch := UPCASE(READKEY); UNTIL ch IN ['I','D','V']; IF ch = 'I' THEN ASSIGN(arq,'PRN') ELSE IF ch = 'D' THEN ASSIGN(arq,'TESTE.DAT') ELSE ASSIGN(arq,'CON'); {$I-} REWRITE(ARQ); {$I+} IF IORESULT <> O THEN WRITELN('Arquivo nao aberto ') ELSE BEGIN WRITELN(arq,'Teste de TEXT '); CLOSE(arq); END; WRITE('Tecle algo para continuar '); READKEY; END.

Este outro exemplo copia o arquivo autoexec.bat para um novo arquivo removendo todas as linhas marcadas com comentrio (rem).

Program ExemploArquivoTexto; Uses CRT, Strings; var arq1, arq2: text; buffer: string; aux: string[3]; i: integer; begin assign(arq1,'c:\autoexec.bat'); assign(arq2,'c:\autoexec.new'); {$I-} reset(arq1); {$I+} if IORESULT <> 0 then begin writeln('Nao foi possivel abrir o arquivo C:\AUTOEXEC,BAT'); Linguagem de Programao II - URI Campus de Frederico Westphalen

9.2 Arquivos Texto em Pascal e Delphi


Uma outra forma de se trabalhar com um arquivo, definindo-o como sendo do tipo Texto. Esta forma de definio permite-nos ter registros de tamanhos diferentes, e cada registro
Linguagem de Programao II - URI Campus de Frederico Westphalen

95

96

end; rewrite(arq2); while not eof(arq1) do begin readln(arq1,buffer); aux:=copy(buffer,1,3); for i:= 1 to 3 do begin aux[i]:=upcase(aux[i]); end; if aux<>'REM' then begin writeln(arq2,buffer); end; end; writeln(arq2,'rem - Alterado pela exemplo de Arquivos Texto usando Pascal!'); flush(arq2); end.

EOF[(VAR <arq> : TEXT)] : BOOLEAN;

9.2.1.3 SEEKEOF Esta funo retorna verdadeiro se encontrado status de final de arquivo. bastante parecida com a funo EOF, exceto que esta salta todos os brancos e tabs quando da leitura. Somente para arquivos do tipo texto. Sua sintaxe: SEEKEOF[(VAR <arq>:TEXT)] : BOOLEAN;

9.2.1.4 SEEKEOLN

9.2.1 Funes para manipulao de arquivos texto


9.2.1.1 APPEND Procedimento que permite a abertura de um arquivo do tipo TEXT, permitindo-se que se faa incluso ao seu final. Se por acaso existir um caractere ^Z (ASCII 26) no arquivo, ser assumido este ponto como fim do mesmo. O arquivo dever ser previamente associado a um nome externo, e aps o uso deste procedimento somente ser permitida a incluso de dados ao seu final. Sua sintaxe: APPEND(var <arq> : TEXT); Este procedimento no permite que se faa a abertura de um arquivo que ainda no existe. O seu uso correto se faz apenas quando o arquivo j existir. Se em seu disco de trabalho existe um arquivo chamado AUTOEXEC.BAT, faa o seguinte teste :

Esta funo retorna verdadeira se encontrada marca de fim de linha, salta todos os caracteres em branco e tabulaes encontradas durante a leitura. Sua sintaxe: SEEKEOLN[(VAR <arq> : TEXT)] : BOOLEAN; 9.2.1.5 FLUSH Este procedimento permite que seja descarregada a rea de Buffer de um arquivo do tipo Texto. Em sua utilizao, pode ser usada a funo IORESULT, que retornar zero caso a operao for bem sucedida. Sua sintaxe : FLUSH(VAR <arq> : TEXT);
Exemplo: PROGRAM teste_flush; var arq : TEXT; BEGIN ASSIGN(arq,'\autoexec.bat'); APPEND(arq); WRITELN(arq,'ECHO INCLUIDO PELO TURBO'); FLUSH(arq); END.

PROGRAM teste_append; VAR arq : TEXT; {define arq do tipo arquivo texto} BEGIN ASSIGN(arq,'\autoexec.bat'); {associa o nome externo a APPEND(arq); WRITELN(arq,'ECHO INCLUIDO PELO TURBO'); CLOSE(arq); END.

arq}

No exemplo anterior, caso no tivssemos nos utilizando da rotina FLUSH, a gravao no teria sido efetivada, pois a informao estaria apenas bufferizada. 9.2.1.6 SETTEXTBUF Este procedimento permite-nos associar um arquivo com tipo TEXTO a uma rea de buffer na rea de dados do programa. Utilize sempre que possivel mltiplos de 128 para o tamanho do Buffer. Normalmente, esta rea j est disposta pelo sistema operacional e corresponde a 128 Bytes. Este comando deve ser usado antes que o arquivo seja aberto, podendo ser usado tanto para
Linguagem de Programao II - URI Campus de Frederico Westphalen

9.2.1.2 EOF(TEXT) Esta funo retorna verdadeiro se for encontrado o fim de um arquivo do tipo texto. A diferena entre EOF para Texto e EOF para arquivos tipados que na primeira, a referncia ao arquivo opcional. Sua sintaxe:
Linguagem de Programao II - URI Campus de Frederico Westphalen

97

98

leitura como para gravao. Este procedimento acelera os procedimentos de leitura e de gravao. Sua sintaxe : SETTEXTBUF(VAR <arq>:TEXT; VAR <buffer> [;<tamanho> : WORD]);

9.3 ARQUIVOS SEM TIPOS EM PASCAL E DELPHI


s vezes, temos a necessidade de manipular arquivos sem saber qual seu tipo de contedo. Poderiamos defini-lo do tipo BYTE, ou ainda, do tipo CHAR, porm se o arquivo tiver um tamanho relativamente grande, sua manipulao ser meio lenta e neste caso, temos algumas opes.

ASSIGN(arqent,nomeent); RESET(arqent,l); WRITE ('Entre com o nome do arquivo de Destino ') ; READLN(nomesai); ASSIGN(arqsai,nomesai); REWRITE(arqsai,l); WRITELN('Copiando ', FileSize(arqent),' bytes...'); REPEAT BLOCKREAD(arqent,buf,sizeof(buf),lidos); BLOCKWRITE(arqsai,buf,lidos,gravados); UNTIL (lidos = 0) OR (gravados <> lidos); Close(arqent); Close(arqsai); END.

9.3.1 Funes para manipulao de arquivos sem tipos


9.3.1.1 BLOKREAD Procedimento que permite a leitura de um ou mais registros (blocos de 128 bytes), num mximo de 65535 bytes (64 K) de um arquivo sem tipo em uma varivel que pode ser de qualquer tipo. Sua sintaxe: BLOCKREAD(VAR <arq>: FILE; VAR <buffer>; <contador> : WORD; [VAR <resultado> : WORD];

de fundamental importncia, que ao abrir o arquivo coloque-se alm da varivel tipo File, tambm o tamanho 1.

9.3.1.3 TRUNCATE Este procedimento faz com que o arquivo seja truncado em seu tamanho, na posio corrente do ponteiro do arquivo. Sua sintaxe ; TRUNCATE(VAR <arq>);

9.3.2 Arquivos com diversas estruturas em Pascal e Delphi


9.3.1.2 BLOCKWRITE Procedimento que permite a gravao de um ou mais registros (bloco de 128 bytes) de um arquivo sem tipo em uma varivel que pode ser de qualquer tipo. Sua sintaxe: BLOCKWRITE(VAR <arq>: FILE; VAR <buffer>; <contador> : WORD; [VAR <resultado> : WORD]; Exemplo que utiliza estes comandos : Um arquivo pode conter diversas estruturas. Para uma leitura correta desses arquivos necessrio conhecer o "layout" desse arquivo. Por exemplo, um arquivo DBF, utilizado por dBase, Clipper, FoxPro e reconhecido por qualquer programa que importe base de dados, dividido em 3 partes distintas: cabealho, atributos dos campos e dados. O cabealho possui um registro com a seguinte definio:
str_dbf = record versao: byte; ano: byte; mes: byte; dia: byte; n_regs: longint; tam_cab: integer; tam_reg: integer; reservado: Array[1..20] of char; end;

PROGRAM teste_block; VAR arqent,arqsai nomeent,nomesai lidos, gravados buf : : : : FILE; STRING[79]; WORD; ARRAY[1..4096] OF CHAR;

A seguir para cada atributo (campo) h o seguinte registro:


BEGIN WRITE('Entre com o nome do arquivo de Origem '); READLN(nomeent); Linguagem de Programao II - URI Campus de Frederico Westphalen descr_atr = record

99

Linguagem de Programao II - URI Campus de Frederico Westphalen

100

nome: array[1..11] of char; tipo: char; reservado1: array[1..4] of char; tamanho: byte; num_dec: byte; reservado2: array[1..14] of char; end;

A quantidade de atributos dada pela frmula:


atributos := trunc((dbf.tam_cab-sizeof(str_dbf))/sizeof(descr_atr));

Os dados so gravados a partir do 1 byte posterior ao tamano do cabealho (cab.tam_cab). No incio de cada registro (conjunto de atributos) gravado um byte para marcar se o registro est deletado (se o caracter for igual a 42 (*)) ou no (se o caracter for igual a 32 (espao em branco)), e so todos gravados em modo texto, sendo que cada registro referente a cada atributo possui o tamanho definido na descrio do atributo (tamanho + num_dec).

Program LeDBF; Uses CRT; TYPE str_dbf = record versao: byte; ano: byte; mes: byte; dia: byte; n_regs: longint; tam_cab: integer; tam_reg: integer; reservado: Array[1..20] of char; end; descr_atr = record nome: array[1..11] of char; tipo: char; reservado1: array[1..4] of char; tamanho: byte; num_dec: byte; reservado2: array[1..14] of char; end; VAR desc: descr_atr; dbf: str_dbf; arq:FILE; quant, i: integer; aux: char; nomeaux: Array[1..256] of string[12]; tipo: Array[1..256] of char; tam, dec: Array[1..256] of byte; buffer: char; nome_arquivo: string; tm, cont, k, qtd, l, tm1, tm2, op, tamanho, zz, byteslidos: integer; BEGIN clrscr; write('Nome do Arquivo: '); Linguagem de Programao II - URI Campus de Frederico Westphalen

readln(nome_arquivo); assign(arq,nome_arquivo); {$I-} reset(arq,1); {$I+} if IORESULT <> 0 then begin writeln('Nome de Arquivo Invalido!'); readkey; exit; end; BLOCKREAD(arq,dbf,32,byteslidos); writeln('versao: ',dbf.versao); writeln('ano: ',dbf.ano); writeln('mes: ',dbf.mes); writeln('dia: ',dbf.dia); writeln('n reg: ',dbf.n_regs); writeln('t_cab: ',dbf.tam_cab); writeln('t_reg: ',dbf.tam_reg); writeln('reserv: ',dbf.reservado); writeln('-------------------------------'); readkey; quant := trunc((dbf.tam_cab-sizeof(str_dbf))/sizeof(descr_atr)); writeln('Blidos: ',byteslidos); writeln('Quant: ',quant); writeln('Tam cab: ',sizeof(str_dbf)); writeln('Tam campos: ',sizeof(descr_atr)); for i:=1 to quant do begin BLOCKREAD(arq,desc,sizeof(descr_atr),byteslidos); tipo[i]:=desc.tipo; tam[i]:=desc.tamanho; nomeaux[i]:=desc.nome; dec[i]:=desc.num_dec; writeln(desc.nome, ' - ',desc.tipo, ' - ',desc.tamanho, ' ',desc.num_dec); end; write('Ler quantos registros - (999 - todos)? '); readln(qtd); seek(arq,dbf.tam_cab); if (qtd=999) then qtd:=dbf.n_regs; cont:=1; while ((cont<=qtd) and (not eof(arq))) do begin writeln(' Registro: ',cont,' -------------------------'); BLOCKREAD(arq,aux,1,byteslidos); if (aux<>' ') then writeln('-> ',aux,' (deletado) '); for k:=1 to quant do begin write(nomeaux[k],': '); for l:= 1 to tam[k] do begin BLOCKREAD(arq,buffer,1,byteslidos); write(buffer); end; writeln; end; readkey; cont:=cont+1; end; writeln(' ************* FIM '); readkey; clrscr; end.

101

Linguagem de Programao II - URI Campus de Frederico Westphalen

102

Principais rotinas de alto nvel:

9.4 Arquivos em C
Um arquivo em C no possui a idia de registro. Podemos gravar dados no formato de caracter (ASCII) ou em binrio (binary file). A seqncia e interpretao dos dados de inteira responsabilidade do programador do sistema. Um arquivo em C uma seqncia contnua de butes gravados em memria secundria. Cada byte do arquivo possui um endereo nico que o deslocamento relativo ao incio do arquivo. Toda a manipulao de arquivos realizada atravs de funes de biblioteca. Existem dois nveis de funes: as rotinas de baixo nvel - mais eficientes, que utilizam diretamente os recursos do sitema operacional - e as de alto nvel - mais fceis de serem utilizadas - construdas sobre as funes de baixo nvel. Para as rotinas de alto-nvel, os arquivos so acessados atravs de ponteiros para estruturas do tipo FILE, definidas em stdio.h. Para as rotinas de baixo nvel os arquivos so identificados por um nmero inteiro que o cdigo identificador do arquivo retornado pelo sistema operacional (file handle). Na estrutura FILE, o nmero identificador do arquivo o campo fd. As rotinas de alto-nvel possuem por sua vez dois conjuntos de rotinas: rotinas para manipulao de arquivos texto e rotinas para manipulao de arquivos binrios. A diferena bsica entre os dois conjuntos que as rotinas de manipulao de arquivos binrios armazenam uma cpia dos bytes da memria principal para a secundria enquanto que as de manipulao de arquivos texto armazenam a representao ASCII dos valores. Principais rotinas de baixo nvel (prototipadas em io.h) access chmod close creat eof getftime lock lseek open read tell unlock write - Verifica se um arquivo existe e se pode ser lido/gravado. - Modifica os atributos de um arquivo. - Fecha um arquivo. - Cria um arquivo. Est em desuso - Verifica se a leitura chegou ao final de um arquivo. - Informa a data de criao/acesso de um arquivo. - Coloca um arquivo em uso exclusivo. utilizada para fazer controle de acesso concorrente em ambiente multi-usurio ou de rede. - Descola o ponteiro de leitura para um byte especfico no arquivo. - Abre/cria um arquivo. - L dados de um arquivo. - Informa em qual byte est o ponteiro do arquivo. - Libera o arquivo do uso exclusivo. - Escreve dados em um arquivo.

fclose feof fflush fgetc fgets fputc fputs fread fscanf fseek ftell fwrite remove rename setvbuf fflushall fprintf

- Fecha um arquivo. - Informa se a leitura chegou ao fim de arquivo. - Esvazia o buffer do arquivo. - L um caracter de um arquivo. - L uma string de um arquivo. - Escreve um caracter em um arquivo. - Escreve uma string em um arquivo. - L dados de um arquivo. - L dados de um arquivo, como scanf - Desloca o ponteiro do arquivo para um determinado byte. - Indica em qual byte se localiza o ponteiro do arquivo. - Escreve em um arquivo. - Remove um arquivo. - Muda o nome de um arquivo. - Modifica o tamanho interno do buffer do arquivo. - Descarrega o buffer de todos os arquivos. - Escreve em um arquivo, no mesmo formato que printf.

Obs: Existem cinco arquivos tipo stream pr-definidos automaticamente abertos quando um programa entra em execuo: stdin stdout stderr stdaux stdprn - Dispositivo padro de entrada (geralmente teclado). - Dispositivo padro de sada (geralmente vdeo). - Dispositivo padro para sada de erros. - Dispositivo auxiliar (porta serial, por exemplo). - Impressora padro do sistema.

que

so

filelenght - Informa o tamanho de um arquivo.

Exemplo:
printf(%d,x);

o mesmo que
fprintf(stdout, %d, x);

Linguagem de Programao II - URI Campus de Frederico Westphalen

103

Linguagem de Programao II - URI Campus de Frederico Westphalen

104

9.4.1 Declarao de arquivos


Quando se usa o conjunto de rotinas de alto nvel, utilizam-se ponteiros do tipo FILE para armazenar uma referncia para um arquivo. FILE na verdade uma estrutura que guarda uma srie de informaes sobre o arquivo. Uma estrutura desse tipo alocada pela rotina fopen e uma referncia para a mesma deve ser armazenada. Exemplo: FILE *arq, *arq1;

No MS-DOS ainda h como segundo caracter de modo as opes: b t especifica que o arquivo binrio especifica que o arquivo texto

A funo fopen retorna NULL se no puder abrir/criar o arquivo. Exemplo:


... char narq[20]; arq1 = fopen(texto.txt,wt); if (arq1 == NULL) printf(No consegui abrir o arquivo\n); strcpy(narq,dados); arq2 = fopen(narq,rb); if (arq2 == NULL) printf(No consegui abrir o arquivo %s,narq); ...

9.4.2 Funes de abertura e fechamento de arquivos


A funo fopen usada para a abertura de arquivos tanto no modo texto como no modo binrio. Em seus parmetros devemos indicar o nome com o qual o arquivo (ou ser) identificado no dispositivo de memria secundria e o modo que se deseja trabalhar com o mesmo (leitura, escrita, alterao, etc). A funo fopen retorna um ponteiro para a estrutura do tipo FILE que descreve o arquivo. Funo fopen Sintaxe: <fstream> = fopen(<nome_arquivo>,<modo>); onde: * * fstream = ponteiro para o arquivo; nomearq = string que contm o nome do arquivo no disco;

Funo fclose A funo fclose deve ser usada toda a vez que no for mais necessrio trabalhar com um arquivo. Libera os buffers alocados pelo sistema operacional para o gerenciamento do arquivo garantindo que todos os dados so efetivamente descarregados no dispositivo de memria secundria. Libera tambm a estrutura do tipo FILE. Sintaxe: fclose <fstream> onde: * fstream = ponteiro para o arquivo

* modo = string constante composta por dois caracteres que indica o modo de abertura do arquivo: modos: w r a abre/cria para escrita. Se j existe, destrudo. abre somente para leitura. abre o arquivo para escrita a partir do fim do mesmo ou cria se o arquivo no existir.

Exemplo:
fclose(arq1); fclose(arq2);

r+ abre um arquivo j existente tanto para leitura como para gravao. Se este arquivo j existir ele no ser destrudo. w+ abre um arquivo tanto para leitura como para gravao. Se este arquivo j existir ele ser destrudo. a+ abre um arquivo para leitura/gravao ao final do arquivo. Se o arquivo no existe ele criado.

9.4.3 Funes de escrita e gravao


9.4.3.1 Funo fwrite A funo fwrite copia uma poro da memria principal para um dispositivo de memria secundria. Recebe como parmetros o endereo do incio da rea e a quantidade de bytes a ser copiada. Sintaxe

Linguagem de Programao II - URI Campus de Frederico Westphalen

105

Linguagem de Programao II - URI Campus de Frederico Westphalen

106

fwrite(<ptr>, <tamanho>, <nro>, <fstream>); onde: * * * * ptr = ponteiro para o incio dos dados a serem gravados tamanho = tamanho do registro lgico; nro = quantidade de registros lgicos (registro fsico = nro x tamanho); fstream = ponteiro para o arquivo;

fread(&buf,sizeof(int),10,arq1);

Exemplo de um programa que grava e escreve na tela uma estrutura de nome e idade:
#include #include #include #include <conio.h> <stdio.h> <stdlib.h> <io.h>

fwrite retorna o nmero de itens que conseguiu gravar no arquivo. 9.4.3.2 Funo fread A funo fread tem a funo inversa da funo fwrite carregando um conjunto de bytes do dispositivo de memria secundria para a memria principal. Possui os mesmos parmetros que fwrite porm com o sentido inverso. Sintaxe fread(<ptr>, <tamanho>, <nro>, <fstream>); onde: * ptr = ponteiro para o incio da rea onde devem ser armazenados os dados lidos; * * * tamanho = tamanho do registro lgico; nro = quantidade de registros lgicos a serem lidos; fstream = ponteiro para o arquivo;

typedef struct { char nome[30]; int idade; }pessoa; pessoa cliente; FILE *arq1; int i, tamanho; void main() { clrscr(); arq1 = fopen("clientes.dat","ab+"); if (arq1==NULL) exit(1); for(i=0;i<4;i++); { printf("nome: "); fflush(stdin); gets(cliente.nome); fflush(stdin); printf("idade: "); scanf("%d",&cliente.idade); fwrite(&cliente,sizeof(cliente),1,arq1); } clrscr(); rewind(arq1); while(!feof(arq1)) { fread(&cliente,sizeof(pessoa),1,arq1); if(!feof(arq1)) { printf("nome: %s - %d anos\n",cliente.nome, \ cliente.idade); } } getch(); }

fread retorna o nmero de itens que conseguiu ler do arquivo. 9.4.3.3 Funo feof - Teste de Fim de Arquivo: A funo de teste de fim de arquivo feof retorna o valor lgico verdadeiro quando o programa tenta ler o arquivo aps o ltimo byte gravado. Sintaxe: <x> = feof (<fstream>); onde: fstream = ponteiro para o arquivo; x = um inteiro que recebe o valor 1 se foi encontrado o fim de arquivo, seno recebe 0. Ex.: while(!feof(arq1))
Linguagem de Programao II - URI Campus de Frederico Westphalen

9.4.4 Funes de Escrita e Gravao em Arquivos Texto


9.4.4.1 Funo fputc A funao fputc permite que se armazene um caracter (um byte) em um arquivo texto.
Linguagem de Programao II - URI Campus de Frederico Westphalen

107

108

Sintaxe: fputc(<char>,<fstream>); onde: * char = caracter a ser gravado; * fstream = ponteiro para o arquivo; 9.4.4.2 Funo fgetc A funao fgetc permite que se leia um caracter (um byte) de um arquivo texto. Sintaxe: <c> = fgetc(<fstream>); onde: * c = varivel que recebe o caracter lido; * fstream = ponteiro para o arquivo; 9.4.4.3 Funo fputs A funao fputs permite que se grave um string em um arquivo texto. Sintaxe: fputs(<str>,<fstream>); onde: * str = ponteiro para o string a ser gravado (substitui o \0 por um \n no momento da gravao); * fstream = ponteiro para o arquivo; 9.4.4.4 Funo fgets A funao fgets permite que se leia um string inteiro de uma s vez de um arquivo texto. L todos os caracteres at encontrar um \n ou estourar o limite estabelecido nos parmetros. Sintaxe: fgets(<str>,<tammax>,<fstream>); onde:

* str = ponteiro para o string a ser lido (carrega todos os caracteres at encontrar um \n e acrescenta um \0 no fim do string). * tammax = nmero mximo de caracteres que podemser lidos. * fstream = ponteiro para o arquivo; 9.4.4.5 Funo fprintf A funao fprintf permite a gravao formatada de dados em um arquivo texto. Os dados so armazendados no arquivo da mesma maneira que seriam jogados no dispositivo de sada padro. A sintaxe igual a da funo printf diferenciando-se apenas pela indicao do arquivo destino. Sintaxe: fprintf (<fstream>, <string de controle>, <lista de argumentos>); * funciona como o comando printf com a diferena que os caracteres so enviados para o arquivo especificado por fstream. 9.4.4.6 Funo fscanf Possui a mesma filosofia de fprintf s que para a leitura de dados. Possui sintaxe idntica a da funo scanf diferenciando-se apenas pela indicao do arquivo fonte. Sintaxe: fscanf (<fstream>, <string de controle>, <lista de argumentos>); Funciona como o comando scanf com a diferena que os caracteres so lidos do arquivos especficado por fstream O programa abaixo um exemplo de programa que utiliza as funes fgets, fputs, fgetc, fputc, fscanf, fprintf, para manipular um arquivo texto.
#include #include #include #include <stdio.h> <conio.h> <stdlib.h> <string.h>

FILE *arq1; char i, caracter, meu_complemento[20], frase_do_arq[80]; void main() { arq1 = fopen("teste.txt","w+t"); if(arq1==NULL) { printf("Nao foi possivel abrir o arquivo!"); exit(1); } strcpy(meu_complemento,"Maravilhoso!"); fprintf(arq1,"Ola Mundo %s\n",meu_complemento); Linguagem de Programao II - URI Campus de Frederico Westphalen

Linguagem de Programao II - URI Campus de Frederico Westphalen

109

110

fputs("Este e' o alfabeto: ",arq1); for(i=65;i<=90;i++) { fputc(i,arq1); } clrscr(); rewind(arq1); fscanf(arq1,"%s",frase_do_arq); printf("%s",frase_do_arq); fgets(frase_do_arq,80,arq1); printf("%s",frase_do_arq); while(!feof(arq1)) { caracter=fgetc(arq1); putchar(caracter); } getch(); }

varivel_long = ftell (ponteiro_arquivo); A funo rewind simplesmente reinicializa para o incio do arquivo o marcador de posio no arquivo apontado por ponteiro_arquivo. A sintaxe : rewind(ponteiro_arquivo);

9.4.6 Arquivos com diversas estruturas


Um arquivo pode conter diversas estruturas. Para uma leitura correta desses arquivos necessrio conhecer o "layout" desse arquivo. Por exemplo, um arquivo DBF, utilizado por dBase, Clipper, FoxPro e reconhecido por qualquer programa que importe base de dados, dividido em 3 partes distintas: cabealho, atributos dos campos e dados. O cabealho possui um registro com a seguinte definio:
typedef struct { char versao; char ano; char mes; char dia; long int n_regs; int tam_cab; int tam_reg; char reservado[20]; } inf_DBF;

9.4.5 Funes "fseek" , "ftell" e "rewind"


As funes fseek, ftell e rewind so usadas para determinar ou modificar a localizao do marcador de posio de arquivo. A sintaxe : fseek (ponteiro_arquivo, bytes_de_deslocamento, de_onde); A funo fseek reinicializa o marcador de posio no arquivo apontado por por ponteiro_arquivo para o nmero de bytes_de_deslocamento a partir: do incio do arquivo (de_onde = 0) da localizao atual do marcador de posio no arquivo (de_onde = 1) do final do arquivo (de_onde = 2). A funo fseek retornar 0 se o reposicionamento for bem sucedido ou EOF se no. Para determinar a quantidade de bytes_de_deslocamento pode-se usar a funo sizeof que retorna o tamanho de uma varivel ou de uma estrutura. EX:
fseek(arq1,sizeof(float),0); fseek(arq1,sizeof(clientes),1);

A seguir para cada atributo (campo) h o seguinte registro:


typedef struct { char nome[11]; char tipo; char reservado[4]; char tamanho; char num_dec; char reservado2[14]; } descr_atrib;

A quantidade de atributos dada pela frmula: atributos = (cab.tam_cab - sizeof(inf_DBF))/sizeof(descr_atrib);

A funo ftell retorna a posio atual do marcador de posio no arquivo apontado por ponteiro_arquivo. Esta posio indicada por um deslocamento medido em bytes, a partir do incio do arquivo. A sintaxe :

Os dados so gravados a partir do 1 byte posterior ao tamano do cabealho (cab.tam_cab). No incio de cada registro (conjunto de atributos) gravado um byte para marcar se o registro est deletado (se o caracter for igual a 42 (*)) ou no (se o caracter for igual a 32 (espao em branco)), e so todos gravados em modo texto, sendo que cada registro referente a cada atributo possui o tamanho definido na descrio do atributo (tamanho + num_dec).
Linguagem de Programao II - URI Campus de Frederico Westphalen

Linguagem de Programao II - URI Campus de Frederico Westphalen

111

112

O seguinte programa l um arquivo DBF:


#include #include #include #include #include <conio.h> <stdio.h> <stdlib.h> <string.h> <io.h>

typedef struct { char versao; char ano; char mes; char dia; long int n_regs; int tam_cab; int tam_reg; char reservado[20]; } str_dbf; typedef struct { char nome[11]; char tipo; char reservado1[4]; char tamanho; char num_dec; char reservado2[14]; } descr_atr; descr_atr desc; str_dbf dbf; FILE *arq; int quant, i; char aux; char nomeaux[256][12]; char tipo[256]; char tam[256]; char dec[256]; int tm, j, k, qtd, l, tm1, tm2, op, tamanho, zz; void main(int argc, char *argv[]) { if (argc!=2) { printf("\nA sintaxe e' ledbf arquivo.dbf\n"); exit(1); } clrscr(); arq=fopen(argv[1],"rb"); if (arq==NULL) { printf("Arquivo Inexistente!"); exit(1); } fread(&dbf,sizeof(str_dbf),1,arq); printf("versao: %d\n",dbf.versao); printf("ano: %d\n",dbf.ano); printf("mes: %d\n",dbf.mes); printf("dia: %d\n",dbf.dia); printf("n reg: %ld\n",dbf.n_regs); printf("t_cab: %i\n",dbf.tam_cab); printf("t_reg: %i\n",dbf.tam_reg); printf("reserv: %s\n",dbf.reservado); printf("-------------------------------\n\n"); Linguagem de Programao II - URI Campus de Frederico Westphalen

tamanho=sizeof(str_dbf); getch(); quant=(int)((dbf.tam_cab-sizeof(str_dbf))/sizeof(descr_atr)); for (i=0;i<quant;i++) { fread(&desc,sizeof(descr_atr),1,arq); tipo[i]=desc.tipo; tam[i]=desc.tamanho; strcpy(nomeaux[i],desc.nome); dec[i]=desc.num_dec; printf("\n%11s - %c - %2d - %2d",desc.nome, desc.tipo, desc.tamanho, desc.num_dec); tamanho += sizeof(descr_atr); } printf("\n\nLer quantos registros - (999 - todos)? "); scanf("%d",&qtd); fseek(arq,dbf.tam_cab,0); if (qtd==999) qtd=dbf.n_regs; j=1; while ((j<=qtd) &&(!(feof(arq)))) { printf("\n\n Registro: %d -------------------------",j); fread(&aux,1,1,arq); if (aux!=' ') printf("\n-> %c (deletado) ",aux); for (k=0;k<quant;k++) { printf("\n %12s: ",nomeaux[k]); for (l=1;l<=tam[k];l++) { fread(&aux,1,1,arq); printf("%c",aux); } } getch(); j++; } printf("\n ************* FIM "); getch(); clrscr(); }

9.5 Resumo do Uso de Arquivos Tipados em Pascal


O primeiro passo para se trabalhar com arquivos definir quais os campos que queremos que constem nos registros e defini-los na seo TYPE do programa. Exemplificando vamos criar um arquivo de clientes que contenha o cdigo, o nome e a cidade. Na seo TYPE do programa vamos incluir nosso novo tipo (clientes):
clientes=record codigo:integer; nome:string[40]; cidade:string[30]; end;

113

Linguagem de Programao II - URI Campus de Frederico Westphalen

114

Clientes o conjunto de informaes que contm o cdigo, o nome e a cidade de cada cliente. Depois necessrio definir uma varivel para o tipo criado, pois somente a criao de tipos no define nada, pois eles no tem ligao direta com o programa. Na seo VAR do programa vamos definir as variveis para o tipo criado. Normalmente se usa uma abreviao do tipo para denominar a varivel, mas pode-se utilizar qualquer nome.
VAR cli:clientes; arq: file of clientes;

Se o programa utilizar a gerao automtica de cdigo, no procedimento incluso devemos: 1. Posicionar o ponteiro no incio do registro: SEEK(ARQ,0). 2. Fazer um loop com o comando WHILE para que enquanto no chegue no final do arquivo, leia todos os registros para armazenar o ltimo cdigo. 3. Criar um codigo auxiliar que armazene o ltimo cdigo vlido ( > 0 ). 4. Testar se o ltimo cdigo maior ou menor que 0 e calcular o novo cdigo para o cliente. 5. Estabelecer uma condio de sada do lao da incluso (Nome vazio, no nosso caso ).

Toda a vez que no programa quisermos fazer referncia aos registros de CLIENTES, vamos utilizar a varivel CLI e toda a vez que quisermos fazer referncia ao arquivo vamos utilizar a varivel ARQ. Antes de se utilizar os comandos para criar, abrir ou fechar o arquivo necessrio associlo com um arquivo que vai ser gerado no Winchester ou no disquete com o comando ASSIGN, como por exemplo:
ASSIGN(ARQ,CLIENTES.DAT);

Observe que se no especificarmos a unidade de disco na qual ser gerado o arquivo CLIENTES.DAT ele ser gerado na unidade que est o programa principal, mas pode-se tambm especificar uma unidade especfica, como por exemplo:
ASSIGN(ARQ,B:CLIENTES.DAT);

Para criar arquivos usado o comando REWRITE(variavel do arquivo). No nosso programa seria utilizado REWRITE(ARQ). Para abrir os arquivos utilizado o comando RESET(ARQ) e para fechar o arquivo o comando CLOSE(ARQ). Em aplicativos torna-se interessante abrir o arquivo uma nica vez no incio do programa principal e caso no exista ento cria-se automaticamente e fech-lo no final do programa principal antes do END. evitando o constante abre-e-fecha arquivo. Para isso usa-se uma diretiva de compilao {$I-} que impede que o programa trave em caso de erro ao tentar abrir um arquivo que no existe e devolve o cdigo do erro na varivel IORESULT para ser analisada. Se o arquivo j existe, o cdigo de erro 0 (zero = sem erro) caso contrrio deve-se criar o arquivo. Em seguida voltamos a fazer com que o programa trave em caso de erro com a diretiva de compilao {$I+}.

procedure incluso var cod:integer; begin cod:=0; cli.codigo:=0; seek(arq,0); { posiciona o ponteiro no 1.0 registro } while(not eof(arq)) do { enquanto nao encontra o fim de arquivo } begin read(arq,cli); { le os registros } if cli.codigo>0 then cod:=cli.codigo; end; repeat { Repete o procedimento ... } if cli.codigo < 0 then begin cli.codigo:=cod+1; { incrementa o codigo para os novos registros } end else begin cli.codigo:=cli.codigo+1; end; write('Nome: '); readln(cli.nome); { le o nome do cliente que esta sendo cadastrado } if (cli.nome <> '') and (cli.nome <> ' ') then begin write('Cidade: '); readln(cli.cidade); write(arq,cli); {grava os registros} end; until (cli.nome='') or (cli.nome=' '); {...ate' que o nome esteja vazio} end;

procedure abre_arquivo; begin assign(arq,'clientes.dat'); {$I-} reset(arq); {$I+} if IORESULT <> 0 then rewrite(arq); end; Linguagem de Programao II - URI Campus de Frederico Westphalen

Se o programa no utilizar a gerao automtica de cdigo, no procedimento incluso devemos: 1. Posicionar o ponteiro no final do arquivo: SEEK(ARQ, FILESIZE(ARQ)). 2. Estabelecer uma condio de sada do lao da incluso (Nome vazio, no nosso caso ).

115

procedure incluso Linguagem de Programao II - URI Campus de Frederico Westphalen

116

var cod:integer; begin cod:=0; cli.codigo:=0; seek(arq,FILESIZE(arq)); { posiciona o ponteiro no final do arquivo } repeat { Repete o procedimento ... } write(Cdigo: ); readln(cli.codigo) write('Nome: '); readln(cli.nome); if (cli.nome <> '') and (cli.nome <> ' ') then begin write('Cidade: '); readln(cli.cidade); write(arq,cli); {grava os registros} end; until (cli.nome='') or (cli.nome=' '); end;

posicionar o ponteiro no 1 registro do intervalo (varivel contadora). atravs de um loop com o comando WHILE ler todos os registros enquanto o cdigo for menor que o segundo valor lido. mostrar na tela os registros cujo cdigo no esteja marcado para excluso (cdigo negativo).

Para Listar todos os registro, devemos posicionar o ponteiro no incio do arquivo, fazer um loop com o comando WHILE, para que enquanto no chegue no final do arquivo, leia os registros e mostre na tela os que no forem cdigo -1 (cdigos marcados para excluso).

procedure lista_tudo; begin seek(arq,0); { posiciona no 1.o registro do arquivo } while (not eof(arq)) do { enquanto nao chega no final do arquivo } begin read(arq,cli); if cli.codigo > 0 then {se codigo for maior que 0 escreve os campos} begin writeln('Codigo: ',cli.codigo); writeln('Nome: ',cli.nome); writeln('Cidade: ',cli.cidade); writeln(' pressione qualquer tecla p/continuar . . .'); readkey; end; end; end;

procedure lista_intervalo; var p:char; pos, x, cod1, cod2:integer; begin write('Listar desde o codigo: '); readln(cod1); write(' ate o codigo: '); readln(cod2); seek(arq,0); cli.codigo := 0; while (cli.codigo < cod2) and (not eof(arq)) do { le ate que encontra o (cod2) } begin read(arq,cli); if cli.codigo > cod1 then begin writeln('Codigo: ',cli.codigo); writeln('Nome: ',cli.nome); writeln('Cidade: ',cli.cidade); writeln(' pressione qualquer tecla p/continuar . . .'); readkey; {espera que seja press. uma tecla para listar outro } end; end; end;

Para listar um registro, alterar um registro ou excluir um registro, o mtodo para localiz-lo sempre o mesmo e pode ser definido por uma funo que recebe o cdigo como parmetro e retorna TRUE se encontrou o cdigo ou retorna FALSE se no o encontrou: posiciona-se o ponteiro no incio do arquivo. procurar atravs de um loop com o comando WHILE o registro desejado, armazenando a sua posio. posicionar no prprio registro para que, se for alterado, o ponteiro j esteja na posio correta.
function achoucliente(cod: integer): boolean; begin achoucliente:=FALSE; seek(arq,0); while not eof(arq) do begin read(arq,cli); if(cli.codigo=cod) then begin seek(arq, filepos(arq)-1); achoucliente:=TRUE; break; end; Linguagem de Programao II - URI Campus de Frederico Westphalen

Para Listar um intervalo, no caso de estar utilizando um program com gerao automtica de cdigo, devemos: ler duas variveis que correspondem ao intervalo a ser listado, posicionar o ponteiro no incio do arquivo, zerar a varivel cli.cdigo para que ele entre sempre no lao da varivel contadora. procurar atravs de um loop com o comando WHILE o primeiro registro do intervalo, armazenar a posio do mesmo no arquivo atravs de uma varivel contadora,
Linguagem de Programao II - URI Campus de Frederico Westphalen

117

118

end;

end; else

writeln(' pressione qualquer tecla p/continuar . . .'); readkey; end begin writeln('Codigo nao encontrado'); writeln(' pressione qualquer tecla p/continuar . . .'); readkey; end;

Com essa funo fica simples fazer a alterao ou excluso: l-se o cdigo a alterar chama-se a funo encarregada de encontrar o cdigo l-se os novos dados e grava-se com a funo read. Observando que a funo de localizao se encarrega de deixar o ponteiro posicionado no registro que se quer alterar se for uma excluso, no precisa ler os novos valores e sim atribu-los como nulo e com cdigo negativo
end;

Para fazer a incluso de registros sem gerao automtica de cdigo devemos: l-se o cdigo a incluir chama-se a funo encarregada de localizar o cdigo somente continua a incluso aps certificar-se que a funo no localizou o cdigo no arquivo, garantindo que o cdigo no est includo no arquivo.

procedure alterar; var codaux, x: integer; begin write('Codigo a alterar: '); readln(codaux); if (achoucliente(codigoaux)) then begin write('Novo Nome: '); readln(cli.nome); write('Nova Cidade: '); readln(cli.cidade); write(arq,cli); {grava os registros na posio correta} end else begin writeln('Codigo nao encontrado'); writeln(' pressione qualquer tecla p/continuar . . .'); readkey; end; end;

procedure incluir var cod, codaux:integer; begin repeat write(Codigo a Incluir: ); readln(codaux); until (not achoucliente(codigoaux)); cli.codigo:=codaux; write('Nome: '); readln(cli.nome); write('Cidade: '); readln(cli.cidade); seek(arq,FILESIZE(arq)); { posiciona o ponteiro no final do arquivo } write(arq,cli); {grava o registro} end;

Para listar um nico registro: l-se o cdigo a listar chama-se a funo encarregada de encontrar o cdigo imprime-se os dados, j que a funo se encarregou de deixar na memria os dados do registro escolhido

A compactao do arquivo, que a eliminao fsica dos registros excludos que foram apenas marcados como nulos uma operao demorada e deve ser evitada. Para no continuar com os espaos desperdiados recomendvel sua reutilizao numa nova incluso, alterando o procedimento incluir para gravar no primeiro registro nulo, ao invs de incluir no final do arquivo. Isso obviamente deixa o arquivo desordenado e deve ser usado com cuidado nas rotinas que prevem um arquivo com numerao automtica e ordenado. A rotina de incluso ficaria assim:
procedure incluir var cod, codaux:integer; begin repeat write(Codigo a Incluir: ); readln(codaux); until (not achoucliente(codigoaux)); cli.codigo:=codaux; write('Nome: '); readln(cli.nome); write('Cidade: '); readln(cli.cidade); seek(arq,0); { posiciona no 1.o registro do arquivo } Linguagem de Programao II - URI Campus de Frederico Westphalen

procedure listar; var codaux, x: integer; begin write('Codigo a alterar: '); readln(codaux); if (achoucliente(codigoaux)) then begin writeln(Nome: ,cli.nome); writeln('Cidade: ',cli.cidade); Linguagem de Programao II - URI Campus de Frederico Westphalen

119

120

while (not eof(arq)) do { enquanto nao chega no final do arquivo } begin read(arq,cli); { l o registro } if cli.codigo < 0 then { se codigo for nulo} begin seek(arq, filepos(arq)-1); { volta um registro } break; { e interrompe a busca } end; end; {se no tiver nenhum nulo, vai at o final do arquivo } write(arq,cli); {grava o registro} end;

Clientes: ter o Form que far as operaes de incluso, consulta, alterao e excluso de Clientes num nico Form. 2. Crie uma nova Unit que conter o cdigo de manipulao de arquivos comum a todas operaes: V em File => New... => 3. Salve a Unit com um nome significativo, por exemplo: UnFuncoesArquivo

Exemplo de Programa Principal


begin abre_arquivo; repeat clrscr; writeln(' MENU PRINCIPAL writeln(' 1 - CADASTRAR CLIENTE writeln(' 2 - LISTAR CADASTRO writeln(' 3 - ALTERAR CADASTRO writeln(' 4 - EXCLUIR CLIENTE writeln(' 9 - FIM writeln(' Escolha uma opcao: readln(o); if o=1 then incluir; if o=2 then listar; if o=3 then alterar; if o=4 then excluir; until o=9; fecha_arquivo; end.

4. Na seo Interface, defina o tipo do registro do arquivo e crie as variveis cli (registro com os dados do cliente) e arqcli (arquivo onde sero gravados/lidos os registros):
TYPE clientes = record codigo:integer; nome:string[40]; cidade:string[30]; end; VAR cli:clientes; arq: file of clientes;

'); '); '); '); '); '); ');

5. Na seo Implementation, crie as funes que sero usadas em todos as operaes: 6. Inclua o prottipo (primeira linha) das funes e procedimentos na seo Interface. 7. A Unit dever ficar assim:
unit UnFuncoesArquivo;

9.6 Manipulao de Arquivos com Delphi


Para trabalhar com arquivos em Delphi, a maneira mais prtica implementar cada operao num Form diferente. Para isso, cada operao pode estar em um Form separado, ou agrupadas por tipo de cadastro. Para exemplificar, vamos criar um programa em Delphi que faz o cadastro dos clientes em arquivos, com as operaes de incluso, consulta, alterao, excluso e listagem, separadas e tambm agrupadas num nico Form. 1. Crie um Form Principal com um Menu com as seguintes Opes: Arquivo Sair: encerra o programa. Cadastros Incluso Cliente: ter o Form de Incluso de Cliente Consulta Cliente: ter o Form de Consulta de Cliente Alterao Cliente: ter o Form de Alterao de Cliente Excluso Cliente: ter o Form de Excluso de Cliente
Linguagem de Programao II - URI Campus de Frederico Westphalen

interface TYPE clientes = record codigo:integer; nome:string[40]; cidade:string[30]; end; VAR cli:clientes; arq: file of clientes; function achoucliente(cod: integer): boolean; procedure abre_arquivo; procedure fecha_arquivo; implementation procedure abre_arquivo; begin assign(arq,'clientes.dat'); {$I-} reset(arq); {$I+}

121

Linguagem de Programao II - URI Campus de Frederico Westphalen

122

if IORESULT <> 0 then rewrite(arq); end; procedure fecha_arquivo; begin close(arq); end; function achoucliente(cod: integer): boolean; begin achoucliente:=FALSE; seek(arq,0); while not eof(arq) do begin read(arq,cli); if(cli.codigo=cod) then begin seek(arq,filepos(arq)-1); {volta um registro para ficar posicionado no prprio registro} achoucliente:=TRUE; break; end; end; end; end.

12. Inclua a unit de Funes de Arquivo neste form. Para isso V em File => Use Unit... e escolha a unit UnFuncoesArquivo. 13. Implemente o evento ao entrar (OnEnter) do Edit1 com o seguinte cdigo, para limpar todos os campos e desabilitar o boto OK, lembrando que s deve ser escrito o cdigo entre o begin e o end, j que a estrutura deve ser gerada pelo Delphi, atravs da caixa do ObjectInspector:
procedure TFrCadIncCliente.Edit1Enter(Sender: TObject); begin Edit1.Clear; Edit2.Clear; Edit3.Clear; button1.enabled:=false; end;

8. Na unit do menu, inclua essa unit criada. Para isso V em File => Use Unit... e escolha a unit UnFuncoesArquivo. 9. No Form do menu, implemente o evento OnCreate, colocando a chamada para o procedimento de abertura do arquivo, para abrir o arquivo ao iniciar o programa:
procedure TFrMenu.FormCreate(Sender: TObject); begin abre_arquivo; end;

14. Implemente o evento ao sair (OnExit) do Edit1:


procedure TFrCadIncCliente.Edit1Exit(Sender: TObject); var cod: integer; {cria uma varivel local } begin cod:= strtointdef(Edit1.text,0); {guarda o cdigo na varivel } if cod > 0 then begin if achoucliente(cod) then {testa se j tem um cliente com esse cdigo } begin showmessage('Cliente j cadastrado'); edit1.setfocus; end else begin button1.enabled:=true; { se no tem, habilita o boto OK } end; end; end;

10. No Form do menu, implemente o evento OnClose, colocando a chamada para o procedimento de fechamento do arquivo, para fechar o arquivo ao encerrar o programa:
procedure TFrMenu.FormClose(Sender: TObject; var Action: TCloseAction); begin fecha_arquivo; end;

11. Crie um form para a incluso de Clientes com a seguinte estrutura:

15. Implemente o evento OnClick do boto OK:


procedure TFrCadIncCliente.Button1Click(Sender: TObject); begin cli.codigo := strtointdef(Edit1.text,0); cli.nome := Edit2.text; cli.cidade := Edit3.text; seek(arq,FILESIZE(arq)); { posiciona o ponteiro no final do arquivo } write(arq,cli); { grava o registro} edit1.setfocus; Linguagem de Programao II - URI Campus de Frederico Westphalen

123

Linguagem de Programao II - URI Campus de Frederico Westphalen

124

end;

21. Implemente o evento OnClick do boto OK:


procedure TFrCadAltCliente.Button1Click(Sender: TObject); begin if achoucliente(strtointdef(Edit1.text,0)) then {se o cliente est cadastrado} begin if (edit2.text <> cli.nome) or (edit3.text <> cli.cidade) then { se houve alterao nos dados} begin if Application.Messagebox('Alterar Dados?', 'Confirmao',MB_APPLMODAL+MB_ICONQUESTION+MB_YESNO)=IDYES then begin { se a resposta for sim } cli.codigo := strtointdef(Edit1.text,0); {atualiza os dados } cli.nome := Edit2.text; cli.cidade := Edit3.text; write(arq,cli); {grava o registro na posio atual do cdigo} edit1.setfocus; end; end; end; end;

16. Implemente o evento OnClick do boto Cancelar:


procedure TFrCadIncCliente.Button2Click(Sender: TObject); begin edit1.setfocus; end;

17. Crie um form semelhante ao anterior, sem o boto OK para a consulta de clientes e implemente os eventos OnEnter do Edit1 e OnClick do boto Cancelar com o mesmo cdigo do form de Incluso, exceto a linha que desabilita o button1 (button1.enabled := false). 18. Implemente o evento ao sair (OnExit) do Edit1 com o seguinte cdigo:
procedure TFrCadConsCliente.Edit1Exit(Sender: TObject); var cod: integer; begin cod:= strtointdef(Edit1.text,0); if cod > 0 then begin if achoucliente(cod) then { se achou o cliente } begin Edit2.text := cli.nome; { mostra no form os dados } Edit3.text := cli.cidade; end else begin showmessage('Cliente no cadastrado'); edit1.setfocus; end; end; end;

22. Crie um form semelhante ao primeiro, para a excluso de dados do clientes e implemente os eventos OnEnter do Edit1 e OnClick do boto Cancelar com o mesmo cdigo do form de Incluso. Ao invs do boto OK coloque o caption Excluir. 23. Implemente o evento ao sair (OnExit) do Edit1 com o seguinte cdigo:
procedure TFrCadExcCliente.Edit1Exit(Sender: TObject); var cod: integer; begin cod:= strtointdef(Edit1.text,0); if cod > 0 then begin if achoucliente(cod) then begin Edit2.text := cli.nome; Edit3.text := cli.cidade; button1.enabled:=true; end else begin showmessage('Cliente no cadastrado'); edit1.setfocus; end; end; end;

19. Crie um form semelhante ao primeiro, para a alterao de dados do clientes e implemente os eventos OnEnter do Edit1 e OnClick do boto Cancelar com o mesmo cdigo do form de Incluso. 20. Implemente o evento ao sair (OnExit) do Edit1 com o seguinte cdigo:
procedure TFrCadAltCliente.Edit1Exit(Sender: TObject); var cod: integer; begin cod:= strtointdef(Edit1.text,0); if cod > 0 then { se um cdigo vlido } begin if achoucliente(cod) then { se o cliente j est cadastrado } begin Edit2.text := cli.nome; { mostra os dados no Form } Edit3.text := cli.cidade; button1.enabled:=true; { habilita o boto OK } end else begin showmessage('Cliente no cadastrado'); edit1.setfocus; end; end; end;

24. Implemente o evento OnClick do boto Excluir:


procedure TFrCadExcCliente.Button1Click(Sender: TObject); begin if achoucliente(strtointdef(Edit1.text,0)) then begin if Application.Messagebox('Excluir Registro?', 'Confirmao',MB_APPLMODAL+MB_ICONQUESTION+MB_YESNO)=IDYES then begin cli.codigo := -1; { altera para um cdigo invlido } cli.nome := ''; { deixa os campos vazios } cli.cidade := ''; write(arq,cli); { grava o registro na posio atual do cdigo} edit1.setfocus; end; end; Linguagem de Programao II - URI Campus de Frederico Westphalen

Linguagem de Programao II - URI Campus de Frederico Westphalen

125

126

Edit1.setfocus; end;

25. Crie um form semelhante ao primeiro com os seguintes botes: OK, Excluir, Cancelar. Este form far todas as operaes de dados do clientes. Implemente os eventos OnEnter do Edit1 e OnClick do boto Cancelar com o mesmo cdigo do form de Incluso. 26. Implemente o evento ao sair (OnExit) do Edit1 com o seguinte cdigo:
procedure TFrCadCliente.Edit1Exit(Sender: TObject); var cod: integer; begin cod:= strtointdef(Edit1.text,0); if cod > 0 then begin if achoucliente(cod) then { se o cdigo j est cadastrado } begin Edit2.text := cli.nome; { mostra os dados } Edit3.text := cli.cidade; button1.enabled:=true; { habilita o boto OK } button2.enabled:=true; { habilita o boto Excluir } end else begin button1.enabled:=true; { habilita somente o boto OK } end; end; end;

29. Altere a propriedade ScrollBars do Memo para ssVertical. 30. Implemente o evento OnClick do boto OK para fechar o Form:
procedure TFrListCliente.Button1Click(Sender: TObject); begin close; end;

27. Implemente o evento OnClick do boto OK:


procedure TFrCadCliente.Button1Click(Sender: TObject); begin if achoucliente(strtointdef(Edit1.text,0)) then { alterao de dados } begin if (edit2.text <> cli.nome) or (edit3.text <> cli.cidade) then begin { se houve alterao nos dados} if Application.Messagebox('Alterar Dados?', 'Confirmao',MB_APPLMODAL+MB_ICONQUESTION+MB_YESNO)=IDYES then begin cli.codigo := strtointdef(Edit1.text,0); cli.nome := Edit2.text; cli.cidade := Edit3.text; write(arq,cli); {grava o registro na posio atual do cdigo} edit1.setfocus; end; end; end else begin { se no achou o cliente ento uma incluso } cli.codigo := strtointdef(Edit1.text,0); cli.nome := Edit2.text; cli.cidade := Edit3.text; seek(arq,FILESIZE(arq)); { posiciona o ponteiro no final do arquivo } write(arq,cli); { grava o registro} end; edit1.setfocus; end;

31. Implemente o evento OnShow do Form de listagem com o seguinte cdigo:


procedure TFrListCliente.FormShow(Sender: TObject); begin memo1.clear; { limpa o memo } memo1.lines.add('Cd - Nome - Cidade '); { escreve o cabealho } seek(arq,0); { posiciona no 1.o registro do arquivo } while (not eof(arq)) do { enquanto nao chega no final do arquivo } begin read(arq,cli); {l os registros } if cli.codigo > 0 then {se codigo for maior que 0 escreve os campos} begin memo1.lines.add(IntToStr(cli.codigo)+' - '+ cli.nome+' - '+cli.cidade); end; end; end;

Implemente os eventos OnClick de cada opo do menu para chamar os forms implementados.

28. Para fazer a listagem dos registros, crie um Form com um Memo e um boto, como o exemplo:
Linguagem de Programao II - URI Campus de Frederico Westphalen

127

Linguagem de Programao II - URI Campus de Frederico Westphalen

128

*endereo_da_casa = 10;

10. PONTEIROS
10.1 Definio de ponteiros
Ponteiro uma varivel que pode manter um endereo de uma varivel. Um modo conveniente e muito eficiente de acessar uma varivel fazer referncia a ela atravs de uma segunda varivel que contm o endereo da varivel a ser acessada (ponteiro). Por exemplo, suponha que voc tenha uma varivel int chamada contedo_da_casa e outra chamada endereo_da_casa que pode conter o endereo de uma varivel do tipo int. Em C, preceder uma varivel com o operador de endereos & retorna o endereo da varivel em lugar do seu contedo. A sintaxe para atribuir o endereo da varivel em lugar do seu contedo. A sintaxe para atribuir o endereo de uma varivel a uma varivel que contm o endereo : endereo_da_casa = &contedo_da_casa Uma varivel que pode manter um endereo, como endereo_da_casa, chamada de varivel ponteiro ou simplesmente um ponteiro. contedo da casa [0318] Esta figura ilustra este relacionamento. A varivel contedo_da_casa foi colocada na memria no endereo 0318. Aps a execuo do comando anterior, o endereo de contedo_da_casa foi atribudo para a varivel ponteiro endereo_da_casa. Pode-se expressar este relacionamento dizendo que endereo_da_casa aponta para contedo_da_casa. Para acessar o contedo da clula cujo endereo est armazenado em endereo_da_casa, somente preceda a varivel ponteiro com um *, como em *endereo_da_casa. Por exemplo, se voc executar os seguintes comandos: endereo_da_casa = &contedo_da_casa; *endereo_da_casa = 10; O valor da clula (varivel) chamada contedo da casa ser 10. Podemos pensar no * como uma instruo para seguir a seta (figura) para encontrar a clula referenciada. Note que, se endereo_da_casa mantiver o endereo de contedo_da_casa, ambos os comandos que seguem tero o mesmo efeito, isto , ambos armazenaro o valor 10 em contedo_da_casa: contedo_da_casa = 10;
Linguagem de Programao II - URI Campus de Frederico Westphalen

contedo da casa 10 [0318]

endereo da casa 0318

10.1.1 Declarao de variveis tipo ponteiro


Como em outras linguagens, C exige uma definio para cada uma das variveis. O seguinte comando define uma varivel ponteiro endereo_da_casa, que pode manter o endereo de uma varivel int: int *endereo_da_casa; Na verdade, h duas partes separadas para esta declarao. O tipo de dado de endereo_da_casa int * e o identificador para a varivel : endereo_da_casa O asterisco aps a int significa aponta para, isto , o tipo de dado int * uma varivel ponteiro que pode manter um endereo para um int. Este um conceito muito importante para memorizar. Em C, ao contrrio de muitas outras linguagens, uma varivel ponteiro guarda o endereo de um tipo de dado particular. Aqui est um exemplo:
char *endereo_para_char;

endereo da casa 0318

int *endereo_para_int;

O tipo de dado endereo_para_char diferente do tipo endereo_para_int. Os erros em tempo de execuo e advertncias durante a compilao podem ocorrer num programa que define um ponteiro para um tipo de dado e ento o utiliza para apontar para algum outro tipo de dado. tambm uma prtica inadequada na programao definir um ponteiro de um modo e depois utiliz-lo de outro:
int *int_ptr; float valor_real = 23.45;

int_ptr = &valor_real; Aqui, a varivel int_ptr foi definida ser do tipo int *, significando que pode conter o endereo de uma clula de memria do tipo int. O terceiro comando tenta atribuir a int_ptr o endereo &valor_real de uma varivel float declarada.

129

Linguagem de Programao II - URI Campus de Frederico Westphalen

130

10.1.2 Usando variveis tipo ponteiro


O seguinte exemplo de cdigo trocar os contedos das variveis valor1 e valor2 usando os operadores de ponteiros:
int valor1 = 10, valor2 = 20, temp; int *int_ptr; int_ptr = &valor1; temp = *int_ptr; *int_ptr = valor2;

*int_ptr = valor2; copia o contedo da varivel valor2 na clula apontada pelo endereo armazenado em int_ptr. valor1 20 [1395] valor2 20 [3321] temp 10 [0579] int_ptr 1395 [1925]

valor2 = temp; O ltimo comando do programa simplesmente copia o contedo da varivel inteira temp em outra varivel inteira valor2. valor1 20 [1395] valor2 10 [3321] temp 10 [0579] int_ptr 1395 [1925]

A primeira linha do programa contm as definies e inicializaes padres. O comando aloca trs clulas para manter um nico int, dando a cada clula um nome, e inicializa duas delas. assumido que a clula chamada valor1 est localizada no endereo 1395, que a clula chamada valor2 est localizada no endereo 3321 e que a clula chamada temp est localizada no endereo 0579.

valor1 10 [1395]

valor2 20 [3321]

temp [0579]

int_ptr [1925]

10.1.3 Inicializando variveis do tipo ponteiro


As variveis do tipo ponteiro, como muitas outras variveis em C podem ser inicializadas em sua definio. Por exemplo, os seguintes dois comandos alocam espao para duas clulas valor1 e int_ptr:
int valor1; int *int_ptr = &valor1;

O segundo comando no programa define int_ptr como um ponteiro para um tipo de dado int. O comando aloca a clula e lhe d um nome (colocado no endereo 1925). Lembre-se que, quando o asterisco combinado com o tipo de dado (neste caso int), a varivel contm o endereo de uma clula do mesmo tipo de dado. Como int_ptr no foi inicializada, ela no aponta para nenhuma varivel int em particular. O terceiro comando atribui a int_ptr o endereo de valor1: valor1 10 [1395] valor2 20 [3321] temp [0579] int_ptr 1395 [1925]

O prximo comando no programa: temp = *int_ptr; valor1 10 [1395] valor2 20 [3321] temp 10 [0579] int_ptr 1395 [1925]

Observe que no foi inicializado *int_ptr (que poderia ser um inteiro qualquer), mas foi inicializado int_ptr (que precisa ser um endereo para um int). Esta inicializao na declarao deixa a interpretao do cdigo bastante confusa, pois o exemplo acima poderia ser escrito com mais clareza, apesar de utilizar uma linha a mais assim:
int valor1; int *int_ptr; int_ptr = &valor1;

J que as strings em C so vetores, podemos inicializar strings nos programas associandoas ao endereo do primeiro caracter, como no exemplo abaixo:
#include <stdio.h> #include <conio.h> void main() { char *palindroma = Socorram o Marrocos; int indice; for(indice=0;indice < strlen(palindroma); indice++) printf(%c,palindroma[indice]); printf(\n); for(indice=strlen(palindroma)-1;indice>=0; indice--)

usa a expresso *int_ptr para acessar o contedo da clula qual int_ptr aponta: valor1. Portanto, o valor inteiro 10 armazenado na varivel temp. Se omitssemos o asterisco na frente de int_ptr, o comando de atribuio ilegalmente armazenaria o contedo de int_ptr (o endereo 1395), na clula chamada temp, que somente pode armazenar um inteiro, e no um endereo. O quinto comando no programa:
Linguagem de Programao II - URI Campus de Frederico Westphalen

131

Linguagem de Programao II - URI Campus de Frederico Westphalen

132

printf(%c,palindroma[indice]); printf(\n); printf(%s,palindroma); printf(\n); printf(palindroma); }

classe = float_ptr; &classe[0] = float_ptr;

10.1.6 Ponteiros para ponteiros


Em C podemos definir variveis ponteiro que apontam para outra varivel ponteiro, que, por sua vez, aponta para os dados. Isto necessrio para programao em ambientes operacionais multitarefa, como Windows, Windows NT e OS/2 que foram projetados para maximizar o uso da memria. Para compactar o uso da memria, o sistema operacional precisa ser capaz de mover objetos na memria quando necessrio. Se seu programa aponta diretamente para a clula de memria fsica onde o objeto est armazenado, e o sistema operacional o mover, haver desastre. Em vez disso, sua aplicao aponta para o endereo da clula de memria que no ser modificada enquanto o programa estiver sendo executado (um endereo virtual), e a clula de memria endereo_virtual mantm o endereo_fsico_atual do objeto de dados, atualizada automaticamente pelo sistema operacional. Para definir um ponteiro para um ponteiro em C, simplesmente aumenta-se o nmero de asteriscos que precedem o identificador como por exemplo: char **char_ptr; Neste exemplo, a varivel char_ptr definida como um ponteiro para um ponteiro que aponta para um tipo de dados char. Cada asterisco lido como ponteiro para. O nmero de ponteiros que precisa ser seguido para acessar o item de dados, ou o nmero de asteriscos que deve ser colocado na varivel para referenciar o valor ao qual ela aponta, chamado de nvel de indireo da varivel ponteiro. O nvel de indireo de um ponteiro determina quanta desreferenciao deve ser feita para acessar o tipo de dados na definio. Observe o exemplo:
int int_dados = 5; int *int_ptr1; int **int_ptr2; int ***int_ptr3; int_ptr1 = &int_dados; int_ptr2 = &int_ptr1; int_ptr3 = &int_ptr2;

10.1.4 Limitaes no operador de endereos


O operador de endereos & no pode ser utilizado em expresses nos seguintes casos: a) No pode ser utilizado com constantes: endereco_variavel = &23;

b) No pode ser utilizado com expresses envolvendo operadores como + / * -: endereco_variavel = &(valor1 + 10); c) No pode ser utilizado precedendo variveis declaradas como register:
register int reg1;

endereco_variavel = &reg1;

10.1.5 Ponteiros para matrizes


Ponteiros e matrizes esto intimamente relacionados. O nome de uma matriz uma constante cujo valor representa o endereo do primeiro elemento da matriz. Por esta razo, um comando de atribuio ou qualquer outro comando no pode modificar o valor do nome de uma matriz. Com as declaraes:
float classe[10]; float *float_ptr;

o nome da matriz classe uma constante cujo valor o endereo do primeiro elemento da matriz de 10 floats. O comando a seguir atribui o endereo do primeiro elemento da matriz varivel ponteiro float_ptr: float_ptr = classe Um comando equivalente : float_ptr = &classe[0]; Entretanto, como float_ptr contm o endereo de um float, os seguintes comandos so ilegais pois tentam atribuir um valor para a constante classe ou seu equivalente &classe[0]:
Linguagem de Programao II - URI Campus de Frederico Westphalen

int dados 5 [1112]

int ptr1 1112 [2368]

int ptr2 2368 [3219]

int ptr3 3219

133

Linguagem de Programao II - URI Campus de Frederico Westphalen

134

10.1.7 Aritmtica com ponteiros


Em C tambm possver a realizao de aritmtica com ponteiros, fazendo-se adio e subtrao com variveis do tipo ponteiro. Ex.:
int *ptr_int; float *ptr_float; int um_inteiro; float um_float; ptr_int = &um_inteiro; ptr_float = &um_float; ptr_int++; ptr_float++;

void (*func)(int); func um ponteiro para uma funo void que possui um inteiro como parmetro; float (*ptf)(int,double); ptf um ponteiro para uma funo que retorna float e possui como parmetros um int e um double.

Os ponteiros para funes tm importantes usos. Por exemplo, considere a funo qsort (ordena um vetor), que tem como um de seus parmetros um ponteiro para uma funo. Ns no podemos passar uma funo por valor, isto , passar o prprio cdigo, mas podemos passar um ponteiro para o cdigo, ou seja, um ponteiro para a funo. Exemplos:

Observe apenas que se o valor de ptr_int antes do incremento fosse 2000, aps o incremento esse valor passou para 2002, pois um incremento de int corresponde a 2 bytes, da mesma forma que ptr_float passaria de 3000 para 3004.

#include <stdio.h> int soma(int a, int b); int sob(int a, int b); void main() { int (*pf)(int,int); int i, a, b, r;

10.2 Ponteiros para funes


Em C possvel que uma funo seja ativada atravs de seu endereo de colocao em memria, ao invs de seu nome. Desta forma, pode-se declarar um ponteiro para uma funo (um varivel que armazena o endereo de uma funo) e evoc-la atravs desse ponteiro. Ex.: int (*ptr_func)(); Neste caso, ptr_func um ponteiro para uma funo que retorna inteiro e no possui parmetros. Se, por exemplo, o programa contiver uma funo chamada calcula: int calcula(void); ptr_func ir armazenar o endereo de calcula se fizermos: ptr_func = calcula; /*observe que nao calcula() */

/* ponteiro para funo /*

for(i=0;i<4;i++) { pf=(i%2==0)?soma:sub; printf(\nDigite um valor: ); scanf(%d,&a); printf(\nDigite outro valor: ); scanf(%d,&b); r=(*pf)(a,b); printf(%d\n, r); } } int soma(int a, int b) { printf(A soma : \n); return(a+b); } int sub(int a, int b); { printf(A subtrao : \n); return(a-b); }

A funo ativada atravs do ponteiro quando se escreve: (*ptr_func)(); Outros exemplos:

Outro caso tpico de aplicao so os vetores de ponteiros para funes:


#include <stdio.h> void zero(); void um(); void dois(); void main()

Linguagem de Programao II - URI Campus de Frederico Westphalen

135

Linguagem de Programao II - URI Campus de Frederico Westphalen

136

{ void (*vet[3])(); /* vetor de ponteiros para funes */ int op; vet[0] = zero; vet[1] = um; vet[2] = dois; do { printf(Digite um nmero entre 0 e 2: ); scanf(%d,&op); (*vet[op])(); } while (op<0 || op>2); } void zero() { printf(Zero!\n); } void um() { printf(Um!\n); } void dois() { printf(Dois!\n); }

write('x: '); readln(x); write('y: '); readln(y); px := @x; writeln('Valor apontado por px: ', px^); px := @y; writeln('Valor apontado por px: ', px^); writeln('X: ',x); writeln('Y: ',y); readkey; end.

Para usar um ponteiro para vetor ou para uma matriz necessrio primeiro criar um tipo para o qual o ponteiro possa apontar e declarar uma varivel ponteiro que aponte para o tipo criado. Podemos observar que uma matriz nada mais do que o endereo do primeiro elemento, portanto o tipo criado no precisa ter o tamanho da matriz a que se quer associar ao ponteiro, mas deve ter as mesmas dimenses da matriz:
type y= array[1..1,1..1] of integer; var px : ^y;

O ponteiro pode ento receber o endereo de uma matriz do mesmo tipo para o qual ele aponta
px := @x;

10.3 Ponteiros em Pascal


Em Pascal temos praticamente todas as funcionalidades dos ponteiros de C e C++, com pequenas diferenas na sintaxe. A declarao de um ponteiro em Pascal : nome_do_ponteiro : ^tipo_de_dado ;

A partir dessa associao, pode-se acessar os elementos da matriz atravs do nome seguido dos ndices ou do ponteiro seguido de ^ e dos ndices
o mesmo que writeln( x[8,5] ); writeln( px^[8,5] );

Exemplo:
px : ^integer; z : ^real; mm : ^char; {ponteiro para um inteiro} {ponteiro para um real} {ponteiro para um char}

Exemplo:
uses crt; type y= array[1..1,1..1] of integer; var x: Array[1..10,1..10] of integer; px: ^y; i, j: integer; begin clrscr; for i:= 1 to 10 do begin for j:= 1 to 10 do begin x[i,j]:=i*10+j; end; end; for i:= 1 to 10 do

Para associar um endereo de uma varivel a um ponteiro usa-se o operador @


px := @x;

Para mostrar o valor apontado pelo ponteiro usa-se o nome do ponteiro seguido de um ^
writeln( px^ );

Exemplo:
uses crt; var x,y: integer; px: ^integer; begin clrscr; Linguagem de Programao II - URI Campus de Frederico Westphalen

137

Linguagem de Programao II - URI Campus de Frederico Westphalen

138

begin for j:= 1 to 10 do begin write(x[i,j] :5); end; writeln; end; writeln( o mesmo que: ); px := @x; for i:= 1 to 10 do begin for j:= 1 to 10 do begin write(px^[i,j] :5); end; writeln; end; readkey; end.

11. ALOCAO DINMICA DE MEMRIA


Quando um programa em C ou Pascal compilado, a memria do computador dividida em quatro zonas que contm o cdigo do programa, todos os dados globais, a pilha, e o heap. O heap a rea de memria livre (algumas vezes chamada de armazm livre) que manipulada com as funes de alocao dinmica malloc e free (C) e Getmem e Freemem (Pascal). Quando malloc (C) ou Getmem (Pascal) chamada, ela aloca um bloco contguo de armazenagem para o objeto especificado e ento retorna um ponteiro para o incio do bloco. A funo free (C) ou Freemem (Pascal) retorna a memria alocada previamente para o heap, permitindo que a poro da memria seja realocada. O argumento passado para malloc um inteiro no-sinalizado que representa o nmero necessrio de bytes de armazenagem. Se houver memria disponvel, malloc retornar void * que pode ser convertido para o tipo desejado de ponteiro. Um ponteiro void significa um ponteiro de tipo desconhecido ou genrico. Um ponteiro void no pode ser usado para referenciar qualquer coisa (pois ele no aponta para qualquer tipo especfico de dado), mas pode conter um ponteiro de qualquer outro tipo. Portanto podemos converter qualquer ponteiro num ponteiro void e reconverter sem qualquer perda de informao. O seguinte exemplo aloca armazenagem para um nmero varivel de valores float:
#include <stdio.h> #include <conio.h> #include <stdlib.h> float *fpt; int i, qtd; void main() { clrscr(); printf("Quantidade de valores: "); scanf("%d",&qtd); fpt = (float *) malloc( sizeof(float) * qtd); for (i=0;i<qtd;i++) { printf("%d valor: ",i+1); scanf("%f",&fpt[i]); } for (i=0;i<qtd;i++) { printf("%d valor: %6.2f\n",i+1,fpt[i]); } getch(); free(fpt); }

Em Pascal tambm pode-se utilizar aritmtica com ponteiro, de modo que incrementandoos em uma unidade eles so incrementados em tantos bytes quanto o tipo para quem eles apontam. Outra forma de mostrarmos uma matriz usando artimtica com ponteiros :
uses crt; var x: Array[1..10,1..10] of integer; px: ^integer; i, j: integer; begin clrscr; for i:= 1 to 10 do begin for j:= 1 to 10 do begin x[i,j]:=i*10+j; end; end; px := @x[1,1]; for i:= 1 to 10 do begin for j:= 1 to 10 do begin write(px^ :5); px^:=px^+1; end; writeln; end; readkey; end.

A funo malloc obtm armazenagem suficiente para tantas vezes o tamanho de um float quanto for solicitado. Cada bloco de armazenagem requisitado inteiramnte separado e distinto de todos os outros. No podemos fazer suposies sobre onde os blocos sero alocados. Os blocos so tipicamente identificados com algum tipo de informao que permite que o sistema

Linguagem de Programao II - URI Campus de Frederico Westphalen

139

Linguagem de Programao II - URI Campus de Frederico Westphalen

140

operacional gerencie sua localizao e tamanho. Quando o bloco no mais necessrio, podemos retorn-lo para o sistema operacional por meio do seguinte comando: free( < nome_ponteiro > ) Em Pascal as funes so semelhantes no modo de operar mas um pouco diferentes na sintaxe. O procedimento Getmem recebe dois parmetros, sendo o primeiro o nome do ponteiro e o segundo a quantidade de bytes a serem alocados. Uma diferena a ser observada que o procedimento de liberao de memria Freemem precisa tambm da informao da quantidade de bytes a serem liberados. O exemplo abaixo em Pascal semelhante ao anterior escrito em C:
uses crt; type vetor = Array [1..1] of real; var fpt: ^vetor; i, qtd: integer; begin clrscr; write('Quantidade de valores: '); readln (qtd); GetMem(fpt, sizeof(real) * qtd); for i:= 1 to qtd do begin write(i,' valor: '); readln(fpt^[i]); end; for i:= 1 to qtd do begin writeln(i,' valor: ', fpt^[i]:6:2); end; readkey; FreeMem(fpt,sizeof(integer)*qtd); end.

#include <conio.h> #include <alloc.h> int **matriz; int *colunas; unsigned long lin, col, i, j; void main() { clrscr(); printf("Memoria livre: %lu bytes\n", (unsigned long) coreleft()); printf("Linhas: "); scanf("%d",&lin); matriz=(int **) malloc(sizeof(int *) * lin); colunas=(int *) malloc(sizeof(int) * lin); printf("Memoria livre: %lu bytes\n", (unsigned long) coreleft()); if (matriz==NULL) { printf("Nao foi possivel alocar memoria\n"); exit(1); } for(i=0;i<lin;i++) { printf("Colunas na linha %d: ",i); scanf("%d",&col); matriz[i]=(int *) malloc(sizeof(int)*col); if(matriz[i]==NULL) { printf("Nao foi possivel alocar memoria\n"); exit(1); } colunas[i]=col; printf("Memoria livre: %lu bytes\n", (unsigned long) coreleft()); } printf("Memoria livre: %lu bytes\n", (unsigned long) coreleft()); for(i=0;i<lin;i++) { printf("Linha %d:\n",i); for(j=0;j<colunas[i];j++) { printf("%d Valor: ",j); scanf("%d",&matriz[i][j]); } } for(i=0;i<lin;i++) { printf("\n"); for(j=0;j<colunas[i];j++) { printf("%5d",matriz[i][j]); } } for(i=0;i<lin;i++) { free(matriz[i]); } free(matriz); free(colunas); printf("\nMemoria livre: %lu bytes\n", (unsigned long) coreleft()); getch(); }

Quando precisamos de variveis com um tamanho desconhecido na compilao, devemos usar alocao dinamica de memria, no heap. Devemos porm tomar o cuidado de liberar a memria quando no precisamos mais da varivel, pois o compilador s devolve automaticamente a memria ocupada pelas variveis locais. Se no liberarmos a memria corretamente, o programa pode vir a travar. A grande vantagem da utilizao de alocao dinmica que permite-se criar estruturas semelhantes a matrizes com dimenses desconhecidas no momento da compilao. Devido a uma limitao da linguagem Pascal, uma matriz ou vetor no pode ocupar mais do que 64 Kbytes de memria, portanto, quando necessitamos de uma matriz ou vetor com mais de 64 Kbytes devemos usar alocao dinmica de memria. Pode-se inclusive criar matrizes com nmero variado de colunas para cada linha, como por exemplo:

#include <stdio.h> #include <stdlib.h> Linguagem de Programao II - URI Campus de Frederico Westphalen

141

Linguagem de Programao II - URI Campus de Frederico Westphalen

142

11.1 Lista encadeada com alocao dinmica de memria:


Uma lista encadeada a forma ideal de armazenamento de dados quando no se sabe antecipadamente quantos itens de dados tero de ser armazenados. Ela funciona ssim: para cada item, existe tambm um ponteiro direcionado para o item de dados seguinte. A qualquer momento, pode-se acrescenta outro item de dados lista, contanto que o que o ltimo ponteiro seja atualizado a fim de apontar para o novo item de dados. Partindo-se do incio da lista, possvel percorr-la utilizando-se o ponterio de cada item, que aponta para o prximo item de dados. O tlimo ponteiro da lista geralmetne um ponteiro NULL, portando, sabemos que estamos no final da lista quando encontramos um ponteiro NULL. preciso tambm termos 3 ponteiros auxiliares, para a alocao dinmica da memria: um ponteiro que aponta para o primeiro elemento, para saber onde inicia a lista, um ponteiro que aponta para o ltimo elemento da lista, para colocarmos o valor do novo ponteiro quando inserido um elemento sem ter que percorrer a lista inteira, e um ponteiro auxiliar, que aponta para a nova rea de memria alocada. Esquematicamente, uma lista encadeada semelhante a: dados ponteiro dados ponteiro dados ponteiro dados NULL

printf("Sem memoria"); exit(1); } ledados(aux,cod); if(prim==NULL) { prim=aux; ult=prim; } else { ult->prox=aux; ult=aux; } } imprime(); getch(); liberamem(); } void ledados(produto *p, int c) { float precoaux; clrscr(); p->codigo=c; fflush(stdin); printf("Codigo: %d\n",p->codigo); printf("Descricao: "); gets(p->descr); fflush(stdin); printf("Preco: "); scanf("%f",&precoaux); p->preco=precoaux; p->prox=NULL; } void imprime() { aux=prim; while(aux!=NULL) { printf("%d - %s - %f\n",aux->codigo, aux->descr, aux->preco); aux = aux->prox; } } void liberamem() { aux=prim; while(aux!=NULL) { free(aux); aux = aux->prox; }

Podemos observar no exemplo a seguir, uma lista encadeada com alocao dinmica de memria.
#include <stdio.h> #include <conio.h> #include <stdlib.h> typedef struct produto { int codigo; char descr[40]; float preco; struct produto *prox; }produto; produto *prim, *ult, *aux; int cod; void ledados(produto *p, int c); void imprime(); void liberamem(); void main() { prim=ult=NULL; while(1) { clrscr(); printf("Codigo: "); scanf("%d",&cod); if (cod<0) break; aux=(produto *) malloc(sizeof(produto)); if (aux==NULL) { Linguagem de Programao II - URI Campus de Frederico Westphalen

} O exemplo abaixo a implementao de uma lista encadeada com alocao de memria simples, sem ordenao sendo toda nova informao includa no final da lista:
#include #include #include #include #include <stdio.h> <stdlib.h> <conio.h> <alloc.h> <ctype.h>

143

void liberar(); Linguagem de Programao II - URI Campus de Frederico Westphalen

144

void listar(); void insere(unsigned char infoaux); struct lista { unsigned char info; struct lista *elo; }; struct lista *pri, *aux, *ult, *pen; unsigned char infoaux; void main() { clrscr(); pri=NULL; ult=NULL; do { gotoxy(1,1); printf("Digite uma Letra: "); infoaux=toupper(getch()); if ((infoaux>=65)&&(infoaux<=90)) insere(infoaux); listar(); } while ((infoaux>=65)&&(infoaux<=90)); getch(); liberar(); } void listar() { struct lista *lult; lult=pri; gotoxy(1,10); while(lult!=NULL) { printf("%c ",lult->info); lult=lult->elo; } } void liberar() { struct lista *lult; lult=pri; gotoxy(1,10); while(lult!=NULL) { aux=lult; lult=lult->elo; free(aux); } } void insere(unsigned char infoaux) { aux=(struct lista *) malloc(sizeof(struct lista)); if (aux==NULL) { printf("Nao foi possivel alocar memoria\n"); exit(1); } if (pri==NULL) Linguagem de Programao II - URI Campus de Frederico Westphalen }

else

{ aux->info=infoaux; aux->elo=NULL; pri=aux; ult=pri; } { aux->info=infoaux; aux->elo=NULL; ult->elo=aux; ult=aux; }

O exemplo abaixo a implementao de uma lista encadeada com alocao de memria com ordenao das informaes, ou seja, as informaes so inseridas na lista de forma que ela sempre est com os dados em ordem crescente:
#include #include #include #include #include <stdio.h> <stdlib.h> <conio.h> <alloc.h> <ctype.h>

void liberar(); void listar(); void insere(unsigned char infoaux); struct lista { unsigned char info; struct lista *elo; }; struct lista *pri, *aux, *ult, *pen; unsigned char infoaux; void main() { clrscr(); pri=NULL; do { gotoxy(1,1); printf("Digite uma Letra: "); infoaux=toupper(getch()); if ((infoaux>=65)&&(infoaux<=90)) insere(infoaux); listar(); } while ((infoaux>=65)&&(infoaux<=90)); getch(); liberar(); } void listar() { struct lista *lult; lult=pri; gotoxy(1,10); while(lult!=NULL) { printf("%c ",lult->info);

145

Linguagem de Programao II - URI Campus de Frederico Westphalen

146

lult=lult->elo; }

void liberar() { struct lista *lult; lult=pri; gotoxy(1,10); while(lult!=NULL) { aux=lult; lult=lult->elo; free(aux); } } void insere(unsigned char infoaux) { int inseri; aux=(struct lista *) malloc(sizeof(struct lista)); if (aux==NULL) { printf("Nao foi possivel alocar memoria\n"); exit(1); } if (pri==NULL) { aux->info=infoaux; aux->elo=NULL; pri=aux; } else { if(pri->info > infoaux) { aux->info=infoaux; aux->elo=pri; pri=aux; } else { if(pri->elo == NULL) { aux->info=infoaux; aux->elo=NULL; pri->elo=aux; } else { inseri=0; pen=pri; ult=pri; while(inseri == 0 && ult->elo != NULL) { if (ult->elo != NULL) { pen=ult; ult=ult->elo; } if (ult->info > infoaux) { aux->info=infoaux; aux->elo=ult; Linguagem de Programao II - URI Campus de Frederico Westphalen

} if (inseri==0) { aux->info=infoaux; aux->elo =NULL; ult->elo =aux; } }

pen->elo=aux; inseri=1; }

O exemplo a seguir apresenta uma lista encadeada com alocao dinmica de memria em Pascal.
program listadinamicaordenada; uses crt; type lista = record info: string[10]; prox: Pointer; end; var aux, pri, ult, pen: ^lista; infoaux: string[10]; procedure listar; begin aux:=pri; gotoxy(1,10); while aux<> nil do begin writeln(aux^.info); aux:=aux^.prox; end; end; procedure liberar; begin aux:=pri; gotoxy(1,10); while aux<> nil do begin ult:=aux; aux:=aux^.prox; dispose(ult); end; end; procedure insere(infoaux: string); var inseri: boolean; begin new(aux); if aux=nil then begin writeln('Nao foi possivel alocar memoria.'); exit; end; aux^.info:=infoaux; if pri=nil then

147

Linguagem de Programao II - URI Campus de Frederico Westphalen

148

begin aux^.prox:=nil; pri:=aux; end else begin if pri^.info > infoaux then begin aux^.prox:=pri; pri:=aux; end else begin if pri^.prox = nil then begin aux^.prox:=nil; pri^.prox:=aux; end else begin inseri:=false; pen:=pri; ult:=pri; while (inseri = false) and (ult^.prox <> nil) do begin if ult^.prox <> nil then begin pen:=ult; ult:=ult^.prox; end; if ult^.info > infoaux then begin aux^.prox:=ult; pen^.prox:=aux; inseri:=true; end; end; if inseri=false then begin aux^.prox:=nil; ult^.prox:=aux; end; end; end; end; end; begin pri:=nil; repeat clrscr; writeln('Digite um nome: '); readln(infoaux); if length(infoaux)>0 then insere(infoaux); listar; until length(infoaux)=0; readkey; liberar; end.

11.2 Exemplo de utilizao de alocao dinmica de memria com Delphi


No exemplo do captulo anterior em que foi criado um cadastro de clientes com manipulao de aruquivos, ficou um problema na listagem do cadastro: Como fazer para listar os registros em ordem de cdigo ou em ordem de nome, j que no arquivo eles estaro desordenados. A soluo : deve-se criar uma estrutura para fazer a ordenao dos mesmos. Uma alternativa colocar os dados num vetor, fazer a ordenao e depois mostrar os valores, porm, como saber o tamanho ideal do vetor no momento da criao do programa. A alocao dinmica de memria serve exatamente para isso: vai se fazer uma nica alocao do exato tamanho que o vetor necessita. Aps alocar o vetor, ele deve ser preenchido com os dados, ordenado, e depois de os dados serem mostrados, pode ser liberada a memria. Outra alternativa criar uma lista encadeada, que a cada registro lido, aloca-se uma posio de memria e faz-se a ligao da lista, j em ordem. A seguir so apresentados dois exemplos, sendo o primeiro com um vetor alocado dinamicamente para ordenar os clientes por cdigo e o segundo com uma lista encadeada, ordenando os clientes por nome. Estes exemplos complementam o programa de cadastro de clientes visto no captulo anterior e pode ser adicionado ao mesmo projeto. Para fazer a listagem em ordem de cdigo (poderia ser qualquer outro campo) usando um vetor dinmico, crie um novo form com a mesma estrutura do Form de Listagem de Clientes e implemente o seguinte cdigo: 1. Na clusula Uses da seo interface, inclua a Unit UnFuncoesArquivo 2. Na seo Type crie um novo tipo que um vetor de clientes (precisamos disso para criar um ponteiro para essa estrutura mais adiante): vetor = Array [1..1] of clientes; 3. O incio da unit deve ficar assim:
unit UnListClienteCod; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, UnFuncoesArquivo; type TFrListClienteCod = class(TForm) Memo1: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormShow(Sender: TObject); private { Private declarations } public { Public declarations } end; vetor = Array [1..1] of clientes; var FrListClienteCod: TFrListClienteCod;

Linguagem de Programao II - URI Campus de Frederico Westphalen

149

Linguagem de Programao II - URI Campus de Frederico Westphalen

150

4. Implemente o evento OnShow do Form para conter o seguinte cdigo:


procedure TFrListClienteCod.FormShow(Sender: TObject); var vetdin: ^vetor; { ponteiro para um vetor dinmico } i, j, qtd, aux: integer; aux2: string; begin qtd:=0; seek(arq,0); { posiciona no 1.o registro do arquivo } while (not eof(arq)) do { enquanto nao chega no final do arquivo } begin read(arq,cli); if cli.codigo > 0 then {se codigo for maior que 0 conta} begin qtd:=qtd+1; {conta quantos registros tem } end; end; GetMem(vetdin, sizeof(clientes) * qtd); {aloca o vetor } i:=0; seek(arq,0); { posiciona no 1.o registro do arquivo } while (not eof(arq)) do { enquanto nao chega no final do arquivo } begin read(arq,cli); if cli.codigo > 0 then {se codigo for maior que 0 insere os campos no vetor} begin i:=i+1; vetdin^[i].codigo := cli.codigo; vetdin^[i].nome := cli.nome; vetdin^[i].cidade := cli.cidade; end; end; for i:= 1 to qtd - 1 do { ordena o vetor em ordem crescente de cdigo} begin for j:=i+1 to qtd do begin if vetdin^[i].codigo > vetdin^[j].codigo then begin aux := vetdin^[i].codigo; vetdin^[i].codigo := vetdin^[j].codigo; vetdin^[j].codigo := aux; aux2 := vetdin^[i].nome; vetdin^[i].nome := vetdin^[j].nome; vetdin^[j].nome := aux2; aux2 := vetdin^[i].cidade; vetdin^[i].cidade := vetdin^[j].cidade; vetdin^[j].cidade := aux2; end; end; end; memo1.clear; { limpa o memo } memo1.lines.add('Cd - Nome - Cidade '); { escreve o cabealho } for i:= 1 to qtd do {percorre o vetor ordenado e escreve os campos } begin memo1.lines.add(IntToStr(vetdin^[i].codigo)+ ' - ' + vetdin^[i].nome + ' - ' + vetdin^[i].cidade); end; FreeMem(vetdin,sizeof(clientes)*qtd); end;

Para fazer a listagem em ordem de nome (poderia ser qualquer outro campo) usando uma lista encadeada com alocao dinmica, crie um novo form com a mesma estrutura do Form de Listagem de Clientes e implemente o seguinte cdigo: 1. Na seo Type crie um novo tipo que um registro (record) com as estrutura da lista de clientes:
lista = record codigo:integer; nome:string[40]; cidade:string[30]; prox: Pointer; end;

2. Na seo var crie as variveis para o controle da lista:


aux, pri, ult, pen: ^lista; { 4 ponteiros para o controle da lista }

3. O incio da unit deve ficar assim:


unit UnListClienteNom; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TFrListClienteNom = class(TForm) Memo1: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormShow(Sender: TObject); private { Private declarations } public { Public declarations } end; lista = record codigo:integer; nome:string[40]; cidade:string[30]; prox: Pointer; end; var FrListClienteNom: TFrListClienteNom; aux, pri, ult, pen: ^lista;

4. Use a unit UnFuncoesArquivo (File => Use Unit... => UnFuncoesArquivo.pas) 5. Na seo implementation crie um procedimento que far a insero dos dados na lista:
procedure insere(c: clientes); var inseri: boolean; begin new(aux); { aloca um novo nodo } Linguagem de Programao II - URI Campus de Frederico Westphalen

Linguagem de Programao II - URI Campus de Frederico Westphalen

151

152

if aux=nil then begin showMessage('Nao foi possivel alocar memoria.'); exit; end; aux^.nome:=c.nome; { preenche com os dados } aux^.codigo:=c.codigo; aux^.cidade:=c.cidade; { faz a ligao da lista j em ordem } if pri=nil then { se a lista est vazia } begin aux^.prox:=nil; pri:=aux; end else begin if pri^.nome > c.nome then { se o nome menor que o 1.o da lista } begin aux^.prox:=pri; pri:=aux; end else begin if pri^.prox = nil then { se a lista s tem 1 elemento } begin aux^.prox:=nil; pri^.prox:=aux; end else { se a lista j tem vrios elementos } begin inseri:=false; pen:=pri; ult:=pri; while (inseri = false) and (ult^.prox <> nil) do begin if ult^.prox <> nil then begin pen:=ult; ult:=ult^.prox; end; if ult^.nome > c.nome then begin { se o nome da lista maior que o nome atual } pen^.prox:=aux; {o prx do penltimo aponta para o novo } aux^.prox:=ult; {o prx do novo aponta para o ltimo} {assim o novo ficar entre o penltimo e o ltimo lido } inseri:=true; end; end; if inseri=false then { se chegou ao final da lista sem inserir } begin ult^.prox:=aux; { insere no fim da lista } aux^.prox:=nil; { e no aponta para ningum } end; end; end; end; end;

while (not eof(arq)) do { enquanto nao chega no final do arquivo } begin read(arq,cli); if cli.codigo > 0 then {se codigo for maior que 0 insere na lista} begin insere(cli); end; end; memo1.clear; { limpa o memo } memo1.lines.add('Cd - Nome - Cidade '); { escreve o cabealho } aux:=pri; while aux<> nil do { percorre a lista mostrando os dados } begin memo1.lines.add(IntToStr(aux^.codigo) + ' - ' + aux^.nome + ' - ' + aux^.cidade); aux:=aux^.prox; end; aux:=pri; while aux<> nil do { percorre a lista liberando a memria } begin ult:=aux; aux:=aux^.prox; dispose(ult); end; end;

Este tipo de ordenao com todos os campos do arquivo sendo colocados na memria pode ser feita se o arquivo possui poucos campos. Se o mesmo tiver vrios campos deve-se colocar na lista ou no vetor somente o campo que se quer indexar (ordenar) e um registro com a posio do registro no arquivo (guarda um nmero inteiro obtido com a funo FilePos). Desta forma, quando quisermos mostrar os demais dados do arquivo, basta usar o comando seek posicionando no registro correto, fazendo a leitura e mostrando os dados. O programa ficaria assim (em negrito est o que foi alterado em relao ao anterior):
unit UnListClienteNom2; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TFrListClienteNom2 = class(TForm) Memo1: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormShow(Sender: TObject); private { Private declarations } public { Public declarations } end; lista = record nome:string[40]; posicao:integer; prox: Pointer; end; var FrListClienteNom2: TFrListClienteNom2; aux, pri, ult, pen: ^lista;

6. Implemente o evento OnShow do Form para conter o seguinte cdigo:


procedure TFrListClienteNom.FormShow(Sender: TObject); begin pri:=nil; seek(arq,0); { posiciona no 1.o registro do arquivo Linguagem de Programao II - URI Campus de Frederico Westphalen

153

Linguagem de Programao II - URI Campus de Frederico Westphalen

154

end; implementation uses UnFuncoesArquivo; {$R *.DFM} procedure insere(n: string; p: integer); var inseri: boolean; begin new(aux); { aloca um novo nodo } if aux=nil then begin showMessage('Nao foi possivel alocar memoria.'); exit; end; aux^.nome:=n; { preenche com os dados } aux^.posicao:=p; { faz a ligao da lista j em ordem } if pri=nil then { se a lista est vazia } begin aux^.prox:=nil; pri:=aux; end else begin if pri^.nome > n then { se o nome menor que o 1.o da lista } begin aux^.prox:=pri; pri:=aux; end else begin if pri^.prox = nil then { se a lista s tem 1 elemento } begin aux^.prox:=nil; pri^.prox:=aux; end else { se a lista j tem vrios elementos } begin inseri:=false; pen:=pri; ult:=pri; while (inseri = false) and (ult^.prox <> nil) do begin if ult^.prox <> nil then begin pen:=ult; ult:=ult^.prox; end; if ult^.nome > n then begin { se o nome da lista maior que o nome atual } pen^.prox:=aux; { o prx do penltimo lido aponta para o novo } aux^.prox:=ult; { o prx do novo aponta para o ltimo} { assim o novo ficar entre o penltimo e o ltimo lido } inseri:=true; end; end; if inseri=false then { se chegou ao final da lista sem inserir } begin ult^.prox:=aux; { insere no fim da lista } aux^.prox:=nil; { e no aponta para ningum } end; end; end; end; Linguagem de Programao II - URI Campus de Frederico Westphalen 155 procedure TFrListClienteNom2.FormShow(Sender: TObject); var p: integer; begin pri:=nil; seek(arq,0); { posiciona no 1.o registro do arquivo } while (not eof(arq)) do { enquanto nao chega no final do arquivo } begin p:=filepos(arq); {guarda a posio do registro antes da leitura } read(arq,cli); if cli.codigo > 0 then {se codigo for maior que 0 insere na lista} begin insere(cli.nome, p); end; end; memo1.clear; { limpa o memo } memo1.lines.add('Cd - Nome - Cidade '); { escreve o cabealho } aux:=pri; while aux<> nil do { percorre a lista j em ordem } begin { usando a lista para posicionar a leitura } seek(arq, aux^.posicao); { posiciona a leitura no arquivo } read(arq, cli); { l o registro e mostra os dados do arquivo} memo1.lines.add(IntToStr(cli.codigo)+' - '+ cli.nome+' - '+cli.cidade); aux:=aux^.prox; end; aux:=pri; while aux<> nil do { percorre a lista liberando a memria } begin ult:=aux; aux:=aux^.prox; dispose(ult); end; end; procedure TFrListClienteNom2.Button1Click(Sender: TObject); begin close; end; end.

Linguagem de Programao II - URI Campus de Frederico Westphalen

156

12. EXERCCIOS
1. Altere o exemplo do clculo de mdia para calcular tambm nmeros reais. 2. Sabendo-se que a mdia de quilmetros por litro de um automvel calculado dividindo-se a quantidade de quilmetros pela quantidade de combustvel, faa um programa em Delphi que leia a quantidade de quilmetros percorridos e a quantidade de combustvel e calcule e escreva a mdia de quilmetros por litro.
3. Pela Frmula de Bskara conseguimos encontrar as 2 razes (x1 e x2) de uma equao de 2 Grau:

considerando que o tempo mximo de durao de um jogo de 24 horas e que o jogo pode iniciar em um dia e terminar no dia seguinte. 7. Fazer um programa em Delphi que l 5 valores e conta quantos destes valores so negativos, escrevendo esta informao. 8. Fazer um programa em Delphi que l um nmero no conhecido de valores e conta quantos deles esto em cada um dos intervalos [0, 25], (25, 50], (50, 75], (75, 100].
Observao: Usar um campo Memo para fazer a leitura dos valores. Para acessar cada uma das linhas usar as propriedades: Memo1.Lines.Count para saber a quantidade de linhas. Memo1.Lines[i] para acessar cada uma das linhas do memo. como no exemplo abaixo:

Fazer um programa em Delphi que leia o valor de a, b, c e calcula e escreve as razes da equao, se houver, ou uma mensagem informando que no existem razes 4. Fazer um programa em Delphi que escreve os nmeros mltiplos de 13 entre 0 e 1000, juntamente com a soma e a quantidade dos mesmos. 5. Faa um programa em Delphi com um menu principal com as seguintes opes: - Arquivo Sair - Clculos Mdias Nmeros Primos - Sobre Mdias: Fazer um form que permita a leitura de 3 valores: a, b, c e calcule e escreva a mdia aritmtica e harmnica correspondente. ma = (a + b + c )/3 mh = 3 / (1/a + 1/b +1/c) Obs.:Para o clculo de mdia harmnica, a nota mnima 1. Nmeros Primos: Fazer um form que leia dois valores e escreva os nmeros primos entre esses dois nmeros lidos. Sair: Sair do programa Sobre: Fazer um form com as informaes de quem produziu o programa. O programa deve ter: Um cone personalizado Um nome personalizado na Barra de Ttulo do aplicativo Uma caixa de dilogo confirmando se o usurio realmente deseja sair do aplicativo 6. Fazer um programa em Delphi que l a hora de incio de um jogo e a hora de trmino do jogo, com horas e minutos. Calcular e escrever a durao do jogo, tambm em horas e minutos,

for i:= 0 to Memo1.Lines.Count -1 do begin showmessage(Memo1.Lines[i]); end;

9. Faa um programa em Delphi que l uma matriz M(6,6) e um valor A e multiplica a matriz M pelo valor A e coloca os valores da matriz multiplicados por A em uma nova matriz. 10. Faa um programa em Delphi que leia uma matriz 5 x 5 e escreva a soma de todas as linhas, colunas, diagonal principal e diagonal secundria.
Observao: Usar um componente Para acessar cada uma StringGrid1.Cells[i,j] . StringGrid para das clulas fazer a usar leitura as dos valores. propriedades:

11. Fazer um programa em Pascal que faa o controle de 10 contas-corrente (banco), com as operaes: Abrir conta Depsito Saque Consulta de Saldo Usar vetores para armazenar os seguintes dados: nro. da conta, saldo, nome do titular. 12. Fazer um programa semelhante ao anterior em Delphi, com um menu e um Form para cada Operao. 13. Fazer um programa semelhante ao anterior em Delphi, com um menu e um Form para cada Operao, usando arquivos ao invs de vetores.

Linguagem de Programao II - URI Campus de Frederico Westphalen

157

Linguagem de Programao II - URI Campus de Frederico Westphalen

158

BIBLIOGRAFIA
GUEZZI, Carlo & JAZAYERI, Mehdi. Conceitos de Linguagem de Programao. Rio de Janeiro, Ed. Campus. 1985. KELLY-BOOTLE, Stan. Dominando o Turbo C. Rio de Janeiro, Ed. Cincia Moderna. 1989. KERNIGHAM, Brian W. & RITCHIE, Dennis M. C: A Linguagem de Programao. Rio de Janeiro, Ed. Campus. 1986. LONGO, Maurcio B.; SMITH Jr., Ronaldo & POLISTCHUCK, Daniel. Delphi 3 Total. Rio de Janeiro, Brasport Livros e Multimdia Ltda. 1997. MECLER, Ian & MAIA, Luiz Paulo. Programao e Lgica com Turbo Pascal. Rio de Janeiro, Ed. Campus. 1989. PALMER, Scott D. Guia do Programador - Turbo Pascal for Windows. Rio de Janeiro, Editora Cincia Moderna. 1992. PAPPAS, Chris H. & MURRAY, Wiliam H. Borland C++. So Paulo, Makron Books. 1995. RINALDI, Roberto. Turbo Pascal 7.0: Comandos e Funes. So Paulo, rica. 1993. SCHILDT, Herbert. Linguagem C: Guia Prtico e Interativo. So Paulo, McGraw-Hill. 1989. WIENER, Richard S. Turbo C Passo a Passo. Rio de Janeiro, Ed. Campus. 1991

Linguagem de Programao II - URI Campus de Frederico Westphalen

159

Você também pode gostar