Você está na página 1de 124

UNIVERSIDADE REGIONAL INTEGRADA E DAS MISSES

DEPARTAMENTO
DE

DO

ALTO URUGUAI

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

1 Semestre/2006

SUMRIO 1. INTRODUO..........................................................................................................................5 2. DADOS.......................................................................................................................................6 2.1 ELEMENTOS DA LINGUAGEM.........................................................................................................6 2.1.1 Elementos definidos pela linguagem:................................................................................6 2.1.2 Elementos definidos pelo Usurio.....................................................................................7 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..........................................................................................................................11 2.4.3 Classes de armazenamento..............................................................................................12 2.5 OPERADORES...........................................................................................................................12 2.5.1 Operadores aritmticos....................................................................................................12 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........................................................................14 2.5.6 Operador Condicional.....................................................................................................15 2.5.7 Operador Vrgula.............................................................................................................15 3. ESTRUTURA DO PROGRAMA...........................................................................................16 3.1 ESTRUTURA DE UM PROGRAMA EM PASCAL..................................................................................16 3.1.1 Identificao do programa..............................................................................................16 3.1.2 Bloco de Declaraes......................................................................................................16 3.1.3 Bloco de Comandos.........................................................................................................17 3.2 ESTRUTURA DE UM PROGRAMA EM C..........................................................................................17 3.2.1 Bloco de Diretivas de Compilao..................................................................................17 3.2.2 Bloco de Declaraes:.....................................................................................................18 3.2.3 Bloco de Implementao:................................................................................................18 4. COMANDOS...........................................................................................................................19 4.1 COMANDOS SIMPLES.................................................................................................................19 4.1.1 Comandos de Entrada e Sada.........................................................................................19 4.1.2 Comandos de Desvio Incondicional................................................................................23 4.2 ESTRUTURAS DE CONTROLE.......................................................................................................25 4.2.1 Seqncia.........................................................................................................................25 4.2.2 Comandos condicionais...................................................................................................25 4.2.3 Comandos de Repetio...................................................................................................30 5. FUNES E PROCEDIMENTOS........................................................................................36 5.1 PROCEDIMENTOS .....................................................................................................................36 5.1.1 Passagem de parmetros ................................................................................................36 5.2 FUNES................................................................................................................................36 5.2.1 Estilos e prottipos das funes.......................................................................................37 5.2.2 Argumentos das funes..................................................................................................37 5.2.3 Tipos de funes...............................................................................................................39 5.3 ARGUMENTOS PASSADOS A PROGRAMAS.........................................................................................41

5.3.1 Argumentos passados a programas em PASCAL............................................................41 5.3.2 Argumentos passados a programas em C........................................................................41 6. MATRIZES..............................................................................................................................43 6.1 MATRIZES EM PASCAL...............................................................................................................43 6.2 MATRIZES EM C......................................................................................................................44 6.3 STRINGS.................................................................................................................................45 6.4 MATRIZES E VETORES COMO PARMETROS DE FUNES....................................................................46 7. PONTEIROS............................................................................................................................49 7.1 DEFINIO DE PONTEIROS..........................................................................................................49 7.1.1 Declarao de variveis tipo ponteiro.............................................................................50 7.1.2 Usando variveis tipo ponteiro........................................................................................50 7.1.3 Inicializando variveis do tipo ponteiro..........................................................................52 7.1.4 Limitaes no operador de endereos.............................................................................53 7.1.5 Ponteiros para matrizes...................................................................................................53 7.1.6 Ponteiros para ponteiros.................................................................................................54 7.1.7 Aritmtica com ponteiros.................................................................................................54 7.2 PONTEIROS PARA FUNES..........................................................................................................55 7.3 PONTEIROS EM PASCAL..............................................................................................................57 8. ESTRUTURAS, UNIES E ITENS DIVERSOS.................................................................60 8.1 ESTRUTURAS...........................................................................................................................60 8.1.1 Passando uma estrutura para uma funo.....................................................................61 8.1.2 Matriz de Estruturas........................................................................................................61 8.1.3 Estruturas dentro de estruturas.......................................................................................62 8.1.4 Ponteiros para estruturas................................................................................................63 8.1.5 Estruturas em Pascal e Delphi.........................................................................................64 8.2 UNIES..................................................................................................................................66 8.3 ITENS DIVERSOS........................................................................................................................68 8.3.1 typedef..............................................................................................................................68 8.3.2 enum.................................................................................................................................68 9. ALOCAO DINMICA DE MEMRIA.........................................................................69 9.1 LISTA ENCADEADA COM ALOCAO DINMICA DE MEMRIA:.............................................................72 10. ARQUIVOS............................................................................................................................78 10.1 ARQUIVO TIPADO EM DELPHI E PASCAL......................................................................................78 10.1.1 Declarao de arquivos.................................................................................................78 10.1.2 Funes de abertura e fechamento de arquivos............................................................79 10.1.3 Funes de escrita e gravao......................................................................................81 10.2 ARQUIVOS TEXTO EM PASCAL E DELPHI.....................................................................................86 10.2.1 Funes para manipulao de arquivos texto...............................................................88 10.3 ARQUIVOS SEM TIPOS EM PASCAL E DELPHI.........................................................90 10.3.1 Funes para manipulao de arquivos sem tipos........................................................90 10.3.2 Arquivos com diversas estruturas em Pascal e Delphi..................................................91 10.4 ARQUIVOS EM C....................................................................................................................94 10.4.1 Declarao de arquivos.................................................................................................96 10.4.2 Funes de abertura e fechamento de arquivos............................................................96 10.4.3 Funes de escrita e gravao.......................................................................................98 10.4.4 Funes de Escrita e Gravao em Arquivos Texto....................................................100 10.4.5 Funes "fseek" , "ftell" e "rewind".............................................................................102 10.4.6 Arquivos com diversas estruturas................................................................................103

11. LINGUAGEM DELPHI......................................................................................................106 11.1 CONCEITOS BSICOS..............................................................................................................108 11.1.1 Programao em Windows: Janelas e eventos............................................................108 11.2 PROGRAMAO ORIENTADA A OBJETO (POO)..........................................................................108 11.3 O AMBIENTE DO DELPHI........................................................................................................109 11.3.1 Arquivos que Compem um Aplicao........................................................................109 11.3.2 Arquivos Gerados pela Compilao............................................................................109 11.4 COMPONENTES ....................................................................................................................110 11.4.1 Nomenclatura...............................................................................................................110 11.4.2 Propriedades................................................................................................................110 11.4.3 Eventos.........................................................................................................................110 11.4.4 Mtodos........................................................................................................................111 11.4.5 Janelas.........................................................................................................................111 11.4.6 TMainMenu..................................................................................................................112 11.4.7 TPopUpMenu...............................................................................................................113 11.4.8 TLabel..........................................................................................................................113 11.4.9 TEdit.............................................................................................................................113 11.4.10 TMemo.......................................................................................................................113 11.4.11 TButton.......................................................................................................................114 11.4.12 TCheckBox.................................................................................................................114 11.4.13 TRadioButton.............................................................................................................114 11.4.14 TListBox.....................................................................................................................114 11.4.15 TComboBox................................................................................................................114 11.4.16 TScrollBox..................................................................................................................115 11.4.17 TGroupBox.................................................................................................................115 11.4.18 TRadioGroup.............................................................................................................115 11.4.19 TPanel........................................................................................................................115 11.4.20 TActionList.................................................................................................................115 11.4.21 TBitBtn.......................................................................................................................115 11.4.22 TMaskEdit..................................................................................................................116 11.4.23 TBevel........................................................................................................................116 11.4.24 TShape........................................................................................................................116 11.4.25 TImage.......................................................................................................................117 11.4.26 TPageControl.............................................................................................................117 11.4.27 TTabSheet..................................................................................................................117 11.4.28 TTimer........................................................................................................................117 11.4.29 TStatusBar..................................................................................................................117 11.4.30 TStatusPanels.............................................................................................................117 11.4.31 TStatusPanel..............................................................................................................118 11.4.32 TStringGrid................................................................................................................118 11.5 CAIXAS DE MENSAGEM..........................................................................................................118 11.5.1 ShowMessage...............................................................................................................118 11.5.2 MessageBox.................................................................................................................118 11.5.3 InputBox.......................................................................................................................120 11.6 DICAS................................................................................................................................120

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. Da mesma forma a linguagem de programao Cyclone uma verso modificada da linguagem de programao C destinada a reduzir esses problemas.

2.
2.1

DADOS
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

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. and case do end function in nil or program set type while PASCAL array const downto file goto label not packed record then until with begin div else for if mod of procedure repeat to var auto char default else float if register signed struct union volatile C break const do enum for int return sizeof switch unsigned while 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.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.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. 7

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.

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.2.1 Tipos predefinidos pela linguagem


PASCAL tipo shortint byte integer word longint real single * double * extended * comp * char boolean string intervalo de representao tamanho -128 a 127 1 byte 0 a 255 1 byte -32.768 a 32.767 2 bytes 0 a 65.535 2 bytes -2.147.483.648 a 2.147.483.647 4 bytes 2.9 x 10 39 a 1.7 x 10 38 6 bytes 45 38 1.5 x 10 a 3.4 x 10 4 bytes 324 308 5.0 x 10 a 1.7 x 10 8 bytes 1.9 x 10 4951 a 1.1 x 10 4932 10 bytes 18 18 -9.2 x 10 a 9.2 x 10 8 bytes os caracteres da tabela ASCII 1 byte TRUE ou FALSE 1 byte tipo estruturado composto por quantidade de caracteres x 1 byte um 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. 8

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

-2 63 a 2 63 8 bytes 2.9 x 10 39 a 1.7 x 10 38 6 bytes 45 38 1.5 x 10 a 3.4 x 10 4 bytes 324 308 5.0 x 10 a 1.7 x 10 8 bytes 1.9 x 10 4932 a 1.1 x 10 4932 10 bytes 63 63 -2 a 2 8 bytes os caracteres da tabela ASCII 1 byte TRUE ou FALSE 1 byte tipo estruturado composto por quantidade de caracteres x 1 byte um 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

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

intervalo de representao -128 a 127 1 byte -32.768 a -32767 2 bytes 3.4 E-38 a 3.4 E38 4 bytes 1.7 E-308 a 1.7 E308 8 bytes 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

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 ...

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. 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

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

10

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

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

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.

11

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.

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++; }

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). 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.

2.5

Operadores

2.5.1 Operadores aritmticos


PASCAL e DELPHI C 12

+ * / MOD DIV

soma subtrao multiplicao diviso resto da diviso inteira inteiro da diviso

+ * / %

soma subtrao multiplicao diviso resto da diviso inteira

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;

+=

*=

/=

%=

> 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 > < >= <= = <> maior que menor que maior ou igual menor ou igual igual diferente > < >= <= == != C 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

13

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. PASCAL e DELPHI and or not xor SHR SHL Exemplos:
C Pascal

C & | ~ ^ >> <<

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

char a, b, c;
a=1; b=3; (C) c = a & b

a, b, c: byte
a:=1; b:=3 (C) c = a | b (Pascal) c:= a or b (C) c = a ^ b 00000001 | 00000011 00000011

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

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: 14

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;

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--) { ... }

15

3.
3.1

ESTRUTURA DO PROGRAMA
Estrutura de um Programa em Pascal

Normalmente um programa Pascal possui trs partes distintas: Identificao do programa, Bloco de declaraes e Bloco de comandos.

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: Serve para o programadore criar seus prprios tipos de dados. 16

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.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: #include <stdio.h> /* inclui a biblioteca padro de comandos de entrada e sada que se encontra no diretrio padro*/

17

#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...

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!); }

18

4.
4.1

COMANDOS
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>);

19

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>);

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);

Cdigos de formato: Normalmente os cdigos de formato so utilizados na sua forma mais simples: %c caracter simples %d %f %s decimal ponto flutuante cadeia de caracteres

%ld inteiro longo %o %x octal hexadecima

%lf double

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; char c; double d;

20

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.

0n idntico ao anterior, apenas com a diferena de que as casas no ocupadas sero preenchidas com zeros. [preciso]: n [tamanho]: l long 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 \xn Exemplos: nova linha retorno do carro tabulao retrocesso (backspace) aspas barra nulo sinal sonoro caracter de cdigo n (em hexadecimal) indica o nmero de casas aps a vrgula.

21

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);

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]

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. Toda entrada correspondente <ENTER>. Ex.:
void main() { float anos, dias; printf(Digite sua idade em anos: ); scanf(%f,&anos); dias=anos*365;

um comando scanf deve sempre ser finalizado por

22

printf(Voc j viveu %f dias\n,dias); }

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] todos os caracteres de A at Z apenas os caracteres a, b ou c todos os caracteres menos a, b, c %[search set]

%[A-Z0-9a-z] maisculas + minsculas + dgitos 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); }

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.

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. 23

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

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

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.

Exemplo em C:
#include <stdio.h> #include <conio.h> #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;

24

fim_ok: printf("Finalizando por bem"); goto fim; fim_qm: printf("Finalizando de qualquer maneira"); fim: getch(); }

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).

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 : IF condio THEN <comando>; IF condio THEN <comando1> ELSE <comando2>; Exemplos em Pascal
uses crt; var x: integer; begin x:=10; if x>15 then uses crt; var x, y: integer; begin x:=10; if (x>15) and (y>15) then

25

begin writeln(X maior que 15); end; end.

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"); } }

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. 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; 26

else if (expresso2) ao2; else if (expresso3) ao3;

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) { printf("X vale 10\n"); } else if (x == 15) { printf("X vale 15\n"); } else { printf("X no vale 5, 10 ou 15\n"); } }

27

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.

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 end; 10: begin writeln('X end; 15: begin writeln('X end; else begin writeln('X end; end; end.

vale 5'); vale 10'); vale 15'); nao vale 5, 10 ou 15');

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) {

28

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

Exemplo:
#include <stdio.h> #include <conio.h> int x; void main() { x = 15; switch(x) { case 5: { printf("X break; } case 10: { printf("X break; } case 15: { printf("X break; } default: { printf("X } } getch(); }

vale 5\n");

vale 10\n");

vale 15\n");

nao vale 5, 10 ou 15\n");

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. 29

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>

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

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 30

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); } }

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. 31

Geralmente estas estruturas so usadas quando um nmero indefinido de repeties esperado. Em Pascal a sintaxe :
WHILE <condio> do <comandos>;

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 :
while (expr_teste) <comandos>;

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); }

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.

Em Pascal a sintaxe do comando : 32

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.

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

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

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. 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. 33

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.

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); } }

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; end.

Exemplo em C:
void main() { int i; for(i=1;i<=10;i++) { if ( i % 2 != 0) continue;

34

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:
#include <stdio.h> #include <conio.h> #include <stdlib.h> void main() { while(1) { printf("Xx "); if ( kbhit()) exit(0); } }

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

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.

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.

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

Funes
Em Pascal as funes podem ser vistas como um procedimento que retorna um nico valor. 36

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.

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.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. 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: 37

... int v; v=30; func1(v,25); ... 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); }

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); printf("%d",a); } void func1(int *p) {

38

int x; scanf("%d",&x); *p = x * 2; }

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); }

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

39

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 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); }

40

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.

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. 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

41

...

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 convert-los de string para nmero com as funes de converso apropriadas (atoi, atol, atof que encontram-se definidas em stdlib.h)

42

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.

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: Notas: Array[1..40,1..3] of integer; Uma matriz pode ser declarada e inicializada declarando-se no bloco de constantes: 43

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));

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]); } } }

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.

44

6.3

Strings

Em Pascal temos o tipo de dado string predefinido na linguagem que nada mais que um vetor de caracteres. 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. 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

strcpy strcspn stricmp

strlen strlwr strncat strncmp

strncpy strnicmp

45

strnset strrchr strrev strset strspn strstr strupr

= 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.

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(); 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]); }

46

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(); } 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]) { int a, b; for (a=0;a<3;a++) { printf("\n"); for (b=0;b<3;b++) { printf("%d ",mat2[a][b]); } } }

47

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]); } } }

48

7.
7.1

PONTEIROS
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; *endereo_da_casa = 10; 49 endereo_da_casa 0318

contedo_da_casa 10 [0318]

endereo_da_casa 0318

7.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;

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.

7.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;

50

int *int_ptr; int_ptr = &valor1; temp = *int_ptr; *int_ptr = valor2;

valor2 = temp; 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]

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]

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: *int_ptr = valor2; copia o contedo da varivel valor2 na clula apontada pelo endereo armazenado em int_ptr.

51

valor1 20 [1395]

valor2 20 [3321]

temp 10 [0579]

int_ptr 1395 [1925]

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]

7.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;

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 associando-as 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--) printf(%c,palindroma[indice]); printf(\n); printf(%s,palindroma); printf(\n); printf(palindroma); }

52

7.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;

7.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]:
classe = float_ptr; &classe[0] = float_ptr;

53

7.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;

int_dados 5 [1112]

int_ptr1 1112 [2368]

int_ptr2 2368 [3219]

int_ptr3 3219

7.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;

54

int um_inteiro; float um_float; ptr_int = &um_inteiro; ptr_float = &um_float; ptr_int++; ptr_float++;

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.

7.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() */

A funo ativada atravs do ponteiro quando se escreve: (*ptr_func)(); Outros exemplos: 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.

55

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:
#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;

/* 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); }

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


#include <stdio.h> void zero(); void um(); void dois(); void main() { 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: );

56

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); }

7.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 ; Exemplo:
px : ^integer; z : ^real; mm : ^char; {ponteiro para um inteiro} {ponteiro para um real} {ponteiro para um char}

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; write('x: '); readln(x); write('y: '); readln(y); px := @x; writeln('Valor apontado por px: ', px^); px := @y;

57

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;

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:
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 begin for j:= 1 to 10 do begin write(x[i,j] :5); end;

58

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.

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.

59

8.
8.1

ESTRUTURAS, UNIES E ITENS DIVERSOS


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,...;

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); }

60

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); }

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;

61

for(i=0;i<5;i++) { 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);

62

} 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); printf("E nasceu no dia %d/%d/%d\n", cliente[i].dnasc.dia, cliente[i].dnasc.mes, cliente[i].dnasc.ano); } }

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;

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>

63

struct produto { int codigo; char descr[80]; float preco; }p1, p2; 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.5 Estruturas em Pascal e Delphi


A declarao RECORD permite-nos definir um registro: <identificador> = RECORD <campo1> : tipo; <campo2> : tipo; ... <campon> : tipo; END;

64

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 campos de um arquivo deve ser feita atravs da referncia do nome do registro e o nome do campo unidos por um ponto (.).

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; 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:

65

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.

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;

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.: 66

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 :
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.

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.

67

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() { 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,

68

9.

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); }

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 operacional gerencie sua localizao e tamanho. Quando o bloco no mais necessrio, podemos retorn-lo para o sistema operacional por meio do seguinte comando: 69

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.

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 #include #include #include

<stdio.h> <stdlib.h> <conio.h> <alloc.h>

70

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(); }

71

9.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

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));

72

if (aux==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; }

} 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: 73

#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; 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); }

74

} 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) { aux->info=infoaux; aux->elo=NULL; pri=aux; ult=pri; } else { 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());

75

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) { 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)

76

{ 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; pen->elo=aux; inseri=1; } } if (inseri==0) { aux->info=infoaux; aux->elo =NULL; ult->elo =aux; } } } } }

77

10.

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.

10.1 Arquivo tipado em Delphi e Pascal


10.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;

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

78

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 }

10.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 procedimento tenha sucesso necessrio que antes de execut-lo, tenhamos utilizado o procedimento ASSIGN. Sua sintaxe : 79

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.

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.

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 Pascal chamada IORESULT. Para no abortar um programa quando ocorre um erro de I/O, usase a diretiva {$I}. Para voltar ao padro, usa-se a diretiva {$I+}. Por exemplo: 80

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.

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.

10.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, ou ainda, fazer manuteno em informaes j existentes. Vejamos ento, como so os comandos que nos permitem tais tarefas:

81

10.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.

10.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:
PROGRAM teste_read_arq; Uses Crt; CONST nomearq = TESTE.DAT; max = 10;

82

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.

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 : 10.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 :

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

83

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.

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. 10.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);

84

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.

10.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;

10.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.

85

10.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.

10.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 86

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. 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);

87

{$I+} if IORESULT <> 0 then begin writeln('Nao foi possivel abrir o arquivo C:\AUTOEXEC,BAT'); 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.

10.2.1 Funes para manipulao de arquivos texto


10.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 :

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}

88

10.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: EOF[(VAR <arq> : TEXT)] : BOOLEAN;

10.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;

10.2.1.4

SEEKEOLN

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; 10.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.

No exemplo anterior, caso no tivssemos nos utilizando da rotina FLUSH, a gravao no teria sido efetivada, pois a informao estaria apenas bufferizada.

89

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

10.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.

10.3.1 Funes para manipulao de arquivos sem tipos


10.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];

10.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 :

PROGRAM teste_biock; VAR arqent,arqsai nomeent,nomesai lidos, gravados : FILE; : STRING[79]; : WORD;

90

buf

: ARRAY[1..4096] OF CHAR;

BEGIN WRITE('Entre com o nome do arquivo de Origem '); READLN(nomeent); 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.

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

10.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>);

10.3.2 Arquivos com diversas estruturas em Pascal e Delphi


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;

91

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


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;

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;

92

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: '); 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],': ');

93

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.

10.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 filelenght getftime - 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 o tamanho de um arquivo. - Informa a data de criao/acesso de um arquivo.

94

lock lseek open read tell unlock write

- 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.

Principais rotinas de alto nvel: 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

95

Exemplo:
printf(%d,x);

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

10.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;

10.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;

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.

r+ abre um arquivo j existente tanto para leitura como para gravao. Se este arquivo j existir ele no ser destrudo. 96

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.

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); ...

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

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

97

10.4.3 Funes de escrita e gravao


10.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 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;

fwrite retorna o nmero de itens que conseguiu gravar no arquivo. 10.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;

fread retorna o nmero de itens que conseguiu ler do arquivo. 10.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>); 98

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)) 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>

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); } }

99

getch(); }

10.4.4 Funes de Escrita e Gravao em Arquivos Texto


10.4.4.1 Funo fputc

A funao fputc permite que se armazene um caracter (um byte) em um arquivo texto. Sintaxe: fputc(<char>,<fstream>); onde: char = caracter a ser gravado; fstream = ponteiro para o arquivo; 10.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; 10.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;

100

10.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; 10.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. 10.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];

101

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); 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(); }

10.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:

102

fseek(arq1,sizeof(float),0); fseek(arq1,sizeof(clientes),1);

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 : 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);

10.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;

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;

103

A quantidade de atributos dada pela frmula: atributos = (cab.tam_cab - sizeof(inf_DBF))/sizeof(descr_atrib); 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). 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();

104

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"); 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(); }

105

11.

LINGUAGEM DELPHI
O que o Delphi ?

O Delphi nada mais que um simples IDE, IDE voce j deve saber um ambiente integrado para desenvolvimento composto por compilador, editor de texto, ferramenta de depurao e algumas frescurinhas a mais. Talvez voc diga, "haa mas isso eu j sabia, IDE aquela Janela com aqueles lindos botaozinhos...". Resposta errada outra vez, um IDE nada tem a ver com Interface Grafica (GUI), apenas um ambiente composto (voce vai ficar careca de saber) pelo compilador, depurador, editor de textos, etc... e nem sempre esse ambiente grafico. Quem ai j no viu o Borland C ? Pois , apesar de ser uma ferramenta que roda do prompt do DOS tem tudo integrado nele mesmo. Possui um IDE, onde se pode abrir varios arquivos simultaneos, um excelente depurador, o editor de texto insupervel e muitas outras coisas extras. Tudo isso, num IDE terminal texto. Incrivel no ? Mudou sua IDEia sobre o IDE ? A diferena entre o IDE DELPHI para os outros IDE's por ai, que o DELPHI um IDE RAD. Um IDE RAD (Rapid Application Development) ? 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 Botao 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 encontralas e inclui-las em sua aplicacao. Mas o DELPHI uma linguagem ou no ? Pois , se alguem lhe perguntar em que linguagem voce cria seus sistemas, no diga "DELPHI" to rapidamente. Voce s deve dizer DELPHI, quando estiver em volta de um meio academico onde as pessoas conheam o DELPHI, tal como, lista de discusso sobre o assunto, forums relacionados, etc... Talvez voce 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 boteszinhos, labelzinhos e depois vende um aplicativo quase sem nenhuma programao.

106

Concluso : Se alguem 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]

O ObjectPascal, a linguagem pascal orientado a objetos, com todo o poder do OOP. Se voce for um timo programador ObjectPascal, talvez nem precise do DELPHI para escrever seus programas. O pessoal do FreePascal (outra linguagem comptivel com ObjectPascal) j faz isso a 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 friozinho)...certamente no seria das tarefas mais agradveis. Temos de dar os parabens a Borland, escrever um IDE decente para uma linguagem no nada fcil. Talvez o tempo de desenvolvimento do IDE (DELPHI), seje igual ou superior ao tempo de desenvolvimento da linguagem. 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. DELPHI e outros RAD's comum em nosso meio, de haver comparao entre ferramentas RADs. A principal delas, o DELPHI(Borland) x VB (Microsoft). Quando comparamos os IDE's no vemos muitas diferenas entre ambos. Ambos so excelentes. Mas quando comparamos as linguagens, digo, ObjectPascal x VisualBasic, ento as diferenas so muitas. A comparao do ObjectPascal x VisualBasic no justa, pois ambos so diferentes num principio bsico : O ObjectPascal uma linguagem totalmente OOP. O VB ainda orientado a eventos. Alguns programadores VB podem argumentar com certa razo que iniciantes em DELPHI no usam OOP, mas a verdade que eles usam, mesmo sem saberem disso! Por exemplo, quando um form em branco criado, o DELPHI acrescenta as linhas "Form1 : TForm1", o que j uma caracteristica de herana em OOP no ObjectPascal. Outra coisa que torna a comparao impossivel que o VisualBasic baseia suas solues em componentes e API, quando voce possui um problema, se voce no tiver um componente adequado ou uma funcao API que resolva o problema, o desenvolvimento fica emperrado. No ObjectPascal e tambm outras linguagens, elas permitem ao programador intermediario, desenvolver suas prprias solues sem depender de terceiros. Pode-se criar as mais diversas aplicaes : emuladores, device-drivers, comunicao com outros dispositivos, etc...

107

11.1 Conceitos bsicos


11.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.

11.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. 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;

108

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.

11.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.

11.3.1 Arquivos que Compem um Aplicao


11.3.1.1
Ext. .DPR .PAS .DFM .CFG .RES .DSK

Arquivos Gerados no desenvolvimento


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).

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

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

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.

11.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.

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

109

11.4 Componentes
11.4.1 Nomenclatura
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.

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

11.4.2.1
Propriedade Align Canvas

Propriedades Comuns
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 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

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

11.4.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?

110

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;

11.4.3.1
Evento OnChange OnClick OnDblClick OnEnter OnExit OnKeyDown OnKeyPress OnKeyUp

Eventos Comuns
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

11.4.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);

11.4.4.1
Mtodo Create Free Show Hide SetFocus Focused BringToFront SendToBack ScrollBy ScaleBy SetBounds

Mtodos Comuns
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

11.4.5 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 111

como classe base para todas as janelas, veja abaixo algumas propriedades, eventos e mtodos dessa classe.
Propriedade Active ActiveContro l AutoScroll BorderIcons BorderStyle FormStyle Icon Menu Position WindowMen u WindowState Evento OnCreate OnDestroy OnShow OnCloseQuer y OnClose OnActivate OnDeactivate OnResize Mtodo Cascade Tile ArrangeIcons ShowModal Show Close Previous Next Descrio Indica se o Form est ativo Determina o controle que receber o foco por default Adiciona barras de rolagem automaticamente, quando necessrio Define quais cones de controle sero visveis, quais botes vo aparecer na barra de ttulo Estilo da borda do Form Tipo de Form, normal, MDI pai, MDI filho ou sempre visvel cone do Form Indica qual o menu do Form Permite controlar a posio e tamanho do Form na exibio Automatiza o item de menu Window (MDI) Estado do Form, maximizada, minimizada ou normal Descrio Quando o Form instanciado Quando o Form liberado da memria Exatamente antes de mostrar o Form chamada para validar se o Form pode ser fechado 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)

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

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). 112

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

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

11.4.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

11.4.9 TEdit
Utilizado para entrada de texto em uma nica linha.
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

11.4.10
TEdit.

TMemo

Permite entrada de dados texto em mltiplas linhas. Contm propriedades e mtodos do

113

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

11.4.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

11.4.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

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.

11.4.13

TRadioButton

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

11.4.14

TListBox

Utilizado para exibir opes em uma lista.


Propriedade Columns MultiSelect ExtendedSelect IntegralHeight Items ItemIndex Selected SelCount Sorted Descrio Nmero de colunas de texto da lista Define se ser permitida a seleo de mltiplos itens 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

11.4.15

TComboBox

Caixa combinada com lista suspensa.

114

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

11.4.16

TScrollBox

Container com barras de rolagem automticas.

11.4.17

TGroupBox

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

11.4.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

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);

11.4.19

TPanel

Componente Container utilizado para agrupar componentes em um painel.


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

11.4.20

TActionList

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

11.4.21

TBitBtn

Boto especializado, com Bitmap. 115

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

11.4.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

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

11.4.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

11.4.24

TShape

Grfico de uma Forma geomtrica.


Propriedade Brush Pen Shape Descrio Preenchimento da figura, objeto do tipo TBrush Tipo da linha, objeto do tipo TPen Forma geomtrica

116

11.4.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

11.4.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

11.4.27

TTabSheet

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

11.4.28

TTimer

Permite a execuo de um evento a cada intervalo de tempo.


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

11.4.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

11.4.30

TStatusPanels

Lista de panels de um StatusBar. 117

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

11.4.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

11.4.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

11.5 Caixas de Mensagem


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

11.5.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!);

11.5.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. 118

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 MB_OKCANCEL MB_RETRYCANCEL MB_YESNO MB_YESNOCANCEL 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 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

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

Exemplo: O cdigo abaixo:


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

Ter como resultado a seguinte caixa de dilogo:

119

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;

11.5.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;

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

Componente Application

Propriedades

Mtodos Initialize; CreateForm Run; Terminate Close Show Showmodal

Form Label Caption Enabled Font Name Enabled Font Maxlength Name PasswordChar ReadOnly

Edit

Setfocus

120

Button

RadioButton

CheckBox

Memo

ListBox

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
Enabled Font ItemIndex Items Name Sorted Text Enabled Font ItemIndex Items Name

Setfocus

Setfocus

Setfocus

Clear Lines.Add Lines.Count Setfocus

Clear Items.Add Items.Count Setfocus


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

ComboBox

RadioGroup

Para aceitar somente nmeros em campos Edit e ComboBox, Inserir o cdigo abaixo no evento OnKeyPress do controle de edio:
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;

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

121

begin SelectNext(Sender as TWinControl, True, True); key:=#0; 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:

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;

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;

e no envento OnExit o cdigo

procedure TForm1.Memo1Exit(Sender: TObject); begin Form1.KeyPreview:=true; end;

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. Exemplo Edit.text := 'Hoje ' + DateToStr(Date); DecodeDate(Date, ano, mes, dia); DecodeTime(Now, Hora, Min, Seg, cent);

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

IntToStr

Edit1.Text := IntToStr(x);

122

StrToIntDef

Str StrToDate StrToFloat StrToInt StrToTime Time TimeToStr Val

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

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

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) var I, erro: Integer; begin Val(Edit1.Text, I, erro); if erro <> 0 then begin Showmessage('Erro); end;

123

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

124