Você está na página 1de 224

Universidade Federal de Santa Catarina Centro Tecnolgico Departamento de Automao e Sistemas Engenharia de Controle e Automao Industrial

Verso 2000/2

Prof. Marcelo Ricardo Stemmer marcelo@das.ufsc.br DAS CTC - UFSC

Informtica Industrial I

DAS/UFSC

SUMRIO
1 INTRODUO INFORMTICA INDUSTRIAL E AOS SISTEMAS DE PRODUO AUTOMATIZADOS.................................................................................................................................. 9 1.1 AUTOMAO DE PROCESSOS CONTNUOS INDUSTRIAIS .............................................................. 10 1.2 AUTOMAO DE PROCESSOS DISCRETOS E DA PRODUO (AUTOMAO DA MANUFATURA) ... 11 1.3 A MANUFATURA INTEGRADA POR COMPUTADOR (CIM) ............................................................. 11 1.3.1 DEFINIO E OBJETIVOS ........................................................................................................... 11 1.3.2 MODELO CIM........................................................................................................................... 11 1.3.3 FERRAMENTAS COMPUTACIONAIS DE APOIO A CIM .................................................................. 13 2 EQUIPAMENTOS UTILIZADOS EM SISTEMAS AUTOMATIZADOS...................................... 15 2.1 EQUIPAMENTOS MECNICOS ........................................................................................................ 15 2.1.1 MDULOS DE PROCESSAMENTO E USINAGEM ............................................................................ 15 2.1.2 MDULOS DE TRANSPORTE E ARMAZENAMENTO...................................................................... 15 2.1.3 MDULOS DE MANUSEIO DE MATERIAIS E FERRAMENTAS ........................................................ 15 2.1.4 MDULOS DE MONTAGEM ........................................................................................................ 15 2.1.5 MDULOS DE CONTROLE DE QUALIDADE ................................................................................. 16 2.2 DISPOSITIVOS DE COMANDO E CONTROLE ................................................................................... 16 3 COMPUTADORES PC / IC............................................................................................................... 24 3.1 HISTRICO .................................................................................................................................... 24 3.2 ARQUITETURA DO PC.................................................................................................................... 24 3.3 PRINCIPAIS COMPONENTES ........................................................................................................... 25 3.3.1 BARRAMENTO DE DADOS E ENDEREOS ................................................................................... 25 3.3.2 FONTE DE ALIMENTAO DO PC ............................................................................................... 26 3.3.3 CONTROLADOR DE INTERRUPES ........................................................................................... 26 3.3.4 TIMER....................................................................................................................................... 27 3.3.5 CONTROLADOR DE DMA (DIRECT MEMORY ACCESS) .............................................................. 28 3.3.6 MEMRIAS ROM E RAM ......................................................................................................... 28 3.3.7 CONTROLADOR DE TECLADO .................................................................................................... 29 3.3.8 TECLADO .................................................................................................................................. 31 3.3.9 INTERFACE PARALELA .............................................................................................................. 33 3.3.10 INTERFACE SERIAL ................................................................................................................. 33 3.3.11 CONTROLADOR DE VDEO ....................................................................................................... 34 3.3.12 UNIDADES DE DISCO / DISQUETE ............................................................................................ 36 3.4 SOFTWARE BSICO DO PC ............................................................................................................ 41 3.4.1 SOFTWARE DA ROM................................................................................................................. 41 3.4.1.1 Rotinas de Inicializao...................................................................................................... 41 3.4.1.2 BIOS.................................................................................................................................. 41 3.4.2 O SISTEMA OPERACIONAL DOS (DISK OPERATING SYSTEM).................................................... 42 4 PROGRAMAO DO PC E DE SISTEMAS COMPUTADORIZADOS ....................................... 44 4.1 INTRODUO ................................................................................................................................. 44 4.2 CONCEITOS BSICOS DA PROGRAMAO EM C ........................................................................... 45 4.2.1 HISTRICO DE C ....................................................................................................................... 45
Marcelo Ricardo Stemmer
2

Informtica Industrial I

DAS/UFSC

4.2.2 CRIANDO UM PROGRAMA EXECUTVEL ................................................................................... 45 4.2.3 A ESTRUTURA BSICA DE UM PROGRAMA EM C ....................................................................... 46 4.2.4 VARIVEIS ............................................................................................................................... 48 4.2.5 TIPOS DE DADOS....................................................................................................................... 48 4.2.6 CONSTANTES ............................................................................................................................ 50 4.2.7 PONTEIROS ............................................................................................................................... 51 4.2.8 EXERCCIOS .............................................................................................................................. 52 4.3 ENTRADA/SADA DO CONSOLE ...................................................................................................... 53 4.3.1 PRINTF() ................................................................................................................................... 53 4.3.2 CPRINTF()................................................................................................................................. 55 4.3.3 SCANF().................................................................................................................................... 56 4.3.4 GETCH(), GETCHE() E GETCHAR()............................................................................................. 57 4.3.5 PUTCH() OU PUTCHAR()............................................................................................................ 57 4.3.6 EXERCCIOS .............................................................................................................................. 57 4.4 OPERADORES................................................................................................................................. 58 4.4.1 OPERADORES ARITMTICOS ..................................................................................................... 58 4.4.2 OPERADORES RELACIONAIS...................................................................................................... 59 4.4.3 OPERADORES LGICOS BINRIOS .............................................................................................. 59 4.4.4 OPERADORES DE PONTEIROS .................................................................................................... 60 4.4.5 OPERADORES INCREMENTAIS E DECREMENTAIS ....................................................................... 60 4.4.6 OPERADORES DE ATRIBUIO .................................................................................................. 62 4.4.7 O OPERADOR LGICO TERNRIO .............................................................................................. 63 4.4.8 PRECEDNCIA ........................................................................................................................... 63 4.4.9 EXERCCIOS:............................................................................................................................. 63 4.5 LAOS............................................................................................................................................ 64 4.5.1 O LAO FOR ............................................................................................................................. 64 4.5.2 O LAO WHILE......................................................................................................................... 65 4.5.3 O LAO DO-WHILE .................................................................................................................. 66 4.5.4 BREAK E CONTINUE .................................................................................................................. 67 4.5.5 GOTO........................................................................................................................................ 67 4.5.6 EXERCCIOS .............................................................................................................................. 67 4.6 COMANDOS PARA TOMADA DE DECISO ...................................................................................... 68 4.6.1 IF .............................................................................................................................................. 68 4.6.2 IF-ELSE..................................................................................................................................... 69 4.6.3 SWITCH .................................................................................................................................... 69 4.6.4 EXERCCIOS .............................................................................................................................. 71 4.7 FUNES ....................................................................................................................................... 72 4.7.1 SINTAXE ................................................................................................................................... 72 4.7.2 EXEMPLOS ................................................................................................................................ 73 4.7.3 PROTOTIPAGEM ........................................................................................................................ 74 4.7.4 CLASSES DE ARMAZENAMENTO ................................................................................................ 75 4.7.4.1 Auto................................................................................................................................... 75 4.7.4.2 Extern ................................................................................................................................ 75 4.7.4.3 Static.................................................................................................................................. 76 4.7.4.4 Variveis Estticas Externas ............................................................................................... 77 4.7.4.5 Register.............................................................................................................................. 77 4.7.5 EXERCCIOS .............................................................................................................................. 77 4.8 DIRETIVAS DO PR-PROCESSADOR ............................................................................................... 78 4.8.1 DIRETIVA #DEFINE .................................................................................................................... 78 4.8.2 MACROS ................................................................................................................................... 79 4.8.3 DIRETIVA #UNDEF .................................................................................................................... 80 4.8.4 DIRETIVA #INCLUDE ................................................................................................................. 80 4.8.5 COMPILAO CONDICIONAL..................................................................................................... 81 4.8.6 OPERADOR DEFINED ................................................................................................................. 81 4.8.7 DIRETIVA #ERROR .................................................................................................................... 82
Marcelo Ricardo Stemmer
3

Informtica Industrial I

DAS/UFSC

4.8.8 DIRETIVA #PRAGMA .................................................................................................................. 82 4.8.9 EXERCCIOS .............................................................................................................................. 82 4.9 MATRIZES ..................................................................................................................................... 82 4.9.1 SINTAXE DE MATRIZES ............................................................................................................. 83 4.9.2 INICIALIZANDO MATRIZES ........................................................................................................ 84 4.9.3 MATRIZES COMO ARGUMENTOS DE FUNES ........................................................................... 85 4.9.4 CHAMADA POR VALOR E CHAMADA POR REFERNCIA ............................................................. 87 4.9.5 STRINGS ................................................................................................................................... 89 4.9.5.1 Strings Constantes .............................................................................................................. 89 4.9.5.2 String Variveis.................................................................................................................. 89 4.9.5.3 Funes para Manipulao de Strings ................................................................................. 90 4.9.6 EXERCCIOS .............................................................................................................................. 91 4.10 TIPOS ESPECIAIS DE DADOS ........................................................................................................ 92 4.10.1 TYPEDEF ................................................................................................................................. 92 4.10.2 ENUMERADOS (ENUM)............................................................................................................ 93 4.10.3 ESTRUTURAS (STRUCT)........................................................................................................... 94 4.10.4 UNIES ................................................................................................................................... 97 4.10.5 BITFIELDS ............................................................................................................................... 98 4.10.6 EXERCCIOS ............................................................................................................................ 99 4.11 PONTEIROS E A ALOCAO DINMICA DE MEMRIA ................................................................ 99 4.11.1 DECLARAO DE PONTEIROS E O ACESSO DE DADOS COM PONTEIROS.................................... 99 4.11.2 OPERAES COM PONTEIROS ................................................................................................ 100 4.11.3 FUNES & PONTEIROS ........................................................................................................ 102 4.11.4 PONTEIROS & MATRIZES ...................................................................................................... 103 4.11.5 PONTEIROS & STRINGS ......................................................................................................... 104 4.11.6 PONTEIROS PARA PONTEIROS ................................................................................................ 106 4.11.7 ARGUMENTOS DA LINHA DE COMANDO ................................................................................ 108 4.11.8 PONTEIROS PARA ESTRUTURAS ............................................................................................. 109 4.11.9 ALOCAO DINMICA DE MEMRIA .................................................................................... 110 4.11.9.1 Malloc() ......................................................................................................................... 111 4.11.9.2 Calloc() .......................................................................................................................... 112 4.11.9.3 Free() ............................................................................................................................. 112 4.11.10 EXERCCIOS ........................................................................................................................ 113 4.12 MANIPULAO DE ARQUIVOS EM C.......................................................................................... 113 4.12.1 TIPOS DE ARQUIVOS ............................................................................................................. 113 4.12.2 DECLARAO, ABERTURA E FECHAMENTO............................................................................ 114 4.12.3 LEITURA E ESCRITA DE CARACTERES..................................................................................... 115 4.12.4 FIM DE ARQUIVO (EOF)........................................................................................................ 115 4.12.5 LEITURA E ESCRITA DE STRINGS ............................................................................................ 116 4.12.6 ARQUIVOS PADRO .............................................................................................................. 116 4.12.7 GRAVANDO UM ARQUIVO DE MANEIRA FORMATADA ........................................................... 117 4.12.8 LEITURA E ESCRITA DE VALORES BINRIOS ........................................................................... 117 4.12.9 EXERCCIOS .......................................................................................................................... 118 4.13 PROGRAMAO EM C++ ........................................................................................................... 119 4.13.1 PALAVRAS-CHAVE EM C++ ................................................................................................... 121 4.13.2 SINTAXE & VARIVEIS ......................................................................................................... 121 4.13.3 LAOS E COMANDOS DE DECISO ......................................................................................... 122 4.13.4 I/O EM C++: STREAM............................................................................................................ 122 4.13.4.1 A stream de sada cout .................................................................................................... 122 4.13.4.2 A stream de entrada cin................................................................................................... 124 4.13.5 FUNES .............................................................................................................................. 125 4.13.5.1 Valores Default Para Argumentos de uma Funo........................................................... 125 4.13.5.2 Sobrecarga de Funes ................................................................................................... 125 4.13.5.3 Funes Inline ................................................................................................................ 125 4.13.5.4 Operador Unrio de Referncia: &.................................................................................. 126
Marcelo Ricardo Stemmer
4

Informtica Industrial I

DAS/UFSC

4.13.6 4.13.7 4.14 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.14.7 4.14.8 4.14.9 4.14.10 4.14.11 4.15 4.15.1 4.15.2 4.15.3 4.15.4 4.15.5 4.16 4.16.1 4.16.2 4.16.3 4.16.4 4.16.5 4.16.6 4.16.7 4.16.8 4.16.9 4.16.10 4.17 4.17.1 4.17.2 4.17.3 4.17.4 4.17.5 4.17.6 4.18 4.18.1 4.18.2 4.18.3 4.18.4 4.18.5 4.18.6

ALOCAO DINMICA DE MEMRIA EM C++ ....................................................................... 126 EXERCCIOS .......................................................................................................................... 127 CLASSES E OBJETOS EM C++ .................................................................................................... 127 TIPO CLASSE E O ENCAPSULAMENTO DE DADOS ................................................................... 129 DEFININDO CLASSES ............................................................................................................. 129 MEMBROS PRIVADOS E PBLICOS ......................................................................................... 130 FUNES-MEMBRO............................................................................................................... 131 CONSTRUTORES & DESTRUTORES ......................................................................................... 131 CRIANDO OBJETOS................................................................................................................ 132 ATRIBUTOS DO TIPO STATIC ................................................................................................. 133 ACESSANDO FUNES E DADOS PBLICOS ........................................................................... 134 OBJETOS CONST.................................................................................................................... 134 TIPO OBJETO ....................................................................................................................... 135 EXERCCIOS ........................................................................................................................ 135 SOBRECARGA DE OPERADORES ................................................................................................ 135 A SOBRECARGA COMO UMA FUNO GLOBAL ...................................................................... 137 LIMITAES E CARACTERSTICAS ......................................................................................... 138 SOBRECARGA DE OPERADORES COMO FUNO-MEMBRO ..................................................... 138 ESTUDO DE CASOS ................................................................................................................ 139 EXERCCIOS .......................................................................................................................... 146 HERANA ................................................................................................................................... 147 DERIVANDO UMA CLASSE ..................................................................................................... 148 DADOS PROTECTED .............................................................................................................. 151 CONSTRUTORES & DESTRUTORES ......................................................................................... 151 CONSTRUTOR DE CPIA & ALOCAO DINMICA ................................................................ 152 CHAMADAS A FUNES ........................................................................................................ 152 HERANA PBLICA E PRIVADA ............................................................................................. 153 CONVERSES DE TIPOS ENTRE CLASSE-BASE E DERIVADA ................................................... 154 NVEIS DE HERANA ............................................................................................................. 154 HERANA MLTIPLA ............................................................................................................ 154 EXERCCIOS ........................................................................................................................ 158 FUNES VIRTUAIS E AMIGAS .................................................................................................. 158 FUNES VIRTUAIS .............................................................................................................. 158 DESTRUTORES VIRTUAIS....................................................................................................... 160 CLASSE-BASE VIRTUAL ........................................................................................................ 161 FUNES AMIGAS ................................................................................................................. 162 CLASSES AMIGAS.................................................................................................................. 163 EXERCCIOS .......................................................................................................................... 164 OPERAES COM ARQUIVOS IOSTREAM .................................................................................. 164 ESTUDO DE CASO .................................................................................................................. 166 A FUNO OPEN() ................................................................................................................ 169 TESTANDO ERROS ................................................................................................................. 169 ESCREVENDO E LENDO EM BUFFERS DE CARACTERES........................................................... 169 IMPRIMINDO EM PERIFRICOS ............................................................................................... 170 EXERCCIOS .......................................................................................................................... 171

5 CONTROLADORES LGICOS PROGRAMVEIS (CLP, PLC) ............................................... 172 5.1 INTRODUO AOS CLPS ............................................................................................................. 172 5.1.1 DEFINIO ............................................................................................................................. 172 5.1.2 REAS DE APLICAO ............................................................................................................ 172 5.1.3 HISTRICO.............................................................................................................................. 173 5.2 ARQUITETURA DOS CLPS............................................................................................................ 173 5.3 FORMAS DE INTERFACEAMENTO HOMEM/MQUINA PARA CLPS ............................................. 175
Marcelo Ricardo Stemmer
5

Informtica Industrial I

DAS/UFSC

5.3.1 INTERFACEAMENTO POR MEIO DAS ENTRADAS E SADAS DO CLP ........................................... 175 5.3.2 INTERFACEAMENTO POR MEIO DE PAINIS INTELIGENTES ........................................................ 176 5.3.3 INTERFACEAMENTO POR MEIO DE TERMINAIS DE PROGRAMAO (TP)................................... 177 5.3.4 INTERFACEAMENTO POR INTERMDIO DE COMPUTADORES TIPO PC / IC.................................. 177 5.4 MDULOS DE ENTRADA E SADA ................................................................................................ 178 5.5 ORGANIZAO INTERNA DE MEMRIA ....................................................................................... 179 5.6 PROGRAMAO DE CLPS ........................................................................................................... 180 5.6.1 INTRODUO .......................................................................................................................... 180 5.6.2 REVISO DE LGEBRA BOOLEANA .......................................................................................... 182 5.6.3 INSTRUCTION LIST (IL) ........................................................................................................... 185 5.6.3.1 Introduo ........................................................................................................................ 185 5.6.3.2 Elementos bsicos ............................................................................................................ 185 5.6.3.3 Exemplo de programao em IL ....................................................................................... 186 5.6.3.4 Vantagens e desvantagens da tcnica ................................................................................ 188 5.6.4 LADDER DIAGRAMM (LD) ...................................................................................................... 188 5.6.4.1 Introduo ........................................................................................................................ 188 5.6.4.2 Elementos bsicos do LD ................................................................................................. 188 5.6.4.3 Estrutura de um programa em LD ..................................................................................... 190 5.6.4.4 Operandos e Instrues de LD .......................................................................................... 192 5.6.4.5 Diagramas equivalentes.................................................................................................... 196 5.6.4.6 Exemplos de programao em LD .................................................................................... 197 5.6.4.7 Vantagens e desvantagens da tcnica ................................................................................ 200 5.6.5 GRAFOS DE COMANDO ETAPA-TRANSIO (GRAFCET, SFC) ............................................... 201 5.6.5.1 Introduo ........................................................................................................................ 201 5.6.5.2 Elementos bsicos do GRAFCET ..................................................................................... 202 5.6.5.3 Regras de Evoluo do GRAFCET................................................................................... 204 5.6.5.4 Estruturas lgicas em GRAFCET ..................................................................................... 206 5.6.5.5 Anlise e validao do GRAFCET ................................................................................... 208 5.6.5.6 Exemplo de programao em GRAFCET ......................................................................... 210 5.6.5.7 Vantagens da tcnica ........................................................................................................ 212 5.7 NORMAS RELEVANTES PARA CLPS ............................................................................................ 212 5.8 INTERLIGAO DE CLPS UTILIZANDO REDES DE COMUNICAO ............................................ 213 5.9 O MERCADO DE CLPS NO BRASIL .............................................................................................. 214 6 SENSORES E ATUADORES INTELIGENTES............................................................................. 216 6.1 6.2 SENSORES INTELIGENTES ........................................................................................................... 216 ATUADORES INTELIGENTES ........................................................................................................ 217

7 ANEXO I TRABALHOS EM C/C++ ............................................................................................ 219

8 ANEXO II TRABALHO DE CLP................................................................................................. 220

9 BIBLIOGRAFIA .............................................................................................................................. 222 9.1 9.2 9.3 CLP ............................................................................................................................................. 222 C/C++ .......................................................................................................................................... 223 HOT SITES ................................................................................................................................... 224

Marcelo Ricardo Stemmer

Informtica Industrial I

DAS/UFSC

NDICE DE FIGURAS
Figura 1 O mbito da informtica industrial................................................................................10 Figura 2 Controle em malha fechada...........................................................................................10 Figura 3 Controle Digital............................................................................................................11 Figura 4 Modelo CIM.................................................................................................................12 Figura 5 - Relao entre as ferramentas computacionais de apoio no ambiente CIM .....................14 Figura 6 - Mdulos de Processamento e Usinagem. .......................................................................17 Figura 7 - Mdulos de Processamento e Usinagem (cont.). ............................................................18 Figura 8 - Mdulos de Transporte e Armazenamento.....................................................................19 Figura 9 - Mdulos de Transporte e Armazenamento (cont.)..........................................................20 Figura 10 - Mdulos de Manuseio de Materiais e Ferramentas.......................................................21 Figura 11 - Mdulos de Montagem................................................................................................22 Figura 12 - Mdulos de Controle de Qualidade..............................................................................23 Figura 13 - Arquitetura interna do PC............................................................................................24 Figura 14 - Barramentos no PC......................................................................................................25 Figura 15 - Controlador de Interrupes no PC..............................................................................27 Figura 16 - Controlador de Teclado no PC.....................................................................................30 Figura 17 - Placa Me de um PC/XT. ............................................................................................31 Figura 18 - Teclado do PC.............................................................................................................33 Figura 19 - Interface Paralela.........................................................................................................33 Figura 20 - Interface Serial. ...........................................................................................................34 Figura 21 Byte de atributo em modo texto. .................................................................................35 Figura 22 - Controlador de disco. ..................................................................................................37 Figura 23 - Estrutura de dados de um disco. ..................................................................................37 Figura 24 - Unidade de Disquete. ..................................................................................................39 Figura 25 - Fator de Interleave.......................................................................................................40 Figura 26 - Ilustrao do processo de criao de um programa em C. ............................................46 Figura 27 - Modelagem aplicando-se o princpio da Herana....................................................... 147 Figura 28 - Hierarquia das Classes Iostream do Compilador Borland C++ 4.5. ............................ 165 Figura 29 - Configurao bsica de um CLP................................................................................ 172 Figura 30 - Arquitetura interna dos CLPs. ................................................................................... 174 Figura 31 - CLP com mdulos de expanso. ................................................................................ 175 Figura 32 - Interfaceamento com operador via E/S do CLP. ........................................................ 175 Figura 33 - Painel "Inteligente".................................................................................................... 177 Figura 34 - Terminais de Programao para CLP......................................................................... 177 Figura 35 Sadas: (a) A rel; (b) A TRIAC; (c) a transistor coletor aberto. ................................ 179 Figura 36 - Tabelas de E/S e de dados. ........................................................................................ 180 Figura 37 O ciclo de varredura de um CLP. .............................................................................. 181 Figura 38 - Lgica de comando com portas lgicas digitais. ........................................................ 185 Figura 39 - Comando de uma furadeira....................................................................................... 187 Figura 40 - Rels e elementos bsicos de Diagramas de Escada. .................................................. 188 Figura 41 - Lgica "E": (a) com rels; (b) em diagrama de escada. .............................................. 189 Figura 42 - Lgica "OU": (a) com rels; (b) em diagrama de escada. ........................................... 189 Figura 43 - Ligao em srie de uma bobina. (a) Rels; (b) Diagrama Escada.............................. 190 Figura 44 - Exemplos de smbolos grficos do Diagrama de Escada (LD) ................................... 190 Figura 45 - formato de uma lgica. .............................................................................................. 191 Figura 46 - Exemplo de Diagrama de Escada............................................................................... 191 Figura 47 - Contador simples....................................................................................................... 193 Figura 48 - Contador Bidirecional. .............................................................................................. 194
Marcelo Ricardo Stemmer
7

Informtica Industrial I

DAS/UFSC

Figura 49 Temporizador. .......................................................................................................... 194 Figura 50 - Soma e Multiplicao................................................................................................ 194 Figura 51 Subtrao.................................................................................................................. 195 Figura 52 Diviso. .................................................................................................................... 195 Figura 53 - Operaes OR, XOR, AND....................................................................................... 195 Figura 54 - Diagrama no representvel no CLP.......................................................................... 196 Figura 55 - Diagrama equivalente ao exemplo anterior. ............................................................... 196 Figura 56 - Cruzamento com sinaleiras........................................................................................ 197 Figura 57 - Diagrama de Escada para o comando da sinaleira. ..................................................... 198 Figura 58 - Esquema do estacionamento a ser controlado. ........................................................... 199 Figura 59 - Conexes de Entrada e Sada no CLP. ....................................................................... 200 Figura 60 - Programa em LD para o estacionamento.................................................................... 201 Figura 61 - Etapa (a) desativada; (b) ativada................................................................................ 202 Figura 62 - Aes (a) condicionais; (b) incondicionais. ............................................................... 202 Figura 63 - Transies e suas receptividades................................................................................ 203 Figura 64 - Receptividade tempo. ................................................................................................ 203 Figura 65 - Exemplo de receptividade tempo. .............................................................................. 203 Figura 66 - Receptividade incondicional...................................................................................... 204 Figura 67 - Arcos (GO). .............................................................................................................. 204 Figura 68 - Arcos de entrada e sada. ........................................................................................... 204 Figura 69 - Condio inicial do grafo. ......................................................................................... 205 Figura 70 - Disparo simples (a) antes; (b) depois. ........................................................................ 205 Figura 71 - Disparo mltiplo (a) antes; (b) depois........................................................................ 205 Figura 72 - Etapa com realimentao........................................................................................... 206 Figura 73 - Divergncia em OU (a) GO; (b) GN.......................................................................... 206 Figura 74 - Convergncia em OU (a) GO; (b) GN. ...................................................................... 207 Figura 75 - Divergncia em E (a) GO; (b) GN. ............................................................................ 207 Figura 76 - Convergncia em E (a) GO; (b) GN........................................................................... 208 Figura 77 Transies A e B em Conflito. .................................................................................. 209 Figura 78 Conflito resolvido (estrutura tipo IF - THEN - ELSE)............................................... 209 Figura 79 Etapas A e B em Paralelo.......................................................................................... 209 Figura 80 (a) Grafo no Determinado; (b) Grafo determinado via intertravamento.................... 210 Figura 81 - Sistema de transporte com AGV................................................................................ 211 Figura 82 - GRAFCET (GN) para o comando do sistema de transporte. ...................................... 212 Figura 83 - CLP com mdulo para interligao em rede. ............................................................. 213 Figura 84 - SDCD com CLPs interligados via rede. ..................................................................... 214 Figura 85 - Faturamento do setor de CLPs no Brasil (1986-1992)................................................ 215 Figura 86 - Grandezas a medir na automao............................................................................... 216 Figura 87 - Configurao bsica de um Sensor inteligente. .......................................................... 217 Figura 88 - Configurao bsica de um Atuador Inteligente......................................................... 218 Figura 89 - Misturador de Tintas (2 cres)................................................................................... 220 Figura 90 - Conexes de Entrada e Sada no CLP ........................................................................ 221

Marcelo Ricardo Stemmer

Informtica Industrial I

DAS/UFSC

1 Introduo Informtica Industrial e aos Sistemas de Produo Automatizados


Em tempos antigos, a economia de todas as civilizaes e culturas era fortemente baseada na agricultura e no comrcio. Toda produo de bens de manufatura era baseada no trabalho artesanal, com muito baixa produtividade. O incio do perodo industrial deu-se somente no sculo XVIII, com a chamada Revoluo Industrial. Este perodo teve incio com a inveno da mquina a vapor na Inglaterra, por volta de 1750, e chegou posteriormente a vrios outros pases (nos EUA, por exemplo, a era industrial s teve incio em torno de 1800). A introduo das primeiras tecnologias de automao (onde o homem substitudo pela mquina) em sistemas industriais de produo (por exemplo, as mquinas a vapor) conduziu a um grande aumento de produtividade e possibilitou a produo em massa de uma variada gama de produtos. Esta produo em massa contribuiu tambm para tornar os produtos mais baratos e acessveis a um pblico consumidor muito maior, o que pode ser visto como um dos primeiros efeitos da automao da produo. Esta mesma produo em massa conduziu, a mais longo prazo, a uma saturao do mercado mundial no sculo XX. A resposta do mercado a esta saturao foi a exigncia de maior diversificao e individualizao dos produtos, que passaram a requerer um menor tempo de projeto, desenvolvimento e produo, alm de ter uma vida til menor, pois a cada ano o consumidor deseja um produto novo, que englobe as ltimas inovaes tecnolgicas. Paralelamente a isto, vem ocorrendo uma crescente exigncia de qualidade por parte do mercado. As tcnicas originais de automao utilizadas na produo em massa no apresentam solues bem adaptadas a estas novas exigncias. A tecnologia da Informtica veio a fornecer a necessria reestruturao do setor produtivo, possibilitando o surgimento da chamada Automao Flexvel, que baseada na idia de equipamentos programveis. Estes equipamentos se caracterizam por poderem ter sua funo e operao alterada modificando apenas o software, sem necessidade de reestruturar o hardware (isto , as mquinas, equipamentos e linhas de produo em si). Enquanto as tecnologias antigas eram concentradas no estudo das melhores formas de manipulao de energia e de materiais, as novas tecnologias de automao flexvel esto concentradas na manipulao da informao. Hoje temos sistemas computacionais em praticamente todos os setores de uma fbrica, e esta tendncia claramente crescente. As mquinas-ferramenta operam por Comando Numrico Computadorizado (CNC), as tecnologias de comando usando rels foram substitudas por Controladores Lgicos Programveis (CLP), os sensores e atuadores so dotados de capacidade local de processamento (microprocessadores e microcontroladores), os processos contnuos so controlados em malha fechada por controladores digitais programveis, e mesmo o homem foi substitudo em muitas funes por robs programveis. Todos estes equipamentos tem que poder trocar informaes entre si, de forma a permitir a realizao prtica de verdadeiras fbricas automticas. Esta necessidade levou ao desenvolvimento das Redes Locais Industriais de comunicao. Tambm foram introduzidos sistemas computacionais que permitem a programao de aplicaes compartilhadas por vrios computadores, formando os chamados Sistemas Distribudos. Tais sistemas requerem tcnicas especiais de programao, tais como a Programao Concorrente. Muitas aplicaes exigem tambm solues diferentes das convencionais e levaram ao uso de tcnicas de Inteligncia Artificial em alguns subsistemas. A informtica industrial , portanto, um ramo da informtica que compreende toda aplicao de sistemas computacionais em automao industrial. Pode ser vista, portanto, como informtica aplicada automao de sistemas industriais de produo e gerncia (ver Figura 1).
Marcelo Ricardo Stemmer
9

Informtica Industrial I

DAS/UFSC

Automao Industrial

Informtica

Informtica Industrial
Figura 1 O mbito da informtica industrial.

Devido a complexidade de tais sistemas industriais, a Informtica Industrial engloba conhecimentos de diversos sub-ramos, cada um em si bastante complexo e incluindo novas tecnologias. Entre estes, podemos citar: Sistemas Distribudos; Programao para Sistemas em Tempo Real; Redes de Computadores (LANs); Inteligncia Artificial (Sistemas Especialistas, Redes Neurais, etc.); Programao de diversos equipamentos "inteligentes" (CLP, CNC, RC, etc.); Sistemas de Superviso e Gerncia, etc. No presente curso daremos nfase ao aspecto da informtica industrial ligado programao de alguns equipamentos "inteligentes". Antes disto, ser dada uma viso geral e introdutria Automao Industrial, de forma a melhor situar neste contexto os equipamentos cujo funcionamento e programao sero estudados. A automao industrial divide-se em dois grandes setores: Automao de Processos Contnuos de Produo Automao da Manufatura (sistemas discretos de produo)

1.1 Automao de Processos Contnuos Industriais


Os processos contnuos industriais se caracterizam pela produo no individualizada de bens, isto , o produto a ser produzido gerado de forma contnua. A produo no medida em unidades, mas em volume, bateladas, lotes, etc. A automatizao de tais processos requer essencialmente a utilizao de conhecimentos na rea de sistemas de controle. A automao de processos contnuos industriais envolve a medio de grandezas fsicas (por meio de sensores), o processamento da informao (por meio de controladores, computadores, etc.) e a correo do comportamento das grandezas de forma a seguir um sinal de referncia desejado (por meio de atuadores) em malhas fechadas com realimentao, de forma contnua no tempo (Figura 2).
Valor de Referncia Controlador Atuador Processo

Sensor Realimentao (Feedback) Grandeza Controlada

Figura 2 Controle em malha fechada.

Marcelo Ricardo Stemmer

10

Informtica Industrial I

DAS/UFSC

Processos industriais contnuos so encontrados, por exemplo, na Indstria qumica, Petroqumica, Siderurgia, Metalurgia (metais no ferrosos), Sistemas de gerao e distribuio de energia, etc. O projeto dos controladores utilizados baseia-se em regras para a obteno de modelos matemticos dos sistemas a controlar, a partir dos quais feita a determinao dos parmetros dos controladores (Teoria de Controle e Servomecanismos). A tendncia aqui o uso do controle digital, onde um computador exerce a funo de controlador, como mostrado na Figura 3.
D/A Co mp utador A/D Sensor Atuador Processo Grande za Controlada

Figura 3 Controle Digital

1.2 Automao de Processos Discretos e da Produo (Automao da Manufatura)


Em processos discretos de produo (manufatura), os objetos produzidos so sempre produtos individualizados. So exemplos de sistemas discretos de produo: industria Automobilstica, Aeronutica, Naval, Eletrodomsticos, Txtil, Calados, Peas, etc. A manufatura envolve diversos subsistemas: Usinagem e processamento de peas mquina-ferramenta Montagem das peas isoladas em peas e produtos finais linha de montagem Teste e medio das peas controle de qualidade Transporte e armazenamento das peas Manuseio das peas e ferramentas para carga e descarga das mquinas manipuladores e robs

O controle em malha fechada utilizado em todos estes subsistemas (controles de posio, fora, torque, velocidade, etc.). O processo de produo como um todo no est submetido a um controle contnuo em malha fechada, mas com a introduo do computador em todos os departamentos da fbrica, tem-se conseguido um melhor controle da produo.

1.3 A manufatura Integrada por Computador (CIM) 1.3.1 Definio e objetivos


A filosofia CIM (Computer Integrated Manufacturing) visa automatizar de forma flexvel todos os processos envolvidos com a manufatura atravs da aplicao adequada de sistemas eltricos/eletrnicos, computacionais e de comunicao (troca de informaes).

1.3.2 Modelo CIM


Para permitir uma maior eficincia neste processo de Automao Flexvel, o modelo CIM prope que a fabrica seja subdividida em diferentes nveis hierrquicos, de acordo com uma estrutura piramidal, apresentada na Figura 4.

Marcelo Ricardo Stemmer

11

Informtica Industrial I

DAS/UFSC

Nivel Hierarquico Administracao corporativa Controle da lucratividade Planejamento (Factory) Gw CAD, CAE, CAP, CAPP, CAQ, etc... Controle da Produtividade Area (Shop) FMS Chao de fabrica FMC Torno, Manipulador, Centro usinagem, etc...

Celula (Cell)

MgU

Subsistema (Subsystem)

... CLP CNC

Controle Fisico

Componente (Component)

Motores, chaves, reles, etc...

Figura 4 Modelo CIM.

Cada um dos nveis hierrquicos indicados na Figura 4 tem suas funes: Tarefas do nvel 0: Componentes aquisio de dados, monitorao, alarmes controle em malha fechada atuao fornecimento de informaes ao nvel 1 Tarefas do nvel 1: Subsistemas ou Unidades (mquinas, robs, etc.) controle do processo ou da mquina processamento e fornecimento de dados aos operadores detectar e responder a qualquer condio de emergncia realizar auto-diagnsticos coletar informaes sobre a produo da unidade, o uso de matria prima, energia e insumos e transferir ao nvel 2 Tarefas do nvel 2: Clulas (agrupamento lgico de unidades) coletar e manter dados de produo, matria-prima, consumo de energia, estoques das unidades otimizar a operao conjunta das unidades sob seu controle (sequnciamento e intertravamento) responder condies de emergncia realizar diagnsticos dos elementos sob controle interface com nvel superior
12

Marcelo Ricardo Stemmer

Informtica Industrial I

DAS/UFSC

Tarefas do nvel 3: rea interconectar clulas entre si, compondo sistemas flexveis de manufatura (FMS) manter base de dados de produo, estoques, utilizao de materiais, insumos e energia preparao e emisso de relatrios de produo estabelecer programa de produo imediato para as clulas da rea otimizar plano de produo da rea interface com nvel superior e inferior Tarefas do nvel 4: Planejamento da planta planejar e projetar o produto e o processo de fabricao estabelecer plano de produo bsico determinar nveis timos de estoques coletar, processar e armazenar dados sobre - uso e disponibilidade de matria-prima, estoques - consumo global de energia - estoques de produtos acabados - controle de qualidade Tarefas do nvel 5: Administrao Corporativa manter interfaces, fornecer informaes sobre estado da planta, da companhia e da produo necessrios para: - gerenciamento da planta e da companhia - atividades de pessoal administrativo (compras, vendas, contabilidade, etc.) fornecer informaes p/ decises estratgicas da companhia interfaceamento com nveis inferiores da hierarquia e com o mundo externo

1.3.3

Ferramentas computacionais de apoio a CIM

CAD - Computer Aided Design

projeto (desenho) do produto definio dados geomtricos (formas, dimenses, tolerncias, etc.) CAE - Computer Aided Engineering anlise de engenharia: anlise da adequao da pea para funes previstas (resistncia deformaes, trao, toro, etc.) simulao de processos elementos finitos (por exemplo, conformao mecnica) CAPP - Computer Aided Process Planning

determinar processo adequado fabricao da pea (fresar, furar, tornear, etc.) escolha da ferramenta, matria-prima, velocidade de corte, etc. (dados tecnolgicos) usa tcnicas de inteligncia artificial gera plano do processo
13

Marcelo Ricardo Stemmer

Informtica Industrial I

DAS/UFSC

CAM - Computer Aided Manufacturing controle e superviso do processo de fabricao em si interage com as mquinas gerao dos programas NC (cdigo G) CAP - Computer Aided Production controle de estoque controle de fluxo de material prioridades e prazos para linhas de produo CAQ - Computer Aided Quality (-Assurance) superviso e anlise do comportamento e desempenho do sistema deteco de erros e suas causas visa, a nvel de planejamento, a garantia da qualidade do produto final usa tcnicas como controle estatstico do processo (SPC, CEP) Estas ferramentas computacionais se interrelacionam conforme mostrado na Figura 5.
ATIVIDADES LIGADAS AO PRODUTO E AO PROCESSO

CAE

BASE DE DADOS

CAD

CAPP

CAP

CAM FMC

ATIVIDADES LIGADAS PRODUO

CAQ

Figura 5 - Relao entre as ferramentas computacionais de apoio no ambiente CIM

Marcelo Ricardo Stemmer

14

Informtica Industrial I

DAS/UFSC

2 Equipamentos utilizados em sistemas automatizados


Os equipamentos apresentados aqui se restringem automao de processos discretos de produo (manufatura). No faremos referncia a fornos industriais, caldeiras, misturadores, etc., encontrados em processos contnuos.

2.1 Equipamentos Mecnicos


Os principais equipamentos mecnicos utilizados em sistemas automatizados de produo (para a automao da manufatura) so:

2.1.1

Mdulos de processamento e usinagem

mquinas operatrizes para torneamento, aplainamento, furao, mandrilamento, fresagem, serragem, etc. prensagem para processos de conformao mecnica centros de usinagem Clulas e Sistemas Flexveis de Manufatura (FMC, FMS) Estes mdulos esto exemplificados na Figura 6 e Figura 7.

2.1.2

Mdulos de Transporte e Armazenamento

dispositivos para armazenamento de peas: - de forma no ordenada (Bunker) - de forma ordenada (Magazine) dispositivos para mudana de local e posio - conveyor tipo esteira - conveyor tipo rolo - sistemas de corrente - veculos guiados automaticamente (AGV) Estes mdulos esto exemplificados na Figura 8 e Figura 9.

2.1.3

Mdulos de Manuseio de Materiais e Ferramentas

manipuladores manuais (teleoperadores) manipuladores programveis (Pick and Place) robs industriais (usados para solda, pintura, manuseio, montagem, usinagem e processamento) Estes mdulos esto exemplificados na Figura 10.

2.1.4

Mdulos de Montagem

difceis de automatizar concebidos para operadores humanos linhas de montagem indstria automobilstica uso de robs Estes mdulos esto exemplificados na Figura 11.
Marcelo Ricardo Stemmer
15

Informtica Industrial I

DAS/UFSC

2.1.5

Mdulos de Controle de Qualidade

sensores e instrumentos de medio mquinas de medir por coordenadas Estes mdulos esto exemplificados na Figura 12.

2.2 Dispositivos de Comando e Controle


Todos os equipamentos mencionados na seo anterior requerem um ou mais dispositivos de comando e controle. A maioria dos dispositivos de comando e controle atuais so computadorizados (apesar de que ainda existam comandos mecnicos manuais, comandos eletromecnicos a rels, comandos eletrnicos analgicos e comandos eletrnicos digitais). Os equipamentos mais importantes so: comandos numricos computadorizados de mquinas-ferramenta (CNC) controladores de robs industriais (RC) sistemas de comunicao (LAN) controladores lgicos programveis (PLC, CLP) computadores (PC, IC, Workstation, computador processo) sensores e atuadores inteligentes

No presente curso estudaremos os trs ltimos tipos de dispositivos (computadores tipo PC e sua verso industrial, o IC, os CLPs e sensores e atuadores inteligentes).

Marcelo Ricardo Stemmer

16

Informtica Industrial I

DAS/UFSC

Figura 6 - Mdulos de Processamento e Usinagem.

Marcelo Ricardo Stemmer

17

Informtica Industrial I

DAS/UFSC

Figura 7 - Mdulos de Processamento e Usinagem (cont.).


Marcelo Ricardo Stemmer
18

Informtica Industrial I

DAS/UFSC

Figura 8 - Mdulos de Transporte e Armazenamento

Marcelo Ricardo Stemmer

19

Informtica Industrial I

DAS/UFSC

Figura 9 - Mdulos de Transporte e Armazenamento (cont.).

Marcelo Ricardo Stemmer

20

Informtica Industrial I

DAS/UFSC

Figura 10 - Mdulos de Manuseio de Materiais e Ferramentas


Marcelo Ricardo Stemmer
21

Informtica Industrial I

DAS/UFSC

Figura 11 - Mdulos de Montagem.

Marcelo Ricardo Stemmer

22

Informtica Industrial I

DAS/UFSC

Figura 12 - Mdulos de Controle de Qualidade.

Marcelo Ricardo Stemmer

23

Informtica Industrial I

DAS/UFSC

3 Computadores PC / IC
Devido ao aumento crescente da capacidade de processamento, acompanhada de uma reduo drstica de preos, os computadores do tipo PC (Personal Computer) tem sido cada vez mais utilizados em todos os setores industriais.

3.1 Histrico
o PC foi introduzido em 1981 pela IBM. Era baseado no 8088 (Intel), com 64 Kb RAM e 4,77 Mhz; em 1983 foi lanado o PC/XT (eXtended Technology), baseado no 8088 com 256 KB RAM, clock de 8 Mhz e disco rgido de 10 MB; em 1984 foi a vez do PC/AT (Advanced Technology), baseado no 80286, com 640 Kb RAM; frequncia de clock de 6, 8 ou 12 Mhz e disco rgido de 20 MB; os modelos baseados no 80386 (de 32 bits) foram lanados em 1987 com 16, 20, 25 ou 33 Mhz; em 1989 foi lanado o 80486 com co-processador matemtico integrado; em 1992 foi lanado o Pentium, seguido rapidamente de novas verses (MMX, Pentium II, Pentium III, Pentium IV), com clock j chegando aos 2.8GHz.

3.2 Arquitetura do PC
A arquitetura bsica do PC mostrada na Figura 13.

Barramento de enderecos (EP)ROM - BIOS - BASIC Barramento de dados

Clock

Processador

RAM

Interfaces I/O paral. serial

Controlador de Video

Controlador de Disco

Outras placas de expansao

impressora

Mouse

Monitor de Video

Floppy disc drive

Hard disc drive

Teclado

Figura 13 - Arquitetura interna do PC.

Os computadores do tipo IC (Industrial Computer) tm a mesma arquitetura bsica, mas so encapsulados para proteo contra umidade, poeira, cavacos, leo, etc., para uso em ambiente industrial. So montados em um rack de ao e o monitor e o teclado (usualmente tipo membrana) so encapsulados.

Marcelo Ricardo Stemmer

24

Informtica Industrial I

DAS/UFSC

3.3 Principais componentes 3.3.1 Barramento de Dados e Endereos

Os barramentos de dados e endereos definem respectivamente o caminho de troca de informaes entre o processador e as demais unidades do sistema e o endereo de acesso de cada unidade (Figura 14).

Dados

Processador Endereos

Controle de Endereamento (Memria ou I/O)

Figura 14 - Barramentos no PC.

- O Barramento de Dados: Para que o processador opere necessrio trocar informaes entre os registros internos da CPU e a memria (RAM ou ROM), bem como acessar outras fontes de informao (dispositivos perifricos). Seguem exemplos da largura dos barramentos de dados de alguns microprocessadores: Processador 8088 (PC/XT) 8086 80286 (PC/AT) 80386, 80486 Pentium Barramento de Dados 8 bits 16 bits 16 bits 32 bits 64 bits Largura dos Registros da CPU 16 bits 16 bits 16 bits 32 bits 32 bits

Um aumento da largura do barramento de dados implica em um aumento da velocidade de troca de informaes entre o processador e as memrias e outros dispositivos. - O Barramento de Endereos: Antes de enviar ou receber dados de qualquer dispositivo ligado ao barramento de dados, o processador tem que selecionar o endereo correspondente deste dispositivo no barramento de endereos. Um dispositivo pode ser endereado utilizando toda a largura do barramento de endereos ou somente os 8 bits mais significativos do mesmo (por razes histricas, os primeiros dispositivos eram endereados usando somente 8 bits). Se toda a largura do barramento de endereos utilizada, diz-se que o dispositivo endereado como memria. Se somente 8 bits so usados, diz-se que o dispositivo endereado como I/O. Vale lembrar que, com 8 bits, somente 256 endereos ou posies de memria (28) podem ser explicitados. Seguem exemplos de caractersticas dos barramentos de endereos de alguns microprocessadores:

Marcelo Ricardo Stemmer

25

Informtica Industrial I

DAS/UFSC

Processador 8085 8088 80286 80386

Barramento de endereos 16 bits 20 bits 24 bits 32 bits

Capacidade de endereamento 65.536 endereos (64Kbytes) 1.048.576 endereos (1Mbytes) 16 Mbytes 4 Gbytes

Segue um exemplo tpico de mapa de memria do IBM-PC: Endereo hexadecimal 00000-0007F 00080-003FF 00400-004FF 00500-9FFFF A0000-AFFFF B0000-B7FFF B8000-BFFFF C0000-C5FFF C6000-C7FFF C8000-CBFFF CC000-CFFFF D0000-EFFFF F0000-FFFFF Contedo vetores de interrupo BIOS vetores de interrupo livres rea de dados da BIOS memria de trabalho do usurio 64 KB reservados vdeo monocromtico vdeo cromtico vdeo EGA vdeo VGA controlador do disco rgido PC Network reservado 128 KB (expanso ROM) rea de programas da BIOS e BASIC residente (ROM)

Os barramentos de dados e endereos seguem vrios padres industriais, definidos pelos fabricantes e por rgos de padronizao (ISO, IEC, EIA). Entre eles temos: EISA, VME, VXE, PCI, PXI, etc. Como estes barramentos so diferentes e quase sempre no so compatveis entre si, toda placa colocada em um slot livre do PC deve ser escolhida de acordo com o barramento em uso.

3.3.2
que:

Fonte de alimentao do PC
+ 5 V : usado em quase todos os CIs que operam em nvel TTL + 12 V : usado em alguns CIs e pelos motores das unidades de disco - 12 V : usado em componentes das interfaces externas (serial) e unidades de disco

A fonte do PC converte a entrada de 110 / 220 V AC em sadas de +5, +12 e -12 volts, sendo

3.3.3

Controlador de Interrupes

Processamento de interrupes um mtodo de controle e resposta eventos externos ao computador (dispositivos de I/O, etc.). As interrupes geradas por dispositivos externos so controladas por um CI especfico, denominado Controlador Programvel de Interrupes. Um dos chips mais extensamente usados para esta funo foi o 8259 PIC (Programmable Interrupt Controller), da Intel. Ele aceita oito linhas de interrupo, vindas de diferentes perifricos, numerados de 0 a 7, sendo que a IRQ 0 tem maior prioridade e a IRQ 7 tem menor prioridade (IRQ = Interrupt Request). O controlador de interrupes informa a ocorrncia de uma interrupo a CPU atravs de um nico sinal (usualmente INTR), fornecendo tambm um cdigo do tipo de interrupo ocorrido, permitindo o uso de rotinas especficas para cada tipo de interrupo. Sua forma de utilizao no PC ilustrada na Figura 15.

Marcelo Ricardo Stemmer

26

Informtica Industrial I

DAS/UFSC
IRQ0 - Timer IRQ1 - Teclado IRQ2 - Reservado 08H 09H 0AH 0BH 0CH 0DH 0FH 0EH Vetor de interrupcao

8259 PIC Interrupt mask register

In service register

Determinacao de prioridades

Interrupt request register

IRQ3 - Serial 2 IRQ4 - Serial 1 (Mouse) IRQ5 - Disco Rigido IRQ6 - Disquete IRQ7 - Impressora

logica de controle buffer dados Barram. dados


INTA

8288
S0 S1 S2 INTR

8088/8086

Figura 15 - Controlador de Interrupes no PC.

Resumo da operao de interrupo: 1. 2. 3. 4. 5. a interrupo de maior prioridade requisitada o 8259 seta o pino INTR no processador principal (por exemplo, 8088) se as interrupes esto habilitadas (STI), o processador sinaliza INTA (interrupt acknowledge) o 8259 envia o nmero do vetor de interrupo pelo barramento de dados nn o processador faz um jump para a rotina endereada pelo vetor de interrupes. O endereo calculado fazendo nn x 4 (uma vez que cada vetor de interrupo ocupa 4 bytes).

Certas interrupes podem ser habilitadas ou desabilitadas escrevendo-se uma mscara de interrupo no registrador prprio do 8259 (Interrupt Mask Register, definido como endereo 21H de I/O no PC), sendo que o valor lgico 0 habilita a interrupo e o valor 1 desabilita. Por exemplo, as instrues em Assembly a seguir mascaram (desabilitam) a interrupo 6: MOV AL,40H OUT 21H,AL

coloca 01000000 em AL habilita todas as interrupes menos a IRQ 6

Se as interrupes no processador principal esto desabilitadas (Interrupt Flag IF = 0), nenhuma interrupo reconhecida, independentemente da mscara de interrupo programada no 8259. Este flag ajustado com os comandos Assembly STI e CLI.

3.3.4

Timer

O timer (usualmente um 8253 ou 8254 da Intel) realiza funes de contagem e temporizao. O 8253, por exemplo, possui 3 contadores independentes, numerados de 0 a 2. Cada contador tem uma entrada para um sinal com freqncia de 0 a 2 Mhz. A sada um sinal com freqncia igual a entrada dividida por um nmero programvel de 16 bits, sendo que: a sada 0 usada como relgio de tempo real, para marcar a hora de criao de arquivos e a data no PC.
Marcelo Ricardo Stemmer

27

Informtica Industrial I

DAS/UFSC

a sada 1 usada para indicar ao controlador de DMA para fazer um memory refresh na RAM dinmica (ver DMA a seguir) a sada 2 ligada ao alto-falante para a gerao de sons determinao da freqncia do som.

3.3.5

Controlador de DMA (Direct Memory Access)

O DMA (por exemplo, um 8237) um processador dedicado, projetado para transferir blocos de dados (tipicamente de at 64 Kbytes) de um local ao outro da memria ou entre dispositivos de I/O e a memria, sem requerer com isto a ateno do processador principal. Com isto possvel, por exemplo, transferir dados do controlador de disco para a memria enquanto o processador principal realiza outras operaes. O chip 8237, muito usado em PCs, possui 4 canais de DMA: o canal 0 usado em conjunto com o canal 1 do timer para executar o memory refresh, lendo ciclicamente (tipicamente a cada 15 s) blocos de 64 Kb que, no entanto no so transferidos para lugar algum. O simples ato de leitura refresca a memria. Sem isto, nenhum programa seria retido na memria do PC por mais que alguns milissegundos. o canal 2 usado para leitura de discos e disquetes, sendo usado para transferir dados entre a memria RAM e o controlador de disco e vice-versa. Os canais 1 e 3 usualmente esto livres para outros perifricos.

3.3.6

Memrias ROM e RAM

O PC utiliza dois tipos bsicos de memria: ROM (Read Only Memory): uma memria no voltil (isto , no perde seu contedo quando desenergizada) pr-gravada que, durante a operao normal do computador, s pode ser lida (a escrita requer um dispositivo especial que no acompanha o PC). No PC, a ROM contm um conjunto de pequenos programas conhecido como BIOS (Basic Input Output System), que permite a inicializao do sistema. As verses originais da IBM costumavam incluir tambm a linguagem BASIC em ROM (o que requeria 40 Kbytes adicionais de ROM). A maioria dos computadores atuais utiliza a verso de ROM conhecida como EPROM(Erasable Programmable ROM), que pode ser apagada utilizando luz ultra-violeta e posteriormente reprogramada (tanto o apagamento quanto a escrita requerem um dispositivo especial). Uma verso ainda mais nova de ROM a EEPROM (Electrically Erasable Programmable ROM), que pode ser apagada com um comando eltrico e reescrita. Um tipo recente de EEPROM conhecido como EAPROM (Electrically Alterable Programmable ROM). Nesta categoria se encontra a memria Flash, que pode ser reescrita sem ser removida do computador. RAM (Random Access Memory): trata-se de uma memria voltil (perde seu contedo se faltar energia) que permite tanto a leitura quanto a escrita de dados. Nela so armazenadas as variveis e os programas no permanentes do computador e por isso tambm chamada de memria de trabalho. Para tal, a RAM costuma ser subdividida em vrios segmentos lgicos endereados por registros da CPU. Por exemplo, nos processadores da Intel utilizamos o registro DS para enderear o Data Segment (segmento de dados, contendo variveis globais), CS para o Code Segment (segmento de cdigo, contendo o programa em si), SS para o Stack Segment (segmento de pilha, contendo variveis locais e parmetros para subrotinas) e ES para o Extra Segment (segmento extra, que tambm contm dados). Em geral no PC se usa RAM dinmica (DRAM, Dynamic RAM), onde cada clula de memria composta de
Marcelo Ricardo Stemmer
28

Informtica Industrial I

DAS/UFSC

um capacitor e um transistor. Devido ao principio capacitivo, a DRAM tem que ser constantemente acessada para manter o contedo (como j vimos, a operao de memory refresh realizada periodicamente com auxlio do timer e do DMA). A RAM esttica (SRAM, Static RAM), onde cada clula de memria constituda de um flip-flop e um transistor, no requer refreshment e mais rpida (tem tempo de acesso menor), mas menos usada porque a DRAM requer menos espao, possui maior capacidade de armazenamento e tem menor custo. Os chips de memria RAM vem passando por inmeras inovaes tecnolgicas, que permitem acesso mais rpido, maior capacidade de armazenamento e menor preo. Os chips so montados em pequenas placas de circuito integrado, conhecidas como pentes ou mdulos de memria. At bem recentemente, os pentes mais usados eram os mdulos de memria SIMM (Single In-Line Memory Modules) de 32 e 64 Mbytes, com tempo de acesso tpico de 60 ns (nanossegundos). Hoje so mais usados os pentes DIMM (Dual In-Line Memory Modules) de 64 e 128 Mbytes, com tempos de acesso que chegam a 0,75 ns para a verso SDRAM (Synchronous Dynamic RAM). A SDRAM apresenta um sinal adicional de clock aos sinais de controle. Os computadores atuais utilizam uma pequena rea de memria esttica SRAM de acesso muito rpido para armazenamento temporrio de dados e partes de programas em uso pela ALU (Arithmetic and Logic Unit), conhecida como memria Cache. Como o tempo de acesso memria cache menor que memria de trabalho normal, seu uso faz com que a execuo dos programas se torne mais rpida.

3.3.7

Controlador de teclado

O chip 8255 um CI que controla, alm do teclado, o alto-falante e, no PC original, as chaves de configurao do sistema (dip-switches que definiam a quantidade de memria presente, nmero de unidades de disco / disquete e tipo de controlador de vdeo presentes, entre outros). Este componente possui 3 portas de 8 bits: Porta A Endereo de I/O 60H Porta B I/O 61H Porta C I/O 62H Registro de Comando 63H Na inicializao do sistema, as portas PA e PC so configuradas como entradas e a porta PB como sada. O significado de cada uma das portas o seguinte: PA (entrada): contm cdigo de varredura da ltima tecla pressionada se o bit 7 de PB igual a 1, caso contrrio l sw1 (dip-switch 1) que indica tipo de vdeo, nmero de discos e quantidade de memria PB (sada): bit 7 = 1 teclado habilitado bit 6 = 0 desabilita clock teclado bit 5 = 0 habilita sinalizao de erros de I/O bit 4 = 0 habilita checagem de erro de memria na RAM bit 3 define funes da porta PC, parte baixa bit 2 livre bit 1 liga e desliga o alto-falante bit 0 habilita timer Port 2

Marcelo Ricardo Stemmer

29

Informtica Industrial I

DAS/UFSC

PC (entrada): bit 7 = 1 sinaliza erro de paridade na RAM bit 6 = 1 sinaliza erro de I/O bit 5 = 1 sada do canal 2 do timer (alto-falante) bit 4 livre bits 3 e 2 se PB, bit 3 = 0, indica quantidade de memria, seno indica nmero de unidades de disco bit 1 se PB, bit 3 = 0, indica presena de coprocessador matemtico, seno, o tipo de vdeo bit 0 se PB, bit 3 = 0, indica loop de teste, caso contrrio, o tipo de vdeo (sw1) O teclado envia os cdigos de varredura das teclas pressionadas de forma serial ao PC. No PC, os dados seriais so convertidos para paralelo por um Registrador de Deslocamento (tradicionalmente a IBM usava o 74LS322) e repassados a porta PA do 8255, como ilustrado na Figura 16.

74LS322 Dados teclado

...

PA

Dados

8088/86

8 Bits convertidos

IRQ1 8259 PIC

sinaliza a presena de dados do teclado (INT09H)

Figura 16 - Controlador de Teclado no PC.

Quando um cdigo de varredura completamente convertido de serial para paralelo (8 bits recebidos), o Registrador de Deslocamento gera uma requisio de interrupo no pino IRQ1 do 8259 (ver controlador de interrupes), que sinaliza o evento CPU. A rotina de tratamento da interrupo da BIOS endereada pelo vetor 09h da Tabela de Vetores de Interrupo l o cdigo de varredura da tecla pressionada da porta PA do 8255 e pe o cdigo ASCII correspondente em um buffer. Este buffer pode posteriormente ser lido pelo BIOS ou diretamente pelo programa de aplicao. A converso de cdigo de varredura para cdigo ASCII feita segundo uma tabela de varredura do teclado. Esta tabela usualmente definida na configurao do PC (no caso do DOS, atravs do arquivo config.sys). Se esta configurao no estiver correta (por exemplo, tem-se um teclado brasileiro e a tabela de converso em uso para um teclado americano ou alemo), os programas de aplicao recebero o cdigo ASCII incorreto para as teclas pressionadas. Uma descrio mais detalhada do tratamento das teclas est na seo 3.3.8. Todos os componentes vistos at aqui (exceto a fonte de alimentao) esto montados na chamada placa me ("mother board"). Um exemplo de placa me apresentado na Figura 17. Os demais componentes que veremos a seguir no esto montados na placa me e so chamados perifricos.
Marcelo Ricardo Stemmer
30

Informtica Industrial I

DAS/UFSC

Figura 17 - Placa Me de um PC/XT.

3.3.8

Teclado

O teclado um dispositivo perifrico de comunicao serial para entrada de dados e comandos que possui um microprocessador dedicado (por exemplo, um 8048), encarregado de fazer uma varredura das teclas para verificar se esto pressionadas e, em caso positivo, identificar e enviar ao computador o cdigo de varredura da tecla em questo (ver Figura 18). Em cada varredura, cada linha de sada do decoder indicado na Figura 18 levada a zero; se a entrada correspondente do multiplexador estiver tambm a zero, a tecla est pressionada, e o 8048 envia serialmente seu cdigo de varredura para o PC (observe que no se trata ainda do cdigo ASCII). Quando a tecla solta, gerado o cdigo de varredura com 80h adicionado (oitavo bit em 1). Por exemplo, quando a tecla ESC pressionada, enviado 01h e quando ela solta enviado 81h. Algumas teclas produzem um cdigo de varredura composto de vrios bytes. Por exemplo, as teclas que aparecem duplicadas no teclado, como a ALT direita e a ALT esquerda, so distinguidas por este meio. Enquanto a tecla ALT esquerda gera o cdigo de varredura 38h, a tecla ALT direita resulta em um cdigo de varredura de 2 bytes, E0h+38h. Certas teclas especiais tm ainda mais bytes em seu cdigo de varredura. Por exemplo, a tecla PAUSE (ou BREAK) gera um
Marcelo Ricardo Stemmer
31

Informtica Industrial I

DAS/UFSC

cdigo de 3 bytes: E1h+1Dh+45h. A tecla PRTSC (Print Screen) gera 4 bytes: E0h+2Ah+E0h+37h. A interpretao destes bytes funo do BIOS. Uma vez recebidos pelo PC, as rotinas de servio do BIOS traduzem os cdigos de varredura em informaes significativas que um programa de aplicao pode usar. Como vimos no item sobre o controlador do teclado, a rotina do BIOS ativada pelo vetor de interrupes 09h l os cdigos de varredura enviados pelo teclado byte a byte da porta PA do 8255 e traduz para valores de 2 bytes. O byte de baixa ordem ou byte principal contm o cdigo ASCII correspondente a tecla pressionada, enquanto o byte de alta ordem ou byte auxiliar costuma conter o cdigo de varredura em si (ao menos no caso de teclas simples). As teclas de funo e as do teclado numrico possuem um zero no byte principal e o cdigo de varredura do teclado no byte auxiliar. Os pares de bytes gerados pelo BIOS so armazenados em um espao de memria conhecido como buffer do teclado, que inicia no endereo de RAM 0040:001Eh. A tarefa de traduzir cdigos de varredura um pouco complicada pela presena de teclas que modificam o significado de um toque: as teclas de shift (CTRL, SHIFT e ALT) e as teclas de chaveamento (CAPS LOCK e NUM LOCK). A informao de estado destas teclas e de outras teclas especiais (INS, SCROLL LOCK e PAUSE) mantida pelo BIOS em dois bytes de status do teclado nas posies de memria RAM 0040:0017h e 0040:0018h. Cada bit destes bytes indica o estado de uma das teclas especiais e mantido atualizado pelo BIOS. Antes de gerar o cdigo traduzido de 2 bytes para as teclas convencionais, o BIOS verifica o estado dos bytes de status. Desta forma a tecla z gera um cdigo final no buffer do teclado diferente do obtido com a combinao SHIFT z (que interpretado como um Z maisculo). Como estes bytes de status esto na memria RAM do PC, eles podem ser tambm acessados e alterados por um programa do usurio. O significado de cada bit dado na tabela a seguir: Byte de status 0040:0017h Significado Ins: 1=ativo; 0=inativo Caps Lock: 1=ativo; 0=inativo Num Lock: 1=ativo; 0=inativo Scroll Lock: 1=ativo; 0=inativo 1=Alt direito pressionado 1=Ctrl direito pressionado 1=Shift esquerdo pressionado 1=Shift direito pressionado Byte de status 0040:0018h Significado 1=Ins pressionado 1=Caps Lock pressionado 1=Num Lock pressionado 1=Scroll Lock pressionado 1=Pause ativo 1=Sys Req pressionado 1=Alt esquerdo pressionado 1=Ctrl esquerdo pressionado

Bit 7 6 5 4 3 2 1 0

Bit 7 6 5 4 3 2 1 0

Os bits 4, 5, 6 e 7 do byte 0040:0017h se comportam como chaves, isto , seus valores so invertidos cada vez que as teclas correspondentes so pressionadas, mas no mudam quando so soltas. Por exemplo, pressionando uma vez Caps Lock o bit 6 vai para 1; pressionando Caps Lock uma segunda vez, o mesmo bit vai para 0. Desta forma, no necessrio manter a tecla Caps Lock pressionada constantemente para gerar letras maisculas. O mesmo efeito produzido para as teclas Ins, Num Lock e Scroll Lock. Esta propriedade til para vrios programas aplicativos (por exemplo, editores de texto como o Word e interpretadores de comando como o COMMAND.COM do DOS). Todos os demais bits de ambos os bytes indicam o estado momentneo das teclas correspondentes. Desta forma, pressionar a tecla Ctrl direita leva o bit 2 do byte 0040:0017h para 1. Ao soltar a tecla, este bit volta a zero. Algumas teclas ou combinaes de teclas ativam diretamente rotinas especiais do BIOS. Por exemplo, CTRL+ALT+DEL ativa uma rotina de reinicializao do PC. No DOS, a tecla PrtSc ativa uma rotina de impresso da tela (ver rotinas da BIOS na seo 3.4.1.2). No windows, PrtSc armazena o contedo da tela na forma de um bitmap na rea de transferncia.

Marcelo Ricardo Stemmer

32

Informtica Industrial I

DAS/UFSC

Matriz de teclas (23 x 4)

+5V

...

...

...

Decoder
Codigo de

8048

varredura da tecla pressionada

...
Multiplexador

Figura 18 - Teclado do PC

3.3.9 Interface Paralela


Interfaces paralelas permitem o envio de dados dispositivos externos taxas de 8 ou mais bits de cada vez. Para isto, requerem cabos com vrios condutores. A aplicao tpica mais usual o interfaceamento com a impressora. Para este uso foi definida uma interface padronizada, denominada CENTRONICS (nome de um fabricante de impressoras que lanou o padro). Alm de 8 bits de dados, a interface CENTRONICS define uma srie de bits de controle, que permitem um Hand-Shake entre o PC e a impressora. A Figura 19 ilustra a ligao entre o PC e a interface paralela.
nivel TTL Dados Placa de interface paralela
CS

0 1

...
7 controle (10 pinos)

8088/86 Decoder

End.

Figura 19 - Interface Paralela.

A maioria das placas de interface paralela utiliza um 8255 (ver controlador de teclado) como componente central. Uma das trs portas usada para dados e as outras 2 portas para controle.

3.3.10

Interface Serial

Pode-se reduzir o nmero de fios necessrios comunicao com dispositivos externos e com isto reduzir significativamente o custo de fiao utilizando uma interface serial.

Marcelo Ricardo Stemmer

33

Informtica Industrial I

DAS/UFSC

A converso interna dos dados de forma paralela (vinda do barramento de dados) para a forma serial realizada por registradores de deslocamento, colocados na placa de controle da interface serial, como ilustrado na Figura 20.
interface serial

Dados

Paralelo

comando

8088/86 Decoder

...
dados serie
CS

End.

Figura 20 - Interface Serial.

O componente mais utilizado para este fim a USART (Universal SynchronousAsynchronous Receiver-Transmitter), normalmente um 8251. Antes de ser utilizado, o 8251 deve ser programado com as caractersticas de comunicao desejadas: taxas de transferncia (Baud Rate) em bits por segundo, nmero de start e stop bits (que definem o inicio e o fim de um caracter), tamanho da palavra (usualmente 7 ou 8 bits) e paridade (para controle de erros de transmisso). O 8251 conectado eletricamente ao mundo exterior pela interface padronizada pela EIA (Electronic Industries Association) RS-232-C. Para permitir o envio de sinais a maiores distncias, a RS-232-C opera com uma tenso mais elevada que o nvel usual TTL (5 volts): -3 a -12V lgico 1 +3 a +12V lgico 0 -3 a +3V indefinido O 8251 seria tambm adequado para a realizao prtica da comunicao com o teclado. Vrios fabricantes fornecem teclados com este componente. O Mouse interligado ao PC atravs de uma interface serial. Cada movimento ou tecla pressionada no mouse convertido em uma mensagem serial, a ser interpretada pelo PC. Quando dados da interface serial esto disponveis, o PC sofre uma interrupo (geralmente IRQ 3 ou 4 do 8259) que ativa uma rotina de tratamento do mouse (acessada pelo usurio atravs do vetor de interrupo 33h). Esta rotina (mouse-driver) tem que ser carregada na memria na inicializao do PC e fica residente na memria. Outra aplicao tpica o MODEM (Modulator/Demodulator), que permite o envio de dados serialmente pela linha telefnica.

3.3.11

Controlador de vdeo

O controlador de vdeo serve de interface entre o PC e o monitor de vdeo. Ele usualmente montado em uma placa separada da placa-me do PC e inserido em um dos slots livres. O controlador de vdeo ligado ao barramento de dados e endereos do PC, possuindo memria prpria, onde armazenado o contedo de cada posio da tela no monitor. A memria de vdeo pode ser acessada tanto pelo controlador de vdeo quanto pelo processador do PC. Com o vdeo mapeado como memria, a informao mostrada na tela pode ser alterada na velocidade que o
Marcelo Ricardo Stemmer
34

Informtica Industrial I

DAS/UFSC

computador escreve dados na memria, permitindo assim grficos de alta velocidade (ao contrrio de terminais de vdeo ligados serialmente ao computador). O controlador de vdeo pode operar tanto no modo texto quanto no modo grfico. A diferena est na forma como os dados so armazenados na memria. No modo grfico, armazenado um valor para cada ponto da tela em um ou mais bits. O controlador de vdeo l as posies de memria e envia os comandos correspondentes para o monitor de forma cclica. No modo texto, no armazenada a imagem da tela na memria, mas sim apenas o cdigo ASCII (American Standard Code for Information Interchange) para cada caracter representado na tela. Os cdigos ASCII so ento traduzidos para imagens na tela por um gerador de caracteres. Cada cdigo ASCII ocupa 1 byte de memria, acrescido de um segundo byte que define atributos (piscando, invertido, cor, etc.). O byte de atributo representado na Figura 21.
Blink Red Green Blue Green

Intens.

Red

Blue

Cr fundo Piscar letras Intensidade

Cr frente

Figura 21 Byte de atributo em modo texto.

O modo texto requer muito menos memria que o modo grfico. Por exemplo, para uma tela com 80 colunas por 25 linhas podemos ter 2000 caracteres (80 x 25), sendo que seriam necessrios 2 Kbytes para armazenar os cdigos ASCII e mais 2 Kbytes para os atributos, totalizando 4 Kbytes Dependendo da resoluo (nmero de pontos da tela) e das cores suportadas, o modo grfico necessita mais memria. Por exemplo, uma resoluo grfica de 640 x 200 pixels com apenas 1 bit por pixel (on/off) utiliza 16 Kbytes (640 x 200 / 8). O uso de cores resulta em ainda mais necessidade de memria, uma vez que vrios bits so necessrios para represent-las (por exemplo, 16 cores requerem 4 bits, j que 24=16). Desta forma, um controlador de vdeo tipo CGA operando na resoluo de 640 x 200 com um palete de 16 cores requer 64 Kbytes (640 x 200 x 4 / 8). Seguem alguns exemplos histricos de tipos de controladores de vdeo: MDA (Monocrome Display Adapter): - somente para texto 255 caracteres ASCII - caracteres ocupam matriz 9 x 14 pixel - somente cor de fundo + uma cor HGA (Hercules Graphics Adapter): - 2 modos de operao (texto 80 x 25, com caracteres de 9 x 14 pixel e grfico de 720 x 348 pixel) - monocromtico CGA (Color Graphics Adapter): - texto 80 x 25, cada caracter 8 x 8 pixel - grfico (320 x 200 com 4 cores, 640 x 200 com 2 cores de um palete de 16 cores) EGA (Enhanced Graphics Adapter): - texto (resoluo 80 x 25 com caracteres 8 x 14 e 80 x 43 com caracteres 8 x 8) - grfico (320 x 200, 640 x 200, 640 x 350, todos com 16 cores de um palete de 64) - EGA plus 640 x 480 - 256 Kbytes RAM
Marcelo Ricardo Stemmer
35

Informtica Industrial I

DAS/UFSC

VGA (Virtual Graphics Adapter): - texto (80 x 25 e 80 x 43 com caracteres de 9 x 14) - grfico (320 x 200 a 640 x 480 com 256 cores de um palete de 262.144 cores, exigindo 256 Kbytes RAM) - super VGA (800 x 600 e 1024 x 768 com 16 cores exigindo 512 Kbytes RAM) Tipos de monitores de vdeo: Modo de Vdeo MDA CGA EGA ( 640 x 350 ) VGA ( 640 x 480 ) VGA (800x600 e 1024x768) Varredura horizontal 18,438 MHz 15,750 MHz 21,800 MHz 31,500 MHz 31,500 MHz Varredura vertical 50 Hz 60 Hz 60 Hz 60 Hz 70 Hz

Para permitir a operao do monitor em qualquer um destes modos, necessria a utilizao de um monitor multissncrono (Multisync), que monitora automaticamente as freqncias de varredura requeridas pelo controlador de vdeo. Nos computadores mais recentes, a placa de vdeo tradicional foi substituda por um novo tipo de perifrico conhecido como GPU (Graphic Processing Unit), que uma placa com processador e memria prprios e, inclusive, rea de cache prpria. Em computadores dotados de uma GPU, a CPU no envia mais placa de vdeo os pixels que compem desenho a ser apresentado na tela, mas sim apenas os parmetros necessrios para realizar um desenho ou animao.

3.3.12

Unidades de Disco / Disquete

As unidades de disco (rgido ou flexvel) se constituem essencialmente de: disco propriamente dito, recoberto de material magntico cabeotes de leitura / escrita (1 para cada face de cada disco) motores de passo, para girar o disco e posicionar cabeotes, incluindo componentes mecnicos e eletrnicos controlador de disco / disquete, que controla os motores e converte dados lidos e escritos pelos cabeotes em informao binria Os dados lidos do disco so colocados pelo controlador de disco direto em RAM, por meio de um canal DMA. A rea de memria a ser utilizada previamente definida pelo processador. O controlador de disco tem que ser inicialmente selecionado via barramento de endereos, aps o que os dados a salvar ou carregar so transferidos pelo barramento de dados (Figura 22).

Marcelo Ricardo Stemmer

36

Informtica Industrial I

DAS/UFSC
Barramento de Endereos Controlador

Posiciona cabeote Seleciona nmero cabeote l/escreve dados

Mother board

de Disco

Barramento de Dados

Seleciona Cilindro e trilha Recebe e envia dados

Figura 22 - Controlador de disco.

Os discos rgidos (Winchesters) geralmente consistem de uma pilha de placas que giram unidas, de forma que as unidades de disco fixo tm vrios cabeotes de leitura / escrita. Disquetes atualmente armazenam dados em ambos os lados, de forma que as unidades de disquete tm dois cabeotes. A Figura 24 apresenta a estrutura de uma unidade de disquete. - Forma de armazenamento de dados: O disco subdividido em trilhas concntricas (tracks) que, por sua vez, so compostas de diversos setores. Cada setor pode armazenar 512 Bytes de informao. O disco pode ter informaes armazenadas em um nico lado (single sided) ou em ambos os lados (double sided). A Figura 23 ilustra a estrutura de um disco e apresenta a frmula para clculo da capacidade de armazenamento de dados.
TRILHA (TRACK)

SETOR = 512 Bytes (SECTOR)

CILINDRO TRILHA LADO 1

TRILHA LADO 2

CAPACIDADE = Numero de Trilhas x Numero de Setores por trilha x Numero de Cabecotes x 512 Bytes

Figura 23 - Estrutura de dados de um disco.

A capacidade de alguns tipos comuns de discos e disquetes apresentada abaixo: Tipo de disco disquete 5 single disquete 5 double Nmero de cilindros 40 40 Setores por trilha 8 9 Cabeas Capacidade 1 160 Kbytes 2 360 Kbytes
37

Marcelo Ricardo Stemmer

Informtica Industrial I

DAS/UFSC

disquete 5 HD disquete 3 double disquete 3 HD disco rgido PC/XT

80 80 80 306

15 9 18 17

2 2 2 4

1,2 Mbytes 720 Kbytes 1,44 Mbytes 10 Mbytes

O tempo de acesso de uma unidade de disco definido como o tempo mdio requerido para posicionar o cabeote sobre um dado setor. Para exemplificar, valores tpicos de tempos de acesso encontrados para alguns discos rgidos mais antigos so: Disco do PC/XT 80 ms Disco do PC/AT 40 ms Disco do 386 28 ms Para efeito de comparao com discos rgidos atuais, temos por exemplo: Um winchester tpico de PC Desktop moderno, como o ST340810A U Series 40810, 40 GB, Ultra ATA/100, 5400 rpm, tem um tempo de acesso mdio de 8.9 ms (Fonte: http://www.seagate.com/cda/products/discsales/desktop/) Um HD para Servidores atual, como o ST318452LC, Cheetah X15 36LP, 18.4 GB, Ultra160 SCSI, 15.000 rpm, tem um tempo de acesso mdio de 3.6 ms (Fonte: http://www.seagate.com/cda/products/discsales/serverdept/) O tempo de acesso de unidades de disquete geralmente da ordem de 10 vezes maior, devido a menor velocidade de rotao dos disquetes.

Marcelo Ricardo Stemmer

38

Informtica Industrial I

DAS/UFSC

Figura 24 - Unidade de Disquete.

Marcelo Ricardo Stemmer

39

Informtica Industrial I

DAS/UFSC

-Fator de Interleave (disco rgido): O controlador de disco escreve / l dados no disco em unidades de 512 bytes (1 setor) de cada vez. Se o processador for rpido, os dados enviados podero ser escritos em setores adjacentes, caso contrrio, os dados sero escritos pulando um determinado nmero de setores, produzindo assim um fator de interleave maior que 1, como ilustrado na Figura 25.

3 4 5 6

2 1 6 3

5 1 8

8 7

FATOR DE INTERLEAVE = 1 (1 rotacao para ler/escrever 1 trilha)

FATOR DE INTERLEAVE = 2 (2 rotacoes para ler/escrever 1 trilha)

Figura 25 - Fator de Interleave.

So valores tpicos de interleave: 3 a 6 para XT, 2 para AT e 1 para 386 / 486 e todos os PCs mais recentes. - Estrutura lgica do disco (DOS): A estrutura lgica de um disco rgido ou disquete definida pelo sistema operacional em uso. Por exemplo, todo disco ou disquete formatado pelo DOS mapeado em quatro reas distintas: rea reservada Tabela de alocao de arquivos (FAT) Diretrio Raiz rea de arquivos (arquivos e subdiretrios) rea reservada: - Contm setor de boot (setor 0): comandos para carregar o sistema operacional e... - tabela com tamanho da rea reservada, tamanho da FAT e nmero de entradas do diretrio raiz FAT (File Allocation Table Tabela de alocao de arquivos): - Contm registro do formato do disco e... - mapa de localizao dos setores usados pelos arquivos Diretrio Raiz: - tabela de contedo do disco: nome, data, tamanho e local de incio de cada entrada no disco - gerado por FORMAT nmero de entradas limitado (1,44MB / 1,2MB 224 diretrios, winchester 512 diretrios) rea de arquivos:
Marcelo Ricardo Stemmer
40

Informtica Industrial I

DAS/UFSC

ocupa maior parte do disco utilizvel pelo usurio para arquivos e subdiretrios ( a partir do DOS 2.0)

3.4 Software bsico do PC 3.4.1 Software da ROM

O software contido na ROM do PC se compe essencialmente de 4 elementos: Rotinas de inicializao: inicializam diversas funes no computador e carregam o sistema operacional; BIOS (basic Input-Output System): o sistema bsico de entrada / sada um grupo de rotinas em linguagem de mquina que do suporte operao do computador; BASIC: ncleo da linguagem Basic que ativado caso o sistema operacional no esteja presente no disco (oferecido no PC da IBM e em alguns compatveis); extenses da ROM: programas adicionados a ROM principal quando novos equipamentos so adicionados ao computador (opcional)

3.4.1.1

Rotinas de Inicializao

As rotinas de inicializao executam as seguintes tarefas: teste de confiabilidade do computador para assegurar que tudo esta funcionando corretamente inicializao dos circuitos e equipamentos padro ligados ao PC definio da tabela de vetores de interrupo, indicando endereos de rotinas da BIOS verificao de quais equipamentos adicionais esto conectados, com eventual chamada das extenses da ROM para a inicializao destes carregamento do sistema operacional do disco (unidade A, B ou C). Para isto, a rotina tem que ler segmentos de boot do disco e se tiver sucesso, passa o controle do computador para o programa gravado neste segmento. Este programa, por sua vez, carrega o resto do sistema operacional. Se o segmento de boot no contiver o programa procurado, o Basic ativado. Para PCs compatveis, uma mensagem de erro apresentada ao invs disto.

3.4.1.2

BIOS

Conceitualmente, o BIOS foi concebido para servir de interface entre os programas de alto nvel (incluindo programas do usurio e o prprio DOS) e o hardware do PC. Todo acesso ao hardware deveria ser executado atravs de funes da BIOS, de forma a garantir a portabilidade dos programas. Todos os servios da BIOS so chamados por meio de interrupes (de software ou hardware). Os endereos de todas as rotinas de servios do BIOS so armazenados na tabela de vetores de interrupo. Alm de atender as interrupes originadas pelo hardware, o BIOS coloca doze interrupes com servios acessveis ao usurio via instruo Assembly INT. Estes servios esto descritos na tabela a seguir.

Resumo dos principais servios oferecidos pelo BIOS:


Marcelo Ricardo Stemmer
41

Informtica Industrial I

DAS/UFSC

Interrupt Vector INT 05H INT 10H

INT 11H

INT 12H INT 13H INT 14H INT 15H INT 16H INT 17H INT 18H INT 19H INT 1AH

Servio PRINT SCREEN: imprime o contedo da tela VIDEO-I/O: rotinas de interface com o controlador de vdeo (modo de operao, tipo e posio do cursor, rolar pgina de vdeo, selecionar pgina de vdeo, acender e definir cor de pontos, mostrar caracter ASCII no vdeo, etc.) EQUIPMENT DETERMINATION: permite determinar quais perifricos opcionais esto conectados ao sistema (impressoras, interfaces, unidades de disco, controlador de vdeo, coprocessador, etc.) no IBM, l dip-switches via 8255 MEMORY SIZE DETERMINATION: para determinar a quantidade de memria instalada DISQUETE- I/O: rotinas de interface com controlador de discos (read, write, format, etc.) RS232C-I/O: servios de comunicao via interface serial (inicializa, l e escreve) CASSETE-I/O: servios de fita cassete (no mais usados) KEYBOARD-I/O: servios do teclado (aguarda digitao tecla, status, etc.) PRINTER-I/O: servios de impressora (inicializa, envia dados, l status, etc.) BASIC: ativa o Basic da ROM (no IBM) BOOT STRAP LOADER: l setor de boot, carregando o DOS TIME AND DATE: servios de hora e data ( l e acerta hora e data)

3.4.2

O Sistema Operacional DOS (Disk Operating System)

O sistema operacional DOS foi originalmente concebido para os computadores IBM-PC em um trabalho conjunto da IBM e da Microsoft. Posteriormente, ambas as empresas passaram a fornecer seus prprios produtos: o MS-DOS, da Microsoft, e o PC-DOS, da IBM. Alm disto, a Digital Research tambm oferece sua verso do DOS, denominada DR-DOS. O produto mais difundido sempre foi o MS-DOS. Ainda se discute que sistema operacional dever herdar o imenso mercado dos PCs no futuro prximo. Os candidatos mais fortes no momento so o Windows 95/98 (Microsoft) e seu sucessor Windows-ME, o Windows-NT (New Technology, da Microsoft, com ncleo semelhante ao MVS/DEC) e seu sucessor Windows-2000, o OS/2 (IBM) e o UNIX (particularmente verso GNU/LINUX). Este ltimo j padro no universo das estaes de trabalho ("Workstations"). O DOS compe-se de 4 partes principais: Boot Strap Loader: residente no setor lgico 0, ativado pela rotina de inicializao da BIOS e carrega o DOS propriamente dito na RAM (3 outras partes ficam residentes na memria). IBMBIO.COM (verso IBM) ou IO.SYS (verso Microsoft): contm extenses do ROM-BIOS. Estas extenses podem se mudanas ou adies bsicas de I/O, rotinas para tratar novos dispositivos perifricos, etc. arquivo escondido, no aparece com o comando DIR. IBMDOS.COM (verso IBM) ou MSDOS.SYS (verso Microsoft): contm as rotinas de servios do DOS. Estes servios, assim como os da BIOS podem ser chamados por um grupo de interrupes, conforme a tabela a seguir. COMMAND.COM: interpretador de comandos do DOS. Compara o que foi digitado com nomes dos comandos internos ou procura no disco um programa com nome correspondente.

Interrupt Vector

Servios oferecidos pelo DOS


42

Marcelo Ricardo Stemmer

Informtica Industrial I

DAS/UFSC

INT 20H INT 21H INT 22H INT 23H INT 24H INT 25H INT 26H INT 27H INT 2FH INT 28H

Trmino de programa (retorno ao DOS) Chamada de servios gerais do DOS (aprox. 75 funes disponveis) Endereo de trmino de programa (uso interno do DOS) Endereo do manipulador de CTRL-C (uso interno do DOS) Endereo do manipulador de erro crtico (uso interno do DOS) Leitura absoluta do disco Escrita absoluta do disco Termina programa e mantm residente (TSR = Terminate and Stay Resident) Acesso programas residentes (interrupo multiplexadora) Interrupo Ociosa (sem ao, ativada enquanto nenhuma tecla pressionada)

Antes de passar o comando do computador ao COMMAND.COM, o programa carregador executa comandos contidos nos arquivos: CONFIG.SYS: carrega drivers de dispositivos. AUTOEXEC.BAT: srie de comandos do DOS desejados pelo usurio na inicializao. Seguem exemplos de alguns comandos mais usuais do DOS: Comando HELP DIR MD RD CD DEL, UNDELETE REN COPY, XCOPY TYPE FORMAT CHKDSK MEM VER TIME DATE PATH LABEL VOL EDIT MODE Funo no DOS Ajuda On-line para comandos DOS Lista contedo de um diretrio Make Directory - Cria diretrio abaixo do corrente Remove Directory - Remove diretrio, caso vazio Change Directory - Muda o diretrio corrente DELete - deleta um arquivo UNDELETE - recupera arquivo REName - Renomeia arquivo Copia contedo de um arquivo de um disco para outro, de um diretrio para outro ou para um arquivo com outro nome Lista na tela contedo de um arquivo (ASCII) Formata disco ou disquete CHecK DiSK - checa contedo e trilhas de um disco para identificar problemas MEMory - Indica contedo da memria de trabalho (RAM) VERsion - Mostra verso do DOS Ajuste e leitura da hora Ajuste e leitura da data Ajusta trilha de procura de arquivos para COMMAND.COM Ajusta denominao para disco Mostra denominao do disco Chama editor padro do DOS Ajuste de modo de vdeo, interface serial e outros Exemplo de uso HELP DEL DIR /AD MD TEMP RD TEMP CD TEMP DEL *.TXT UNDELETE A1.TXT REN A.DOC B.DOC COPY A:T1.TXT B:T2.TXT

TYPE T2.DOC FORMAT A:/4 CHKDSK C:/F MEM /C VER TIME 10:25:15 DATE 10.25.93 PATH C:\DOS LABEL A:TESTE VOL A: EDIT A:P1.ASM MODE COM1:96,E,8,1

Marcelo Ricardo Stemmer

43

Informtica Industrial I

DAS/UFSC

4 Programao do PC e de sistemas computadorizados*


4.1 Introduo
Atualmente, emprega-se cada vez mais sistemas computacionais na automatizao de processos industriais. Um engenheiro que atua nesta rea deve conhecer os sistemas computacionais disponveis e ser capaz de selecionar o melhor equipamento para uma dada aplicao. Alm disto, este profissional deve conseguir instalar o sistema, configur-lo e acima de tudo program-lo para que este execute a tarefa de automatizao atendendo requisitos industrias, como confiabilidade, tolerncia a falhas ou comportamento determinstico com restries temporais (sistemas temporeal). Neste contexto, a programao destes sistemas se faz de suma importncia. Basicamente, a inteligncia dos sistemas automatizados implementada atravs de programas computacionais, comandando os componentes de hardware para executar a tarefa com o comportamento desejado. Nas ltimas dcadas, o desenvolvimento em hardware permitiu que, cada vez mais, os processos industrias sejam automatizados e interligados atravs de sistemas computacionais. Entretanto, a evoluo em software no se deu na mesma velocidade que a de hardware. Desta forma, um dos grandes paradigmas tecnolgicos hoje o desenvolvimento de programas para a realizao de tarefas complexas e que exigem um alto grau de inteligncia. A maneira de se comunicar com um computador chama-se programa e a nica linguagem que o computador entende chama-se linguagem de mquina. Portanto todos os programas que se comunicam com a mquina devem estar em linguagem de mquina. Entretanto, para permitir uma maior flexibilidade e portabilidade no desenvolvimento de software, foram implementados nos anos 50 os primeiros programas para a traduo de linguagens semelhantes humana (linguagens de "alto nvel") em linguagem de mquina. Os referidos programas de traduo para a linguagem de mquina podem ser classificados em duas categorias: Interpretadores: Um interpretador l a primeira instruo do programa, faz uma verificao de consistncia de sua sintaxe e, se no houver erro, converte-a para a linguagem de mquina para finalmente execut-la. Segue, ento, para a prxima instruo, repetindo o processo at que a ltima instruo seja executada ou a verificao de consistncia aponte algum erro. So muito bons para a funo de depurao ("debugging") de programas, mas so lentos. Ex.: BASIC Interpretado, Java. Compiladores : Traduzem o programa inteiro em linguagem de mquina antes de serem executados. Se no houver erros, o compilador gera um programa em disco com o sufixo .OBJ com as instrues j traduzidas. Este programa no pode ser executado at que sejam agregadas a ele rotinas em linguagem de mquina que lhe permitiro a sua execuo. Este trabalho feito por um programa chamado editor de ligaes, linkeditor ou simplesmente linker, que, alm de juntar eventuais bibliotecas e mdulos necessrios ao programa .OBJ, cria um produto final em disco usualmente com sufixo .EXE (isto depende do sistema operacional em uso) que pode ser executado diretamente a partir do sistema operacional. Compiladores bem otimizados produzem cdigo de mquina quase to eficiente quanto aquele gerado por um programador que trabalhe direto em Assembly. Oferecem em geral menos facilidades de depurao que interpretadores, mas os programas so mais rpidos (na ordem de 100 vezes ou mais). Ex.: BASIC Compilado, FORTRAN, PASCAL, MDULA - 2, C, C++, etc. Alm da maior velocidade, outras vantagens dos compiladores podem ser mencionadas:
*

captulo atualizado com auxlio do estagirio de docncia Alexandre Orth, CPG-EEL, em 2000/1
44

Marcelo Ricardo Stemmer

Informtica Industrial I

DAS/UFSC

desnecessria a presena do interpretador ou do compilador para executar o programa j compilado e linkeditado; programas .EXE no podem ser alterados, o que protege o cdigo-fonte.

Estudaremos aqui uma das linguagens de alto nvel mais utilizadas na indstria: a linguagem "C", e posteriormente a sua sucessora, a linguagem C++, resultado da introduo da programao Orientada a Objetos linguagem C. A programao uma atividade que requer pacincia, concentrao e organizao. O aprendizado desta tcnica deve acontecer de forma gradual para que o programador entenda bem os conceitos envolvidos e compreenda os diversos mecanismos disponveis. Por isso, o aluno deve prosseguir neste aprendizado no seu ritmo, permitindo-se consolidar os conhecimentos atravs dos exemplos e exerccios. O aluno deve buscar formar uma boa base antes de se preocupar com as estruturas mais complexas. A caminhada feita passo passo, com calma e segurana.

4.2 Conceitos Bsicos da Programao em C 4.2.1 Histrico de C


O compilador "C" vem se tornado o mais difundido em ambiente industrial. A linguagem "C" se originou das linguagens BCPL e B desenvolvidas em 1970. A primeira verso de "C" foi implementada para o sistema operacional UNIX pela Bell Laboratories, especificamente por Dennis M. Ritchie e Ken Thompson no incio da dcada de 70, e rodava em um DEC PDP11 (Digital Equipment Corporation). A linguagem C foi utilizada para portar o UNIX para outros computadores. A linguagem "C" possui uma caracterstica dual: considerada linguagem estruturada de alto nvel e... "Assembly" de alto nvel, que permite escrever programas muito prximos linguagem de mquina. A linguagem C vem sendo usada para desenvolver muitas aplicaes como compiladores, interpretadores, processadores de texto e mesmo sistemas operacionais (ex.: UNIX, MS-DOS, Turbo Pascal for Windows, etc.). A linguagem de programao C tornou-se rapidamente uma das mais importantes e populares, principalmente por ser muito poderosa, portvel, pela padronizao dos compiladores existentes (atravs da norma ANSI C) e flexvel. Os programas em C tendem a ser bastante compactos e de execuo rpida. A linguagem C baseada em um ncleo pequeno de funes e estruturas bsicas. Desta forma, todo programa desenvolvido a partir deste ncleo bsico. Isto implica na grande portabilidade de C, haja visto que basta a implementao deste ncleo bsico para um dado processador e automaticamente j estar disponvel um compilador C para este processador. Por esta razo, existem compiladores C para a grande parte dos sistemas computacionais atualmente disponveis. Devido tambm a este pequeno ncleo, um programador C capaz de desenvolver programas to eficientes, pequenos e velozes quanto os programas desenvolvidos em Assembly. Por isso, diz-se que C tambm uma linguagem de baixo nvel, i.e., prxima da linguagem de mquina.

4.2.2 Criando um Programa Executvel


Para criar um programa em C, inicie por datilografar o seu cdigo com o auxlio de um processador de textos em modo ASCII. Grave o programa em disco dando a ele um nome como sufixo .C. O programa assim gerado chamado de cdigo fonte.

Marcelo Ricardo Stemmer

45

Informtica Industrial I

DAS/UFSC

Na seqncia, compile o cdigo fonte seguindo as instrues do seu compilador, o que criar um programa com o sufixo .OBJ em disco. O programa gerado chamado de objeto. Por fim, basta linkeditar o objeto seguindo as instrues do seu linkeditor, o que criar, no caso dos sistemas operacionais DOS e Windows, um programa com sufixo .EXE em disco. O programa gerado chamado de executvel. A Figura 26 apresenta o processo de gerao de um programa em C.
compilar linkar
Programa: "Ol Mame!!!"

Arq1.C

Arq1.Obj

ABC

linkar

Arq2.Obj MyProgram.Exe
linkar

Arq3.Obj
CPU

Figura 26 - Ilustrao do processo de criao de um programa em C.

4.2.3 A Estrutura Bsica de um Programa em C


A forma geral de um programa em "C" a seguinte:
< diretivas do pr-processador > < declaraes globais >; main() { < declaraes locais >; / comentrio / < instrues >; } < outras funes >

Vamos comear por um programa bem simples em C. Voc pode escrever este programa em um arquivo ASCI e salv-lo com um nome terminando em .C . O programa serve para escrever na tela a frase Bom Dia!!!!.
/* Programa : Bom Dia! */ #include <stdio.h> void main() { printf(Bom Dia!!!!); }

Na primeira linha, os smbolos /* e */ servem para delimitar um comentrio do programa. muito importante que os programas sejam comentados de forma organizada. Isto permite que
Marcelo Ricardo Stemmer
46

Informtica Industrial I

DAS/UFSC

outras pessoas possam facilmente entender o cdigo fonte. Os comentrios no so interpretados pelo compilador, servindo apenas para a documentao e esclarecimento do programador. Depois, segue-se com uma diretiva para o pr-processador #include <stdio.h>. Isto advm do fato de C ter um ncleo pequeno de funes bsicas. Ao escrever esta linha de cdigo, o pr-processador ir acrescentar ao programa todas as funcionalidades definidas na biblioteca stdio (Standard Input Output, entrada e sada padro) e ir link-la posteriormente ao programa. Desta forma, voc poder usufruir de todos os servios disponveis nesta biblioteca. Ela necessria em nosso exemplo, pois usamos a funo printf, que requer esta biblioteca. Por fim, temos a funo main(). Esta funo indica ao compilador em que instruo deve ser comeada a execuo do programa. Portanto, esta funo deve ser nica, aparecendo somente uma vez em cada programa. O programa termina quando for encerrada a execuo da funo main(). No caso deste programa exemplo, ela no recebe nenhum parmetro e tambm no retorna parmetro nenhum. Isto fica explcito atravs da palavra-chave void (ingls para vazio) escrita na frente do programa. Se em vez de void tivssemos escrito int, isto significaria que a funo main() deveria retornar um valor do tipo inteiro ao final de sua execuo. Como este o valor retornado pela funo main(), este tambm ser o valor retornado pelo programa aps a sua execuo. As funes e as suas caractersticas sero apresentadas em detalhes nos prximos captulos.
int main() { printf(Bom Dia!!!!); return 0; /* indica ao OS que no ocorreu nenhum erro durante a execuo do programa */ }

Todo o corpo de uma funo em C inicializado e finalizado atravs das chaves { e }. Estas chaves definem o bloco de instrues a serem executados por esta funo. A primeira instruo dada dentro do programa printf(Bom Dia!!!!);. Printf uma funo definida em stdio.h para escrever dados na janela console. Todas as instrues de programa tem que ser declaradas dentro de alguma funo (na main() ou outra qualquer). Todas as instrues devem estar dentro das chaves que iniciam e terminam a funo e so executadas na ordem em que as escrevemos. As instrues C so sempre encerradas por um ponto-e-vrgula (;). O ponto-e-vrgula parte da instruo e no um simples separador. Esta instruo uma chamada funo printf(), os parnteses nos certificam disso e o ponto-e-vrgula indica que esta uma instruo. Nota-se que a funo chamada escrevendo-se o nome desta e colocando-se os parmetros desta entre parnteses. A final de cada instruo em C, faz-se necessrio o acrscimo de um pontoe-vrgula. As variveis em C podem estar dentro de uma funo ou no incio do arquivo fonte. Variveis declaradas no incio do arquivo fonte so consideradas globais, isto , so visveis (i.e. acessveis) para todas as funes do programa. Variveis declaradas dentro de uma funo so consideradas locais, isto , visveis somente pela funo onde so declaradas. "C" distingue nomes de variveis e funes em maisculas de nomes em minsculas. Voc pode colocar espaos, caracteres de tabulao e pular linhas vontade em seu programa, pois o compilador ignora estes caracteres. Em C no h um estilo obrigatrio. Entretanto, procure manter os programas to organizados quanto for possvel, pois isto melhora muito a legibilidade do programa, facilitando o seu entendimento e manuteno.

Marcelo Ricardo Stemmer

47

Informtica Industrial I

DAS/UFSC

4.2.4 Variveis
As variveis so o aspecto fundamental de qualquer linguagem de computador. Uma varivel em C um espao de memria reservado para armazenar um certo tipo de dado e tendo um nome para referenciar o seu contedo. O espao de memria de uma varivel pode ser compartilhado por diferentes valores segundo certas circunstncias. Em outras palavras, uma varivel um espao de memria que pode conter, a cada tempo, valores diferentes.
/* Programa : Exemplo de variveis! */ #include <stdio.h> void main() { int num; num = 2; printf(Este o nmero dois: %d, num); }

/* declarao */ /* atribui um valor */ /* acessa a varivel */

A primeira instruo, int num; um exemplo de declarao de varivel, isto , apresenta um tipo, int, e um nome, num. A segunda instruo, num = 2; atribui um valor varivel num e este valor ser acessado atravs de seu nome. Usamos o operador de atribuio (=) para este fim. A terceira instruo chama a funo printf() mandando o nome da varivel como argumento. Esta l o valor da varivel e substitui na posio indicada por %d, compondo assim a frase apresentada na tela. O emprego da funo printf() ser apresentado em detalhe posteriormente. Em C, todas as variveis devem ser explicitamente declaradas (Isto no o caso de todas as linguagens. Em Fortran, por exemplo, variveis que comeam com i, j ou k so automaticamente consideradas inteiros pelo compilador). Se voc tiver mais de uma varivel do mesmo tipo, poder declar-las de uma nica vez separando seus nomes por vrgulas.
int aviao, foguete, helicoptero;

4.2.5 Tipos de Dados


O tipo de uma varivel informa a quantidade de memria, em bytes, que esta ir ocupar e a forma como o seu contedo ser armazenado. Em C existem apenas 5 tipos bsicos de variveis, que so: Identificador char int float double void Categoria Caracter Inteiro Real de ponto flutuante Real de ponto flutuante de dupla preciso Sem valor (vazio).

Com exceo de void, os tipos de dados bsicos podem estar acompanhados por modificadores na declarao de variveis. Os modificadores de tipos oferecidos em C so:

Marcelo Ricardo Stemmer

48

Informtica Industrial I

DAS/UFSC

Modificadores signed unsigned long short

Efeito Bit mais significante usado como sinal Bit mais significante parte do nmero (s +) Estende preciso Reduz preciso

A associao entre identificadores e modificadores resulta nos seguintes tipos de dados: Tipo (signed) char unsigned char (short) (signed) int (short) unsigned int (signed) long int unsigned long int float long float double Tamanho 1 Byte 1 Byte 2 Bytes 2 Bytes 4 Bytes 4 Bytes 4 Bytes 8 Bytes 8 Bytes Valores possveis -128 a +127 0 a 255 -32.768 a +32.767 0 a 65.535 -2.147.483.648 a +..647 0 a 4.294.967.295 3,4E-38 a 3,4E+38 1,7E-308 a 1,7E+308 1,7E-308 a 1,7E+308

Observao: As declaraes que aparecem na tabela acima entre parnteses (), indicam que estas declaraes so optativas. Por exemplo short unsigned int indica a mesma preciso que unsigned int. O tipo int tem sempre o tamanho da palavra da mquina, isto , em computadores de 16 bits ele ter 16 bits de tamanho. Emprega-se o complemento de dois dos nmeros positivos para o clculo e representao dos nmeros negativos. A escolha de nomes significativos para suas variveis pode ajud-lo a entender o que o programa faz e prevenir erros. Uma varivel no pode ter o mesmo nome de uma palavra-chave de C (nomes reservados). Em C, letras minsculas e maisculas so diferentes. Tabela de Palavras Chave em C: auto default float break do for case double goto char else if const enum int continue extern long

register return short signed sizeof static

struct switch typedef union unsigned void

volatile while

Segue um exemplo de programa que emprega as variveis apresentadas.


void main() { float y; int i; double x = 3.24; char c = 'a'; i = 100; y = (float) i; }
Marcelo Ricardo Stemmer

/ / / / / /

varivel varivel varivel varivel varivel converte

Real no inicializada Inteira no inicializada Double inicializada com 3.24 Char inicializada com a i recebe o valor 100 tipos

/ / / / / /

49

Informtica Industrial I

DAS/UFSC

Preste ateno na operao y= (float) i;. Esta operao muito empregada para converso de tipos de variveis diferentes. Suponha que voc tenha uma varivel x de tipo A e queira converte-la para o tipo B e armazen-la em y deste tipo. Voc pode executar esta operao atravs da operador:
y = ((B) x);

Ateno: Cuidado ao converter variveis com preciso grande para variveis com preciso pequena, ou seja, variveis que utilizam um nmero diferente de bits para representar dados. Voc pode perder informaes importantes por causa desta converso. Por exemplo, se voc converter um float num int, voc perder todos os dgitos depois da vrgula (preciso).
void main() { float y = 3.1415; int x = 0; x = (int) y; /* Equivalente : }

x = 3; */

4.2.6 Constantes
Um constante tem valor fixo e inaltervel. No primeiro programa exemplo, mostramos o uso de uma cadeia de caracteres constante juntamente com a funo printf():
printf(Bom Dia!!!!);

H duas maneiras de declarar constantes em C: a) usando a diretiva #define do pr-processador:


# define < nome da constante > < valor >

Esta diretiva faz com que toda apario do nome da constante no cdigo seja substituda antes da compilao pelo valor atribudo. No reservado espao de memria no momento da declarao define. A diretiva deve ser colocada no inicio do arquivo e tem valor global (isto , tem valor sobre todo o cdigo). Exemplo:
#define size 400 #define true 1 #define false 0 /* no usa ";" nem "=" */

b) utilizando a palavra-chave "const":


const < tipo > < nome > = < valor >;

Esta forma reserva espao de memria para uma varivel do tipo declarado. Uma constante assim declarada s pode aparecer do lado direito de qualquer equao (isto eqivale a dizer que no pode ser atribudo um novo valor quela varivel durante a execuo do programa). Exemplo:
const char letra = 'a'; const int size = 400; const double gravidade = 9.81;

Marcelo Ricardo Stemmer

50

Informtica Industrial I

DAS/UFSC

/* Programa: Exemplo do uso de Constantes */ #define Size 4 void main() { const char c = c; const int num = 10; int val = Size; }

Em C uma constante tipo caracter (char) escrita entre aspas simples, uma constante tipo cadeia de caracteres entre aspa duplas e constantes numricas com o nmero propriamente dito. Exemplos de constantes: a) caracter: a b) cadeia de caracteres: Bom Dia !!!! c) nmero: -3.141523

4.2.7 Ponteiros
Uma das mais poderosas caractersticas oferecidas pela linguagem C o uso de ponteiros. Um ponteiro proporciona um modo de acesso a variveis sem referenci-las diretamente. O mecanismo usado para isto o endereo da varivel. De fato, o endereo age como intermedirio entre a varivel e o programa que a acessa. Basicamente, um ponteiro uma representao simblica de um endereo. Portanto, utilizase o endereo de memria de uma varivel para acess-la. Um ponteiro tem como contedo um endereo de memria. Este endereo a localizao de uma outra varivel na memria. Dizemos que uma varivel aponta para uma outra quando a primeira contm o endereo da segunda. A declarao de ponteiros tem um sentindo diferente da de uma varivel simples. A instruo:
int *px;

declara que *px um dado do tipo int e que px um ponteiro, isto , px contm o endereo de uma varivel do tipo int. Para cada nome de varivel (neste caso px), a declarao motiva o compilador a reservar dois bytes de memria onde os endereos sero armazenados. Alm disto, o compilador deve estar ciente do tipo de varivel armazenada naquele endereo (neste caso, inteiro). O endereo de uma varivel pode ser passado um ponteiro atravs do operador &, como apresentado abaixo:
/* Exemplo com Ponteiros */ void main() { int num, valor; /* declara as varivel inteira num e valor int *ptr; /* declara um ponteiro para um inteiro ptr = 0; /* inicializa o ponteiro com o endereo 0 ptr = &num; /* atribui ao ptr o endereo da varivel num num = 10; /* atribui a varivel inteira o valor 10 valor = *ptr; /* acessa o contedo apontado por ptr e /* atribui a valor }

*/ */ */ */ */ */ */

Marcelo Ricardo Stemmer

51

Informtica Industrial I

DAS/UFSC

Neste programa, primeiro declaramos duas variveis inteiras. Em seguida, declara-se um ponteiro para uma varivel do tipo inteira. Este ponteiro tem o seu contedo inicializado com 0. Este um procedimento normal na manipulao de ponteiros, muito empregado para evitar o aparecimento de erros, pois, enquanto o endereo de um ponteiro for nulo, isto indicar que este endereo contm uma valor invlido e, portanto, o contedo representado por este endereo no deve ser acessado. Na seqncia, emprega-se o operador & para obter o endereo da varivel num e armazenar este endereo em ptr. Logo aps, atribumos a varivel inteira num o valor 10. Como ptr contm o endereo de num, logo ptr poder j acessar o valor 10 armazenado na varivel num. Isto feito na ltima linha, onde o contedo apontado por ptr acessado e copiado para a varivel valor. Outro exemplo da manipulao de ponteiros:
void main() { int i, j, *ptr; /* cria as variveis */ i = 1; /* i recebe o valor 1 */ j = 2; /* j recebe o valor 2 */ ptr = &i; /* ptr recebe o valor do endereo de i */ *ptr = *ptr + j; /* eqivale : i = i + j */ }

Nosso objetivo neste momento no apresentar todas as potencialidades dos ponteiros. Estamos aqui apresentando os ponteiros primeiramente como um tipo de dado especial. O importante aqui entender o contedo de um ponteiro e como este pode ser empregado. Posteriormente, apresentaremos as funcionalidades dos ponteiros a medida que formos evoluindo no aprendizado de C.

4.2.8 Exerccios
2.1. Crie o seu programa Hello, World! ou Ol, Mame!; 2.2. Crie um programa que contenha todos os tipos de variveis possveis e as combinaes dos modificadores possveis. Inicialize estas variveis com valores tpicos. Use o mtodo para a converso de tipos para converter: a) A varivel do tipo char em todos os outros tipos de variveis. b) A varivel do tipo double em todos os outros tipos de variveis. Discuta o que acontece com a preciso das variveis. 2.3. Crie um programa que exemplifique a utilizao de ponteiros. Que contenha pelo menos a declarao de um ponteiro, sua inicializao com zero, a obteno do endereo de uma varivel com o operador & e o acesso ao dado representado pelo ponteiro. 2.4. Utilize as diretivas #define para criar constantes e empregue estas constantes para inicializar as variveis do programa acima. 2.5. Analise o seguinte programa:
/* Testando 1,2,3 */ #define Default_Y 2
52

Marcelo Ricardo Stemmer

Informtica Industrial I

DAS/UFSC

void main() { const int num = 10; int y = Default_Y; const int *ptr = 0; ptr = &num; *ptr = *ptr + y; }

Aponte onde est o erro e explique porque.

4.3 Entrada/Sada do Console


As rotinas de entrada/sada do console se encontram nas bibliotecas "stdio.h" (Standard Input Output) e "conio.h" (Console Input Output) e, por isso, estas bibliotecas devem ser includas nos programas aplicativos atravs da diretiva include:
#include <stdio.h> #include <conio.h>

Algumas das funes de entrada e sada para a console mais utilizadas so apresentadas a seguir:

4.3.1 Printf()
A funo printf() uma das funes de E/S (entrada e sada) que podem ser usadas em C. Ela no faz parte da definio de C mas todos os sistemas tm uma verso de printf() implementada. Ela permite a sada formatada na tela. J vimos duas aplicaes diferentes da funo printf():
printf(Bom Dia!!!!); printf(Este o nmero dois: %d, num);

A funo printf()pode ter um ou vrios argumentos. No primeiro exemplo, colocamos um nico argumento: Bom Dia !!!!. No segundo entretanto, colocamos dois: Este o nmero dois: %d , que est esquerda, e a varivel num a direita da vrgula que separa os argumentos. A sintaxe geral de printf() a seguinte:
printf(string de formatao, < lista de parmetros >);

O string de formatao pode conter caracteres que sero exibidos na tela e cdigos de formatao que indicam o formato em que os argumento devem ser impressos. No nosso segundo exemplo, o cdigo de formatao %d solicita a printf() para imprimir o segundo argumento em formato decimal na posio do string onde aparece o %d. Cada argumento deve ser separado por uma vrgula. Alm do cdigo de formatao decimal (%d), printf()aceita vrios outros. O prximo exemplo mostra o uso do cdigo %s para imprimir uma cadeia de caracteres:
/* Exemplo da funo Printf() */ #include <stdio.h>

Marcelo Ricardo Stemmer

53

Informtica Industrial I

DAS/UFSC

void main() { printf(%s esta a %d milhoes de milhas \n do sol., Venus, 67); }

A sada ser: Venus esta a 67 milhoes de milhas do sol. Aqui, alm do cdigo de formatao, a expresso de controle de printf() contm um conjunto de caracteres estranho: \n. O \n um cdigo especial que informa a printf() que o restante da impresso deve ser feito em uma nova linha. A combinao de caracteres \n representa, na verdade, um nico caractere em C, chamado de nova-linha (equivalente ao pressionamento da tecla Enter em um editor de texto). Os caracteres que no podem ser obtidos diretamente do teclado para dentro do programa (como a mudana de linha) so escritos em C, como a combinao do sinal \ (barra invertida) com outros caracteres. Por exemplo, \n representa a mudana de linha. A string de formatao define a forma como os parmetros sero apresentados e tem os seguintes campos: "%[Flags] [largura] [.preciso] [FNlh] < tipo > [\Escape Sequence]" onde: Flags + em branco # Efeito justifica sada a esquerda apresenta sinal (+ ou -) do valor da varivel apresenta branco se valor positivo, sinal de - se valor negativo apresenta zero no incio p/ octais apresenta Ox para hexadecimais apresenta ponto decimal para reais

largura = nmero mximo de caracteres a mostrar preciso = nmero de casas aps a vrgula a mostrar F = em ponteiros, apresentar como "Far" => base : offset (xxxx : xxxx) N = em ponteiros, apresentar como "Near" => offset h = apresentar como "short" l = apresentar como "long" Escape Sequence \\ \ \0 \a \b \f \n \o \r \t \x Efeito Barra Aspas Nulo Tocar Sino (Bell) Backspace Retrocesso Salta Pgina de Formulrio Nova Linha Valor em Octal Retorno do Cursor Tabulao Valor em hexadecimal

Marcelo Ricardo Stemmer

54

Informtica Industrial I

DAS/UFSC

Tipo %c %d,%i %e,%E %f %l,%ld %lf %o %p %s %u %x

Formato Caracter Inteiro decimal (signed int) Formato cientfico Real (float) Decimal longo Real longo (double) Octal (unsigned int) Pointer xxxx (offset) se Near, xxxx : xxxx (base: offset) se Far Apontador de string, emite caracteres at aparecer caracter zero (00H) Inteiro decimal sem sinal (unsigned int) Hexadecimal

Abaixo seguem alguns exemplos da formatao apresentada acima:


/* Programa com exemplos da formatao da sada com Printf() */ #include <stdio.h> void main() { float x; double y = -203.4572345; int a, b; a = b = 12; x = 3.141523; printf("Bom dia"); printf("\n\t\tBom dia\n"); /* pula linha aps escrever bom dia */ printf("O valor de x %7.3f\n", x); printf("Os valores de i, j e y so: %d %d %lf \n", a, b, y); }

Observao: Caso voc queira imprimir na tela os caracteres especiais \ ou %, voc deve escreve-los na funo printf() de forma duplicada, o que indicar ao compilador que este no se trata de um parmetro da funo printf() mas sim que deseja-se imprimir realmente este caracter. O exemplo abaixo apresenta este caso:
#include <stdio.h> void main() { int reajuste = 10; printf(O reajuste foi de %d%%. \n, reajuste); }

a sada ser: O reajuste foi de 10%.

4.3.2 Cprintf()
Basicamente cprintf() igual a printf(), mas usa as coordenadas atuais do cursor e da janela que forem ajustados anteriormente, bem como ajustes de cr de caracteres. Utilize esta funo para escrever na tela em posies pr-definidas.
Marcelo Ricardo Stemmer
55

Informtica Industrial I

DAS/UFSC

4.3.3 Scanf()
A funo scanf() outra das funes de E/S implementadas em todos os compiladores C. Ela o complemento de printf() e nos permite ler dados formatados da entrada padro (teclado). A funo scanf() suporta a entrada via teclado. Um espao em branco ou um CR/LF (tecla Enter) definem o fim da leitura. Observe que isto torna inconveniente o uso de scanf() para ler strings compostas de vrias palavras (por exemplo, o nome completo de uma pessoa). Para realizar este tipo de tarefa, veremos outra funo mais adequada na parte referente strings. Sua sintaxe similar de printf(), isto , uma expresso de controle seguida por uma lista de argumentos separados por vrgula:
scanf(string de definio das variveis, <endereo das variveis>);

O string de definio pode conter cdigos de formatao, precedidos por um sinal % ou ainda o caracter * colocado aps o % que avisa funo que deve ser lido um valor do tipo indicado pela especificao, mas no deve ser atribudo a nenhuma varivel (no deve ter parmetros na lista de argumentos para estas especificaes). A lista de argumentos deve consistir nos endereos das variveis. O endereo das variveis pode ser obtido atravs do operador & apresentado na seo sobre ponteiros (ver 4.2.7). Exemplo:
/* Programa exemplo do uso de Scanf() */ #include <stdio.h> void main() { float x; printf ("Entre com o valor de x : "); scanf ("%f", &x); /* l o valor do tipo float (%f) e armazena na varivel x (&x) */ }

Esta funo funciona como o inverso da funo printf(), ou seja, as variveis que devero ser lidas so definidas da mesma forma que com printf(). Desta forma, os parmetros de scanf() so em geral os mesmos que os parmetros de printf(), como visto no exemplo acima. O string de formatao de scanf() igual ao de printf(). Por isso, veja as tabelas de formatao de printf() para conhecer os parmetros de scanf(). Outro exemplo de scanf():
/* Segundo Programa exemplo do uso de Scanf() */ #include <stdio.h> main() { float anos, dias; printf(Digite a sua idade em anos: ); scanf(%f, &anos); dias = anos*365; printf(Sua idade em dias e %.0f.\n, dias); }

Marcelo Ricardo Stemmer

56

Informtica Industrial I

DAS/UFSC

4.3.4 Getch(), Getche() e Getchar()


A funo getchar() aguarda a digitao de um nico caracter e quando o usurio apertar a tecla [enter], esta funo adquire o caracter e retorna com o seu resultado. getchar() imprime na tela o caracter digitado. A funo getch()l um nico caracter do teclado sem ecoa-lo na tela, ou seja, sem imprimir o seu valor na tela. A funo getche() tem a mesma operao bsica, mas com eco. Ambas as funes no requerem que o usurio digite [enter] para finalizar a sua execuo (veja exemplo abaixo, junto funo putch()).

4.3.5 Putch() ou Putchar()


A funo putch() apresenta um nico caracter na tela, recebendo-o como parmetro. A funo putchar() executa a mesma operao. Exemplo:
/* Exemplo das funes: getch(), getche(), putch() e putchar() */ #include <stdio.h> #include <conio.h> void main() { char c1, c2; c1 = getch(); /* l caracter c1 mas no mostra na tela c2 = getche(); /* l caracter c2, escrevendo-o na tela printf("\nO primeiro valor digitado foi: "); putch(c1); /* escreve valor de c1 na tela printf("\nO segundo valor digitado foi: "); putchar(c2); }

*/ */ */

4.3.6 Exerccios
3.1. Escreva um programa que contenha uma nica instruo e imprima na tela: Esta e a linha um. Esta e a linha dois. 3.2. Escreva um programa que imprima na tela: Um Dois Trs. 3.3. Escreva um programa que pea os dados da conta bancria de um cliente e, posteriormente, escreve na tela os dados do cliente tambm de forma organizada. 3.4. Escreva um programa que exemplifique todos os tipos de formataes fornecidas por printf().

Marcelo Ricardo Stemmer

57

Informtica Industrial I

DAS/UFSC

3.5. Escreva um programa que pea ao usurio para entrar com um valor real (float), converta este valor para uma varivel do tipo char e depois imprima o seu valor na tela em formato decimal e em formato caracter. 3.6. Faa um programa que pea ao usurio para entrar com um caracter , converta este nmero para um valor inteiro e apresente na tela o valor deste nmero em formato float e o endereo da varivel que o contm. Utilize ponteiros para armazenar e acessar este valor.

4.4 Operadores 4.4.1 Operadores Aritmticos


C uma linguagem rica em operadores, em torno de 40. Alguns so mais usados que outros, como o caso dos operadores aritmticos. C oferece 6 operadores aritmticos binrios (operam sobre dois operandos) e um operador aritmtico unrio (opera sobre um operando). So eles: Binrios: = Atribuio + Soma Subtrao * Multiplicao / Diviso % Mdulo (devolve o resto da diviso inteira) Unrio: Menos unrio (indica a troca do sinal algbrico do valor) O operador = j conhecido dos exemplos apresentados anteriormente. Em C, o sinal de igual no tem a interpretao dada em matemtica. Representa a atribuio da expresso direita ao nome da varivel esquerda. Os operadores + - / * representam as operaes aritmticas bsicas de soma, subtrao, diviso e multiplicao. A seguir est um programa que usa vrios operadores aritmticos e converte temperatura Fahrenheit em graus Celsius.
/* Programa Exemplo dos operadores: + - * / */ #include <stdio.h> void main() { int ftemp = 0; int ctemp = 0; printf("Digite temperatura em graus Fahrenheit: "); scanf("%d", &ftemp); ctemp = (ftemp - 32)*5/9; printf("Temperatura em graus Celsius e %d", ctemp); }

O operador mdulo (%) aceita somente operandos inteiros. Resulta o resto da diviso do inteiro sua esquerda pelo inteiro sua direita. Por exemplo, 17%5 tem o valor 2, pois quando dividimos 17 por 5 teremos resto 2.

Marcelo Ricardo Stemmer

58

Informtica Industrial I

DAS/UFSC

4.4.2 Operadores Relacionais


Os operadores relacionais so usados para fazer comparaes. Em C no existe um tipo de varivel chamada booleana, isto , que assuma um valor verdadeiro ou falso. O valor zero (0) considerado falso e qualquer valor diferente de 0 considerado verdadeiro e representado pelo inteiro 1. Os operadores relacionais comparam dois operandos e retornam 0 se o resultado for falso e 1 se o resultado for verdadeiro. Os operadores relacionais disponveis em C so: Operador C && || ! < <= > >= == != ?: Funo E OU NO MENOR MENOR OU IGUAL MAIOR MAIOR OU IGUAL IGUAL DIFERENTE OPERADOR CONDICIONAL TERNRIO

O programa a seguir mostra expresses booleanas como argumento da funo printf():


/* Exemplo de Operadores Relacionais */ #include <stdio.h> void main() { int verdade, falso; verdade = (15 < 20); falso = (15 == 20); printf("Verdadeiro = %d, falso = %d\n", verdade, falso); }

Note que o operador relacional igual a representado por dois sinais de iguais. Um erro comum o de usar um nico sinal de igual como operador relacional. O compilador no o avisar que este um erro. Por qu? Na verdade, como toda expresso C tem um valor verdadeiro ou falso, este no um erro de programa e sim um erro lgico do programador.

4.4.3 Operadores lgicos binrios


Este operadores so empregados para comparar os bits contidos em duas variveis e, por isso, so denominados operadores lgicos binrios. Ou seja, estes operadores fazem uma comparao lgica entre cada bit dos operandos envolvidos. Os operadores binrios disponveis so: Operador C & | ^ ~ << >>
Marcelo Ricardo Stemmer

Funo E lgico OU lgico Ou Exclusivo No Desloca esquerda Desloca direita


59

Informtica Industrial I

DAS/UFSC

A seguir temos um exemplo da aplicao deste operadores.


/* Exemplo usando Operadores Binrios */ #include <stdio.h> void main() { int i, j, k; i = 1; j = 2; printf("\ti = %x (00000001)\n\tj = %x (00000010)", i, j); k = i & j; /* k = i AND j */ printf("\n\t i & j => %x (00000000)", k); k = i ^ j; /* k = i XOR j */ printf("\n\t i ^ j => %x (00000011)", k); k = i << 2; /* k = i deslocando 2 bits esquerda (4) */ printf("\n\t i << 2 => %x (00000100)", k); }

Primeiro o programa faz uma comparao binria e(&) entre o nmero 1 (0x00000001) e o nmero 2 (0x00000010). Por isso o resultado obtido logicamente 0, ou seja, 0x00000000. Em seguida, o programa faz um comparao binria ou (^) entre estes dois nmeros, resultando agora, lgicamente, 3, ou seja, (0x00000011). Por fim, o programa desloca o nmero 1 em duas casas para a esquerda, representado no programa pelo operador << 2. Assim, o resultado o nmero 4 ou, em binrio, (0x00000100). A partir deste exemplo fica clara a utilizao destes operadores.

4.4.4 Operadores de Ponteiros


Estes operadores j foram apresentados anteriormente na seo sobre ponteiros (ver 4.2.7). O primeiro operador serve para acessar o valor da varivel, cujo endereo est armazenado em um ponteiro. O segundo operador serve para obter o endereo de uma varivel. Operador & Funo Acesso ao contedo do ponteiro Obtm o endereo de uma varivel

O programa abaixo apresenta novamente o aplicao destes operadores.


/* Operadores de Ponteiros */ void main() { int i, j, *ptr; ptr = &i; /* atribui a ptr o endereo da varivel i */ j = *ptr; /* atribui a j o contedo do endereo definido por */ /* ptr = valor de i ! */ }

4.4.5 Operadores Incrementais e Decrementais


Uma das razes para que os programas em C sejam pequenos em geral que C tem vrios operadores que podem comprimir comandos de programas. Neste aspecto, destaca-se os seguintes operadores:

Marcelo Ricardo Stemmer

60

Informtica Industrial I

DAS/UFSC

Operador ++ --

Funo Incrementa em 1 Decrementa em 1

O operador de incremento (++) incrementa seu operando em 1. Este operador trabalha de dois modos. O primeiro modo chamado pr-fixado e o operador aparece antes do nome da varivel. O segundo o modo ps-fixado em que o operador aparece seguindo o nome da varivel. Em ambos os casos, a varivel incrementada. Porm quando ++n usado numa instruo, n incrementada antes de seu valor ser usado, e quando n++ estiver numa instruo, n incrementado depois de seu valor ser usado. O programa abaixo mostra um exemplo destes operadores, ressaltando esta questo.
/* Operadores de Incremento */ #include <stdio.h> void main() { int n, m, x, y; n = m = 5; x = ++n; y = m++; printf("O resultado e:\n n = %d; x = ++n = %d;\n m = %d; y = m++ = %d;", n, x, m, y); }

Vamos analisar duas expresses seguintes. a) k = 3*n++; Aqui, primeiro n multiplicado por 3, depois o resultado atribudo a k e, finalmente, n incrementado de 1. b) k = 3*++n; Aqui, primeiro n incrementado em 1, depois n multiplicado por 3 e, por fim, o resultado atribudo a k. Dica: Para evitar problemas, faa uso de parnteses para guiar a execuo do programa evitando que o compilador no compreenda a ordem correta de executar a operao. Abaixo, temos um outro exemplo dos operadores incrementais apresentado vrias aplicaes destes operadores:
/* Operadores Incrementais 2 */ void main() { int i = 10; int *ptr = 0; i = i + 1; /* incrementa i */ i++; /* incrementa i */ i = i - 1; /* decrementa i */ i--; /* decrementa i */ ptr = &i; /* recebe o endereo de i */ (*ptr)++; /* incrementa valor de i */ ptr++; /* incrementa em 2 Bytes (1 inteiro ocupa 2 Bytes) */ /* o valor do endereo apontado pelo ponteiro ptr */ }

Marcelo Ricardo Stemmer

61

Informtica Industrial I

DAS/UFSC

Ateno para a ltima instruo ptr++. Esta instruo ir altera o endereo armazenado em ptr. Se o valor deste ponteiro for acessado, o dado representado por este ponteiro no tem nenhuma relao mais com a varivel i, podendo conter qualquer dado. Por isso, tome cuidado ao manipular ponteiros para no acessar variveis com uso desconhecido. Isto poder fazer com que o seu programa gere erros fatais para o sistema operacional.

4.4.6 Operadores de Atribuio


O operador bsico de atribuio (=) pode ser combinado com outros operadores para gerar instrues em forma compacta. Cada um destes operadores usado com um nome de varivel sua esquerda e uma expresso sua direita. A operao consiste em atribuir um novo valor varivel que depender do operador e da expresso a direita. Se x uma varivel, exp uma expresso e op um operador, ento: x op= exp; eqivale x = (x)op(exp); Operador C: = += -= = /= %= >>= <<= &= |= ^= Funo: A = B A += B; A -= B; A = B; A /= B; A %= B; A >>= B; A <<= B; A &= B; A |= B; A ^= B;

A A A A A A A A A A

= = = = = = = = = =

A A A A A A A A A A

+ B; - B; B; / B; % B; >> B; << B; & B; | B; ^ B;

Exemplo: /* Operadores de Atribuio */ #include <stdio.h> void main() { int total = 0; int cont = 10; printf("Total=%d\n", total += 1; printf("Total=%d\n", total ^= 2; printf("Total=%d\n", total <<= 2; printf("Total=%d\n", total *= cont; printf("Total=%d\n", }
Marcelo Ricardo Stemmer

total); total); total); total); total);

62

Informtica Industrial I

DAS/UFSC

4.4.7 O Operador Lgico Ternrio


O operador condicional possui uma construo um pouco estranha. o nico operador em C que opera sobre trs expresses. Sua sintaxe geral possui a seguinte construo:
exp1 ? exp2 : exp3

A exp1 avaliada primeiro. Se seu valor for diferente de zero (verdadeira), a exp2 avaliada e seu resultado ser o valor da expresso condicional como um todo. Se exp1 for zero, exp3 avaliada e ser o valor da expresso condicional como um todo. Na expresso:
max = (a>b)?a:b;

a varivel que contm o maior valor numrico entre a e b ser atribuda a max. Outro exemplo:
abs = (x > 0) ? x : -x; /* abs o valor absoluto de x */

A expresso
printf( %d uma varivel %s !, x, ((x%2)?Impar:Par);

imprime mpar se x for um nmero mpar, caso contrrio imprimir par.

4.4.8 Precedncia
O operador ! o de maior precedncia, a mesma que a do operador unrio. A tabela seguinte mostra as precedncias dos operadores: Operadores ! - ++ -* / % + < > <= >= == != && || = += -= *= Tipos Unrios; no lgicos e menos aritmticos Aritmticos Aritmticos Relacionais Relacionais Lgico & Lgico OU Atribuio

/=

%=

4.4.9 Exerccios:
4.1. Qual o resultado da seguinte expresso:
int a = 1, b = 2, c = 3; int result = ++a/a&&!b&&c||b--||-a+4*c>!!b;

4.2. Escreva uma expresso lgica que resulte 1 se o ano for bissexto e 0 se o ano no for bissexto. Um ano bissexto se for divisvel por 4, mas no por 100. Um ano tambm bissexto se for divisvel por 400. 4.3. Faa um programa que solicite ao usurio o ano e imprima Ano Bissexto ou Ano No-Bissexto conforme o valor da expresso do exerccio anterior. Utilize o operador condicional. 4.4. Num cercado, h vrios patos e coelhos. Escreva um programa que solicite ao usurio o total de cabeas e o total de ps e determine quantos patos e quantos coelhos encontram-se nesse cercado.

Marcelo Ricardo Stemmer

63

Informtica Industrial I

DAS/UFSC

4.5. Uma firma contrata um encanador a 20.000,00 por dia. Crie um programa que solicite o nmero de dias trabalhados pelo encanador e imprima a quantia lquida que dever ser paga, sabendo-se que so descontados 8% para imposto de renda. 4.6. Faa um programa que solicite um caractere do teclado por meio da funo getch(); se for uma letra minscula imprima-a em maisculo, caso contrrio imprima o prprio caracter. Use uma expresso condicional 4.7. Faa um programa que solicite ao usurio uma seqncia binria com 16 bits. Transforme esta seqncia de 0 e 1 em um nmero inteiro. Depois manipule este nmero inteiro para verificar se os bits 0, 3, 7, 14 esto habilitados (valor igual a 1). Pea a usurio se ele deseja modificar algum bit especfico da palavra. Se ele quiser, modifique o bit desejado para o valor por ele fornecido.

4.5 Laos
Em C existem 3 estruturas principais de laos: o lao for, o lao while e o lao do-while.

4.5.1 O Lao For


O lao for engloba 3 expresses numa nica, e til principalmente quando queremos repetir algo um nmero fixo de vezes. Sintaxe:
for(inicializao ; teste ; incremento) instruo;

Os parnteses seguindo a palavra chave for contm trs expresses separadas por ponto-evrgulas, chamadas respectivamente de : expresso de inicializao, expresso de teste e expresso de incremento. As 3 expresses podem ser compostas por quaisquer instrues vlidas em C. Inicializao: executada uma nica vez na inicializao do lao. Serve para iniciar variveis. Teste: esta a expresso que controla o lao. Esta testada quando o lao iniciado ou reiniciado. Sempre que o seu resultado for verdadeiro, as instrues do lao sero executadas. Quando a expresso se tornar falsa, o lao terminado. Incremento: define a maneira como a varivel de controle do lao ser alterada cada vez que o lao repetido (conta++). Esta instruo executada, toda vez, imediatamente aps a execuo do corpo do lao.
for( conta = 0; conta < 10; conta++ ) printf(conta=%d\n, conta);

Exemplo:
/*Lao For 1*/ #include <stdio.h> void main() { int conta; for(conta = 0; conta < 10; conta += 3) printf("conta=%d\n", conta); }

Marcelo Ricardo Stemmer

64

Informtica Industrial I

DAS/UFSC

Qualquer uma das expresses de um lao for pode conter vrias instrues separadas por vrgulas. A vrgula na verdade um operador C que significa faa isto e isto. Um par de expresses separadas por vrgula avaliado da esquerda para a direita.
/* Forma Flexvel do Lao for */ #include <stdio.h> void main() { int x, y; for( x=0, y=0; x+y < 100; x = x+1, y++) printf("%d\n", x+y); }

Podemos usar chamadas a funes em qualquer uma das expresses do lao. Qualquer uma das trs partes de um lao for pode ser omitida, embora os pontos-e-vrgulas devam permanecer. Se a expresso de inicializao ou a de incremento forem omitidas, elas sero simplesmente desconsideradas. Se a condio de teste no est presente considerada permanentemente verdadeira. O corpo do lao pode ser composto por vrias instrues, desde que estas esteja delimitadas por chaves { }. O corpo do lao pode ser vazio, entretanto o ponto-e-vrgula deve permanecer para indicar uma instruo vazia. Quando um lao est dentro de outro lao, dizemos que o lao interior est aninhado . Para mostrar esta estrutura preparamos um programa que imprime a tabuada.
/* tabuada */ #include <stdio.h> void main() { int i,j,k; printf("\n"); for(k=0; k<=1; k++) { printf("\n"); for(i=1; i<5; i++) printf("Tabuada do %3d ", i+4*k+1); printf("\n"); for(i=1; i<=9; i++) { for(j = 2+4*k; j<=5+4*k; j++) printf("%3d x%3d = %3d ", j, i, j*i); printf("\n"); } } }

4.5.2

O Lao While

O lao while utiliza os mesmos elementos que o lao for, mas eles so distribudos de maneira diferente no programa. Sintaxe:
while(expresso de teste) instruo;

Marcelo Ricardo Stemmer

65

Informtica Industrial I

DAS/UFSC

Se a expresso de teste for verdadeira (diferente de zero), o corpo do lao while ser executado uma vez e a expresso de teste avaliada novamente. Este ciclo de teste e execuo repetido at que a expresso de teste se torne falsa (igual a zero), ento o lao termina. Assim como o for, o corpo do lao while pode conter uma instruo terminada por (;), nenhuma instruo desde que possua um (;) ou um conjunto de instrues separadas por chaves { }. Abaixo temos um exemplo, onde um lao while substituiu um antigo lao for.
/*Lao While 1*/ #include <stdio.h> void main() { int conta = 0; while(conta < 10) { printf("conta=%d\n", conta); conta++; } }

Quando se conhece a priori o nmero de loops que o lao deve fazer, recomenda-se o uso do lao for. Caso o nmero de iteraes dependa das instrues executadas, ento recomenda-se o uso do lao while. Os laos while podem ser aninhados como o lao for. C permite que no interior do corpo de um lao while, voc possa utilizar um outro lao while.

4.5.3 O Lao Do-While


O lao Do-While cria um ciclo repetido at que a expresso de teste seja falsa (zero). Este lao bastante similar ao lao while. A diferena que no lao do-while o teste de condio avaliado depois do lao ser executado. Assim, o lao do-while sempre executado pelo menos uma vez. A sintaxe a seguinte:
do { instruo; } while(expresso de teste);

Embora as chaves no sejam necessrias quando apenas uma instruo est presente no corpo do lao do-while, elas so geralmente usadas para aumentar a legibilidade. Exemplo usando os laos while e do-while:
/* Programa de Exemplo do lao Do-While */ #include <stdio.h> #include <conio.h> #include <stdlib.h> /* requerida para rand() */ void main() { char ch, c; int tentativas; do { ch = rand()%26 + 'a'; tentativas = 1;
Marcelo Ricardo Stemmer
66

Informtica Industrial I

DAS/UFSC

printf("\nDigite uma letra de 'a' a 'Z':\n"); while((c=getch())!= ch) { printf("%c e incorreto. Tente novamente. \n\n",c); tentativas++; } printf("\n%c e correto",c); printf("\nvoce acertou em %d tentativas", tentativas); printf("\nQuer jogar novamente? (s\\n): "); }while(getche()=='s'); }

4.5.4 Break e Continue


O comando break pode ser usado no corpo de qualquer estrutura do lao C. Causa a sada imediata do lao e o controle passa para o prximo estgio do programa. Se o comando break estiver em estruturas de laos aninhados, afetar somente o lao que o contm e os laos internos a este. O comando continue fora a prxima interao do lao e pula o cdigo que estiver abaixo. Nos laos while e do-while um comando continue faz com que o controle do programa v diretamente para o teste condicional e depois continue o processo do lao. No caso do lao for, o computador primeiro executa o incremento do lao e, depois, o teste condicional, e finalmente faz com que o lao continue.

4.5.5 Goto
O comando goto faz com que o programa pule para a instruo logo aps o label passado como parmetro. Este comando era muito usado nos primeiros programas de computador, anteriores a era da programao estruturada, mas seu uso desnecessrio e desaconselhado. Foi implementado somente para manter a compatibilidade com outros compiladores e para evitar a necessidade de reescrever inmeras bibliotecas de funes j existentes antes do advento da programao estruturada. A instruo goto tem duas partes: a palavra goto e um nome. O nome segue as convenes de nomes de variveis C. Por exemplo:
goto parte1;

Para que esta instruo opere, deve haver um rtulo (label) em outra parte do programa. Um rtulo um nome seguindo por dois pontos.
parte1: printf(Anlise dos Resultados.\n);

A instruo goto causa o desvio do controle do programa para a instruo seguinte ao rtulo com o nome indicado. Os dois pontos so usados para separar o nome da instruo.

4.5.6 Exerccios
5.1. Escreva um programa que imprima os caracteres da tabela ASCII de cdigos de 0 a 255. O programa deve imprimir cada caracter, seu cdigo decima e hexadecimal. Monte uma tabela usando os parmetros de formatao de printf(). 5.2. Escreva um programa, utilizando um lao while, que leia caracteres do teclado. Enquanto o usurio no pressionar a tecla ESC de cdigo 27, os caracteres lidos no so ecoados no
Marcelo Ricardo Stemmer

67

Informtica Industrial I

DAS/UFSC

vdeo. Se o caracter lido for uma letra minscula, o programa a imprime em maisculo e, se for qualquer outro caracter, ele mesmo impresso. 5.3. Elabore um programa que solicite um nmero inteiro ao usurio e crie um novo nmero inteiro com os dgitos em ordem inversa. Por exemplo o nmero 3567 deve ser escrito 7653. 5.4. Escreva um programa que desenhe uma moldura na tela do micro, desenhando um sol com as suas iniciais no meio da tela e escrevendo Feliz Natal e o seu nome embaixo.

4.6 Comandos para Tomada de Deciso


Uma das tarefas fundamentais de qualquer programa decidir o que deve ser executado a seguir. Os comandos de deciso permitem determinar qual a ao a ser tomada com base no resultado de uma expresso condicional. Isto significa que podemos selecionar entre aes alternativas dependendo de critrios desenvolvidos no decorrer da execuo do programa. C oferece 3 principais estruturas de deciso: if, if-else, switch. Estas estruturas so o tema desta seo.

4.6.1 If
O comando if usado para testar uma condio e caso esta condio seja verdadeira, o programa ir executar uma instruo ou um conjunto delas. Este um dos comandos bsicos para qualquer linguagem de programao. Sintaxe:
if(expresso de teste) instruo;

Como C no possui variveis booleanas, o teste sobre a condio opera como os operadores condicionais, ou seja, se o valor for igual a zero (0) a condio ser falsa e se o valor for diferente de zero, a condio ser verdadeira. Como os laos, o comando if pode ser usado para uma nica instruo ou para um conjunto delas. Caso se utilize para um conjunto de instrues, este conjunto deve ser delimitado por chaves { e }. Um comando if pode estar dentro de outro comando if. Dizemos ento que o if interno est aninhado. O programa abaixo mostra exemplos do uso e da sintaxe dos comandos if. O primeiro if mostra a forma aninhada do comando if, o segundo apresenta a sintaxe bsica e o ltimo um exemplo onde o comando if executa um bloco de instrues.
/* Programa exemplo para o comando if */ #include <stdio.h> #include <conio.h> void main() { char ch; printf("Digite uma letra de 'a' a 'Z':"); ch = getche(); if(ch >= 'A') /* Dois comandos if aninhados */ if(ch <= 'z') printf("\n Voce digitou um caracter valido!");

Marcelo Ricardo Stemmer

68

Informtica Industrial I

DAS/UFSC

if(ch == 'p') /* Forma bsica de um comando if */ printf("\nVoce pressionou a tecla 'p'!"); if(ch != 'p') /* Comando if executando um bloco de instrues */ { printf("\nVoce no digitou a tecla 'p'!); printf(\n Digite qualquer caracter para finalizar."); ch = getche(); } }

4.6.2 If-Else
No exemplo anterior, o comando if executar um nica instruo ou um grupo de instrues se a expresso de teste for verdadeira e no far nada se a expresso de teste for falsa. O comando else, quando associado ao if, executar uma instruo ou um grupo de instrues entre chaves se a expresso de teste do comando if for falsa. O if-else tambm permite o aninhamento de outros comandos if, ou if-else dentro do bloco de instrues aps o else. Sintaxe:
if(expresso de teste) instruo_1; else instruo_2;

Exemplo:
/* Programa exemplo do If-Else */ #include <stdio.h> void main() { int x, y; for(y=1; y<24; y++) /* passo de descida */ { for(x=1; x<24; x++) /* passo de largura */ if(x==y || x==24-y) /* diagonal? */ printf("\xDB"); /* cor escura */ else printf("\xB0"); /* cor clara */ printf("\n"); /* Nova Linha */ } }

4.6.3 Switch
O comando switch permite selecionar uma entre vrias aes alternativas. Embora construes if-else possam executar testes para escolha de uma entre vrias alternativas, muitas vezes so deselegantes. O comando switch tem um formato limpo e claro. A instruo switch consiste na palavra-chave switch seguida do nome de uma varivel ou de um nmero constante entre parnteses. O corpo do comando switch composto de vrios
Marcelo Ricardo Stemmer
69

Informtica Industrial I

DAS/UFSC

casos rotulados por uma constante e opcionalmente um caso default. A expresso entre parnteses aps a palavra-chave switch determina para qual caso ser desviado o controle do programa. O corpo de cada caso composto por qualquer nmero de instrues. Geralmente, a ltima instruo break. O comando break causa a sada imediata de todo o corpo do switch. Na falta do comando break, todas as instrues aps o caso escolhido sero executadas, mesmo as que pertencem aos casos seguintes. Sintaxe:
switch(varivel ou constante) { case constante1: instruo; instruo; break; case constante2: instruo; instruo; break; case constante3: instruo: instruo: break; default: instruo; instruo; }

Voc no poder usar uma varivel nem uma expresso lgica como rtulo de um caso. Pode haver nenhuma, uma ou mais instrues seguindo cada caso. Estas instrues no necessitam estar entre chaves. O corpo de um switch deve estar entre chaves. Se o rtulo de um caso for igual ao valor da expresso do switch, a execuo comea nele. Se nenhum caso for satisfeito e existir um caso default, a execuo comear nele. Um caso default opcional. No pode haver casos com rtulos iguais. A seguir apresentamos um exemplo que calcula o dia da semana a partir de uma data. O ano deve ser maior ou igual a 1600, pois nesta data houve uma redefinio do calendrio.
/* Exemplo do comando switch */ /* Calcula o dia da semana a partir de uma data */ #include <stdio.h> #include <conio.h> void main() { int D, M, A, i; long int F = 0; do { do { printf("\nDigite uma data na forma dd/mm/aaaa: "); scanf("%d/%d/%d", &D, &M, &A);
Marcelo Ricardo Stemmer
70

Informtica Industrial I

DAS/UFSC

} while(A<1600 || M<1 || M>12 || D<1 || D>31); F = A + D + 3*(M-1) - 1; if(M<3) { A--; i = 0; } else i = .4*M+2.3; F+= A/4 - i; i = A/100 + 1; i *= .75; F -= i; F %= 7; switch(F) { case 0: printf("\nDomingo"); break; case 1: printf("\nSegunda-Feira"); break; case 2: printf("\nTerca-Feira"); break; case 3: printf("\nQuarta-Feira"); break; case 4: printf("\nQuinta-Feira"); break; case 5: printf("\nSexta-Feira"); break; case 6: printf("\nSabado"); break; } }while(getche()!=27); /* Tecla ESC no for pressionada */ }

4.6.4 Exerccios
6.1. Crie um programa que desenhe na tela um tabuleiro de xadrez. 6.2. Crie um programa que desenhe na tela o seu quadro de horrios deste semestre. 6.3. Escreva um programa que solicite ao usurio trs nmeros inteiros a, b, e c onda a maior que 1. Seu programa deve somar todos os inteiros entre b e c que sejam divisveis por a. 6.4. A seqncia de Fiboncci a seguinte: 1, 1, 2, 3, 5, 8, 13, 21, ...
Marcelo Ricardo Stemmer
71

Informtica Industrial I

DAS/UFSC

Os dois primeiros termos so iguais a 1. Cada termo seguinte igual `a soma dos dois anteriores. Escreva um programa que solicite ao usurio o nmero do termo e calcule o valor do termo. Por exemplo: se o nmero fornecido pelo usurio for igual a 7, o programa dever imprimir 13. 6.5. Implemente um jogo da velha, onde o programa desenha na tela um tabuleiro e voc pede a dois usurios (A e B) na respectiva ordem, que jogada eles querem realizar e depois atualiza o desenho. O programa deve perceber quando o jogo acabou e anunciar o vencedor.

4.7 Funes
As funes servem para agrupar um conjunto de instrues de acordo com a tarefa que elas desempenham. Uma vez implementada corretamente esta tarefa, basta usar a sua funo correspondente. Por exemplo, quando usamos printf() para imprimir informaes na tela, no nos preocupamos como o programa realiza esta tarefa, pois a funo j fornece este servio de forma adequada. As funes, quando bem empregadas, facilitam bastante a organizao modular do programa, permitem a reutilizao de partes do programa e facilitam a sua manuteno. Uma funo uma unidade de cdigo de programa autnoma projetada para cumprir uma tarefa particular. A principal razo da existncia de funes impedir que o programador tenha que escrever o mesmo cdigo repetidas vezes.

4.7.1 Sintaxe
A estrutura de uma funo C bastante semelhante da funo main(). A nica diferena que main()possui um nome especial pois a funo main() a primeira a ser chamada quando o programa executado. Sintaxe:
<tipo retorno> <nome>(<tipo parmetro> <nome parmetro>, <...> <...>) { <declaraes locais>; <comandos>; return <expresso ou valor compatvel com o tipo de retorno>; }

O tipo de retorno define o tipo de dado o qual a funo retornar com o resultado de sua execuo. Nome indica qual o nome da funo. Em seguida temos a lista de argumentos da funo inseridos entre os parnteses aps o nome da funo e separados por vrgulas. Os argumentos so declarados no cabealho da funo com o tipo parmetro e em seguida o nome do parmetro. Um funo pode ter tantos argumentos quanto voc queira definir. Mesmo quando uma funo no necessita de parmetros, o nome desta deve ser seguido por parnteses ( ) sem nenhum parmetro no seu interior. A lista de instrues a serem executadas pela funo vem aps a lista de parmetros deve ser delimitada por chaves { e }. As instrues utilizam os parmetros para executarem a tarefa. Dentro do bloco de instrues da funo, primeiramente declara-se e inicializa-se as variveis locais e posteriormente temos os comandos da funo (instrues). O comando return encerra a funo e retorna ao ponto do programa onde esta foi chamada. No entanto, return no precisa ser o ltimo comando da funo. Infelizmente, uma funo em C s pode retornar um resultado e este repassado atravs de return. Algumas linguagens, como Matlab, permitem que uma funo retorne mais do que uma nica varivel contendo o resultado.
Marcelo Ricardo Stemmer
72

Informtica Industrial I

DAS/UFSC

Funes com tipo de retorno void, no utilizam o comando return pois estas no retornam nenhum tipo de dado. O comando return utilizado quando queremos finalizar esta funo antes de executar todas as instrues. Neste caso, ele aparece sem nenhum parmetro a sua direita, somente o ponto-e-vrgula. Quando uma funo no tem um tipo de retorno definido, o compilador C considera que o tipo de retorno adotado void. Do mesmo modo que chamamos uma funo de biblioteca C (printf(), getche(), ...) chamamos nossas prprias funes. Os parnteses que seguem o nome so necessrios para que o compilador possa diferenciar a chamada a uma funo de uma varivel que voc esqueceu de declarar. Visto que a chamada de uma funo constitui uma instruo de programa, deve ser encerrada por ponto-e-vrgula. Entretanto, na definio de uma funo, o ponto-e-vrgula no pode ser usado.

4.7.2 Exemplos
Abaixo apresentamos um exemplo do emprego das funes:
/* Beeptest - Exemplo do uso de funes */ /* Testa a funo doisbeep */ #include <stdio.h> /* doisbeep() */ /* toca o alto-falante duas vezes */ doisbeep() { int k; printf("\x7"); /* Beep 1 */ for(k=1; k<10000; k++) /* Gera um pequeno delay */ ; printf("\x7"); /* Beep 2 */ } /* funo principal */ void main() { doisbeep(); printf("Digite um caracter: "); getche(); doisbeep(); }

A declarao da funo doisbeep() equivalente a seguinte declarao:


void doisbeep(void)

Isto acontece pois quando o tipo retornado ou o parmetro for void (representando que nenhum dado ser passado), estes podem ser omitidos j que C considera este tipo como default. Em C, todos os argumentos de funes so passados por valor. Isto significa que funo chamada dada uma cpia dos valores dos argumentos, e ela cria outras variveis temporrias para armazenar estes valores. A diferena principal que, em C, uma funo chamada no pode alterar o valor de uma varivel da funo que chama; ela s pode alterar sua cpia temporria. C permite a criao de funes recursivas, isto , uma funo que dentro do seu corpo de instrues {} existe uma chamada de funo a si prpria. Este caso funciona como uma chamada para uma outra funo qualquer. Basta que, na definio da funo, voc faa uma chamada a prpria funo e voc j ter implementado uma funo recursiva. Entretanto, tenha cuidado com funes recursivas para no fazer com que o programa entre em loops infinitos. Exemplo:
Marcelo Ricardo Stemmer
73

Informtica Industrial I

DAS/UFSC

long int Fatorial(long int i) { if(i > 1) return i*Fatorial(i-1); else return 1; }

Cada chamada recursiva da funo fatorial coloca mais uma varivel i do tipo long int na pilha (stack). portanto necessrio ter cuidado com funes recursivas, pois estas podem causar um estouro da pilha.
/* Esfera - Exemplo de funo */ /* calcula a rea da esfera */ #include <stdio.h> float area(float r); /* declarao do prottipo da funo */ float potencia(float num, int pot); void main() { float raio = 0; printf("Digite o raio da esfera: "); scanf("%f", &raio); printf("A area da esfera e' %.2f", area(raio)); } /* area() */ /* retorna a rea da funo */ float area(float r) /* definio da funo */ { return (4*3.14159*potencia(r,2)); /* retorna float */ } /* potencia() */ /* eleva a uma potncia positiva, um parmetro dado */ float potencia(float num, int pot) { float result = 0; /* declarao de var. local */ int i = 0; if(pot < 0) return 0; /* Indica que houve erro */ if(pot == 0) return 1; result = num; for(i = 1; i < pot; i++) result *= num; return result; }

4.7.3 Prototipagem
Toda funo que for utilizada em main() e que for declarada aps main(), tem que ser prototipada. O prottipo consiste de uma verso simplificada do cabealho da funo, na forma:
<tipo retorno> <nome da funo> (<tipo dos parmetros>);

Marcelo Ricardo Stemmer

74

Informtica Industrial I

DAS/UFSC

Se main() for declarado por ltimo, nenhuma prototipagem necessria. Prottipos so tambm utilizados para escrever programas compostos de vrios mdulos, como veremos mais a frente. Feita a declarao do prottipo da funo, esta poder ser chamada ou definida em qualquer parte do seu programa, por isso que o prottipo de uma funo tem um papel importante para a organizao e flexibilidade do seu cdigo fonte. O programa anterior e o exemplo abaixo apresentam a forma de se criar o prottipo de uma funo.
double Raiz(double); /* prottipo */ main() { double x,y; x = 4.0; y = Raiz(x); } double Raiz(double valor) { /* <calculo da raiz de valor>; */ return valor; }

4.7.4 Classes de Armazenamento


Todas as variveis e funes em C tm dois atributos: um tipo e uma classe de armazenamento. Os tipos ns j conhecemos. As 4 classes de armazenamento sero vistas a seguir: auto, extern, static e register.

4.7.4.1

Auto

As variveis que temos visto em todos os nossos exemplos esto confinadas nas funes que as usam; isto , so visveis ou acessveis somente s funes onde esto declaradas. Tais variveis so chamadas locais ou automticas e so criadas quando a funo chamada e destrudas quando a funo termina a sua execuo. As variveis declaradas dentro de uma funo so automticas por default. Variveis automticas so as mais comuns dentre as 4 classes. A classe de variveis automticas pode ser explicitada usando-se a palavra auto. As duas declaraes abaixo so equivalentes:
auto int n; int n;

4.7.4.2

Extern

Todas as funes C e todas as variveis declaradas fora de qualquer funo tm a classe de armazenamento extern. Variveis com este atributo sero conhecidas por todas as funes declaradas depois dela. A declarao de variveis externas feita da mesma maneira como declaramos variveis dentro do bloco de uma funo. Uma varivel definida fora de qualquer funo dita extern. A palavra extern indica que a funo usar mais uma varivel externa. Este tipo de declarao, entretanto, no obrigatrio se a definio original ocorre no mesmo arquivo fonte. Abaixo temos um exemplo:
/* Exemplo da varivel de tipo extern */ #include <stdio.h>
Marcelo Ricardo Stemmer
75

Informtica Industrial I

DAS/UFSC

/* Declarao de variveis extern */ int teclanum; /* Declarao de funes */ void parimpar(void); void main() { extern teclanum; printf("Digite teclanum: "); scanf("%d", &teclanum); parimpar(); } /* parimpar() */ /* checa se teclanum par ou impar */ void parimpar(void) { extern teclanum; if(teclanum % 2) printf("teclanum e' impar. \n"); else printf("teclanum e' par. \n"); }

4.7.4.3

Static

Variveis static de um lado se assemelham s automticas, pois so conhecidas somente as funes que as declaram e de outro lado se assemelham s externas pois mantm seus valores mesmo quando a funo termina. Declaraes static tm dois usos importantes e distintos. O mais elementar permitir a variveis locais reterem seus valores mesmo aps o trmino da execuo do bloco onde esto declaradas.
/* uso do tipo static */ #include <stdio.h> /* declarao de prottipo */ void soma(); void main() { soma(); soma(); soma(); } /* soma() */ /* usa varivel static */ void soma() { static int i = 0; i++;
Marcelo Ricardo Stemmer
76

Informtica Industrial I

DAS/UFSC

printf("i = %d\n", i); }

Observe que i no inicializada a cada chamada de soma(). Portanto, a sada ser:


i = 0 i = 1 i = 2

4.7.4.4

Variveis Estticas Externas

O segundo e mais poderoso uso de static associado a declaraes externas. Junto a construes externas, permite um mecanismo de privacidade muito importante programao modular. A diferena entre variveis externas e externas estticas que variveis externas podem ser usadas por qualquer funo abaixo de (a partir das) suas declaraes, enquanto que variveis externas estticas somente podem ser usadas pelas funes de mesmo arquivo-fonte e abaixo de suas declaraes. Isto , voc pode definir uma varivel static em um arquivo fonte onde esto todas as funes que necessitam acesso a esta varivel. Os demais arquivos fontes no tero acesso a ela.

4.7.4.5

Register

A classe de armazenamento register indica que a varivel associada deve ser guardada fisicamente em um lugar onde possa ser acessada muito mais rapidamente. No caso das variveis tipo register, isto feito diretamente em um registrador da CPU. Um registrador da mquina uma rea da CPU onde pode-se armazenar variveis do tipo inteiro ou char. Opera como uma varivel do tipo auto, mas possui um tempo de acesso muito menor, isto , o programa torna-se mais rpido usando register. Variveis que usualmente utilizam este tipo so as variveis de laos e argumentos de funes, justamente, para que possamos aumentar a velocidade do programa. Como os computadores possuem um nmero limitados de registradores (depende da CPU em uso), o seu programa tambm s poder utilizar um nmero limitado de variveis register. Mas isto no nos impede de declarar quantas variveis register quisermos. Se todos os registradores estiverem ocupados o computador simplesmente ignora a palavra register das nossas declaraes.
register int i; for(i = 0; i< 10; i++) printf(Nmero: %d, i);

4.7.5 Exerccios
7.1. Um nmero primo qualquer inteiro positivo divisvel apenas por si prprio e por 1. Escreva uma funo que receba um inteiro positivo e, se este nmero for primo, retorne 1, caso contrrio retorne 0. Faa um programa que imprima na tela os n primeiros nmeros primos, onde n ser fornecido pelo usurio. 7.2. Crie um programa para gerar nmeros aleatrios, utilizando variveis static para armazenar o valor da semente.

Marcelo Ricardo Stemmer

77

Informtica Industrial I

DAS/UFSC

7.3. Crie um programa para calcular o fatorial de um nmero, para tal implemente uma funo recursiva. 7.4. Escreva um programa que solicite ao usurio um ano e imprima o calendrio desse ano. Utilize os programas desenvolvidos nos exerccios 4.2 e 4.3. Organize o programa de forma adequada atravs de funes. 7.5. Escreva uma funo recursiva de nome soma() que receba um nmero inteiro positivo n como argumento e retorne a soma dos n primeiros nmeros inteiros. Por exemplo, se a funo recebe n = 5, deve retornar 15, pois:
15 = 1 + 2 + 3 + 4 + 5

4.8 Diretivas do Pr-Processador


O pr-processador C um programa que examina o cdigo fonte em C e executa certas modificaes nele, baseado em instrues chamadas diretivas. O pr-processador faz parte do compilador e pode ser considerado uma linguagem dentro da linguagem C. Ele executado automaticamente antes da compilao. Diretivas do pr-processador seriam instrues desta linguagem. As instrues desta linguagem so executadas antes do programa ser compilado e tm a tarefa de alterar os cdigos-fonte, na sua forma de texto. Instrues para o pr-processador devem fazer parte do texto que criamos, mas no faro parte do programa que compilamos, pois so retiradas do texto antes da compilao. Diretivas do pr-processador so instrues para o compilador propriamente dito. Mais precisamente, elas operam diretamente no compilador antes do processo de compilao ser iniciado. Linhas normais de programa so instrues para o microprocessador; diretivas do pr-processador so instrues para o compilador. Todas as diretivas do pr-processador so iniciadas com o smbolo # (sustenido). As diretivas podem ser colocadas em qualquer parte do programa, mas costume serem colocadas no incio do programa, antes de main(), ou antes do comeo de uma funo particular.

4.8.1 Diretiva #define


A diretiva #define pode ser usada para definir constantes simblicas com nomes apropriados. Por exemplo, podemos criar uma constante para conter o valor de pi:
#define PI 3.14159

e depois utilizar o valor desta constante no programa:


area_esfera = (4*raio*raio*PI);

Quando o compilador encontra #define, ele substitui cada ocorrncia de PI no programa por 3.14159. O primeiro termo aps a diretiva #define (PI), que ser procurada, chamada identificador. O segundo termo (3.14159), que ser substituda, chamada texto. Um ou mais espaos separam o identificador do texto. Note que s podemos escrever um comando deste tipo por linha. Observe tambm que no h ponto-e-vrgula aps qualquer diretiva do pr-processador. A diretiva #define pode ser usada no s para definir constantes, como mostra o exemplo seguinte:
#include <stdio.h> #define ERRO printf("\n Erro.\n")

Marcelo Ricardo Stemmer

78

Informtica Industrial I

DAS/UFSC

void main() { int i; printf("\nDigite um numero entre 0 a 100: "); scanf("%d", &i); if(i<0||i>100) ERRO; }

4.8.2 Macros
A diretiva #define tem a habilidade de usar argumentos. Uma diretiva #define com argumentos chamada de macro e bastante semelhante a uma funo. Eis um exemplo que ilustra como um macro definido e utilizado:
/* Exemplo do uso de Macros*/ #include <stdio.h> #define PRN(n) printf("%.2f\n",n); void main() { float num1 = 27.25; float num2; num2 = 1.0/3.0; PRN(num1); PRN(num2); }

Quando voc usar a diretiva #define nunca deve haver espao em branco no identificador. Por exemplo, a instruo
#define PRN (n) printf(%.2f\n,n)

no trabalhar corretamente, porque o espao entre PR e (n) interpretado como o fim do identificador. Para definir um texto muito grande devemos delimitar a linha anterior com uma barra invertida \ e prosseguir com a definio em outra linha. Toda ocorrncia de PRN(n) em seu programa substituda por printf(%.2f\n,n). O n na definio do macro substitudo pelo nome usado na chamada ao macro em seu programa, portanto PRN(num1) ser substitudo por printf(%.2f\n,num1). Assim, n age realmente com um argumento. Macros aumentam a clareza do cdigo, pois permitem a utilizao de nomes sugestivos para expresses. Por segurana, coloque parnteses envolvendo o texto todo de qualquer diretiva #define que use argumentos, bem como envolvendo cada argumento. Por exemplo:
#define SOMA(x,y) x+y ans = 10 * SOMA(3,4);

O compilador substitura SOMA(3,4) por 3+4, e o computador executar:


ans = 10 * 3+4;

ou seja, um erro. Para evitar isto, voc deve definir a macro da seguinte forma:
#define SOMA(x,y) ((x)+(y))

Como macros so simples substituies dentro dos programas, o seu cdigo aparecer em cada ponto do programa onde forem usadas. Assim, a execuo do programa ser mais rpida que a chamada a uma funo toda vez que se fizer necessrio. Em contrapartida, o cdigo do programa
Marcelo Ricardo Stemmer
79

Informtica Industrial I

DAS/UFSC

ser aumentado, pois o cdigo do macro ser duplicado cada vez que o macro for chamado. Outra vantagem do uso de macros a no necessidade de especificar o tipo do dado.

4.8.3 Diretiva #undef


A diretiva #undef remove a mais recente definio criada com #define.
#define #define #define ... #undef #define ... #undef ... #undef ... #undef GRANDE ENORME SOMA(x,y) GRANDE ENORME 10 ENORME ENORME SOMA 3 8 ((x)+(y)) /* cancela a definio de GRANDE /* redefine ENORME para o valor 10 /* ENORME volta a valer 8 /* cancela a definio de ENORME /* cancela a macro SOMA */ */ */ */ */

Observe que, para remover um macro, somente o nome do macro deve constar na diretiva #undef. No deve ser includa a lista de argumento.

4.8.4 Diretiva #include


A diretiva #include causa a incluso de uma cdigo fonte em outro. Aqui est o exemplo de sua utilidade: suponha que voc escreveu vrias frmulas matemticas para calcular reas de diversas figuras. Os arquivos de incluso so textos escritos em caracteres ASCII normais, criados geralmente para incorporar definies de constantes, macros, prottipos de funes, definies de tipos de dados complexos e declaraes de variveis externas. Geralmente, os arquivos de incluso tm um nome terminado com o sufixo .h (de header, cabealho). Por exemplo, o arquivo conio.h contm o prottipo das funes getch() e getche() e por esse motivo includo nos programas que fazem uso destas funes. Voc pode colocar estas frmulas em macros em um programa separado. No instante em que voc precisar reescrev-las para a utilizao em seu programa use a diretiva #include para inserir este arquivo no seu cdigo fonte. Exemplo:
#define #define #define #define PI AREA_CIRCULO(raio) AREA_RETANG(base,altura) AREA_TRIANG(base,altura) 3.14159 (PI*(raio)*(raio)) ((base)*(altura)) ((base)*(altura)/2)

Grave o programa acima como areas.h. Quando voc quiser utilizar estas macros, basta incluir nos seus outros programas uma das diretivas abaixo: #include <areas.h> /* para arquivos localizados na biblioteca do compilador */ #include areas.h /* para arquivos locais ou localizados na biblioteca do compilador */ O uso consciente das diretivas #define e #include podem melhorar muito o desempenho e a organizao do seus projetos de software. Procure explor-las para conhecer todo os seus potenciais.

Marcelo Ricardo Stemmer

80

Informtica Industrial I

DAS/UFSC

4.8.5 Compilao Condicional


O pr-processador oferece diretivas que permitem a compilao condicional de um programa. Elas facilitam o desenvolvimento do programa e a escrita de cdigos com maior portabilidade de uma mquina para outra ou de um ambiente a outro. So elas, as diretivas:
#if, #ifdef, #ifndef, #elif, #else e #endif

Cada diretiva #if deve terminar pela diretiva #endif. Entre #if e #endif pode ser colocado qualquer nmero de #elif, mas s se permite um nica diretiva #else. A diretiva #else opcional e, se estiver presente, deve ser a ltima anterior a #endif. Abaixo apresentamos um exemplo onde definimos o valor de uma constante com #define e depois a utilizamos para fazer uma compilao condicional :
#define DEBUG 1 ... #if DEBUG == 1 printf(\nERRO = , erro1); #elif DEBUG == 2 printf(\nERRO = , erro2); #else printf(\nERRO no documentado.); #endif

Para testar constantes definidas com #define que no tenham valor nenhum, podemos utilizar #ifdef e #ifndef. Por exemplo:
#define VERSAO_DEMO ... #ifdef VERSAO_DEMO #define NUM_REC 20 #include progdemo.h else #define NUM_REC MAXINT #include program.h #endif

O ltimo exemplo mostra como um nico programa-fonte pode gerar dois executveis diferentes: se a diretiva que define VERSAO_DEMO for inserida, o executvel poder manipular somente 20 registros e estar criada a verso demo de seu programa. Caso esta diretiva no esteja presente, o programa poder manipular o nmero mximo de registros. A diretiva #ifndef verifica a no-definio da constante. Por exemplo:
#ifndef WINDOWS #define VERSAO \nVerso DOS #else #define VERSAO \nVerso Windows #endif

4.8.6 Operador defined


Um alternativa ao uso de #ifdef e #ifndef o operador defined.
#if defined(UNIX) && !defined(INTEL_486) ... #endif
Marcelo Ricardo Stemmer
81

Informtica Industrial I

DAS/UFSC

4.8.7 Diretiva #error


A diretiva #error provoca uma mensagem de erro do compilador em tempo de compilao.
#if TAMANHO > TAMANHO1 #error Tamanho incompatvel #endif

4.8.8 diretiva #pragma


#pragma inline - indica ao compilador C a presena de cdigo Assembly no arquivo. #pragma warn - indica ao compilador C para ignorar "warnings" (avisos)

4.8.9 Exerccios
8.1. Escreva uma macro que tenha valor 1 se o seu argumento for um nmero mpar, e o valor 0 se for par. 8.2. Escreva uma macro que encontre o maior entre seus trs argumentos. 8.3. Escreva uma macro que tenha valor 1 se o seu argumento for um caractere entre 0 e 9, e 0 se no for. 8.4. Escreva uma macro que converta um dgito ASCII entre 0 e 9 a um valor numrico entre 0 e 9. 8.5. Escreva um programa que solicite ao usurio uma letra e retorne o nmero equivalente desta letra na tabela ASCII em decima e hexadecimal. Utilize a compilao condicional para gerar um programa com interface para diferentes lnguas, por exemplo uma para portugus e outra para ingls. Caso nenhuma das duas for definidas, gere um erro de compilao. Dica, coloque o texto de cada lngua em um header diferente. Por exemplo, os textos em portugus ficam definidos em progport.h e os textos em ingls em progingl.h 8.6. Faa com que o programa do exerccio 7.4, escreva o calendrio de um ano qualquer dado pelo usurio em trs lnguas diferentes: alemo, ingls e portugus. Utilize a mesma idia que o programa anterior.

4.9 Matrizes
Uma matriz um tipo de dado usado para representar uma certa quantidade de variveis de valores homogneos. Imagine que voc esteja precisando armazenar e manipular as notas de um ano inteiro de um conjunto de 40 alunos. Voc certamente precisar de uma maneira conveniente para referenciar tais colees de dados similares. Matriz o tipo de dado oferecido por C para este propsito. Um matriz uma srie de variveis do mesmo tipo referenciadas por um nico nome, onde cada varivel diferenciada atravs de um nmero chamado subscrito ou ndice. Colchetes so usados para conter o subscrito. A declarao:
int notas[5];

aloca memria para armazenar 5 inteiros e anuncia que notas uma matriz de 5 membros ou elementos.
Marcelo Ricardo Stemmer
82

Informtica Industrial I

DAS/UFSC

Vamos agora fazer um programa que calcula a mdia das notas da prova do ms de Junho de 5 alunos.
/* Exemplo de matrizes /* mdia das notas de 5 alunos #include #define <stdio.h> NUM_ALUNOS */ */

void main() { int notas[NUM_ALUNOS]; /* Declarao de matrizes */ int i, soma; for(i=0; i<NUM_ALUNOS; i++) { printf("Digite a nota do aluno %d: ", i); scanf("%d", &notas[i]); /* atribuindo valores a matriz */ } soma = 0; for(i=0; i<NUM_ALUNOS; i++) soma = soma + notas[i]; /* lendo os dados da matriz */ printf("Media das notas: %d.", soma/NUM_ALUNOS); }

4.9.1 Sintaxe de Matrizes


As dimenses so definidas entre colchetes, aps a definio convencional do tipo de varivel.
<Tipo> <nome> [<dimenso1>] [<dimenso2>] ... ;

Em C, matrizes precisam ser declaradas, como quaisquer outras variveis, para que o compilador conhea o tipo de matriz e reserve espao de memria suficiente para armazen-la. Os elementos da matriz so guardados numa seqncia contnua de memria, isto , um seguido do outro. O que diferencia a declarao de uma matriz da declarao de qualquer outra varivel a parte que segue o nome, isto , os pares de colchetes [ e ] que envolvem um nmero inteiro, que indica ao compilador o tamanho da matriz. A dimenso da matriz vai depender de quantos pares de colchetes a declarao da matriz tiver. Por exemplo:
int notas[5]; /* declarao de uma matriz unidimensional = vetor */ unsigned float tabela[3][2]; /* matriz bidimensional */ char cubo[3][4][6]; /* matriz tridimensional */

Analisando-se a primeira declarao: a palavra int declara que todo elemento da matriz do tipo int, notas o nome dado a matriz e [5] indica que a nossa matriz ter 5 elementos do tipo int. Por definio uma matriz composta por elementos de um nico tipo. O acesso aos elementos da matriz feito atravs do nmero entre colchetes seguindo o nome da matriz. Observe que este nmero tem um significado diferente quando referencia um elemento da matriz e na declarao da matriz, onde indica o seu tamanho. Quando referenciamos um elemento da matriz, este nmero especifica a posio do elemento na matriz. Os elementos da matriz so sempre numerados por ndices iniciados por 0 (zero). Assim, o elemento referenciado pelo nmero 2
Marcelo Ricardo Stemmer
83

Informtica Industrial I

DAS/UFSC

notas[2]

no o segundo elemento da matriz mas sim o terceiro, pois a numerao comea em 0. Assim o ltimo elemento da matriz possui um ndice, uma unidade menor que o tamanho da matriz. O acesso com notas[i] pode ser tanto usado para ler ou escrever um dado na matriz. Voc pode tratar este elemento como um varivel simples, no caso de notas[i], como uma varivel inteira qualquer. Como proceder caso voc no conhea a quantidade de termos que voc precisa para a sua matriz? Aplique a idia apresentada no programa exemplo acima, com a diretiva:
#define NUM_ALUNOS 5

para alocar um nmero maior de termos, de forma a possuir espao suficiente alocado para conter todos os possveis termos da matriz. Ateno: A linguagem C no realiza verificao de limites em matrizes; por isto nada impede que voc v alm do fim da matriz. Se voc transpuser o fim da matriz durante uma operao de atribuio, ento atribuir valores a outros dados ou at mesmo a uma parte do cdigo do programa. Isto acarretar resultados imprevisveis e nenhuma mensagem de erro do compilador avisar o que est ocorrendo. Como programador voc tem a responsabilidade de providenciar a verificao dos limites, sempre que necessrio. Assim a soluo no permitir que o usurio digite dados para elementos da matriz acima do limite.

4.9.2 Inicializando Matrizes


Em C a inicializao de uma matriz feita em tempo de compilao. Matrizes das classes extern e static podem ser inicializadas. Matrizes da classe auto no podem ser inicializadas. Lembre-se de que a inicializao de uma varivel feita na instruo de sua declarao e uma maneira de especificarmos valores iniciais pr-fixados. O programa a seguir exemplifica a inicializao de uma matriz:
/* exemplo de inicializao de matrizes /* programa que produz troco #include #define <stdio.h> LIM */ */

void main() { int d, valor, quant; static int tab[] = {50, 25, 10, 5, 1}; printf("Digite o valor em centavos: "); scanf("%d", &valor); for(d=0; d<LIM; d++) { quant = valor/tab[d]; printf("Moedas de %d centavos = %2d\n", tab[d], quant); valor %= tab[d]; } }

A instruo que inicializa a matriz :


static int tab[] = {50, 25, 10, 5, 1};

Marcelo Ricardo Stemmer

84

Informtica Industrial I

DAS/UFSC

A lista de valores colocada entre chaves e os valores so separados por vrgulas. Os valores so atribudos na seqncia, isto , tab[0] = 50, tab[1] 25, tab[2] 10 e assim por diante. Note que no foi necessria a declarao da dimenso da matriz. Caso tivssemos escrito explicitamente a dimenso da matriz, esta deveria se maior ou igual a dimenso fornecida pelo colchetes. Se h menos inicializadores que a dimenso especificada, os outros sero zero. um erro ter-se mais inicializadores que o necessrio. Se em seu programa voc deseja inicializar uma matriz, voc deve criar uma varivel que existir durante toda a execuo do programa. As classes de variveis com esta caracterstica so extern e static. A linguagem C permite matrizes de qualquer tipo, incluindo matrizes de matrizes. Por exemplo, uma matriz de duas dimenses uma matriz em que seus elementos so matrizes de uma dimenso. Na verdade, em C, o termo duas dimenses no faz sentido pois todas as matrizes so de uma dimenso. Usamos o termo mais de uma dimenso para referncia a matrizes em que os elementos so matrizes. As matrizes de duas dimenses so inicializadas da mesma maneira que as de dimenso nica, isto , os elementos (matrizes) so colocados entre as chaves depois do sinal de igual e separados por vrgulas. Cada elemento composto por chaves e seus elementos internos separados por vrgulas. Como exemplo segue abaixo uma matriz bidimensional:
char tabela[3][5] { {0, 0, 0, {0, 1, 1, {1, 1, 0, = 0, 0}, 1, 0}, 0, 1} };

Cada elemento da matriz tabela na verdade ser outra matriz, ento por exemplo:
tabela[2] == {1, 1, 0, 0, 1}

Da mesma maneira se aplica para matrizes de trs ou mais dimenses:


int tresd[3][2][4] = { { {1, 2, 3, 4} , {5, 6, 7, 8} }, { {7, 9, 3, 2} , {4, 6, 8, 3} }, { {7, 2, 6, 3} , {0, 1, 9, 4} } };

A matriz de fora tem trs elementos, cada um destes elementos uma matriz de duas dimenses de dois elementos onde cada um dos elementos uma matriz de uma dimenso de quatro nmeros. Como podemos acessar o nico elemento igual a 0 na matriz do exemplo anterior? O primeiro ndice [2], pois o terceiro grupo de duas dimenses. O segundo ndice [1], pois o segundo de duas matrizes de uma dimenso. O terceiro ndice [0], pois o primeiro elemento da matriz de uma dimenso. Ento, temos que a primitiva abaixo verdade:
Tresd[2][1][0] == 0

4.9.3 Matrizes como Argumentos de Funes


C permite passar um matriz como parmetro para uma funo. A seguir apresentamos o mtodo de Ordenao Bolha como exemplo de passagem de matrizes como argumentos. Este um mtodo famoso de ordenao de elementos em uma matriz devido a sua simplicidade e eficincia. A funo comea considerando a primeira varivel da matriz, list[0]. O objetivo colocar o menor item da lista nesta varivel. Assim, a funo percorre todos os itens restantes da lista, de list[1] a list[tam-1], comparando cada um com o primeiro item. Sempre que encontrarmos um item
Marcelo Ricardo Stemmer

85

Informtica Industrial I

DAS/UFSC

menor, eles so trocados. Terminada esta operao, tomado o prximo item, list[1]. Este item dever conter o prximo menor item. E novamente so feitas as comparaes e trocas. O processo continua at que a lista toda seja ordenada.
/* Ordena.c /* ordena os valores da matriz */ */

#include <stdio.h> #define TAMAX 30 void ordena(int list[], int tam); void main() { int list[TAMAX], tam=0, d; do { printf("Digite numero: "); scanf("%d", &list[tam]); } while(list[tam++] != 0); ordena(list, --tam); for(d=0; d<tam; d++) printf("%d\n", list[d]); } /* ordena(), ordena matriz de inteiros */ void ordena(int list[], int tam) { int register j, i; int temp; for(j = 0; j < tam-1; j++) for(i = j + 1; i < tam; i++) if(list[j] > list[i]) { temp = list[i]; list[i] = list[j]; list[j] = temp; } }

O nico elemento novo no programa acima a instruo:


ordena(list, --tam);

ela uma chamada funo ordena() que ordena os elementos de uma matriz segundo o mtodo bolha. Esta funo tem dois argumentos: o primeiro a matriz list e o segundo a varivel que contm o tamanho da matriz. A matriz foi passada como argumento da funo quando escrevemos somente o seu nome como parmetro da funo. Quando desejamos referenciar um elemento da matriz devemos acess-lo atravs do nome da matriz seguida de colchetes, onde o ndice do elemento escrito entre os colchetes. Entretanto se desejamos referenciar a matriz inteira, basta escrever o nome desta, sem colchetes. O nome de uma matriz desacompanhada de colchetes representa o endereo de memria onde a matriz foi armazenada. O operador & no pode ser aplicado a matriz para se obter o endereo desta, pois, a endereo da matriz j est referenciado no seu nome. Portanto, a instruo abaixo seria invlida:
Marcelo Ricardo Stemmer
86

Informtica Industrial I

DAS/UFSC

&list;

O operador & somente pode ser aplicado a um elemento da matriz. Portanto, a instruo:
int *ptr = &list[0];

ser vlido e ir retornar o endereo da primeira varivel da matriz. Como a rea de memria ocupada por uma matriz comea atravs do primeiro termo armazenado nesta, portanto, os endereos da matriz e do primeiro elemento sero equivalentes:
list == &list[0];

Assim, a funo ordena() recebe um endereo de uma varivel int e no um valor inteiro e deve declar-lo de acordo. O tipo :
int []

indica um endereo de uma varivel int.

4.9.4 Chamada Por Valor e Chamada Por Referncia


Quando um nome de uma simples varivel usado como argumento na chamada a uma funo, a funo toma o valor contido nesta varivel e o instala em uma nova varivel e em nova posio de memria criada pela funo. Portanto as alteraes que forem feitas nos parmetros da funo no tero nenhum efeito nas variaes usadas na chamada. Este mtodo conhecido como chamada por valor. Entretanto, as matrizes so consideradas um tipo de dado bastante grande, pois so formadas por diversas variveis. Por causa disto, a linguagem C determina ser mais eficiente existir uma nica cpia da matriz na memria, sendo portanto irrelevante o nmero de funes que a acessem. Assim, no so passados os valores contidos na matriz, somente o seu endereo de memria. Desta forma, a funo usa o endereo da matriz para acessar diretamente os elementos da prpria matriz da funo que chama. Isto significa que as alteraes que forem feitas na matriz pela funo afetaro diretamente a matriz original. Quando se passa o nome de uma matriz para uma funo, no se cria uma cpia dos dados desta mas sim, utiliza-se diretamente os dados da matriz original atravs do endereo passado. Esta tipo de passagem de parmetros denominado passagem de parmetros por referncia ou por endereo. A seguir apresentamos um exemplo de passagem de uma matriz bidimensional como parmetro de uma funo. O programa exemplo avalia a eficincia de funcionrios de uma loja, quanto ao nmero de peas vendidas por cada um. O primeiro ndice da matriz indica o nmero de funcionrios da loja e o segundo ndice, o nmero de meses a serem avaliados.
/* Exemplo da matrizes bidimensionais /* histograma horizontal #include <stdio.h> */ */

#define FUNC 4 /* numero de funcionrios */ #define MES 3 /* numero de meses */ #define MAXBARRA 50 /* tamanho mximo da barra */ void grafico(int p[][MES], int nfunc); /* declarao da funo */ void main() { int pecas[FUNC][MES]; /* declarao de matriz bidimensional*/ int i, j; for(i=0; i<FUNC; i++)
Marcelo Ricardo Stemmer

87

Informtica Industrial I

DAS/UFSC

for(j=0; j<MES; j++) { printf("Numero de pecas vendidas pelo funcionario"); printf("%d no mes %d: ", i+1, j+1); scanf("%d", &pecas[i][j]); } grafico(pecas, FUNC); } /* grafico(), desenha um histograma */ void grafico(int p[][MES], int nfunc) { int register i, j; int max, tam = 0, media[FUNC]; for(i=0; i<nfunc; i++) { media[i] = 0; for(j=0; j<MES; j++) media[i] += p[i][j]; media[i] /= MES; } max = 0; for(i = 0; i< nfunc; i++) if(media[i]>max) max = media[i]; printf("\n\n\n\n FUNC - MEDIA\n--------------\n"); for(i=0;i<FUNC; i++) { printf("%5d - %5d : ", i+1, media[i]); if(media[i]>0) { if((tam=(int)(((float)media[i])*MAXBARRA/max)) <= 0) tam = 1; } else tam = 0; for(; tam>0; --tam) printf("%c", '>'); printf("\n"); } }

O mtodo de passagem do endereo da matriz para a funo idntico ao da passagem de uma matriz de uma dimenso, no importando quantas dimenses tem a matriz, visto que sempre passamos o seu endereo.
grafico(pecas, FUNC);

Como no h verificao de limites, uma matriz com a primeira dimenso de qualquer valor pode ser passada para a funo chamada. Mas uma funo que recebe uma matriz bidimensional dever ser informada do comprimento da segunda dimenso para saber como esta matriz est organizada na memria e assim poder operar com declaraes do tipo:
pecas[2][1]

pois, para encontrar a posio na memria onde pecas[2][1] est guardada, a funo multiplica o primeiro ndice (2) pelo nmero de elementos da segunda dimenso (MES) e adiciona o segundo

Marcelo Ricardo Stemmer

88

Informtica Industrial I

DAS/UFSC

ndice (1), para finalmente somar ao endereo da matriz (pecas). Caso o comprimento da segunda matriz no seja conhecido, ser impossvel saber onde esto os valores.

4.9.5 Strings
C no possui um tipo de dado especial para tratar strings. Desta forma, uma das aplicaes mais importante de matrizes em C justamente a criao do tipo string, caracterizado por uma seqncia de caracteres armazenados terminados por \0 (que possui o valor 0 na tabela ASCII) em uma matriz. Por esta razo que C no fornece uma estrutura amigvel para a manipulao de string comparada com outras linguagens como Pascal, por exemplo. Somente com o advento da orientao a objetos (C++) que C veio a fornecer uma estrutura amigvel e flexvel para tratar strings. Esta estrutura ser vista somente nos captulos posteriores. Aqui, apresentaremos strings na sua forma bsica em C. String uma matriz tipo de char que armazena um texto formado de caracteres e sempre terminado pelo caractere zero (\0). Em outras palavras, string uma srie de caracteres, onde cada um ocupa um byte de memria, armazenados em seqncia e terminados por um byte de valor zero (\0). Cada caracter um elemento independente da matriz e pode ser acessado por meio de um ndice.

4.9.5.1

Strings Constantes

Qualquer seqncia de caracteres delimitadas por aspas duplas considerada pelo compilador como uma string constante. O compilador aloca uma matriz com tamanho uma (1) unidade maior que o nmero de caracteres inseridos na string constante, armazenando estes caracteres nesta matriz e adicionando automaticamente o caracter delimitador de strings \0 no final da matriz. Vrios exemplos de strings constantes esto presentes ao longo deste texto, tais como : printf(Bom Dia!!!!); O importante lembrar que o compilador sempre adiciona o caracter \0 a strings constantes antes de armazen-las na forma de matriz para poder marcar o final da matriz. Observe que o caracter \0, tambm chamado de NULL, tem o valor zero decimal (tabela ASCII), e no se trata do caracter 0, que tem valor 48 decimal (tabela ASCII). A terminao \0 importante, pois a nica maneira que as funes possuem para poder reconhecer onde o fim da string.

4.9.5.2

String Variveis

Um das maneiras de receber uma string do teclado atravs da funo scanf() pelo formato %s. A funo scanf() l uma string at voc apertar a tecla [enter], adiciona o caracter \0 e armazena em uma matriz de caracteres. Perceba que o endereo da matriz e passado escrevendo-se somente o nome da matriz. Abaixo apresentamos um exemplo, onde fica claro que se voc digitar uma frase com um nmero maior de caracteres do que a matriz alocada, (char[15]) um erro de memria ir ocorrer. Isto se deve ao fato de scanf() no testar a dimenso de matriz e simplesmente adquirir uma seqncia de caracteres at encontrar um caracter [enter], espao simples ou tabulao. Depois ela armazena a string na matriz fornecida, sem testar a dimenso da matriz. A definio de uma string segue o mesmo formato da definio de matrizes, entretanto o tipo empregado o tipo char.
/* string 1, l uma string do teclado e imprime */ #include <stdio.h> void main() { char nome[15]; /* declara uma string com 15 caracteres */
Marcelo Ricardo Stemmer

89

Informtica Industrial I

DAS/UFSC

printf("Digite seu nome: "); scanf("%s", nome); printf("Saudacoes, %s.", nome); }

Se voc escrever Pedro Silva no programa acima, a funo scanf() ir eliminar o segundo nome. Isto se deve ao fato de que scanf() utiliza qualquer espao, quebra de linha ou tabulao para determinar o fim da leitura de uma string. Neste caso, a funo gets() se aplica de forma mais eficiente para a aquisio de strings. A funo gets() adquire uma string at ser pressionada a tecla [enter], adicionando o caracter \0 para especificar o fim da string e armazen-la em uma matriz. Desta forma podemos utilizar gets() para ler strings com espaos e tabulaes. Para imprimir strings utilizamos as duas funes principais printf() e puts(). O formato de impresso de strings com prinf() ns j conhecemos, basta escrever o parmetro %s no meio da string de formatao de printf() e posteriormente passar o nome da matriz de caracteres, terminada com \0, como parmetro. Puts() tem uma sintaxe bem simples tambm. Chamando a funo puts() e passandose o nome da matriz de caracteres terminada por \0 como parmetro, teremos a string impressa na tela (sada padro) at encontrar o caracter \0. Aps a impresso, puts() executa uma quebra de linha automaticamente [enter], o que impossibilita a sua aplicao para escrever duas strings na mesma linha. Abaixo , temos um exemplo:
char nome[] = Alexandre Orth; puts(nome);

Em C, a inicializao formal de strings ocorre da mesma maneira que para uma matriz, ou seja, inicializamos termo por termo como a seguir:
char text[] = {B, o, m, , d, i, a, !, \0};

C fornece ainda uma maneira simples, que foi apresentada no exemplo anterior. Note que, na inicializao formal, temos que adicionar explicitamente o caracter \0 para determinar o fim da matriz. J na forma simples, o compilador faz isto automaticamente para voc.

4.9.5.3

Funes para Manipulao de Strings

Em C existem vrias funes para manipular matrizes e tentar tornar a vida do programador um pouco mais fcil. Veremos aqui as 4 funes principais: strlen(), strcat(), strcmp() e strcpy(). Note que estas funes exigem que o caracter \0 esteja delimitando o final da string. A funo strlen() aceita um endereo de string como argumento e retorna o tamanho da string armazenada a partir deste endereo at um caractere antes de 0, ou seja, ela retorna o tamanho da matriz que armazena a string menos um, descontando assim o caracter de final da string \0. Sintaxe de strlen(): strlen(string); A funo strcat() concatena duas strings, isto , junta uma string ao final de outra. Ela toma dois endereos de strings como argumento e copia a segunda string no final da primeira e esta combinao gera uma nova primeira string. A segunda string no alterada. Entretanto, a matriz da primeira string deve conter caracteres livres (ou seja, caracteres alocados localizados aps o delimitador de final de string \0) suficientes para armazenar a segunda string. A funo

Marcelo Ricardo Stemmer

90

Informtica Industrial I

DAS/UFSC

strcat() no verifica se a segunda string cabe no espao livre da primeira. Sintaxe de strcat(): strcat(string1, string2); A funo strcmp() compara duas strings e retorna:
< 0 0 > 0 : : : no caso da string 1 < que a string 2 no caso da string 1 = a string 2 no caso da string 1 > que a string2

Neste contexto, menor que (<) ou maior que (>) indica que, se voc colocar string1 e string2 em ordem alfabtica, o que aparecer primeiro ser menor que o outro. Sintaxe de strcmp(): strcmp(string1, string2); A funo strcpy() simplesmente copia uma string para outra. Note, que a string1 deve conter espao suficiente para armazenar os dados da string2. Sintaxe da funo strcpy(): strcpy(string1, string2); Abaixo vamos mostrar um exemplo que apagar um caracter do interior de uma string. Neste exemplo vamos implementar a funo strdel() que move, um espao esquerda, todos os caracteres que esto a direita do caracter sendo apagado.
/* delete, apaga caractere de uma string */ #include <stdio.h> void strdel(char str[], int n); void main() { char string[81]; int posicao; printf("Digite string, [enter], posicao\n"); gets(string); scanf("%d", &posicao); strdel(string, posicao); puts(string); } /* strdel(), apaga um caractere de uma string */ void strdel(char str[], int n) { strcpy(&str[n], &str[n+1]); }

4.9.6 Exerccios
9.1. Crie um programa para calcular a matriz transposta de uma dada matriz. Aloque uma memria para uma matriz bidimensional com dimenso mxima de 10x10. Crie uma funo para inicializar a matriz com zero. Depois questione o usurio para sob a dimenso da matriz que ele deseja calcular a transposta, considerando a dimenso mxima permitida. Depois, adquira os valores dos termos que compem a matriz, solicitando ao usurio que fornea estes dados. Por fim, calcule a transporta da matriz e escreva na tela o resultado final da matriz.
Marcelo Ricardo Stemmer
91

Informtica Industrial I

DAS/UFSC

9.2. Continue o programa anterior e agora calcule o tamanho de memria alocada para a matriz e que no est sendo utilizada. Ou seja, considerando o tipo de dado da matriz, que a matriz inicial tem tamanho 10x10 e o tamanho utilizado pelo usurio, quantos bytes de memria o computador alocou para a matriz e quantos bytes de memria o usurio realmente utilizou. Crie uma funo que calcule este dado comparando duas matrizes de dimenses quaisquer. Reflita sobre este problema. 9.3. A decomposio LDU uma decomposio famosa de matrizes aplicada para calcular inversas de matrizes e resolver problemas de equaes lineares. Utilize o programa 9.1 e crie um programa que calcule a decomposio LDU de uma matriz, preferencialmente, com pivotamento. 9.4. Escreva uma funo que indique quantas vezes aparece um determinado caracter em uma dada string. 9.5. Escreva uma funo que localize um caracter em uma string e depois o substitua por outro. 9.6. Escreva uma funo que insira um determinado character em uma determinada posio de uma string. 9.7. Escreva uma funo que retire todos os caracteres brancos, tabulaes ou nova linha [enter] de uma dada string. 9.8. Escreva um programa que converta todas os caracteres minsculos de uma string para o correspondente caracter maisculo. 9.9. Refaa o seu exerccio 6.2 para criar uma tabela com os seus horrios ocupados e compromissos na semana. Armazene o valor de cada compromisso atravs de uma tabela de strings. Inicialize a tabela com valor 0, e solicite ao usurio que fornea o seu horrio. Por fim, apresente na tela o resultado obtido.

4.10 Tipos Especiais de Dados


Em C podemos definir novos tipos de dados, adicionando complexidade aos tipos de dados j existentes. Com a finalidade de tornar a vida do programador mais fcil e permitir que este crie novos tipos de dados, compostos pelos tipos de dados j pr-existentes (char, int, float, double e matrizes destes tipos).

4.10.1

Typedef

Typedef nos apresenta a primeira forma de criar um novo tipo de dado. Typedef permite a definio de novos tipos de variveis. Os novos tipos so sempre compostos de uma ou mais variveis bsicas agrupadas de alguma maneira especial . Sintaxe:
typedef <tipo> <definio>;

Exemplo da definio de um novo tipo de dado:


typedef double real_array [10]; /* novo tipo */ real_array x, y; /* declara variveis tipo real_array */

Marcelo Ricardo Stemmer

92

Informtica Industrial I

DAS/UFSC

No exemplo acima, ambas x e y foram declaradas como sendo do tipo real-array e por isso, representam um vetor de valores reais (double) com capacidade para armazenar 10 dados deste tipo.

4.10.2

Enumerados (Enum)

Permitem atribuir valores inteiros seqenciais constantes. Tipos enumerados so usados quando conhecemos o conjunto de valores que uma varivel pode assumir. A varivel deste tipo sempre int e, para cada um dos valores do conjunto, atribumos um nome significativo para represent-lo. A palavra enum enumera a lista de nomes automaticamente, dando-lhes nmeros em seqncia (0, 1, 2, etc.). A vantagem que usamos estes nomes no lugar de nmeros, o que torna o programa mais claro. Abaixo apresentamos exemplos da aplicao de tipos enumerados e de suas definies:
/* Exemplo de tipos enumerados */ /* definio de novos tipos de dados */ enum dias { segunda, /* atribui: segunda = 0; */ terca, /* atribui: terca = 1; */ quarta, /* atribui: quarta = 2; */ quinta, /* atribui: quinta = 3; */ sexta, /* atribui: sexta = 4; */ sabado, /* atribui: sabado = 5; */ domingo /* atribui: domingo = 6; */ }; enum cores { verde = 1, azul = 2, preto, /* como no foi dado valor, recebe valor anterior + 1 = 3 */ branco = 7 }; enum boolean { false, /* false = 0 */ true /* true = 1 */ }; void main() { enum dias dia1, dia2; /* declara varivel "dias" do tipo enum */ enum boolean b1; /* declara varivel do tipo enum boolean */ dia1 = terca; dia2 = terca + 3; if (dia2 == sabado) b1 = true; }

/* dia2 = sexta */

A palavra enum define um conjunto de nomes com valores permitidos para esse tipo e enumera esses nomes a partir de zero (default) ou, como em nosso programa, a partir do primeiro valor fornecido. Se fornecemos um valor a alguns nomes e no a outros, o compilador atribuir o prximo valor inteiro aos que no tiverem valor. A sintaxe fica clara no exemplo acima.
Marcelo Ricardo Stemmer
93

Informtica Industrial I

DAS/UFSC

Um varivel de tipo enumerado pode assumir qualquer valor listado em sua definio. Valores no listados na sua definio no podem ser assumidos por esta varivel. Tipos enumerados so tratados internamente como inteiros, portanto qualquer operao vlida com inteiros permitida com eles.

4.10.3

Estruturas (Struct)

Structs permitem definir estruturas complexas de dados, com campos de tipos diferentes. Observe que nas matrizes (arrays), todos os campos so do mesmo tipo. As structs permitem, entretanto, criar elementos semelhantes a arrays, mas composta de elementos com tipos diferentes de dados. Por meio da palavra-chave struct definimos um novo tipo de dado. Definir um tipo de dado significa informar ao compilador o seu nome, o seu tamanho em bytes e o formato em que ele deve ser armazenado e recuperado na memria. Aps ter sido definido, o novo tipo existe e pode ser utilizado para criar variveis de modo similar a qualquer tipo simples. Abaixo apresentamos as duas sintaxe que podem ser empregadas para a definio de estruturas e para a declarao de variveis deste tipo: Sintaxe : struct <nome> /* Definio */ { <tipo> <nome campo>; }[<variveis deste tipo>]; /* Declarao de Variveis */ struct <nome> <nome varivel>; Exemplo : struct Dados_Pessoais { char Nome[81]; int Idade; float Peso; } P1; /* Declarao de Variveis */ struct Dados_Pessoais P2, P3; typedef struct Dados_Pessoais { char Nome [ 81]; int Idade; float Peso; } Pessoa; /* Declarao de variveis/ Pessoa P1, P2; Definir uma estrutura no cria nenhuma varivel, somente informa ao compilador as caractersticas de um novo tipo de dado. No h nenhuma reserva de memria. A palavra struct indica que um novo tipo de dado est sendo definido e a palavra seguinte ser o seu nome. Desta forma, faz-se necessrio a declarao de variveis deste tipo. Na primeira sintaxe, mostramos no exemplo como podemos declarar um varivel do tipo da estrutura Dados_Pessoais j na definio da estrutura (P1) e como podemos criar outras variveis deste tipo ao longo do programa (P2 e P3). J na segunda sintaxe, a forma da declarao de variveis deve ser sempre explcita, como mostrado no exemplo. Uma vez criada a varivel estrutura, seus membros podem ser acessados por meio do operador ponto. O operador ponto conecta o nome de uma varivel estrutura a um membro desta. Abaixo, fornecemos exemplos de acesso as variveis definidas por meio de estruturas:
gets(P1.Nome); P1.Idade = 41;
Marcelo Ricardo Stemmer
94

typedef struct <nome> /* Def.*/ { <tipo> <nome campo>; } <nome tipo>; /* Declarao de variveis/ <nome tipo> <nome varivel>;

Informtica Industrial I

DAS/UFSC

P3.Peso = 75.6;

A linguagem C trata os membros de uma estrutura como quaisquer outras variveis simples. Por exemplo, P1.Idade o nome de uma varivel do tipo int e pode ser utilizada em todo lugar onde possamos utilizar uma varivel int. A inicializao de estruturas semelhante inicializao de uma matriz. Veja um exemplo:
struct data { int dia; char mes[10]; int ano; }; data natal = { 25, Dezembro, 1994}; data aniversario = { 30, Julho, 1998};

Uma varivel estrutura pode ser atribuda atravs do operador igual (=) a outra varivel do mesmo tipo:
aniversario = natal;

Certamente constatamos que esta uma estupenda capacidade quando pensamos a respeito: todos os valores dos membros da estrutura esto realmente sendo atribudos de uma nica vez aos correspondentes membros da outra estrutura. Isto j no possvel, por exemplo, com matrizes. Estruturas no permitem operaes entre elas, somente entre os seus membros. Aps definirmos um tipo de dado atravs de uma estrutura, podemos incluir este tipo de dado como membro de uma outra estrutura. Isto cria o que chamamos tipos aninhados de estruturas, onde uma estrutura contm no seu interior como membro outra estrutura. Esta operao funciona assim como uma matriz bidimensional na verdade uma matriz de matrizes unidimensionais. Estruturas podem ser passadas para funes assim como qualquer outra varivel, sendo declarada e utilizada da mesma forma. Funes podem tambm retornar uma estrutura como o resultado do seu processamento. Para tal, basta declarar o tipo de retorno de uma funo como sendo um tipo declarado por uma struct. Esta uma forma de fazer com que uma funo retorne mais de um parmetro. Podemos criar uma matriz para estruturas assim como criamos uma matriz de um tipo qualquer, basta declarar o tipo da matriz como o tipo definido pela estrutura. A seguir apresentamos um exemplo envolvendo matrizes de estruturas, onde trataremos de uma matriz de estruturas que contm os dados necessrios para representar um livro. A forma de acesso aos membros da estrutura, armazenadas na matriz fica clara no exemplo. As funes atoi() e atof() apresentadas no exemplo abaixo servem para converter strings para um tipo inteiro ou float, respectivamente, e esto definidas em stdlib.
/* livros, mantm lista de livros na memria */ #include <stdio.h> #include <stdlib.h> /* para atof() e atoi() */ /* definio de tipos */ struct list { char titulo[30]; char autor[30]; int regnum;
Marcelo Ricardo Stemmer

95

Informtica Industrial I

DAS/UFSC

double };

preco;

/* declarao de variveis e funes */ struct list livro[50]; int n = 0; void novonome(); void listatotal(); void main() { char ch; while(1) { printf("\nDigite 'e' para adicionar um livro"); printf("\n'l' para listar todos os livros: "); ch = getche(); switch(ch) { case 'e' : novonome(); break; case 'l': listatotal(); break; default: puts("\nDigite somente opcoes validas!!!!"); } } } /* novonome(), adiciona um livro ao arquivo */ void novonome() { char numstr[81]; printf("\nRegistro %d. \nDigite titulo: ", n+1); gets(livro[n].titulo); printf("\nDigite autor: "); gets(livro[n].autor); printf("\nDigite o numero do livro (3 digitos): "); gets(numstr); livro[n].regnum = atoi(numstr); /* converte string p/ int */ printf("\nDigite preco: "); gets(numstr); livro[n].preco = atof(numstr); n++; } /* listatotal(), lista os dados de todos os livros */ void listatotal() { int i; if(!n) printf("\nLista vazia.\n"); else for(i=0; i<n; i++)
Marcelo Ricardo Stemmer
96

Informtica Industrial I

DAS/UFSC

{ printf("\nRegistro: %d.\n", i+1); printf("\nTitulo: %s.\n", livro[i].titulo); printf("\nAutor: %s.\n", livro[i].autor); printf("\nNumero do registro: %3d.\n", livro[i].regnum); printf("\nPreco: %4.3f. \n", livro[i].preco); } }

4.10.4

Unies

A palavra union usada, de forma semelhante a struct, para agrupar um nmero de diferentes variveis sob um nico nome. Entretanto, uma union utiliza um mesmo espao de memria a ser compartilhado com um nmero de diferentes membros, enquanto uma struct aloca um espao diferente de memria para cada membro. Em outras palavras, uma union o meio pelo qual um pedao de memria ora tratado como uma varivel de um certo tipo, ora como outra varivel de outro tipo. Por isso, unies so usadas para poupar memria e o seu uso no recomendado a no ser em casos extremamente necessrios, pois a utilizao irresponsvel das unies podem causar a perda de dados importantes do programa. Quando voc declara uma varivel do tipo union, automaticamente alocado espao de memria suficiente para conter o seu maior membro. Sintaxe:
union <nome> { <tipo> <campo1>; : <tipo n> <campo n>; };

Exemplo do emprego das unies:


typedef unsigned char byte; union Oito_bytes { double x; /*um double de 8 bytes */ int i[4]; /* um array com 4 inteiros = 8 bytes */ byte j[8]; /* um array de 8 bytes */ } unionvar; void main() { unionvar.x = 2.7; unionvar.i[1] = 3; /* sobreescreve valor anterior ! */ }

Para verificar que o tamanho de uma varivel union igual ao tamanho do maior membro, vamos utilizar a funo sizeof(). A funo sizeof() resulta o tamanho em bytes ocupado por uma dada varivel. Veja o teste realizado abaixo, onde apresentamos o valor em bytes ocupado por cada membro da unio e o valor em bytes ocupado pela unio inteira. Podemos verificar tambm que todos os membros da unio ocupam a mesma posio da memria utilizando o operador & para obter a posio da memria onde esto armazenados os dados.

Marcelo Ricardo Stemmer

97

Informtica Industrial I

DAS/UFSC

/* Sizeof(), mostra o uso de sizeof() */ #include <stdio.h> union num { char str[20]; int i; float f; } x; // Cria a variavel do tipo union num. void main() { printf("Sizeof(str[20]) =%d bytes, mem:%p.\n",sizeof(x.str), x.str); printf("Sizeof(i) = %d bytes, \tmem: %p.\n", sizeof(x.i), &(x.i)); printf("Sizeof(f) = %d bytes, \tmem: %p.\n", sizeof(x.f), &(x.f)); printf("Sizeof(x) = %d bytes, \tmem: %p.\n", sizeof(x), &(x)); }

A sada do programa ser como esperado:


Sizeof(str[20]) = 20 bytes, mem: 50EF:0D66. Sizeof(i) = 2 bytes, mem: 50EF:0D66. Sizeof(f) = 4 bytes, mem: 50EF:0D66. Sizeof(x) = 20 bytes, mem: 50EF:0D66.

4.10.5

Bitfields

Bitfields so um tipo especial de estrutura cujos campos tem comprimento especificado em bits. Estas so teis quando desejamos representar dados que ocupam somente um bit. Sintaxe:
struct <nome> { <tipo> <campo> : <comprimento em bits>; };

Exemplo aplicando bitfields:


#define ON 1 #define OFF 0 struct Registro_Flags { unsigend int Bit_1 unsigend int Bit_2 unsigend int Bit_3 unsigend int Bit_4 unsigend int Bit_5 unsigend int Bit_6 unsigend int Bit_7 unsigend int Bit_8 }; /* declara bitfield */ : : : : : : : : 1; 1; 1; 1; 1; 1; 1; 1;

main( ) { struct Registro_Flags


Marcelo Ricardo Stemmer

Flags;

/* declara varivel Flags */


98

Informtica Industrial I

DAS/UFSC

Flags.Bit_1 = ON; Flags.Bit_2 = OFF; }

4.10.6

Exerccios

10.1 Escreva uma estrutura para descrever um ms do ano. A estrutura deve ser capaz de armazenar o nome do ms, a abreviao em letras, o nmero de dias e o nmero do ms. Escreva tambm um tipo enumerado para associar um nome ou uma abreviao ao nmero do ms. 10.2 Declare uma matriz de 12 estruturas descritas na questo anterior e inicialize-a com os dados de um ano no-bissexto. 10.3 Escreva uma funo que recebe o nmero do ms como argumento e retorna o total de dias do ano at aquele ms. Escreva um programa que solicite ao usurio o dia, o ms e o ano. Imprima o total de dias do ano at o dia digitado. 10.4 Escreva um programa para cadastrar livros em uma biblioteca e fazer consultas a estes. 10.5 Refaa o programa do exerccio 8.6 utilizando as estruturas aqui desenvolvidas. 10.6 Crie uma estrutura para descrever restaurantes. Os membros devem armazenar o nome, o endereo, o preo mdio e o tipo de comida. Crie uma matriz de estruturas e escreva um programa que utilize uma funo para solicitar os dados de um elemento da matriz e outra para listar todos os dados. 10.7 Crie um programa que faa o controle de cadastro de usurios e controle de alocao para uma locadora de fitas de vdeo. Utilize uma estrutura para os clientes e outra para as fitas.

4.11 Ponteiros e a Alocao Dinmica de Memria


No captulo sobre tipos de dados, definimos o que era ponteiro. Ponteiros so tipos especiais de dados que armazenam o endereo de memria onde uma varivel normal armazena os seus dados. Desta forma, empregamos o endereo dos ponteiros como uma forma indireta de acessar e manipular o dado de uma varivel. Agora apresentaremos diversas aplicaes de ponteiros, justificaremos por que este so intensivamente empregados na programao C e apresentaremos algumas de suas aplicaes tpicas.

4.11.1

Declarao de Ponteiros e o Acesso de Dados com Ponteiros

C permite o uso de ponteiros para qualquer tipo de dado, sendo este um dado tpico de C (int, float, double, char) ou definido pelo programador (estruturas, unies). Como havamos visto anteriormente (4.2.7), os ponteiros so declarados da seguinte forma:
<tipo> * <nome da varivel> = <valor inicial>; float *p, float *r = 0;

A sintaxe basicamente a mesma que a declarao de variveis, mas o operador * indica que esta varivel trata de um ponteiro, por isso *p e *r so do tipo float e que p e r so ponteiros para variveis float. Lembrando,
*p = 10;

Marcelo Ricardo Stemmer

99

Informtica Industrial I

DAS/UFSC

faz com que a varivel endereada por p tenha o seu valor alterado para 10, ou seja, * um operador que faz o acesso a varivel apontada por um ponteiro. O operador & aplicado a uma varivel normal retorna o valor do seu endereo, podemos dizer ento:
int num = 15; p = &num; /* p recebe o endereo de num */

4.11.2

Operaes com Ponteiros

A linguagem C oferece 5 operaes bsicas que podem ser executadas em ponteiros. O prximo programa mostras estas possibilidades. Para mostrar o resultado de cada operao, o programa imprimir o valor do ponteiro (que um endereo), o valor armazenado na varivel apontada e o endereo da varivel que armazena o prprio ponteiro.
/* operacoes com ponteiros */ #include <stdio.h> void main() { int x = 5, y = 6; int *px; int *py = 0; /* ponteiro inicializado com 0 */ printf("Endereco contigo incialmente em :\n"); printf("\tpx = %p \n\tpy = %p.\n", px, py); printf("Cuidado ao usar ponteiros nao incializados como px!!!\n\n"); px = &x; py = &y; if(px<py) printf("py - px = %u\n", py-px); else printf("px - py = %u\n", px-py); printf("px = printf("py = px++; printf("px = py = px + 3; printf("py = printf("py } %p, \t*px = %d, \t&px = %p\n", px, *px, &px); %p, \t*py = %d, \t&py = %p\n\n", py, *py, &py); %p, \t*px = %d, \t&px = %p\n\n", px, *px, &px); %p, \t*py = %d, \t&py = %p\n", py, *py, &py); px = %u\n", py-px);

Resultado do programa:
Endereo contido inicialmente em: px = 21CD:FFFF py = 0000:0000 Cuidado ao utilizar ponteiros no inicializados como px!!!! px py = 1 px = 4F97:2126, *px = 5, py = 4F97:2124, *py = 6,

&px = 4F97:2120 &py = 4F97:211C &px = 4F97:2120 &py = 4F97:211C

px = 4F97:2128, *px = 20375, py = 4F97:212E, *py = 20351, py px = 3


Marcelo Ricardo Stemmer

100

Informtica Industrial I

DAS/UFSC

Primeiramente, o programa exemplo acima declara as variveis inteiras x e y, declarando dois ponteiros para inteiros tambm. Note que um ponteiro foi inicializado com 0 e o outro no. Para mostrar a importncia da inicializao de ponteiros, resolvemos mostrar na tela o valor inicial destes. Caso, tentssemos acessar o valor da varivel apontada pelo ponteiro py, o programa no executaria esta operao pelo fato do ponteiro conter um endereo invlido 0. Entretanto, se tentarmos acessar o valor da varivel apontada por px, o computador executar esta operao sem problema, pois o endereo est vlido, e assim poderemos cometer um erro gravssimo acessando reas de memrias inadequadas ou proibidas. Inicialize sempre os seus ponteiros com o valor zero ou NULL. Em seguida, atribumos um valor vlidos aos ponteiros utilizando o operador (&) para obter o endereo das variveis x e y. O operador (*) aplicado na frente do nome do ponteiro, retornar o valor da varivel apontada por este ponteiro. Como todas as variveis, os ponteiros variveis tm um endereo e um valor. O operador (&) retorna a posio de memria onde o ponteiro est localizado. Em resumo: O nome do ponteiro retorna o endereo para o qual ele aponta. O operador & junto ao nome do ponteiro retorna o endereo onde o ponteiro est armazenado. O operador * junto ao nome do ponteiro retorna o contedo da varivel apontada. No programa acima, apresentamos esta idia de forma clara, mostrando na tela estes valores para os dois respectivos ponteiros. Podemos incrementar um ponteiro atravs de adio regular ou pelo operador de incremento. Incrementar um ponteiro acarreta a movimentao do mesmo para o prximo tipo apontado. Por exemplo, se px um ponteiro para um inteiro e px contm o endereo 0x3006. Aps a execuo da instruo:
px++;

o ponteiro px conter o valor 0x3008 e no 0x3007, pois a varivel inteira ocupa 2 bytes. Cada vez que incrementamos px ele apontar para o prximo tipo apontado, ou seja, o prximo inteiro. O mesmo verdadeiro para decremento. Se px tem valor 0x3006 depois da instruo:
px--;

ele ter valor 0x3004. Voc pode adicionar ou subtrair de e para ponteiros. A instruo:
py = px + 3;

far com que py aponte para o terceiro elemento do tipo apontado aps px. Se px tem valor 0x3000, depois de executada a instruo acima, py ter o valor 0x3006. Novamente, tenha cuidado na manipulao de ponteiros para no acessar regies invlidas de memria ou ocupadas por outros programas. Voc pode encontrar a diferena entre dois ponteiros. Esta diferena ser expressa na unidade tipo apontado, ento, se py tem valor 0x4008 e px o valor 0x4006, a expresso
py - px

ter valor 1 quando px e py so ponteiros para int. Testes relacionais com >=, <=, > e < so aceitos entre ponteiros somente quando os dois operandos so ponteiros. Outro cuidado a se tomar quanto ao tipo apontado pelo operandos. Se

Marcelo Ricardo Stemmer

101

Informtica Industrial I

DAS/UFSC

voc comparar ponteiros que apontam para variveis de tipo diferentes, voc obter resultados sem sentido. Variveis ponteiros podem ser testadas quanto igualdade (==) ou desigualdade (!=) onde os dois operandos so ponteiros (px == py) ou um dos operandos NULL (px != NULL ou px != 0).

4.11.3

Funes & Ponteiros

Um das maneiras mais importantes para passar argumentos para uma funo ou para que a funo retorne um resultado atravs de ponteiros. Ponteiros so empregados em funes principalmente quando necessitamos de umas das seguintes caractersticas: ponteiros permitem que uma funo tenha acesso direto as variveis da funo chamadora, podendo efetuar modificaes nestas variveis; para tipos de dados complexos ou de grande dimenso (estruturas, matrizes, ...) mais fcil e mais rpido acessar estes dados indiretamente atravs de um ponteiro do que realizar uma cpia destes para que a funo possa utilizar o valor copiado. Podemos utilizar ponteiros de estruturas complexas ou matrizes como forma de fazer com que funes retornem mais de um valor como resultado; A passagem de parmetro com ponteiros geralmente mais rpida e eficiente do que com o prprio dado, haja visto que o compilador no faz uma cpia deste dado e um ponteiro necessita somente de 4 bytes para armazenar o seu valor. Para tal, basta que em vez da funo chamadora passar valores para a funo chamada, esta passe endereos usando operadores de endereos (&). Estes endereos so de variveis da funo chamadora onde queremos que a funo coloque os novos valores. Estes endereos devem ser armazenados em variveis temporrias da funo chamada para permitir posteriormente o seu acesso. No exemplo a seguir mostramos como ponteiros podem ser usados como parmetros da funo.
/* testa funca que altera dois valores */ #include <stdio.h> void altera(int *, int *); void main() { int x = 0, y = 0; altera(&x, &y); printf("O primeiro e %d, o segundo e %d.", x, y); } /* altera(), altera dois numeros da funcao que chama*/ void altera(int *px, int *py) { if(px != 0) *px = 3; if(py != 0) *py = 5; }

Note, que o objetivo da funo prover modificaes nas duas variveis x e y. Numa forma simples, s poderamos efetuar esta operao utilizando-se uma estrutura para conter x e y, ou

Marcelo Ricardo Stemmer

102

Informtica Industrial I

DAS/UFSC

criando uma funo para alterar cada parmetro. Entretanto, passando-se o endereo das variveis x e y permitimos a funo chamada que altera-se diretamente os seus valores. O valor do endereo das variveis foi obtido com o operador &. A funo necessitou apenas da declarao de um tipo ponteiro em seu cabealho para estar apta a receber endereos de variveis como um de seus parmetros. Uma vez conhecidos os endereos e os tipos das variveis do programa chamador, a funo pode no somente colocar valores nestas variveis como tambm tomar o valor j armazenado nelas. Ponteiros podem ser usados no somente para que a funo passe valores para o programa chamador, mas tambm para que o programa chamador passe valores para a funo. Outro aspecto importante o teste efetuado antes de utilizar a o ponteiro recebido como parmetro:
if(px != 0) *px = 3;

Isto serve para que a funo verifique se o valor de endereo recebido vlido. Tome muito cuidado com a manipulao de ponteiros, um erro no programa ou em uma funo do sistema operacional, pode gerar um ponteiro invlido e o acesso a rea de memria representada por este ponteiro pode causar um erro fatal no seu programa. Este um dos mtodos para prever erros com ponteiros.

4.11.4

Ponteiros & Matrizes

Voc no percebe, mas C trata matrizes como se fossem ponteiros. O tipo matriz na verdade uma forma mais amigvel que C fornece para tratar um ponteiro que aponta para uma lista de variveis do mesmo tipo. O compilador transforma matrizes em ponteiros quando compila, pois a arquitetura do microcomputador entende ponteiros e no matrizes. Qualquer operao que possa ser feita com ndices de uma matriz pode ser feita com ponteiros. O nome de uma matriz um endereo, ou seja, um ponteiro. Ponteiros e matrizes so idnticos na maneira de acessar a memria. Na verdade, o nome de uma matriz um ponteiro constante. Um ponteiro varivel um endereo onde armazenado um outro endereo. Suponha que declaramos uma matriz qualquer :
int table = {10, 1, 8, 5, 6}

e queremos acessar o terceiro elemento da matriz. Na forma convencional por matriz, fazemos isto atravs da instruo:
table[2]

mas a mesma instruo pode ser feita com ponteiros, considerando que o nome do vetor na verdade um ponteiro para o primeiro elemento do vetor:
*(table+2)

A expresso (table+2) resulta no endereo do elemento de ndice 2 da matriz. Se cada elemento da matriz um inteiro (2 bytes), ento vo ser pulados 4 bytes do incio do endereo da matriz para atingir o elemento de ndice 2. Em outras palavras, a expresso (table+2) no significa avanar 2 bytes alm de table e sim 2 elementos da matriz: 2 inteiros se a matriz for inteira, 2 floats se a matriz for float e assim por diante. Ou seja,
*(matriz + indice) == matriz[indice]

Marcelo Ricardo Stemmer

103

Informtica Industrial I

DAS/UFSC

Existem duas maneiras de referenciar o endereo de um elemento da matriz: em notao de ponteiros, matriz+indice, ou em notao de matriz, &matriz[indice]. Vamos mostrar um exemplo para esclarecer estes conceitos:
/* media de um numero arbitrario de notas */ /* exemplo de ponteiros */ #include <stdio.h> #define LIM 40 void main() { float notas[LIM], soma = 0.0; int register i = 0; do { printf("Digite a nota do aluno %d: ", i); scanf("%f", notas+i); if(*(notas+i) > 0) soma += *(notas+i); }while(*(notas+i++) > 0); printf("Media das notas: %.2f", soma/(i-1)); }

O operador de incremento ou decremento no pode ser aplicado a ponteiros constantes. Por exempo, no podemos substituir o comando (notas + i++) por (notas++), haja visto que notas um ponteiro constante. Para fazer isto, precisamos criar um ponteiro varivel qualquer, atribuir a ele o endereo da matriz e depois incrementar o valor deste ponteiro:
float * ptr = 0; ptr = notas; (notas + i++) == (ptr++) /* so equivalentes */

Como, ptr apontar para uma matriz do tipo float, o operador (++) incrementa em 4 bytes a cada operao. Podemos passar matrizes como parmetros para funes, passando-se como parmetro um ponteiro para o primeiro elemento da matriz e depois utilizando este ponteiro para acessar todos os elementos da matriz. Esta sintaxe funciona exatamente igual como se estivessemos passando um ponteiro de uma varivel normal como parmetro. Veja a seco anterior para verificar esta sintaxe.

4.11.5

Ponteiros & Strings

Como strings so na verdade tratadas em C como matrizes simples de caracteres finalinazadas por 0 (caracter \0), podemos utilizar as facilidades fornecidas pelos ponteiros para manipular strings tambm. Abaixo mostramos um exemplo que ilustra este caso:
/* procura um caractere em uma string */ #include <stdio.h> #include <conio.h> char * procstr(char *, char); void main() { char *ptr;
Marcelo Ricardo Stemmer

104

Informtica Industrial I

DAS/UFSC

char ch, lin[81]; puts("Digite uma sentenca: "); gets(lin); printf("Digite o caractere a ser procurado: "); ch=getche(); ptr = procstr(lin, ch); printf("\nA string comeca no endereco %p.\n", lin); if(ptr) /* if(ptr != 0) */ { printf("Primeira ocorrencia do caractere: %p.\n", ptr); printf("E a posicao: %d", ptr-lin); } else printf("\nCaractere nao existe.\n"); } char * procstr(char * l, char c) { if(l == 0) return 0; while((*l != c)&&(*l != '\0')) l++; if(*l != '\0') return l; return 0; }

Primeiramente, fornecemos aqui um exemplo de funo que retorna como resultado um ponteiro. Note que, antes de acessarmos o valor deste ponteiro, testamos se este um ponteiro vlido para no cometer nenhum erro acessando uma rea imprpria da memria. O programa utilizou a manipulao de ponteiros para localizar a posio de um caracter em uma string e fornecer a sua posio ao usurio. A maioria das funes em C manipulam strings como ponteiros e, por isso, so extremamente rpidas e otimizadas. Em vez de declararmos uma string como uma tabela, podemos faze-lo diretamente como sendo um ponterio. O tipo (char *) reconhecido em C como sendo um tipo string, ou seja, um ponteiro para uma sequncia de caracteres. Por isso, as inicializaes abaixo so equivalentes:
char * salute = Saudacoes; char salute[] = Saudacoes;

Entretanto, esta inicializao alocar memria somente para o correspondente nmero de caracteres da string passada mais um caracter \0 para delimitar a string. Nenhum espao a mais de memria ser alocado neste caso. As duas formas provocam o mesmo efeito, mas so diferentes: a primeira declara salute como um ponteiro varivel e a segunda como um ponteiro constante. O valor de um ponteiro constante no pode ser modificado, j um ponteiro varivel pode ter seu valor modificado, por um incremento (++), por exemplo. Podemos criar em C matrizes de ponteiros para strings. Esta uma das maneiras mais econmicas para alocar memria para uma matriz de strings sem desperdiar memria. Por exemplo, a inicializao:
static char * list[5] = { Katarina, Nigel, Gustavo,
Marcelo Ricardo Stemmer

105

Informtica Industrial I

DAS/UFSC

Francisco, Airton

};

Vai alocar uma matriz com 5 elementos, onde cada elemento conter o valor de um ponteiro para uma lista de caracteres (string). Desta forma, o espao de memria necessrio para alocar ser somente o tamanho estritamente necessrio. Como a string de ponteiros, basta alocar espao para cada elemento de 2 bytes, enquanto que a sequncia de carateres apontado por este ponteiro pode estar em qualquer posio de memria. Se quizessemos fazer a mesma inializao utilizando uma matriz de vetores de caracteres, isto implicaria que teramos que alocar uma tabela MxN para conter todos os caracteres e isto nos levaria a disperdiar algumas posies da memria que no chegaram nunca a conter algum caracter, j que as strings se caracterizam por conter um comprimento diferentes de caracteres. Por isto, uma das razes para se inicializar strings com ponteiros a alocao mais eficiente de memria. Uma outra razo a de obter maior flexibilidade para manipular matrizes de strings. Por exemplo, suponha que desejsemos reordenar as strings da matriz acima. Para fazer isto, no precisamos remover as strings de sua posio e escrev-las em outra matriz na ordem correta, basta trocar de posio os ponteiros que apontam para as strings. Reordenando os ponteiros, obteremos a ordem desejada das strings sem ter que se preocupar em reescrever as strings em outra posio de memria.

4.11.6

Ponteiros para Ponteiros

A habilidade da linguagem C de tratar partes de matrizes como matrizes cria um novo tpico de C, ponteiros que apontam para ponteiros. Esta habilidade d a C uma grande flexibilidade na criao e ordenao de dados complexos. Vamos analisar um exemplo de acesso duplamente indireto de dados derivados de uma matriz de duas dimenses.
/* uso de ponteiros para ponteiros */ #include <stdio.h> #define LIN 4 #define COL 5 void main() { static int tabela[LIN][COL] = { {13, 15, 17, 19, 21}, {20, 22, 24, 26, 28}, {31, 33, 35, 37, 39}, {40, 42, 44, 46, 48} }; int c = 10; int j, k; int * ptr = tabela; for(j=0; j<LIN; j++) for(k=0; k<COL; k++) *(ptr + j*COL + k) += c; for(j=0; j<LIN; j++) { for(k=0; k<COL; k++) printf("%d ", *(*(tabela+j)+k)); printf("\n"); } }
Marcelo Ricardo Stemmer
106

Informtica Industrial I

DAS/UFSC

Neste exemplo, estamos utilizando o ponteiro tabela para acessar os termos da matriz bidimensional. Mas como fazer para acessar um termo posicionado em tabela[i][j]? Como tabela uma matriz para inteiros, cada elemento ocupar dois bytes e cada coluna com 5 elementos ocupar 10 bytes. Abaixo, mostramos o armazenamento desta tabela na memria (Os endereos esto em nmeros decimais para facilitar o entendimento). Tabela: Mem\offset 1000 1010 1020 1030 i\j i\offset 0 1 2 3 0 0 13 20 31 40 1 2 15 22 33 42 2 4 17 24 35 44 3 6 19 26 37 46 4 8 21 28 39 48

Vamos tentar agora acessar o elemento tabela[2][4], onde a tabela tem dimenso 4x5. a) *(tabela + 2*5 + 4) Note que, podemos tratar uma matriz mxn como sendo um vetor simples de inteiros, pois as linhas so posicionadas na memria uma aps a outra. Ento, se calcularmos a posio de memria ocupada por tabela[2][4], poderemos acessar o seu valor atravs de um ponteiro: int * ptr = tabela : contm o endereo inicial da matriz, no caso 1000. (ptr + 2*5) == (ptr + 10) : contm a posio incial da terceira linha da tabela (tabela[2]), no caso 1020 pois cada elemento ocupa 2 bytes (int). Isto fica claro na matriz acima. Sabendo-se que a terceira linha comea aps 2 linhas com 5 elementos, basta adicionar o nmero de termos contidos nestas linhas ao ponteiro da matriz e obtemos um ponteiro para o ncio da linha 2. ((ptr + 2*5) + 4) == (ptr + 14) : contm a posio de memria onde est o termo tabela[2][4], no caso 1028. Com o ponteiro da linha, queremos agora acessar o termo 4 desta linha. Ento, basta adicionar 4 ao ponteiro da linha, que obtemos um ponteiro para o referido termo. *(ptr + 2*5 + 4) == *(ptr + 14) : calculada a posio de memria onde est o referido termo, basta utilizar o operador (*) para acess-lo. b) *( *(tabela + 2) + 4) Considere a declarao da seguinte tabela 4x5:
int tabela[4][5];

Queremos agora criar um vetor que contenha a terceira linha desta tabela. Podemos fazer isto, usando uma das duas declaraes equivalentes:
int linha[5] = tabela[2]; int linha[5] = *(tabela + 2); /* eq. 1 */

Note que, uma matriz na verdade um vetor contendo outras matrizes de ordem menor. Na declarao acima, fazemos a atribuio de um elemento da matriz tabela, isto , um vetor com 5 inteiros, para uma matriz que contm 5 inteiros. A diferena das notaes que a segunda utiliza a manipulao de ponteiros na sua declarao. Agora, vamos acessar o quinto termo de linha, isto , linha[4]. Podemos fazer isto pelo mtodo convecional de matrizes ou por ponteiros. Os dois mtodos abaixo so equivalentes: int num = linha[4]; int num = *(linha + 4);
Marcelo Ricardo Stemmer
107

Informtica Industrial I

DAS/UFSC

Desta forma, conseguimos acessar indiretamente o termo tabela[2][4]. Primeiro atribumos a terceira linha da tabela a um vetor simples e depois acessamos o quinto elemento deste vetor. Entretanto, C nos permite realizar o mesmo mtodo de acesso, sem criar este passo intermedirio, basta fazer:
int tabela[4][5]; int num = *(*(tabela + 2) + 4); /* tabela[2][4]; */

Assim, *(tabela+2) retorna o endereo da terceira linha da matriz tabela, equivalente a escrevermos &tabela[2][0]. Ao adicionarmos 4 a este endereo, calculamos o endereo do quinto elemento nesta linha. Portanto, o endereo do quinto elemento (*(tabela+2)+4) e o contedo deste endereo *(*(tabela+2)+4), que 39. Esta expresso m ponteiro para ponteiro. Este princpio aplicado para matrizes de qualquer dimenso, em outras palavras:
tabela[j][k] = *(*(tabela + j) + k); cubo[i][j][k] = *(*(*(cubo + i) + j) + k);

Desta maneira, C nos permite criar ponteiros para ponteiros e fazer estruturas to complexas e flexveis quanto desejarmos. O operador *(ptr) pode ento ser aninhado para obter o valor final apontado pela seqncia de ponteiros. Esta tcnica pode fornecer grande velocidade de execuo e economia de memria, mas tenha cuidado para construir um cdigo claro de forma a evitar problemas devido a um gerenciamento ruim destes ponteiros.

4.11.7

Argumentos da Linha de Comando

C permite que um programa receba uma listas de parmetros atravs da funo main(). A forma geral da funo main dada por:
int main(int argc, char* argv[]);

onde argc o nmero de argumentos passados para a funo, e argv uma matriz de string que contm todos os argumentos passados. A funo main() nesta forma geral necessita retornar um valor indicado o resultado do programa ao sistema operacional.No caso, o retorno do valor 0 indicar que o programa foi executado adequadamente. Suponha que voc tenha criado um programa chamado jogo e tenha executado ele no sistema operacional com a linha de comando:
C:> jogo xadrex.txt 2 3.14159

Ao executar o programa passo--passo, verificaremos que argc ser igual a 4, indicando que o usurio forneceu 4 parmetros ao programa. Sendo que os parmetros esto armazenados em argv na forma de string e contero os seguintes valores:
argv[0] argv[1] argv[2] argv[3] == == == == jogo; xadrex.txt; 2; 3.14159;

Conhecendo como funciona os parmetros da funo main(), voc j pode utilizar a atribuio abaixo para obter os valores fornecidos, bastando converter o parmetro do formato ASCII para o tipo de dado requerido :
char * param = argv[3];

Marcelo Ricardo Stemmer

108

Informtica Industrial I

DAS/UFSC

4.11.8

Ponteiros para Estruturas

Como j mostramos ponteiros so mais fceis de manipular que matrizes em diversas situaes, assim ponteiros para estruturas so mais fceis de manipular que matrizes de estruturas. Vrias representaes de dados que parecem fantsticas so constitudas de estruturas contendo ponteiros para outras estruturas. O nosso prximo exemplo mostra como definir um ponteiro para estrutura e us-lo para acessar os membros da estrutura.
/* mostra ponteiro para estrutura */ #include <stdio.h> struct lista /* declara estrutura */ { char titulo[30]; char autor[30]; int regnum; double preco; }; int main(int argc, char * argv[]) { static struct lista livro[2] = { { "Helena", "Machado de Assis", 102, 70.50 }, { "Iracema", "Jose de Alencar", 321, 63.25 } }; struct lista *ptrl = 0; /* ponteiro para estrutura */ printf("Endereco #1: %p #2: %p\n", &livro[0], &livro[1]); ptrl = &livro[0]; printf("Ponteiro #1: %p #2: %p\n", ptrl, ptrl + 1); printf("ptrl->preco: R$%.2f \t (*ptrl).preco: R$%.2f\n", ptrl->preco, (*ptrl).preco); ptrl++; /* Aponta para a proxima estrutura */ printf("ptrl->titulo: %s \tptrl->autor: %s\n", ptrl->titulo, ptrl->autor); return 0; }

A declarao feita como se estivssemos declarando uma varivel de qualquer tipo, adicionando-se o operador (*) na frente do nome da varivel. Por isso, a declarao de um ponteiro para uma estrutura feita na forma : struct lista *ptrl; O ponteiro ptrl pode ento apontar para qualquer estrutura do tipo lista. A atribuio de um endereo a um ponteiro de estrutura funciona da mesma forma como uma varivel qualquer, empregando-se o operador (&): ptrl = &(livro[0]); Vimos no captulo sobre estruturas como fazer o acesso a um elemento de uma estrutura atravs do operador (.). Por exemplo, se quizermos ler o valor do preco da primeira estrutura da matriz livro, procederamos da forma:
livro[0].preco = 89.95;

Mas como proceder com ponteiros? Podemos faz-lo de duas formas.

Marcelo Ricardo Stemmer

109

Informtica Industrial I

DAS/UFSC

Primeiro, podemos utilizar o operador (*) para obter a estrutura apontada por um ponteiro e depois empregar o operador normal (.) para acessar um elemento desta estrutura. Aplicando no exemplo acima, teremos:
(*ptrl).preco = 89.95;

O segundo mtodo utiliza o operador (->) que nos permite acessar um elemento de uma estrutura apontada por um dado ponteiro. Aplicando-se este operador no problema acima, temos:
ptrl->preco = 89.95;

Em outras palavras, um ponteiro para estrutura seguido pelo operador (->) trabalha da mesma maneira que o nome de uma estrutura seguido pelo operador (.). importante notar que ptrl um ponteiro, mas ptrl->preco um membro da estrutura apontada. Neste caso, ptrl>preco uma varivel double. O operador (.) conecta a estrutura a um membro dela; o operador (->) conecta um ponteiro a um membro da estrutura.

4.11.9

Alocao Dinmica de Memria

A linguagem C oferece um conjunto de funes que permitem a alocao ou liberao dinnmica de memria. Desta forma, podemos alocar memria para um programa de acordo com a sua necessidade instntanea de memria. A memria de trabalho do computador (RAM) usualmente subdividida em vrios segmentos lgicos dentro de um programa. Estes segmentos so: segmento de dados, onde so alocadas as variveis globais (extern), definidas em prerun-time; o segmento de cdigo, onde esto as instrues de mquina do programa em si; o segmento de pilha (stack), onde as funes alocam provisriamente suas variveis locais (auto). Este segmento tambm usado para passagem de parmetros; o segmento extra, que pode conter mais variveis globais; Toda a rea de memria restante entre o fim do programa e o fim da RAM livre chamado de heap. O heap usado para a criao de variveis dinmicas, que so criadas em run-time (isto , durante a execuo do programa). Este tipo de variveis til quando no se sabe de antemo quantas variveis de um determinado tipo sero necessrias para a aplicao em questo. Quando escrevemos um programa utilizando o mtodo de declarao de variveis visto anteriormente (alocao esttica de memria), o programa ao ser executado alocar somente um bloco fixo de memria para armazenar todos os seus dados. Isto resolve o problema de termos um espao de memria alocado para podermos armazenar os dados do programa. Entretanto, como visto no captulo de matrizes, este mtodo no otimiza a utilizao do espao de memria alocado. Por exemplo, imagine que voc precise de uma matriz temporria para armazenar alguns dados temporrios durante a execuo de uma dada funo de manipulao de matrizes. Para tal, voc dever declarar esta matriz na funo, o que implicar que o computador ir alocar um bloco de memria para esta matriz. Este espao de memria ficar alocado ao seu programa durante toda a execuo deste, apesar do programa s utilizar uma vez esta matriz e, posteriormente, no precisar mas desta matriz e nem do espao de memria alocado a esta. Com a alocao dinmica de memria, podemos, em tempo de execuo, fazer com que um programa aloque um determinado espao de memria, utilize este espao por um determinado tempo e depois o libere, para que outros programas possam vir a utiliz-lo. No caso do nosso exemplo, podemos fazer com que sempre que a funo for chamada, ela alocar um espao de memria para armazenar a referida matriz e aps o seu uso, o programa liberar este bloco de
Marcelo Ricardo Stemmer
110

Informtica Industrial I

DAS/UFSC

memria para que outro programa o utilize. Desta forma, se executarmos esta funo apenas uma vez, o programa ir liberar esta memria posteriormente, permitindo assim que outros programas faam um uso mais adequado desta. Desta forma, a alocao dinmica de memria utilizada em programas para alocar e liberar blocos temporrios de memrias durante a execuo de um programa (por isso chamado alocao dinmica). Este bloco de memria solicitado ao sistema operacional que procura um espao livre de memria para o programa. Se o sistema operacional achar um bloco de memria livre do tamanho do bloco solicitado, este passa o bloco de memria para o controle do programa e no ir permitir que nenhum outro programa utilize esta memria enquanto ela estiver alocada. No final do seu uso, o programa libera novamente esta memria ao sistema operacional. Outro exemplo de aplicao da alocao dinmica de memria na utilizao de matrizes quando no sabemos de antemo quantos elementos sero necessrios. Desta forma, podemos utilizar a alocao dinmica de memria para somente alocar a quantidade necessria de memria e no momento em que esta memria for requerida.

4.11.9.1

Malloc()

A funo malloc() utilizada para fazer a alocao dinmica de um bloco de memria a um dado programa. A funo malloc() toma um inteiro sem sinal como argumento. Este nmero representa a quantidade em bytes de memria requerida. A funo retorna um ponteiro para o primeiro byte do novo bloco de memria que foi alocado. importante verificar que o ponteiro retornado por malloc() para um tipo void. O conceito de ponteiro para void deve ser introduzido para tratar com situaes em que seja necessrio que uma funo retorne um ponteiro genrico, i.e., que possa ser convertido em um ponteiro para qualquer outro tipo de dado. Este ponteiro void pode ser convertido para um ponteiro do tipo de dado desejado (int, float, struct, ...) empregando-se o mtodo de converso de tipos apresentado na seco sobre tipos de dados (ver 4.2.5). No prximo exemplo, mostraremos o seu emprego novamente. Quando a funo malloc() no encontrar espao suficiente de memria para ser alocado, esta retornar um ponteiro NULL, i.e., um ponteiro invlido. O exemplo abaixo mostra como a funo malloc() opera. Este programa declara uma estrutura chamada xx e chama malloc() 4 vezes. A cada chamada, malloc() retorna um ponteiro para uma rea de memria suficiente para guardar um nova estrutura.
/* testa malloc() */ #include <stdio.h> struct xx { int numl; char chl; }; void main() { struct xx *ptr = 0; int j; printf("sizeof(struct xx) = %d\n", sizeof(struct xx)); for(j=0; j<4; j++) { ptr = (struct xx *) malloc(sizeof(struct xx)); printf("ptr = %x\n", ptr); } }
Marcelo Ricardo Stemmer
111

Informtica Industrial I

DAS/UFSC

Note que em nenhuma parte do programa declaramos qualquer varivel estrutura. De fato, a varivel estrutura criada pela funo malloc(); o programa no conhece o nome desta varivel; mas sabe onde ela est na memria, pois malloc() retorna um ponteiro para ela. As variveis criadas podem ser acessadas usando ponteiros, exatamente como se tivessem sido declaradas no incio do programa. A cada chamada de malloc() devemos inform-la do tamanho da estrutura que queremos guardar. Ns podemos conhecer este tamanho adicionando os bytes usados por cada membro da estrutura, ou atravs do uso de um novo operador em C unrio chamado sizeof(). Este operador produz um inteiro igual ao tamanho, em bytes, da varivel ou do tipo de dado que est em seu operando. Por exemplo, a expresso
sizeof(float)

retornar o valor 4, haja vista que um float ocupa 4 bytes. No programa exemplo, usamos sizeof() em printf() e ele retorna 3, pois a estrutura xx consiste em um caracter e um inteiro. Ento, sizeof() forneceu o tamanho em bytes da estrutura para que malloc() pudesse alocar o espao de memria requerido. Feito isto, malloc() retornou um ponteiro do tipo void, que foi convertido para o tipo struct xx atravs da expresso:
(struct xx *)

4.11.9.2

Calloc()

Uma outra opo para a alocao de memria o uso da funo calloc(). H uma grande semelhana entre calloc() e malloc() que tambm retorna um ponteiro para void apontando para o primeiro byte do bloco solicitado. A nova funo aceita dois argumentos do tipo unsigned int. Um uso tpico mostrado abaixo:
long * memnova; memnova = (long *) calloc(100, sizeof(long));

O primeiro argumento o nmero de clulas de memrias desejada e o segundo argumento o tamanho de cada clula em bytes. No exemplo acima, long usa quatro bytes, ento esta instruo alocar espao para 100 unidades de quatro bytes, ou seja, 400 bytes. A funo calloc() tem mais uma caracterstica: ela inicializa todo o contedo do bloco com zero.

4.11.9.3

Free()

A funo free()libera a memria alocada por malloc() e calloc(). Aceita, como argumento, um ponteiro para uma rea de memria previamente alocada e ento libera esta rea para uma possvel utilizao futura. Sempre que um espao de memria for alocado, este deve ser necessariamente liberado aps o seu uso. Se no for liberada, esta memria ficar insdiponvel para o uso pelo sistema operacional para outros aplicativos. A utilizao consciente da alocao e liberao dinmica de memria, permite em um uso otimizado da memria disponvel no computador. A funo free()declara o seu argumento como um ponteiro para void. A vantagem desta declarao que ela permite que a chamada funo seja feita com um argumento ponteiro para qualquer tipo de dado.
long * memnova; memnova = (long *)calloc(100, sizeof(long));
Marcelo Ricardo Stemmer
112

Informtica Industrial I

DAS/UFSC

/* usa memnova */ free(memnova); /* libera a memria alocada */

4.11.10 Exerccios
11.1 Escreva um programa que receba duas strigns como argumentos e troque o contedo de string1 como string2. 11.2 Escreva um programa que inverta a ordem dos caracteres de uma string. Por exemplo, se a string recebida Saudacoes deve ser modificada para seocaduaS. 11.3 Reescreva o programa do exerccio 9.1 utilizando alocao dinmica de memria. 11.4 Reescreva o programa do exerccio 9.3 utilizando alocao dinmica de memria. 11.5 A lista encadeada se assemelha a uma corrente em que as estruturas esto penduradas sequencialmente. Isto , a corrente acessada atravs de um ponteiro para a primeira estrutura, chamado cabea, e cada estrutura contm um ponteiro para a sua sucessora, e o ponteiro da ltima estrutura tem valor NULL (0) indicando o fim da lista. Normalmente uma lista encadeada criada dinamicamente na memria. Crie um programa com uma lista encadeada para armazenar dados de livros em uma biblioteca. 11.6 Crie um programa com lista encadeada para catalogar clientes e fitas em uma vdeo locadora. 11.7 Crie uma estrutura para descrever restaurantes. Os membros devem armazenar o nome, o endereo, o preo mdio e o tipo de comida. Crie uma lista ligada que apresente os restaurantes de um certo tipo de comida indexados pelo preo. O menor preo deve ser o primeiro da lista. Escreva um programa que pea o tipo de comida e imprima os restaurantes que oferecem ete tipo de comida. 11.8 Escreva um programa para montar uma matriz de estruturas para armazenar as notas de 40 alunos. O primeira coluna da matriz deve conter o nome do aluno, a segunda o telefone, a terceira a data de nascimento, depois seguem as notas em lista e na ltima coluna deve ser calculada a mdia at o presente momento. A professora deve ser capaz de inserir e retirar alunos, e poder editar os dados dos alunos. A professora deve poder tambm lista os dados de todos alunos na forma de uma tabela na tela do computador. A lista de alunos deve ser indexada pelo nome destes. Utilize a idia da lista ligada e da alocao dinmica de memria.

4.12 Manipulao de Arquivos em C


Neste captulo, veremos brevemente a manipulao de arquivos em C. Em um captulo posterior, ser apresentada novamente a manipulao de arquivos utilizando C++.

4.12.1

Tipos de Arquivos

Uma maneira de classificar operaes de acesso a arquivos conforme a forma como eles so abertos: em modo texto ou em modo binrio. Arquivos em modo texto, operam em dados armazenados em formato texto, ou seja, os dados so traduzidos para caracteres e estes caracteres so escritos nos arquivos. Por esta razo, fica mais fcil de compreender os seus formatos e localizar possveis erros.

Marcelo Ricardo Stemmer

113

Informtica Industrial I

DAS/UFSC

Arquivos em modo binrio, operam em dados binrios, ou seja, os dados escritos neste formato so escritos na forma binria, no necessitando de nenhuma converso do tipo do dado utilizado para ASCII e ocupando bem menos memria de disco (arquivos menores). Uma outra diferena entre o modo texto e o modo binrio a forma usada para guardar nmeros no disco. Na forma de texto, os nmeros so guardados como cadeias de caracteres, enquanto que na forma binria so guardados com esto na memria, dois bytes para um inteiro, quatro bytes para float e assim por diante.

4.12.2

Declarao, abertura e fechamento

C declara um tipo especial de estrutura, chamada FILE, para operar com arquivos. Este tipo definido na biblioteca stdio.h, que deve ser incluida na compilao com a diretiva #include para permitir operaes sobre arquivos. Os membros da estrutura FILE contm informaes sobre o arquivo a ser usado, tais como: seu atual tamanho, a localizao de seus buffers de dados, se o arquivo est sendo lido ou gravado, etc. Toda operao realizada sobre um arquivo (abertura, fechamento, leitura, escrita) requer um apontador para uma estrutura do tipo FILE:
FILE *File_ptr;

A abertura de um arquivo feita com a funo fopen():


File_ptr = fopen(Nome do Arquivo,<I/O mode>);

onde as opes para a abertura do arquivo esto listadas abaixo: I/O mode Funo: Read, abre arquivo para leitura. O arquivo deve existir. r Write, abre arquivo para escrita. Se o arquivo estiver presente ele ser destrudo e w reinicializado. Se no existir, ele ser criado. Append, abre arquivo para escrita. Os dados sero adicionados ao fim do arquivo se a este existir, ou um novo arquivo ser criado. Read, abre um arquivo para leitura e gravao. O arquivo deve existir e pode ser r+ atualizado. Write, abre um arquivo para leitura e gravao. Se o arquivo estiver presente ele ser w+ destrudo e reinicializado. Se no existir, ele ser criado. Append, abre um arquivo para atualizaes ou para adicionar dados ao seu final. a+ Text, arquivo contm texto dados em ASCII. t Binary, arquivo contm dados em binrio. b A funo fopen() executa duas tarefas. Primeiro, ela preenche a estrutura FILE com as informaes necessrias para o programa e para o sistema operacional, assim eles podem se comunicar. Segundo, fopen() retorna um ponteiro do tipo FILE que aponta para a localizao na memria da estrutura FILE. A funo fopen() pode no conseguir abrir um arquivo por algum motivo (falta de espao em disco, arquivo inexistente, etc.) e por isso esta retornar um ponteiro invlido, isto , contendo o valor NULL (0). Por isso, teste sempre se o ponteiro fornecido por fopen() vlido antes de utilizado, caso contrrio o seu programa pode vir a ter uma falha sria. Quando terminamos a gravao do arquivo, precisamos fech-lo. O fechamento de um arquivo feito com a funo fclose():
fclose(File_ptr);

Marcelo Ricardo Stemmer

114

Informtica Industrial I

DAS/UFSC

Quando fechamos um arquivo que o sistema operacional ir salvar as suas modificaes ou at mesmo criar o arquivo, no caso de ser um arquivo novo. At ento, o sistema operacional estava salvando as alteraes em um buffer antes de escrever estes dados no arquivo. Este procedimento executado para otimizar o tempo de acesso ao disco empregado pelo sistma operacional. Por isso, no esquea de fechar um arquivo, seno os seus dados podem ser perdidos e o arquivo no seja criado adequadamente. Uma outra razo para fechar o arquivo a deliberar as reas de comunicao usadas, para que estejam disponveis a outros arquivos. Estas reas incluem a estrutura FILE e o buffer. Uma outra funo que fecha arquivos a funo exit(). A funo exit() difere da funo fclose() em vrios pontos. Primeiro, exit() fecha todos os arquivos abertos. Segundo, a funo exit() tambm termina o programa e devolve o controle ao sistema operacional. A funo fclose() simplesmente fecha o arquivo associado ao ponteiro FILE usado como argumento.

4.12.3

Leitura e escrita de caracteres

A funo usada para ler um nico caracter de um arquivo getc() enquanto que a funo putc() escreve um caracter em um arquivo. Abaixo, apresentamos exemplos destas funes: Escrita
#include <stdio.h> FILE *fileptr; char filename[65]; char mychar; fileptr = fopen(filename,w); putchar(mychar,fileptr); fclose(fileptr);

Leitura
#include <stdio.h> FILE *fileptr; char filename[65]; int mychar; int i = 0; fileptr = fopen(filename,r); mychar = getchar(fileptr); while(mychar != EOF) { printf(%c, mychar); mychar = getchar(fileptr); } fclose(fileptr);

4.12.4

Fim de Arquivo (EOF)

EOF um sinal enviado pelo sistema operacional para indicar o fim de um arquivo. O sinal EOF (Fim de Arquivo) enviado pelo sistema operacional para o programa C no um caracter, e sim um inteiro de valor 1 e est definido em stdio.h. Perceba que no exemplo anterior de leitura de caracteres, ns usamos uma varivel inteira para guardar os caracteres lidos para que possamos interpretar o sinal de EOF. Se usarmos uma varivel do tipo char, o caractere de cdigo ASCII 255 decimal (0xFF em Hexa) ser interpretado como EOF. Queremos usar todos os caracteres de 0 a 255 em nosso arquivo e uma varivel inteira nos assegura isto. Neste exemplo, EOF usado para ler todos os caracteres de um dado arquivo, quando no conhecemos de antemo a quantidade de caracteres deste arquivo. A marca de fim de arquivo pode ser diferente para diferentes sistemas operacionais. Assim, o valor de EOF pode ser qualquer. O seu arquivo stdio.h define EOF com o valor correto para o seu sistema operacional; assim, em seus programas, use EOF para testar fim de arquivo. O fim de um arquivo pode tambm ser determinado utilizando-se a funo feof(), que recebe como parmetro um ponteiro vlido para a estrutura FILE.

Marcelo Ricardo Stemmer

115

Informtica Industrial I

DAS/UFSC

4.12.5

Leitura e escrita de strings

A funo fputs() escreve uma string em um arquivo e, por isso, toma dois argumentos, sendo o primeiro a matriz de caracteres que ser gravada e o segundo o ponteiro para a estrutura FILE do arquivo a ser gravado. Observe que a funo fputs() no coloca automaticamente o caractere de nova-linha no fim de cada linha. No programa exemplo abaixo, fazemos isto explicitamente com o caracter \n. A funo gets() l uma linha por vez de um arquivo texto. A funo gets() toma 3 argumentos. O primeiro um ponteiro para o buffer onde ser colocada a linha lida. O segundo um nmero inteiro que indica o limite mximo de caracteres a serem lidos. Na verdade, este nmero deve ser pelo menos um maior que o nmero de caracteres lidos, pois gets() acrescenta o caractere NULL (\0) na prxima posio livre. O terceiro argumento um ponteiro para a estrutura FILE do arquivo a ser lido. A funo termina a leitura aps ler um caractere de nova linha (\n) ou um caractere de fim de arquivo (EOF). Escrita:
#include <stdio.h> FILE *fileptr; char filename[65]; char line[81]; fileptr = fopen(filename, w); fputs(line, fileptr); /* fprintf(fileptr,%s\n, line) */ fputs(\n, fileptr); /* pode ser usado aqui no lugar */ fclose(fileptr); /* dos dois fputs */

Leitura:
#include <stdio.h> FILE *fileptr; char filename[65]; char line[81]; fileptr = fopen(filename, r); fgets(line, 80, fileptr); /* fscanf(fileptr, %s, line); */ close(fileptr); /* pode ser usado no lugar de fgets */

4.12.6

Arquivos Padro

C define um conjunto de arquivos padro utilizados para acessar alguns perifricos do computador (como a impressora) ou para ler da entrada padro (normalmente o teclado) ou escrever para a sada padro (normalmente a tela). Desta forma, _streams[] foi criada como uma matriz de estruturas FILE. Se voc perder um tempo e analisar o seu arquivo stdio.h, encontrar vrias constantes simblicas definidas como:
#define #define #define #define #define stdin stdout stderr stdaux stdprn (&_streams[0]) (&_streams[1]) (&_streams[2]) (&_streams[3]) (&_streams[4])

Estas constantes podem ser usadas para acessar qualquer um dos 5 arquivos padro que so predefinidos pelo MS-DOS e abertos automaticamente quando o seu programa inicia a sua execuo e fechados ao seu fim.

Marcelo Ricardo Stemmer

116

Informtica Industrial I

DAS/UFSC

Nome: stdin stdout stderr stdaux stdprn

Perifrico: Standard input device (teclado) Standard output device (tela) Standard error device (tela) Standard auxiliary device (porta serial) Standard printing device (impressora paralela)

Cada uma destas constantes pode ser tratada como um ponteiro para uma estrutura FILE dos arquivos in, out, err, aux e prn respectivamente. Voc pode usar os ponteiros FILE definidos em stdio.h para acessar os perifricos predefinidos pelo MS-DOS ou usar seus nomes e definir os ponteiros necessrios. Como exemplo, a instruo:
fgets(string, 80, stdin);

l uma string do teclado. A instruo:


fputs(string, stdprn);

imprimir uma string na impressora.

4.12.7

Gravando um Arquivo de Maneira Formatada

Nos captulos iniciais apresentamos a funo printf() para imprimir na tela dados de forma formatada. Para realizar a mesma tarefa, entretanto no para escrever na tela mas sim para um arquivo, foi criada a funo fprintf(). Esta funo similar a printf() exceto que o ponteiro para FILE tomado como primeiro argumento. Como em printf(), podemos formatra os dados de vrias maneiras; todas as possibilidades de formato de printf() operam com fprintf(). Da mesma forma foi criada a funo fscanf(), que como scanf(), l um dado formatado. A diferena consiste que fscanf() l um dado de um arquivo e recebe um ponteiro para FILE como primeiro argumento. Exemplo :
#include <stdio.h> FILE *fptr; int size = 0; fptr = fopen(dados.txt, rw); fscanf(fptr, %d, &size); fprintf(fptr, %s %d %f, Casa Nova, 12, 13.45); fclose(fptr);

4.12.8

Leitura e escrita de valores binrios

Quando desejamos operar com arquivos no modo binrio, basta adicionar o caracter b no I/O Mode da funo open(), como apresentado anteriormente. As funes apresentadas anteriormente podem ser usadas para ler e escrever no modo binrio, entretanto apresentaremos aqui duas novas funes que facilitam este processo: fwrite() e fread(). Estas funes so empregadas para escrever/ler os dados armazenados em um bloco de memria (um buffer de memria) em um arquivo. Aplicaes tpicas e na escrita/leitura de dados complexos como matrizes e estruturas. A funo fwrite() toma 4 argumentos. O primeiro um ponteiro do tipo void que aponta para a localizao na memria do dado a ser gravado. O segundo argumento um nmero inteiro que indica o tamanho do tipo de dado a ser gravado. Normalmente, pode-se utilizar o operador
Marcelo Ricardo Stemmer
117

Informtica Industrial I

DAS/UFSC

sizeof() para se obter este valor. O terceiro argumento um nmero inteiro que informa a fwrite() quantos itens do mesmo tipo sero gravados. O quarto argumento um ponteiro para a estrutura FILE do arquivo onde queremos gravar. A funo fread() toma tambm 4 argumentos. O primeiro um ponteiro void para a localizao da memria onde sero armazenados os dados lidos. O segundo indica tambm a quantidade de bytes do tipo de dado a ser lido. O terceiro argumento informa a quantidade de itens a serem lidos a cada chamada, e o quarto argumento um ponteiro para a estrutura FILE do arquivo a ser lido. A funo fread() retorna o nmero de itens lidos. Normalmente este nmero deve ser igual ao terceiro argumento. Se for encontrado o fim do arquivo, o nmero ser menor que o valor do terceiro argumento, podendo ser zero caso nenhum dado tenha sido lido. As funes fread()e fwrite() trabalham com qualquer tipo de dado, incluindo matrizes e estruturas, e armazenam nmeros em formato binrio. Escrita:
fileptr = fopen(filename, wb); fwrite(&dados, sizeof(dados),1 ,fileptr);

Leitura:
fileptr = fopen(filename, rb); fread(&dados,sizeof(dados),1 ,fileptr);

Se "filename" for inicializado com prn, os dados so enviados a impressora. Exemplo:


fileptr=fopen(filename,rb); while(!feof(fileptr)) { fread(&dados, sizeof(dados),1,fileptr); } fclose(fileptr);

4.12.9

Exerccios

12.1 Escreva um programa que imprima um arquivo na tela de 20 em 20 linhas. O arquivo de entrada deve ser fornecido na linha de comando. A cada impresso de 20 linhas, o programa aguarda o pressionamento de uma tecla. 12.2 Escreva um programa que imprima o tamanho de um arquivo em bytes. O nome do arquivo deve ser fornecido na linha de comando. 12.3 Escreva um programa que criptografa um arquivo usando o operador de complemento de bit-a-bit (~). Quando o programa executado para um arquivo j criptografado, o arquivo recomposto e volta ao original. 12.4 Refaa o problema 11.5, agora salvando a lista de livros em um arquivo. Permita que o usurio possa retirar um livro desta lista, apagando-o do arquivo, ou adicionar um livro em uma posio determinada na lista, reescrevendo a lista no arquivo. Utilize o modo texto para a manipulao de arquivos. 12.5 Como o exemplo anterior, refaa o problema 11.6 mas agora utilizando o modo binrio.

Marcelo Ricardo Stemmer

118

Informtica Industrial I

DAS/UFSC

4.13 Programao em C++


A linguagem C foi e continua sendo uma das linguagens mais importantes na rea da informtica. Apesar do seu timo desempenho em termos de programas otimizados, velozes e portteis, sofreu duras crticas com relao a qualidade do cdigo gerado considerando-se outros aspectos de relevncia da engenharia de software como: legibilidade do cdigo, sua reusabilidade e facilidade de manuteno. Um programa de computador sempre busca representar uma dada realidade (mundo real ou modelo abstrato: matemtico) atravs de uma linguagem de programao. Quando criamos qualquer programa simples de computador, estamos na verdade criando um modelo da realidade e usando este modelo para analisar e estudar esta realidade. O nvel de detalhe com que criamos um programa depende diretamente do nvel de detalhe necessrio para modelar o ambiente de acordo com as necessidades impostas pelo usurio. Modelar um determinado ambiente complexo utilizando-se somente as estruturas e funcionalidades disponveis por C (linguagem estrutural) uma tarefa rdua. Por esta razo, alguns programadores em C no conseguem muitas vezes entender determinados cdigos em C, pois no conseguem entender o modelo da realidade gerado por este programa ou a sua estrutura. Neste sentido, criou-se uma forma totalmente nova e revolucionria para se modelar e simular um ambiente dado (mundo real ou sistema abstrato): a Orientao a Objetos. A Orientao a Objetos busca modelar um ambiente utilizando-se dos prprios elementos presentes neste ambiente, ou seja, os objetos. Todo ambiente pode ser modelado e simulado a partir de uma descrio dos objetos que o compe e das relaes entre eles. Por exemplo, suponha que voc esteja criando um programa para permitir que um arquiteto crie um modelo grfico de uma sala-de-estar e apresente este modelo ao seu cliente. Empregando a metodologia de Orientao a Objetos, primeiramente o arquiteto ter que identificar os objetos que compem a sala-de-estar que, considerando o nvel de abstrao do seu modelo, devem ser descritos. Neste caso, podemos facilmente listar alguns objetos que podem ser definidos: janela, porta, parede, sof, mesa, quadro, tapete, vaso de flores, etc. A quantidade de objetos e o nvel de detalhe da sua descrio dependero necessariamente do nvel de abstrao do modelo, ou seja, daquilo que o arquiteto considera importante que esteja no modelo. Por exemplo, representar o objeto mesa pode significar para um marceneiro definir a sua geometria, o tipo de material, o tipo de verniz requerido e o tipo do seu acabamento, enquanto que para um arquiteto significa definir a textura da mesa, o tom da sua cor, o seu custo, a durabilidade desta, etc. Por isso, importante ter em mente, as necessidades do seu cliente antes de criar um modelo super detalhado e ineficiente. Aps a definio dos objetos que compem um dado ambiente, precisamos definir as relaes entre estes. Por exemplo, precisamos definir que um objeto porta e um objeto janela esto posicionados sob a mesma parede, ou seja, so propriedades de um terceiro objeto chamado parede. Assim, como outro objeto parede pode no conter uma janela mas um objeto do tipo quadro. Podemos at criar um objeto chamado sala que contm todos os objetos presente na sala descrita pelo arquiteto e permitir que este arquiteto venha criar futuramente outros objetos como cozinha ou quarto e possa, assim, modelar toda uma residncia. Com este breve esclarecimento j apontamos algumas das propriedades vantagosas fornecidas pela programao Orientada a Objetos. A linguagem C++ foi criada a partir da linguagem C, acrescentando novas estruturas e mecanismos que possibilitam a gerao de programas segundo a metodologia de Orientao a Objetos. Algumas linguagens como Smalltalk refletem muito mais a cultura ou a metodologia Orientada a Objetos, favorecendo a gerao de programas segundo esta metodologia. C++ uma espcie de adaptao de C a metodologia de Orientao a Objetos e, por isso, no possui todas as facilidades e mecanismos de uma linguagem puramente Orientada a Objetos como Smalltalk. Entretanto, C++ herda de C a capacidade de gerar
Marcelo Ricardo Stemmer
119

Informtica Industrial I

DAS/UFSC

programas pequenos, otimizados, de baixo-nvel e portveis. Estes motivos propiciaram a grande difuso que a linguagem C++ vem sofrendo nos ltimos anos. A gerao de cdigos em C++ requer normalmente um tempo maior de desenvolvimento que um programa em C normal. Entretanto os ganhos em reusabilidade e em diminuio dos tempos de manuteno do programa, fazem com que C++ seja mais atrativo para a gerao de mdios e grandes sistemas. Emprega-se C basicamente quando temos que fazer um programa em pouco tempo, com grandes restries na dimenso do cdigo e no tempo disponvel para o processamento do programa (requisistos de tempo-real). A reusabilidade advm do fato que objetos definidos para representar um dado ambiente, podem ser empregados para representar um outro ambiente. Por exemplo, para representar o ambiente sala-de-estar, haviamos definido o objeto mesa. Podemos, entretanto, utilizar o mesmo objeto mesa para representar o ambiente cozinha, sem precisar redefini-lo novamente. Neste aspecto, ganhamos em tempo de desenvolvimento. A modelagem orientada a objetos fornece uma estrutura bem clara para o cdigo fonte do programa. Isto permite que outro programador possa entender o programa criado, reutilizar partes em outros programas e, ainda, facilmente localizar erros no cdigo fonte. Por exemplo, suponha que na hora em que o programa estiver desenhando o objeto mesa na tela para o cliente do arquiteto aparea algum defeinto na mesa. Poderemos, ento, facilmente concluir que: ou o objeto mesa esta mal representado (erro dentro da definio do objeto mesa), ou a relao deste objeto com os demais esta mal definida (por exemplo, a posio deste objeto na sala), ou o mecanismo responsvel pelo desenho deste objeto na tela no est operando corretamente. Isto nos permite que, rapidamente, possamos localizar, isolar e, em seguida, corrigir este erro. A programao orientada a objeto se baseia no encapsulamento de uma estrutura de dados com as prprias rotinas de tratamento dos mesmos e na capacidade de herana destes dados e rotinas por outros objetos derivados. A programao orientada a objeto trz consigo uma srie de vantagems e tambm algumas desvantagems. Como vantagems pode-se citar: existem muitas ferramentas de apoio ao desenvolvimento de programas; os programas tem uma estrutura altamente modular, o que permite um mais fcil controle e expanso dos mesmos. Por exemplo, basta alterar as caractersticas de um objeto "me" para que todos os objetos "filhos" (que herdaram propriedades) sejam tambm automaticamente alterados de forma correspondente; a programao orientada a objeto se baseia fortemente na prpria forma de pensar humana, ao contrario da forma algortmica e procedural da programao convencional. Por outro lado, h tambm desvantagems relativas a esta forma de programao: grande necessidade de memria; grande complexidade de gerenciamento interno das estruturas dos objetos, o que implica em velocidade de execuo menor. difcil otimizao de tempo de execuo dos programas. A otimizao de programas freqntemente requer uma violao das prprias regras de programao orientada a objeto.

Estas desvantagems tem se tornado menos crticas nos ltimos anos devido ao grande aumento da velocidade de processamento dos computadores bem como ao aumento de sua capacidade de memria. Nesta etapa do trabalho, buscaremos agora apresentar os mecanismos mais importantes fornecidos pela linguagem C++, descrevendo no somente a sintaxe de C++ mas tambm conceitos envolvidos na programao Orientada a Objetos. Neste captulo, apresentaremos como C++ brevemente quais so as novidades da linguagem C++. Posteriormente, apresentaremos os demais mecanismos da orientao a objetos.

Marcelo Ricardo Stemmer

120

Informtica Industrial I

DAS/UFSC

4.13.1

Palavras-chave em C++
catch class delete friend inline new operator private protected public template this virtual

A linguagem C++ inclui apenas 14 novas palavras reservadas s j existentes no C:

4.13.2

Sintaxe & Variveis

A linguagem C permite a declarao de variveis dentro de uma funo, somente antes da chamada a instrues que desta funo, ou seja, primeiro declaramos as variveis e depois podemos efetuar uma dada instruo. Em C++, alm destas formas pode-se declarar uma varivel em qualquer ponto de um programa, inclusive entre instrues ou mesmo dentro delas. Em C++, no necessrio utilizar a palavra typedef para se definir uma estrutura. A prpria etiqueta especificando nome (estrutura ou unio) j um tipo nome. Mesmo que no tenhamos usado o typedef, o compilador C++ permitir declaraes de variveis estruturadas sem a necessidade de struct. Assim, podemos redefinr a estrutura list da seguinte maneira :
struct list { char titulo[30]; char autor[30]; int regnum; double preco; }; list * livros; // declarao de uma varivel do tipo list

Em C++, toda varivel que no for declarada explicitamente como static, ser considerada do tipo extern automaticamente. Alm deste default, o C++ ampliou o conceito de escopo para variveis de tipos compostos (estruturas e classes). Essa ampliao consiste em tornar visvel ou inacessvel membros particulares de estruturas e classes. Abordaremos isto quando do estudo de classes. Suponha que ao definir uma funo voc tenha criado uma varivel local com o mesmo nome que uma varivel global (extern). Ao utilizar o nome da varivel, voc estar acessando dentro da funo somente a varivel local. Entretanto, voc pode utilizar o operador :: (escopo) para acessar a varivel global. Veja o exemplo:
int n = 10; // varivel extern, referenciada por: n ou ::n void calc() { int n = 5; // varivel auto, local n = ::n; // varivel local recebe o valor da var. extern. }

A linguaguem C++ apresenta uma outra forma de comentrios: uma linha iniciada pelo para de caracteres de barra //, como indicam os seguintes exemplos:
// Este um comentario em C++ // Aps a barra dupla, tudo comentrio at o final da linha.

Marcelo Ricardo Stemmer

121

Informtica Industrial I

DAS/UFSC

4.13.3

Laos e Comandos de Deciso

A linguagem C++ no modifica a sintaxe ou o comportamento dos laos e comandos condicionais do C. Porm, permite a declarao de variveis na regio de inicializao do for, ou seja, antes do lao estas variveis inexistem. Exemplo:
int j =0; for(int i =0, j=3; i+j<10; i = j++ )

4.13.4

I/O em C++: Stream

A linguagem C++ segue permite a utilizao dos mecanismos de I/O definidos em C, mas define novas bibliotecas, mais adequadas ao paradigma da Orientao a Objetos. Essas bibliotecas constituem a chamada biblioteca Stream do C++, sendo esta biblioteca toda definida em termos de classes de objetos. Nela esto os trs objetos: cin, cout e cerr; destinados entrada e sada de dados via terminal ou via arquivos. As definies e declaraes necessrias para o uso de streams esto contidas no arquivo <iostream.h>.

4.13.4.1

A stream de sada cout

Cout um objeto de uma clase de I/O predefinida em C++. Para mostrar os dados em um programa C++, deve-se utilizar a stream cout. Por default cout est associada a uma sada padro (stdout), i.e., o ao terminal de vdeo. Sintaxe de cout :
cout << expresso;

onde, << : o operador de insero usado a fim de direcionar a sada de dados para a sada padro (vdeo). expresso : qualquer combinao de caracteres ou varivel. Abaixo apresentamos alguns exemplos da utilizao de cout. Note que em nenhuma das declaraes da stream cout so formatados os dados a serem apresentados. Essa formatao feita pela prpria stream. Variveis
int x = 2; float f = 1.2, g = 3; double dou = 2.14; char ch = F;

C++
cout << x = cout << f << cout << valor << dou << << x; << g; = \nsex = << ch;

Resultado
x = 2 1.20 3.00 valor = 2.14 sex = F

No ltimo exemplo acima, mostramos o uso do caracter especial \n para fazer com que o computador pule uma linha antes de continuar escrevendo dados na tela. Podemos utilizar todos os caracteres especiais definidos para printf() da mesma maneira que utilizamos agora \n. Uma lista completa destes caracteres est em 4.3.1. O objeto cout utiliza flags de formatao para sinalizar as opes de formatao dos dados. Os flags (sinalizadores) de formato (definidos em <iomanip.h>) so os seguintes: Manipulador skipws left Right Internal Dec
Marcelo Ricardo Stemmer

Significado ignora o espao em branco na entrada sada ajustada esquerda sada ajustada direita preenchimento aps indicador de sinal ou base converso em decimal
122

Informtica Industrial I

DAS/UFSC

oct Hex Showbase showpoint uppercase showpos scientific fixed unitbuf stdio

converso em octal converso em hexadecimal mostra o indicador de base na sada mostra ponto decimal (para float) sada hexadecimal maiscula mostra o sinal + em inteiros positivos usa notao cientfica de ponto flutuante 1.23E2 usa notao de ponto flutuante 1.23 libera (flush) todas as streams depois da insero libera (flush) stdout, stderr depois de insero

A sintaxe para usar esses sinalizadores (ou flags) a seguinte:


cout.setf(ios::<sinalizador>); // para ligar cout.setf(ios::scientific); cout << 12.345; // Imprimir : 0.12345E2 cout.unsetf(ios::<sinalizador>); // para desligar cout.unsetf(ios::scientific); cout << 12.345 // Imprimir: 12.345

O objeto cout permite estabelecer o tamanho de um campo para a impresso. Isto significa que podemos definir o nmero de colunas que sero ocupados por um valor ou texto a ser impresso. Geralmente, a definio de tamanho de campos usada para alinhamento e esttica de um relatrio. Os manipuladores de formato so utilizados para manipular a formatao dos dados em streams de sada. Alguns manipuladores so idnticos ao sinalizadores, a diferena est na forma mais compacta e na incluso de outra biblioteca de classes <iomanip.h>. Manipulador dec oct hex ws endl ends flush setbase(n) resetiosflags(long) setiosflags(long) setfill(int n) setprecision(int n) setw(int n) Significado passa ara base decimal passa ara base octal passa ara base hexadecimal extrai caracteres de espao em branco insere nova linha e libera stream insere trmino nulo em string \0 libera o buffer de sada ostream alocado ajusta o formato de converso para a base n. default n = 0; limpa os bits de formato em ins ou outs especificadas. ajusta os bits de fomato em ins ou outs especificadas. ajusta o caracter de preenchimento para n ajusta a preciso do ponto flutuante para n ajusta o tamanho do campo para n

Exemplo do uso destes manipuladores:


// Exemplo do emprego de Cout #include <iostream.h> #include <iomanip.h> void main() { float lap = 4.875, bor = 234.5421234546; int can = 42, cad = -8;
Marcelo Ricardo Stemmer

123

Informtica Industrial I

DAS/UFSC

cout cout cout cout cout cout cout }

<< << << << << << <<

"\n\n" << setiosflags(ios::left); setprecision(2); "\n\t" << "Lapis " << setw(12) "\n\t" << "Borracha " << setw(12) "\n\t" << "Canetas " << setw(12) "\n\t" << "Cadernos " << setw(12) "\n\t" << setfill('.') << "Fitas

<< << << <<

lap; bor; can; cad; " << setw(12) << "TYE";

Observao: Se o tamanho do campo especificado em setw for menor que o tamanho mnimo necessrio para imprimir o valor associado, a impresso utilizar o numro necessrio de colunas, ignorando o tamanho do campo. Outro exemplo do emprego destes manipuladores:
// Exemplo do emprego de hex, dec e #include <iostream.h> void main() { int n = 15; cout << "\n" << "Hexadecimal \t" cout << "\n" << "Decimal \t" cout << "\n" << "Octal \t" } oct

<< hex << n; << dec << n; << oct << n;

4.13.4.2

A stream de entrada cin

A forma de entrar com dados em um programa C++ atravs do objeto cin. Tratra-se de um fluxo associado entrada padro do computador (stdin, i.e, o teclado). A sintaxe de cin :
cin >> varivel;

onde >> : o operador de extrao usado para direcionar a entrada de dados entrada padro (teclado). Atravs do contexto, o compilador sabe que este operador no ser o operador para deslocamento de bits mas sim o operador de leitura de dados. varivel : o nome da varivel onde desejamos guardar os valores lidos. Na tabela a seguir, apresentamos alguns exemplos da leitura de dados atravs de cin. Note que em C++ no necessrio formatar o dado que est sendo lido. Cin faz isto automaticamente, de acordo com a declarao da varivel. Variveis C++ C
scanf(%d,&x); scanf(%f %f, &f, &g); scanf(%Lf %c, &dou, &ch);

int x; cin >> x; float f,g; cin >> f >> g; double dou; char ch; cin >> dou >> ch;

O objeto cin faz com que o programa aguarde que voc digite o dado a ser adquirido e pressione a tecla [ENTER] para finalizar a entrada. O operador >> pode apresentar-se diversas vezes numa instruo com a finalidade de permitir a introduo de diversos valores ao mesmo tempo. Mltiplas entradas so digitadas separadas por um espao em branco. O objeto cin entende um espao em branco como trmino de uma entrada e o [ENTER] como finalizador geral. Podemos ler nmeros em outras bases numricas, utilizando os manipuladores hex, dec e oct apresentados anteriormente.

Marcelo Ricardo Stemmer

124

Informtica Industrial I

DAS/UFSC

int n = 0; cin >> hex >> n;

A biblioteca stream define outras funes para leitura e escrita de dados que no sero aqui apresentadas. Todas as funes apresentadas na seco 4.3 podem ser aqui empregadas.

4.13.5 4.13.5.1

Funes Valores Default Para Argumentos de uma Funo

C++ permite a definio de valores default para argumentos de funes. Isto significa que, caso a chamada da funo omita algum parmetro, a funo pode usar o default previamente definido. A forma de definir valores default explicit-los na declarao da funo, omitindo ou no o nome das variveis. Uma vez definidos na declarao, os valores default no devem ser repetidos na definio, pois o compilador reconhece nisto uma duplicidade de default. O exemplo a seguir apresenta a declarao do default de uma funo e chamadas por ele viabilizadas:
unsigned int pares(int, int = 0); int n1 = pares(20,3); int n2 = pares(20); // prottipo

Se o primeiro argumento foi omitido, todos os subsequentes devero ser omitidos. Se o segundo argumento for omitido, todos os subsequentes devero ser omitidos e assim por diante. Podemos escrever funes que tenham parmetros inicializados com um valor default e parmetros no-inicializados, mas aps a primeira inicializao todos os parmetros seguintes devem ser inicializados. Exemplo: void linha( int n = 20, char ch, int cor); // Declarao invlida void linha(int n, char ch = *, int cor = 0); // Declarao vlida.

4.13.5.2

Sobrecarga de Funes

Sobrecarregar funes significa criar uma famlia de funes com o mesmo nome, mas com a lista de parmetros diferentes. Funes sobrecarregadas devem ter a lista de parmetros diferentes ou em nmero ou em tipo. Quando a funo chamada, a lista de parmetros passada para ela que permite ao sistema identificar qual o cdigo adequado. Por exemplo, podemos definir a famlia de funes abaixo, lembrando que devemos definir cada funo como se fosse nica:
int cubo(int n); float cubo(float n); double cubo(double n);

4.13.5.3

Funes Inline
int cubo(int n);

A palavra-chave inline, quando colocada como primeiro elemento do cabealho da definio de uma funo, causa a insero de uma nova cpia da funo em todo lugar onde ela chamada.
inline

A definio de uma funo inline deve preceder a primeira chamada a ela. Ou seja, se a funo for chamada em main(), seu cdigodeve ser escrito antes de main(). Isto necessrio, pois o compilador deve conhecer de antemo o cdigo da funo para poder inseri-la dentro do programa. Uma funo um cdigo presente uma nica vez no programa que pode ser executado muitas vezes. Assim, um dos motivos para escrever funes o de poupar memria. Quando uma

Marcelo Ricardo Stemmer

125

Informtica Industrial I

DAS/UFSC

funo pequena e queremos aumentar a velocidade de execuo de um programa, tranformamos-a em inline.

4.13.5.4

Operador Unrio de Referncia: &

O operador de referncia cria outro nome para uma varivel j criada. As instrues:
int n; int & n1 = n; // toda referncia deve ser inicializada

informam que n1 outro nome para n. Toda operao em qualquer dos nomes tem o mesmo resultado. Uma referncia no uma cpia da varivel a quem se refere. a mesma varivel sob nomes diferentes. O uso mais importante para referncias ao passar argumentos para funes. Os exemplos de argumentos de funes vistos at o momento so passados por valor ou por ponteiros. Quando argumentos so passados por valor, a funo chamada cria novas variveis do mesmo tipo dos argumentos e copia nelas o valor dos argumentos passados. Desta forma, a funo no tem acessoa s variveis originais da funo qe chamou, portanto no as pode modificar. A principal vantagem da passagem por referncia a de que a funo pode acessar as variveis da funo que chamou. Alm desse benefcio, este mecanismo possibilita que uma funo retorne mais de um valor para a funo que chama. Os valores a serem retornados so colocados em referncias de variveis da funo chamadora. A passagem por referncia possui as vantagens da passagem de parmetros por ponteiros, i.e. acesso direto a varivel fornecida como parmetro. No entanto, ponteiros exigem que tenhamos cuidado ao manipular o endereo das variveis para no causar um erro fatal de acesso a memria. Este tipo de preocupao j no existe com passagem por referncia, pois no lidamos com o endereo da varivel mas sim com uma cpia do seu nome. Funes que recebem argumentos por referncia utilizam o operador & somente na definio do tipo do argumento e possuem chamadas idnticas a uma funo normal. Exemplo:
void reajusta( float& num, void main() { float preco = 10; reajusta( preco, 5); reajusta( preco); } void reajusta( float& num, { num *= p; } float& p = 15); // Prottipo

// Chamada a funo // Chamada usando o argumento default float& p) //Definio

4.13.6

Alocao Dinmica de Memria em C++

A alocao dinmica de memria em C++ feita com os operadores new (alocao) e delete (liberao), anlogos as funes malloc() e free(). Em C++, o gerenciamento dinmico de memria to relevante que as palavras new e delete foram incorporadas a linguagem. A diferena bsica entre os operadores C++ e C est na confiabilidade e facilidade de uso. Por exemplo, o tamanho do tipo para o qual se pede memria deve ser informado malloc(), enquanto que new descobre esse tamanho automaticamente. Declarao C: Declarao C++
double *ptr; prt = (double*)malloc(sizeof(double)); double *ptr; ptr = new double;

Marcelo Ricardo Stemmer

126

Informtica Industrial I

DAS/UFSC

C++ j fornece um ponteiro para o tipo de dado fornecido, no necessitando das converses de tipo requeridas por malloc(). Outra vantagem que C++ define quanto de memria necessrio, diminuindo o risco que o programador faa algum tipo de erro. Uma vantagem importante que os operadores new e delete podem ser sobrecarregados (reimplementados) para um tipo de dado criado pelo programador. Isto permite que o programador controle como ser alocada memria para o seu tipo de dado. Sempre que uma memria alocada para uma varivel no for mais necessria, devemos libera-la utilizando o operador delete. As formas de utilizar o operador new (alocao de memria) e delete (liberao de memria) so: a) como operador ou funo
ptr_tipo = new tipo; int * ptr1 = new int; delete ptr1; ptr_tipo = new(tipo); int * ptr2 = new(int); delete ptr2;

b) alocao e liberao de matrizes


ptr_tipo = new tipo[tamanho_matriz]; int * ptr3 = new int[10]; delete[] ptr3; // ou, explicitamente: delete[10] ptr3;

c) alocao e liberao de matrizes de ponteiros


ptr_ptr_tipo = new tipo * [tamanho_matriz]; int * * ptr4 = new int * [10]; delete[] ptr4; // ou, explicitamente: delete[10] ptr4;

Analogamente ao que ocorre a funo malloc() do C, o operador new retorna um ponteiro nulo quando a memria disponvel insuficiente. Assim, devemos sempre verificar se a alocao foi realizada com sucesso, ou seja, se o ponteiro contm um endereo diferente de zero.

4.13.7

Exerccios

13.1 Reescreva alguns programas dos exerccios anteriores utilizando agora os novos mecanismos C++ como cout, cin e passagem de parmetros por referncia. 13.2 Escreva um programa que desenhe na tela o grfico da funo y = cos(x) + x/2. Utilize cout e cin para isto. Desenhe todos os elementos do grfico: ttulo, legenda, linhas horizontal e vertical e numerao. Marque os pontos pertencentes ao grfico com o caracter (*). 13.2 Crie um programa para fazer cadastro de doentes em um hospital. Utilize estruturas e funes, com passagem de parmetros por referncia. O programa deve apenas adquirir os dados e quando o usurio terminar o cadastro, o programa deve imprimir na tela todas as fichas feitas. 13.3 Modifique o programa acima para utilizar agoar a alocao dinmica em C++ e organize agora as fichas por ordem alfabtica do nome do paciente.

4.14 Classes e Objetos em C++


No captulo anterior comeamos a apresentar a idia da Orientao a Objetos em C++. Agora vamos comear a explicar o que so classes e objetos. Suponha que estamos criando um programa de computador que jogue xadrez contra o usurio. Primeiramente, como no problema do arquiteto, temos um ambiente a modelar (no caso o jogo de xadrez) e vamos utilizar os componentes deste ambiente para descrev-lo. Analisando-se rapidamente um jogo de xadrez, apontamos vrios elementos que devem ser modelados.
Marcelo Ricardo Stemmer
127

Informtica Industrial I

DAS/UFSC

Podemos modelar o tabuleiro definindo a suas dimenses, quantas posies livres existem, a cor do tabuleiro, definir mtodos para desenhar este tabuleiro na tela e mtodos para controlar a posies das peas no tabuleiro. Podemos em seguida modelar todas as peas do jogo de xadrez. Cada uma destas peas ser um objeto do nosso programa. Para cada pea, i.e. cada objeto pea, devemos definir algumas propriedades desta como tipo (peo, rei, rainha, torre, bispo e cavalo), de que time pertence (se pertence ao time do computador ou ao time do usurio), a cor desta pea e o seu desenho geomtrico. Alguns mtodos tambm so necessrios como definir a maneira como esta pea pode ser movimentada no tabuleiro, a posio inicial desta pea no tabuleiro, como esta pea pode ser desenhada na tela, etc. Aqui j fica bem clara a idia do que sejam os objetos no jogo. O tabuleiro e cada uma de suas peas sero objetos no nosso programa. Desta forma, podemos modelar cada elemento isolado, permitindo assim uma boa estrutura para o programa e capacidade de reutilizao. Mas o que vem a ser as classes do nosso programa. Classes definem tipos de objetos. Quando modelamos as peas do tipo peo, percebemos que temos vrios elementos no nosso ambiente com estas caractersticas, i.e., temos mltiplas instncias do objeto peo. Ento, definimos uma classe chamada peo e definimos nesta classe todos as propriedades e mtodos definidos para o elemento peo. Adicionamos um ndice para podermos referenciar cada elemento peo isoladamente. Assim, definida a classe peo, podemos criar quantas instncias (objetos) desta classe quanto desejarmos. Todo objeto deve ser modelo a partir da definio da classe que o representa. Desta forma, temos que definir as classes para as demais peas do xadrex como o rei e a rainha. Entretanto, podamos ter criado somente uma classe entitulada: peas do xadrex. Desta forma no teremos uma classe para cada tipo de pea do xadrez mas uma classe que representa todos os tipos de peas de xadrez. Definir esta classe ser uma atividade muito mais complexa e insegura (no sentido de poder gerar erros) que definir cada tipo de pea isoladamente. Por exemplo, nesta classe a dimenso da pea de xadrez e o mtodo com que esta deve ser movimentada no tabuleiro vo ser diferentes para cada tipo de pea (peo, torre, bispo, ...). Isto nos leva a ter definies complexas para as atributos e mtodos desta classe. Devemos utilizar a primeira representao ou a segunda? Bom, depende do nvel de abstrao que desejamos (nvel de detalhamento). Se o programador achar mais fcil tratar somente um tipo genrico de pea de xadrez, no a motivos para refinar este modelo. Se o programador desejar ter um controle diferenciado para cada tipo das peas, ento melhor refinar o modelo e criar uma classe para cada tipo. O bom senso que define o quanto voc deve ou no refinar um modelo, tome cuidado para no criar classes desnecessrias. Voc pode estar achando que terminamos, ou seja, que o jogo de xadrez j est modelado definindo-se o tabuleiro e as peas. Est seria uma intuio normal, pois estes so os elementos que vemos quando jogamos xadrez. Mas no podemos esquecer de definir alguns elementos abstratos que esto inseridos no modelo. O primeiro o prprio jogador. No queremos que o computador jogue contra o usurio, ento devemos ter que modelar o jogador, definindo as suas propriedades como a cor da suas peas e os seus mtodos, que aqui incluem as suas estratgias de jogo. Outro elemento necessrio uma espcie de juiz, que controlar as regras do jogo, saber quando a vez do usurio ou do programador, isto , devemos definir uma classe que controlar a execuo do programa. Por fim, devemos ainda definir alguns elementos necessrios para a interface do programa, como uma janela na tela onde desenharemos o tabuleiro, o mouse para que o usurio possa mexer as suas peas e todos os demais elementos necessrios. Para cada um destes elementos, deveremos definir as propriedades e mtodos que segundo esta nossa aplicao podem modelar corretamente o nosso ambiente. Quando criamos as classes de objetos, tambm definimos as relaes entre eles. Descrevendo os componentes do ambiente e a relao entre eles, j teremos ento uma representao similar deste.

Marcelo Ricardo Stemmer

128

Informtica Industrial I

DAS/UFSC

Neste captulo seguimos apresentando a sintaxe para definio de classes de objetos em C++.

4.14.1

Tipo Classe e o Encapsulamento de Dados

A idia fundamental de linguagens orientadas a objetos a possibilidade de combinar num nico registro campos que contero dados e campos que so funes para operar os campos de dados do registro. Uma unidade assim chamada classe. Uma instncia (varivel) de uma classe chamada objeto e conter campos de dados e funes. Definir uma classe no cria nenhum objeto, do mesmo modo que a existncia do tipo int no cria nenhuma varivel inteira. As funes de um objeto so chamadas funes-membro ou mtodos e, de modo geral, so o nico meio de acesso aos campos de dados tambm chamados de variveis de instncia. Se o programa necessita atribuir um valor a alguma varivel de instncia, deve chamar uma funo-membro que recebe o valor como argumento e faz a alterao. Devemos evitar o acesso a variveis de instncia diretamente. Desta forma, os campos de dados estaro escondidos para ns, o que previne alteraes acidentais ou invlidas. Dizemos ento que os campos de dados e suas funes esto encapsulados (de cpsula) numa nica entidade. As palavras encapsular e esconder so termos tcnicos da definio de linguagens orientadas a objetos. O conceito de esconder dados significa que eles estaro confinados dentro da classe e no podero ser alterados, por descuido, por funes que no pertenam a classe. Se alguma modificao ocorrer em variveis de instncia de um certo objeto, sabemos exatamente quais funes interagiram com elas: so as funes-membro do objeto. Nenhuma outra funo pode acessar esses dados. Isso simplifica a escrita, manuteno e alterao do programa. Um programa em C++ consiste em um conjunto de objetos que se comunicam por meio de chamadas s funes-membro.

4.14.2

Definindo Classes

Vamos comear com um exemplo que mostra os elementos bsicos na definio de classes e criao de objetos. O exemplo cria uma classe para representar um retngulo.
// Exemplo de uma classe #include <iostream.h> class Retangulo // Define a classe { private: int bas, alt; // atributos privados public: static int n; // atributos publicos // Construtores e Destrutores Retangulo() Retangulo(int a, int b=0); ~Retangulo() // metodos da classe void Init(int b, int h) void PrintData();
Marcelo Ricardo Stemmer
129

{ bas=0; alt=0; n++; }

{ n--; }

{ bas = b; alt = h; }

Informtica Industrial I

DAS/UFSC

}; Retangulo::Retangulo(int a, int b) { bas = a; alt = b; n++; } void Retangulo::PrintData() // Define funcao membro { cout << "\nBase = " << bas << " Altura = " << alt; cout << "\nArea = " << (bas*alt); } // incializacao da variavel estatica int Retangulo::n = 0; void main() { Retangulo X(2,3); Retangulo Y[5]; // Declaracao de objetos Retangulo C[2] = { Retangulo(2,3), Retangulo(5,1) }; Y[0].Init( 5, 3); // Chama funcao membro de inicializacao

X.PrintData(); // Chama funcao membro Y[1].PrintData(); (C + 1)->PrintData(); cout << "\n Quantidade de Objetos : " << C[1].n; }

A classe Retngulo possui trs atributos e 5 funes. Agrupar dados e funes numa mesma entidade o fundamento da programao orientada a objetos. A primeira tarefa na orientao a objetos definir as classes. Uma definio de classe sempre comea pela palavra-chave class seguida do nome da classe (Retangulo, neste exemplo), de seu corpo delimitado por chaves e finalizado com um ponto-e-vrgula.

4.14.3

Membros Privados e Pblicos

O corpo da definio da nossa classe contm as palavras private e public seguidas de doispontos. Elas especificam a visibilidade dos membros. Os membros definidos aps private: so chamados de parte privada da classe e podem ser acessados pela classe inteira, mas no fora dela. Um membro privado no pode ser acessado por meio de um objeto. Este conceito equivalente relao existente entre uma funo e as suas variveis locais (auto), elas no so visveis fora da funo. Geralmente, na parte privada da classe so colocados os membros que contero dados. No entanto, pode-se colocar tambm funes que s podero ser chamadas por outras funes da prpria classe. Dizemos ento que esses dados e funes estaro escondidos. A seco pblica da classe formada pelos membros definidos aps public: e pode ser acessada por qualquer funo-membro e por qualquer outra funo do programa onde um objeto foi declarado. Os membros pblicos fazem a interface entre o programador e a classe. Geralmente, na parte pblica de uma classe so colocadas as funes que iro operar os dados. Podemos, entretanto,
Marcelo Ricardo Stemmer
130

Informtica Industrial I

DAS/UFSC

colocar dados na parte pblica da classe, entretanto estes dados podero ser acessados diretamente pelos objetos desta classe. Ento, no poderemos controlar o acesso a este dado da classe. No exemplo acima, os dados bas e alt tem acesso privado, enquanto que o dado n e todas as funes tem acesso pblico.

4.14.4

Funes-Membro

Funes-membro, tambm chamadas mtodos, so as que esto dentro da classe. Na classe Retangulo, definimos 5 funes-membro: Retangulo(), Retangulo(int, int), ~Retangulo(), Init(int, int) e PrintData(). Estas funes executam operaes comuns em classes: atribuem valores aos dados e imprimem certos resultados. Observe que a funo Init(int, int) recebe como parmetro dois nmeros inteiros e tm seu cdigo definido dentro da definio da classe. Funes-membro de cdigo definido dentro da classe so criadas como inline por default, tornando a execuo desta mais rpida mas ocupando um espao maior de memria para armazenar o programa. Podemos, entretanto, definir funes-membro em algum lugar do programa fora da classe, contanto que o seu prottipo seja escrito dentro do corpo da definio da classe. Isto informa ao compilador que elas fazem parte da classe, mas foram definidas fora dela. No nosso exemplo, definimos a funo PrintData()fora da classe. Observe que na definio destas funes membro, o nome da funo precedido pelo nome da classe (no caso: Retangulo) e por um smbolo formado por dois caracteres de dois-pontos (::). Este smbolo chamado operador de resoluo de escopo. Este operador o meio pelo qual informamos ao compilador que a funo sendo definida est associada quela classe particular. No nosso exemplo, o operador de resoluo escopo informa que a funo PrintData() membro da classe Retangulo. Sendo assim, a definio completa fica:
Retangulo::Retangulo(int a, int b) { bas = a; alt = b; n++; }

4.14.5

Construtores & Destrutores

Muitas vezes conveniente inicializar um objeto (instncia da classe) quando ele criado, sem necessidade de efetuar uma chamada a funo-membro para que os dados sejam inicializados. A inicializao automtica de um objeto efetuada por meio da chamada a uma funo-membro especial quando o objeto criado. Esta funo-membro conhecida como construtor. Um construtor uma funo-membro que tem o mesmo nome da classe e executada automaticamente toda vez que um objeto criado. Quando um objeto da classe Retangulo criado, chama-se automaticamente o construtor da classe para inicializar os dados desta. Observe que um construtor no deve retornar valor nenhum. O motivo ele ser chamado diretamente pelo sistema e portanto no h como recuperar um valor de retorno. Por isso, que declaramos um construtor, sem nenhum tipo, nas instrues :
Retangulo() { bas=0; alt=0; n++; } Retangulo(int a, int b=0);

No nosso exemplo, o construtor Retangulo() foi definido dentro da classe enquanto que o construtor Retangulo(int, int) foi definido fora desta, ficando claro na definio que um construtor no retorna nenhum tipo de dado.
Marcelo Ricardo Stemmer
131

Informtica Industrial I

DAS/UFSC

Um construtor pode perfeitamente chamar uma funo-membro. O seu cdigo igual ao de qualquer outra funo, exceto pela falta de tipo. Podemos sobrecarregar construtores para podermos criar objetos de forma diferenciada. No nosso exemplo fica clara esta aplicao. Podemos utilizar o construtor Retangulo() para inicializar o objetos com dados default, ou utilizar o construtor Retangulo(int, int) para explicitamente fornecer os valores iniciais para os dados da classe. Note que este segundo construtor faz uso de valores default para os parmetros, permitindo assim que o usurio precise fornecer somente o primeiro parmetro. O compilador decide qual construtor chamar de acordo com os parmetros passados. O construtor Retangulo() tem um importncia imensa em C++, chamado de construtor default. Sempre que um objeto for criado, se nenhum outro construtor puder se utilizado (nenhum dado pode ser fornecido), ento com certeza o construtor default ser utilizado. Por exemplo, quando criamos uma matriz de objetos de uma classe. No interessante ter que inicializar cada objeto individualmente. Por isso, o programa utiliza o construtor default para criar todos os objetos juntos e inicializar todos com este construtor. Desta forma, podemos sempre garantir uma inicializao dos dados com o construtor default. Outro elemento importante o construtor de cpia, utilizado para iniciar um objeto como sendo uma cpia fiel de um objeto j existente. Este operador, pode ser definido passando-se como parmetro do construtor o objeto que desejamos copiar. Aplicando no nosso exemplo, teramos:
Retangulo(Retangulo Ret);

Uma funo destrutora chamada automaticamente toda vez que um objeto destrudo (liberado da memria) e tem o mesmo nome da classe precedido de um til (~):
~Retangulo() { n--; }

Da mesma forma que um construtor, os destrutores no podem ter valor de retorno. O destrutor tambm no pode receber argumentos (por isso, cada classe possui somente um construtor) nem pode ser chamado explicitamente pelo programador.

4.14.6

Criando Objetos

Aps a definio da classe Retangulo, podemos declarar uma ou mais instncias desse tipo. Uma instncia de uma classe chamada objeto, como j mencionamos anteriormente. No nosso exemplo, criamos objetos da classe Retangulo atravs das instrues:
Retangulo X(2,3); Retangulo Y[5]; // Declaracao de objetos Retangulo C[2] = { Retangulo(2,3), Retangulo(5,1) };

A primeira instruo cria um objeto da classe Retangulo chamado X, inicializando-o como o construtor Retangulo(int, int). A segunda instruo cria uma matriz unidimensional de objetos da classe Retangulo. Neste caso, o construtor default empregado para a inicializao dos objetos. A terceira instruo cria um matriz unidimensional de objetos da classe Retangulo. A matriz inicializada com um conjunto de objetos Retangulo. Note que a inicializao de matrizes de objetos mantm o formato anterior, ou seja, elementos delimitados por chaves, separados por vrgulas e o fim da instruo definido pelo (;) ponto-e-vrgula. Observe que a definio da classe no cria nenhum objeto, somente o descreve. Este conceito idntico ao das estruturas que, quando definidas, no criam nenhuma varivel. Declarar um objeto similar a declarar uma varivel de qualquer tipo; o espao de memria reservado.
Marcelo Ricardo Stemmer
132

Informtica Industrial I

DAS/UFSC

4.14.7

Atributos do Tipo Static

Cada objeto de uma classe possui a sua prpria cpia dos dados da classe. Entretanto, muitas vezes desejamos que todos os objetos de uma classe tenham acesso um mesmo item de dado. Este item faria o mesmo papel de uma varivel externa, porm ser visvel somente a todos os objetos daquela classe. Quando um dado membro declarado como static, criado um nico item para a classe como um todo, no importando o nmero de objetos declarados. Isto significa que o programa alocou somente um espao de memria onde todos os objetos desta classe iro acessar este dado. A informao de um membro static compartilhada por todos os objetos da mesma classe. Um membro static definido com um atributo qualquer da classe, tendo a mesma visibilidade de um membro normal da classe. Abaixo, mostramos a declarao de um membro static com visibilidade pblica da classe Retangulo.
static int n;

Dados static devem ser obrigatoriamente redefinidos fora da definio da classe. Voc pode considerar que a definio de um atributo da classe como static, simplesmente notifica o compilador que existe um varivel global (extern) que ser utilizados por todos os objetos desta classe para armazenar este atributo. A declarao desta varivel fora da classe que irar realmente criar esta varivel, alocando memria para esta. Esta declarao feita em qualquer lugar fora da classe, da seguinte forma:
int Retangulo::n = 0;

Note que a palavra chave static no foi empregada e que utilizamos Retangulo:: para indicar que n pertence a classe Retangulo, ou seja, s pode ser acessado atravs desta classe. Nesta declarao, podemos efetuar a inicializao desta varivel, como apresentado acima. Este tipo de varivel pode ser bem til. No programa exemplo, a utilizamos para contar o nmero de objetos criados. Note que cada vez que criamos um objeto, chamamos o seu construtor que incrementar automaticamente n. Se destruirmos um objeto, chamamos o seu destrutor que ir decrementar n. Desta forma, n conta automaticamente o nmero de objetos existentes de uma certa classe. Observao: um dado do tipo static no pode ser inicializado no construtor de uma classe pois, se no, toda vez que criarmos um objeto desta classe, estaremos reinicializando o valor desta varivel static para todos os demais objetos. Funes podem ser definidas como static. Funes static tm caractersticas similares as variveis static. So utilizadas para implementar recursos comuns a todos os objetos da classe. Funes-membro static agem independentemente de qualquer objeto declarado. Conseqentemente, estas funes no podem acessar nenhum membro no-static da classe. Funes membro static acessam somente membros static de classe. Funes static podem ser chamadas usando a mesma sintaxe utilizada para acessar dados static.
class moeda { private: static float US; public: static void usvalor() { cout << \nDigite o valor do dlar: ; cin >> US; } }; moeda::usvalor();
Marcelo Ricardo Stemmer
133

Informtica Industrial I

DAS/UFSC

4.14.8

Acessando Funes e Dados Pblicos

Os membros pblicos de um objeto so acessados por meio do operador ponto. A sintaxe similar de acesso aos membros de estrutura. As funes-membro s podem ser chamadas quando associadas ao objeto especfico pelo operador ponto. Uma funo-membro age sobre um objeto particular e no sobre a classe como um todo. Nosso programa fornece algums exemplos deste tipo de acesso: Primeiro, acessando a funo Init(int, int) do primeiro objeto da matriz Y:
Y[0].Init( 5, 3); // Chama funcao membro de inicializacao

Aqui, acessando a funo PrintData():


X.PrintData(); Y[1].PrintData(); // Chama funcao membro

Note que podemos utilizar este operador para acessar dados pblicos:
cout << "\n Quantidade de Objetos : " << C[1].n;

Como n uma varivel global (static) associada classe Retangulo, podemos acessar este dado sem associ-lo a nenhum objeto ou at mesmo, sem nunca ter criado um objeto desta classe. Ao definir esta varivel fora da classe, nos j alocamos memria para ela fosse inicializada. Para acess-la, basta utilizar o operador (::) para referenciar a classe associada a esta varivel. Portanto, no caso de variveis static, ambas instrues abaixo so equivalentes:
C[1].n == Retangulo::n

O operador (->) pode ser utilizado quando tempos um ponteiro para um objeto e queremos acessar um membro (dado ou funo) pblico desta classe. No nosso exemplo, empregamos este operador na instruo abaixo:
(C + 1)->PrintData();

4.14.9

Objetos Const

O qualificador const na declarao de um objeto indica que o objeto uma constante e nenhum de seus dados pode ser alterado. Por exemplo, a instruo abaixo cria X como um objeto constante, ou seja, os dados de X no podem ser alterados em tempo de execuo:
const Retangulo X(2,3);

Quando um objeto constante declarado, o compilador probe a ele o acesso a qualquer funo membro, pois no consegue identificar quais funes alteram os seus dados. Entretanto, h um modo de informar ao compilador que uma funo-membro no altera nenhum dado do objeto e que poderemos cham-la por meio de um objeto constate. Ao colocar a palavra const aps os parnteses que envolvem a lista de parmetros da funo, estaremos indicando que a funo no modifica o objeto. A palavra const deve ser adicionada tanto no prottipo da funo quanto na sua declarao. Desta forma possvel acess-la a partir de um objeto const. Por exemplo, vamos transformar a funo PrintData() em const, para podermos utilizla junto com o objeto X:
class Retangulo { void PrintData() const; };
Marcelo Ricardo Stemmer

134

Informtica Industrial I

DAS/UFSC

void Retangulo::PrintData() const // Define funcao membro { cout << "\nBase = " << bas << " Altura = " << alt; cout << "\nArea = " << (bas*alt); }

4.14.10 Tipo Objeto


Objetos de classes podem ser usados normalmente como qualquer outro tipo de dado. Por isso podemos utiliz-los para definir matrizes de objetos ou para passar como parmetro, da mesma forma que fazemos com outros tipos de dados. As funes membro so criadas e colocadas na memria somente uma vez para a classe toda. As funes membro so compartilhadas por todos os objetos da classe. No caso dos dados, para cada objeto declarado, uma nova regio na memria alocada de forma que cada objeto possui o seu conjunto de dados.

4.14.11 Exerccios
14.1 Crie um programa para calcular a mdia das notas dos alunos de uma turma. Modele cada aluno com o seu conjunto de notas como sendo uma classe. Imprima na tela usando cout. 14.2 Usando a idia da lista ligada apresentada captulo de estruturas, crie um programa para representar restaurantes empregando uma lista ligada construda com classes. 14.3 Crie um programa que faa o controle de cadastro de usurios e controle de alocao para uma locadora de fitas de vdeo. Utilize uma classe para os clientes e outra para as fitas, e emprege o mtodo da lista ligada para gerenciar um vetor dinmico. O usurio de poder incluir/retirar um cliente ou uma fita, fazer uma pesquisa, pedir a lista de clientes e a lista de fitas ou alterar algum parmetro destas. 14.4 Escreva um programa para controlar o acesso das vagas de um estacionamento. Armazene dados importantes do carro como chapa do carro, a hora de entrada, a hora de sada. Controle a lotao do estacionamento e verifique se existem vagas disponveis. O programa deve gerar automaticamente o preo do estacionamento, quando o usurio retirar o carro. No esquea que alguns clientes podem ficar mais tempo do que o tempo notificado. 14.5 Modelo o problema do jogo do xadrez apresentado no incio do captulo. Mas no jogue contra o computador mas contra um outro usurio usando o mesmo micro.

4.15 Sobrecarga de Operadores


O sentido do polimorfismo o de um nico nome para definir vrias formas distintas. Em C++, chamamos de polimorfismo a criao de uma famlia de funes que compartilham do mesmo nome, mas cada uma tem cdigo independente. O resultado da ao de cada uma das funes da famlia o mesmo. A maneira de atingir esse resultado distinta. Como exemplo, suponhamos que desejemos calcular o salrio lquido de todos os funcionrios de uma empresa. Nessa empresa, h horistas, mensalistas, os que ganham por comisso, etc. Criamos um conjunto de funes em que cada uma tem um mtodo diferente de calcular o salrio. Quando a funo chamada, C++ saber identificar qual a funo com o cdigo adequado ao contexto.

Marcelo Ricardo Stemmer

135

Informtica Industrial I

DAS/UFSC

A sobrecarga um tipo particular de polimorfismo. Como exemplo, tomemos o operador aritmtico (+). Em C++, usamos esse operador para somar nmeros inteiros ou para somar nmeros reais:
5 + 4 3.7 + 12.5

O computador executa operaes completamente diferentes para somar nmeros inteiros e nmeros reais. A utilizao de um mesmo smbolo para a execuo de operaes distintas chamada sobrecarga. O polimorfismo e a sobrecarga so habilidades nicas em linguagens orientadas a objetos. Os operadores em C++ so definidos como funes normais, onde o nome da funo o smbolo do operador e os parmetros da funo so os operandos do operador. Por exemplo, o operador de soma para nmeros inteiros possui uma declarao do tipo:
int operator +(int a, int b);

Ou seja, a operao (a+b), vista por C++ como uma chamada a funo acima declarada. Quando escrevermos em nosso cdigo esta operao, C++ utilizar a definio desta funo para efetuar a operao. Note que a nica diferena na declarao ou definio de um operador que o nome de um operador definido pela palavra chave operator seguida de espao mais o smbolo que representa o operador, neste caso (+). Assim, podemos tratar qualquer operador como sendo uma funo normal mas que possui um nome especial e uma forma especial de chamada. Perceba que, quando escrevemos no cdigo (a+b), C++ interpreta esta instruo como uma chamada a funo operator + e passa para esta os parmetros a e b. Se os operadores so tratados por C++ como uma funo qualquer, qual a razo da sua existncia? Suponha, que tenhamos definido a seguinte funo que executa a operao (a + b) :
int soma(int a, int b);

Qual das duas formas abaixo mais clara e intuitiva para se escrever a soma de dois nmeros? int c = soma( a, b); int c = a + b; claro que ser a segunda forma. Por isso, podemos tornar o nosso cdigo-fonte muito mais organizado e claro empregando-se os operadores ao invs de funes normais. Assim como qualquer outra funo em C++, os operadores podem ser sobrecarregados para outras aplicaes, i.e., podemos redefinir os operadores para serem empregados em outros tipos de dados criados pelo programador. Suponha que tenhamos criado uma classe para representar os nmeros complexos, chamada complexo. Ento, com a sobrecarga do operador (+) poderemos redefinir a seguinte funo para dois elementos da nossa classe:
complexo A, B; A = A + B;

Note que esta definio bem intuitiva e clara. Esta caracterstica muito importante para o programador, permitindo que este possa definir como os operadores existentes em C++ atuaro com relao aos tipos de dados definidos pelo programador. Somente os operadores j existentes em C++ podem ser sobrecarregados (redefinidos) para operar sobre novos tipos de dados definidos pelo programador. Por exemplo, no podemos definir o smbolo (#) como um operador, pois este smbolo no declarado por C++ como sendo um operador.
Marcelo Ricardo Stemmer
136

Informtica Industrial I

DAS/UFSC

Sobrecarregar um operador significa redefinir o seu smbolo, de maneira que ele se aplique tambm a tipos de dados definidos pelo usurio como classes e estruturas. Sobrecarregar uma funo significa utilizar um mesmo nome para tarefas parecidas, mas de cdigos de programa diferentes. Vrias funes com o mesmo nome podem apresentar diferentes implementaes (trechos de programa). No instante em que voc encontrar uma limitao pelo modo como os operadores C++ trabalham, pode mud-los conforme as suas necessidades, por meio de sobrecargas.

0.0.0 A Sobrecarga como uma Funo Global


A implementao de sobrecargas de operadores definida por meio de funes chamadas operadoras. Estas funes podem ser criadas como membros de classes ou como funes globais, acessveis a todo o programa. A seguir vamos apresentar a sobrecarga do operador ++() incremento prefixado para a classe Ponto, criada para representar um ponto localizado no espao bidimensional e que, por esta razo, contm as coordenadas x e y do ponto.
//Ponto2 - Mostra a sobrecarga de operadores #include <iostream.h> class Ponto { public: int X, Y; Ponto(int aX = 0, int aY = 0) { X = aX; Y = aY; } void PrintPt() const {cout << '(' << X << ','<< Y <<')';} }; Ponto operator ++(Ponto ObjPonto) //incremento prefixado { ++ObjPonto.X; ++ObjPonto.Y; return ObjPonto; } void main() { Ponto P1(1,2); cout << "\n p1 = "; P1.PrintPt(); cout << "\n++p1 = "; (++P1).PrintPt(); }

A classe Ponto uma classe normal, possui dois atributos com acesso publico, uma funo construtora para inicializar os atributos e uma funo para imprimir os dados na tela. Sobrecarregamos o operador ++() para incrementar os dados contidos em um objeto desta classe. Aps a declarao da classe, segue a declarao do operador. Note que o operador declarado como qualquer funo global, a nica diferena a palavra-chave operator na frente do smbolo ++. O operador recebe como parmetro um objeto da classe Ponto e retorna tambm um objeto desta classe. O operador recebe somente um parmetro, pois no caso, este um operador unrio e, por definio, s pode receber um nico parmetro. O operador acessa os dados pblicos da classe Ponto e incrementa cada um deles, retornando o prprio objeto passado como parmetro com o resultado da operao.
Marcelo Ricardo Stemmer
137

Informtica Industrial I

DAS/UFSC

Em seguida, empregamos o novo operador incrementando o objeto P1 e imprimindo na tela o resultado gerado por este operador.

0.0.0 Limitaes e Caractersticas


A sobrecarga de operadores permite uma nova implementao da maneira como um operador funciona. Entretanto, necessrio respeitar a definio original do operador. Por exemplo, no possvel mudar um operador binrio (que trabalha com dois operandos) para criar um operador unrio (que trabalha com um nico operando). No permitido tambm estender a linguagem inventando nossos operadores representados com smbolos novos. Por exemplo, no se pode inventar uma operao usando o smbolo ##. Este smbolo no um operador vlido em C++ e voc no poder torn-lo um operador. Devemos limitar-nos aos operadores j existentes. A definio de operadores deve obedecer precedncia original do operador. Por exemplo, o operador de multiplicao (*) tem precedncia sobre o de adio (+). No possvel modificar a precedncia de operadores por meio de sobrecargas. Nem todos os operadores podem ser sobrecarregados. Os seguintes operadores no podem ser sobrecarregados: o operador ponto de acesso a membros e o operador condicional ternrio (?:). Os operadores unrios operam sobre um nico operando. Exemplos de operadores unrios so o de incremento (++), decremento (--) e menos unrio (-). Por outro lado; os operadores binrios operam sobre dois operandos (+, -, *, /, >, +=, etc...). Por causa desta diferena, uma ateno especial deve ser dada ao uso de cada tipo. Quando definimos um operador como sendo uma funo-membro de uma classe, o primeiro parmetro passado para a funo operadora ser considerado automaticamente como sendo um objeto desta classe. Declarar um operador como sendo membro de uma classe, permite que este tenha acesso a todos os dados desta classe, tenha as permisses de acesso como qualquer outra funo membro e possa desfrutar das vantagens fornecidas pela herana de classes, apresentada no prximo captulo. Na declarao de operadores como funes globais, os operadores unrios recebero um nico parmetro enquanto que os operadores binrios recebero dois parmetros. J na declarao de operadores como funes-membro de uma dada classe, j que o primeiro operando sempre um objeto da classe, os operadores binrios no recebero parmetros enquanto que os operadores binrios recebero um nico parmetro. Uma funo operadora deve ter definido um tipo de retorno, para que o resultado da operao com este tipo possa ser atribudo a outras variveis. Por exemplo, ao definir o operador (a+b), temos que definir que esta operao retorna algum valor do tipo da varivel c, para poder executar a seguinte instruo: c = a + b;

4.15.4

Sobrecarga de Operadores como Funo-Membro

No exemplo anterior, apresentamos a declarao do operador de incremento pr-fixado redefinido globalmente. Vamos agora, redefinir este operador com uma funo-membro da classe Ponto.
#include <iostream.h> class Ponto { private: int X, Y;
Marcelo Ricardo Stemmer
138

Informtica Industrial I

DAS/UFSC

public: Ponto(int aX = 0, int aY = 0) { X = aX; Y = aY; } void PrintPt() const {cout << '(' << X << ','<< Y <<')';} Ponto operator ++() //incremento prefixado { ++X; ++Y; Ponto Temp(X,Y); return Temp; } }; void main() { Ponto P1, P2(2,3); cout << "\n p1 = "; P1.PrintPt(); cout << "\n++p1 = "; (++P1).PrintPt(); cout << "\n++p2 = "; (++P2).PrintPt(); P2 = ++P1; cout << "\n p2 = "; P2.PrintPt(); }

Neste exemplo, efetuamos algumas modificaes importantes. Os dados da classe Ponto, passaram a ter acesso privado, no podendo mais ser acessados por nenhuma funo global. Sobrecarregamos o operador incremento prefixado como sendo uma funo-membro da classe Ponto, note que agora esta funo no recebe nenhum parmetro. A definio da funo praticamente igual a anterior, retirando-se o parmetro. Esta funo uma funo inline da classe Ponto, por esta definida dentro da definio da classe. A funo operadora ++() agora cria um objeto temporrio da classe Ponto para conter o resultado da operao e ser utilizado como retorno da funo. Veremos a seguir, formas diferentes de retornar o resultado de uma funo operadora. Por fim, nada foi modificado no emprego do operador sobrecarregado. Note na funo main(), que o emprego do operador no sofreu nenhuma modificao pelo fato deste ser declarado como uma funo global ou uma funo membro.

4.15.5

Estudo de Casos

Agora apresentaremos a sobrecarga de um grupo importante de operadores em C++ que serviro como exemplo para a sobrecarga de qualquer outro operador existente. Com este exemplo, discutiremos outros aspectos da sobrecarga e voc perceber tambm a utilidade desta ferramenta. O primeiro exemplo cria uma classe para armazenar as notas dos alunos. A sobrecarga de dois operadores foi efetuada. C++ no faz a checagem de limites de matrizes. Por causa disto, a manipulao de matrizes em C++ apresenta vrias falhas e permite erros acidentais de sobreposio de dados de memria se forem usados ndices que ultrapassam o limite de dimenso da matriz. Por isso, efetuamos a sobrecarga do operador [] para testar o limite da matriz. O outro operador, converter um objeto da classe Matriz para um ponteiro float. Isto torna os objetos desta classe mais genricos, podendo ser empregados facilmente para outras aplicaes.

Marcelo Ricardo Stemmer

139

Informtica Industrial I

DAS/UFSC

//Notas : Sobrecarga do operador [] #include <iostream.h> #include <iomanip.h> const MAX = 50; class Matriz { private: float n[MAX]; public: Matriz(); float & operator [](int i); // sobrecarga [] float Media(int i); operator float *() const // Funcao Conversora { return (float *)n; } }; Matriz::Matriz() { for(int i = 0; i<MAX; i++) n[i] = 0.0; } float & Matriz::operator [](int i) { static float x = -1; if(i >= 0 && i < MAX) return n[i]; else { cout << "\nFora de Limite!"; return x; } } float Matriz::Media(int i) { float m = 0.0; for(int j = 0; j < i; j++) m += n[j]; return m/float(i); } void main() { Matriz Notas; cout << setprecision(2); int i = 0; do { cout << "Digite a nota do aluno " << (i + 1) << " : "; cin >> Notas[i]; }while (Notas[i++] >= 0); i--; float * Temp = Notas; cout << "\nNota do Segundo Aluno " << *(Temp + 1); cout << "\n\nMedia das notas : " << Notas.Media(i); }
Marcelo Ricardo Stemmer
140

Informtica Industrial I

DAS/UFSC

O programa cria uma matriz fixa para armazenar as notas dos alunos, imprimindo a mdia das notas no final. A novidade a funo operator[] que checa se o ndice especificado est dentro do limite de dimensionamento da matriz. Se estiver, a funo retorna uma referncia ao elemento correspondente da matriz privada. Se no estiver, a funo imprime uma mensagem de erro e retorna uma referncia a uma varivel static float com valor 1. Isto previne a sobreposio de outras regies da memria caso o limite da matriz seja ultrapassado. A funo operator [] sobrecarrega o operador binrio [] e est definida dentro da classe Matriz. Por isso, recebe um nico parmetro int i. A funo definida fora da classe, e por isso escrevemos Matriz:: antes do nome operator [], para indicar que se trata de uma funo membro. Observe que a funo operator [] retorna uma referncia a um elemento da matriz n. Dessa forma, a expresso notas[i] age como o prprio elemento da matriz privada, podendo ser usado em instrues como :
cin >> notas[i]; notas[i] = 67.75;

Retornar uma referncia no simplesmente eficiente, mas sim necessrio. Caso contrrio, no teremos acesso direto a um elemento da classe mas a uma cpia deste, no podendo assim alterar o valor deste elemento com instrues de atribuio como as declaradas acima. A funo operator [] cria uma varivel static, pois no podemos retornar uma referncia para uma varivel local (automtica) j que esta ser destruda ao final da execuo da funo. Aqui comeamos a discutir alguns aspectos sobre o operador de atribuio (=). Voc sabe que o operador = pode atribuir o valor de uma varivel simples a outra do mesmo tipo. Podemos tambm atribuir um objeto a outro da mesma classe usando instrues como:
Obj2 = Obj1;

Geralmente, quando o valor de um objeto atribudo a outro de mesma classe, o valor de todos os seus membros de dados so simplesmente copiados no novo objeto. O compilador no executa nenhuma instruo especial no uso de atribuies entre tipos definidos pelo usurio. A complexidade surge quando a atribuio entre variveis de tipos diferentes. Podemos converter um valor float para uma varivel inteira atravs de uma das seguintes instrues:
int i = int(3.141567); int i = (int) 3.141567;

Assim como podemos converter um tipo bsico em outro tipo, podemos tambm converter um objeto de uma classe em um tipo bsico ou em um objeto de outra classe. Para converter um tipo definido pelo programador, como classes, num tipo bsico necessrio sobrecarregar o operador de mold, criando uma funo chamada conversora. No exemplo anterior, sobrecarregamos o operador float *() como sendo uma funo da classe Matriz, para converter um objeto desta classe em um ponteiro para uma lista de valores float:
operator float *() const // Funcao Conversora { return (float *)n; }

Este operador foi chamado pela instruo:


float * Temp = Notas;

que poderia ter sido escrita na forma explcita:


float * Temp = float *(Notas);

Marcelo Ricardo Stemmer

141

Informtica Industrial I

DAS/UFSC

As duas formas tm exatamente o mesmo efeito. Primeiro o compilador procura pela sobrecarga da operao de atribuio =() para este tipo, se no encontra, ento o compilador procura pela funo conversora para este tipo. Note que a funo conversora no declara um tipo de retorno, o prprio nome da funo j define o tipo de retorno. No prximo exemplo vamos adicionar um conjunto de operadores a classe Ponto definida anteriormente, para apresentar outras caractersticas e exemplos da sobrecarga de operadores.
// Classe Ponto ... exemplo da sobrecarga de operadores #include <iostream.h> enum bool { false, true }; class Ponto { public: int X, Y; Ponto(int aX = 0, int aY = 0) { X = aX; Y = aY; }

Ponto operator ++(); // prefixado Ponto operator ++(int); // pos-fixado Ponto operator +(Ponto const aP) const; Ponto operator +=(int const aN); bool operator ==(Ponto const aP) const; Ponto operator =(int aN); }; Ponto Ponto::operator ++() //prefixado { ++X; ++Y; return *this; } Ponto Ponto::operator ++(int) //pos-fixado { ++X; ++Y; return Ponto(X-1, Y-1); } Ponto Ponto::operator +(Ponto const aP) const { return Ponto(X + aP.X, Y + aP.Y); } Ponto Ponto::operator +=(int const aN) { X += aN; Y += aN; return *this; } bool Ponto::operator ==(Ponto const aP) const { return ((X == aP.X)&&(Y == aP.Y)); } Ponto Ponto::operator =(int aN) { X = aN; return *this; }

Marcelo Ricardo Stemmer

142

Informtica Industrial I

DAS/UFSC

class PFloat { public: float X, Y; PFloat(float aX = 0, float aY = 0) { X = aX; Y = aY; } operator Ponto() const // Converte tipo { return Ponto((int) X, (int) Y); } };

// Operadores para objetos Iostream ostream & operator<<(ostream & OS, Ponto const aP) { OS << '(' << aP.X << ','<< aP.Y <<')'; } void main() { Ponto P1, P2(2,3), P3; P3 = 2; PFloat Pf( 2.12, 3.14); P1 = Pf; cout << "\n p1 = " << P1; cout << "\n ++p1 = " << ++P1; cout << "\n p2 == p1 ? -> " << (P1 == P2); cout << "\n p2 = " << P2; cout << "\n p2 + p1 = " << (P2+P1); cout << "\n pf = " << Pf; cout << "\n p3 = " << P3; }

Comeamos definindo um tipo enum, para representar os valores booleanos. A classe Ponto possui agora os atributos X e Y como sendo dados pblicos, somente para facilitar o acesso a estas variveis. Ponto possui tambm um construtor default para a inicializao dos dados. Os primeiros operadores sobrecarregados no exemplo so os operadores unrios de incremente pr-fixado e ps-fixado. Dentre os operadores unrios existentes em C++, a sobrecarga dos operadores de incremento e decremento apresenta uma dificuldade maior pelo fato de eles operarem de forma diferente quando prefixados ou ps-fixados. A declarao :
Ponto operator ++(); // prefixado

notifica o compilador da sobrecarga do operador prefixado. A definio do operador idntica a definio apresentada anteriormente. A primeira diferena que a agora operador est definido fora da definio da classe. A segunda diferena esta na forma como retornamos o resultado da operao. Podemos faze-la de trs formas:
a) Ponto Temp( X, Y); return Temp; return Temp( X, Y);
143

b)

Marcelo Ricardo Stemmer

Informtica Industrial I

DAS/UFSC

c)

return *this;

As duas primeiras formas criam um objeto temporrio, armazenam nele os valores obtidos na operao e retornam este objeto temporrio. Neste caso, no podemos utilizar a passagem de parmetros por referncia pois estes objetos temporrios sero destrudos ao trmino da funo. O terceiro utiliza o ponteiro especial this. O ponteiro this um ponteiro especial que pode ser acessado por todas as funes-membro do objeto. Este ponteiro aponta para o prprio objeto. Qualquer funo-membro pode acessar o endereo do objeto do qual membro por meio do ponteiro this. Quando um objeto criado, o compilador atribui o endereo do objeto ao ponteiro this. Usamos o ponteiro this quando queremos que uma funo-membro retorne o prprio objeto do qual membro. Para retornar o prprio objeto, devemos utilizar *this. Aps o operador de incremento prefixado, definimos o operador de incremento ps-fixado. Mas como pode o compilador distinguir os dois, sendo que ambos utilizam o mesmo smbolo e possuem o mesmo operando? Neste caso, C++ adicionou um parmetro inteiro ao operador de incremento ps-fixado, para distingui-lo do prefixado. Este parmetro int no serve para nada, a no ser para podermos distinguir a declarao dos dois tipos de operadores. Por isso, que declaramos este operador da seguinte forma:
Ponto operator ++(int); // pos-fixado

Observe que esta funo operadora definida como a anterior. Entretanto, agora no podemos utilizar o ponteiro this para retornar o prprio objeto mas temos que criar um objeto temporrio que conter o valor a ser retornado. Isto ocorre por que no operador ps-fixado, primeiro ns utilizamos a varivel para depois increment-la. Em seguida, temos a definio dos operadores binrios aritmticos (+) e (+=). Um operador binrio definido como uma funo-membro possuir somente um parmetro, como foi dito anteriormente. Uma classe pode redefinir vrias vezes os operadores binrios, desde que em cada definio tenha um tipo de dado diferente como operando. No exemplo, o operador (+) implementa a soma de dois objetos da classe Ponto, enquanto que o operador (+=) implementa a soma de um valor inteiro a um objeto da classe Ponto, armazenando o resultado no prprio objeto. O operador (+) cria um objeto temporrio para conter o resultado enquanto que o operador (+=) utiliza o ponteiro this para retornar o prprio objeto como resultado. Depois, temos a sobrecarga do operador binrio lgico (==) . Como os operadores acima, este recebe um nico parmetro, que no caso ser outro objeto da classe Ponto. O tipo de retorno aqui um tipo booleano (inteiro), j que o operador do tipo lgico. O programador tem liberdade em C++ para definir a aplicao que ser dada para um operador. Por exemplo, um programador pode sobrecarregar um operador binrio de bis (^=) para atuar como um operador lgico ente objetos de uma dada classe, retornando um valor do tipo inteiro. No significa que um operador lgico, somente poder ser sobrecarregado para efetuar operaes lgicas entre objetos. Podemos, por exemplo, redefinir um operador lgico para efetuar uma operao aritmtica ou qualquer outra operao entre dois objetos. C++ no controla a maneira como utilizamos os operadores com os novos tipos de dados. C++ somente no permite a criao de novos operadores e solicita que o nmero de parmetros definido para cada operador seja respeitado. O que o operador faz, de responsabilidade puramente do programador. Seguindo com o nosso exemplo, o prximo operador definido um operador de atribuio (=), utilizado para atribuir um inteiro a um objeto do tipo Ponto, possuindo a seguinte declarao:
Ponto operator =(int aN);

Marcelo Ricardo Stemmer

144

Informtica Industrial I

DAS/UFSC

O operador atribui a dimenso X do objeto ponto o valor de aN. Note que a forma de declarar e definir o operador a mesma utilizada nos exemplos acima. Este operador tambm utiliza o ponteiro this para retornar o prprio objeto. A novidade aqui aparece quando utilizamos este operador para converter um inteiro em um objeto do tipo Ponto. Esta uma das formas importantes para converter um tipo em outro, e aparece quando executamos a seguinte instruo e atribumos 2 ao objeto Ponto P3:
P3 = 2;

Em seguida, criamos a classe PFloat parecida com a classe Ponto, para exemplificar a converso de objetos de uma classe em objetos de outra classe. Note que PFloat contm as coordenadas de um ponto x e y com valores float. Esta classe, possui tambm um construtor default. A novidade surge na declarao do operador de converso para objeto da classe Ponto:
operator Ponto() const // Converte tipo { return Ponto((int) X, (int) Y); }

No exemplo anterior apresentamos a converso de um objeto da classe Matriz para um ponteiro do tipo float. Aqui, mostramos como podemos criar uma funo conversora para converter um objeto de uma classe em outra classe. A funo operator Ponto() const converter um objeto da classe PFloat para um objeto da classe Ponto. A mesma sintaxe pode ser aplicada para converte qualquer tipo de objeto em uma outra classe. Poderamos tambm implementar esta converso de outras duas formas diferentes. 1) Sobrecarregando o operador de atribuio da classe Ponto, para atribuir um objeto da classe PFloat em um objeto da classe Ponto. 2) Criando um construtor na classe Ponto, que receba como nico parmetro um objeto da classe PFloat:
Ponto::Ponto(PFloat P1) { X =(int)P.X; Y =(int)P.Y;}

O resultado desta converso aparece na execuo da seguinte instruo:


P1 = Pf;

Por fim, sobrecarregamos o operador global de insero de dados em objetos da classe ostream. Como vimos nos captulos anteriores, as classes stream controlam o acesso a entradas e sadas do computador. Em especial, a classe istream controla a entrada padro e a classe ostream controla a sada padro. Lembrando, que o objeto cout pertence classe ostream e o objeto cin classe istream. As classes stream redefiniram os operadores << e >> para operar sobre todos os tipos bsicos existentes em C++. Desta forma, podemos escrever instrues como:
cout << Bom Dia! cin >> n;

chamando automaticamente as funes de leitura e escrita da classe stream atravs da sobrecarga de operadores. Na verso anterior da classe Ponto, utilizvamos a funo PrintPt() para imprimir o valor de um objeto desta classe na tela. Entretanto, podemos fazer isto de uma forma muito mais elegante definindo o operador << para receber como operandos um objeto da classe ostream e um objeto da classe Ponto.
// Operadores para objetos Iostream ostream & operator<<(ostream & OS, Ponto const aP) {
Marcelo Ricardo Stemmer
145

Informtica Industrial I

DAS/UFSC

OS << '(' << aP.X << ','<< aP.Y <<')'; }

Na sobrecarga deste operador, definimos como o objeto da classe Ponto ser apresentado na tela. Definida esta sobrecarga, podemos ento passar um objeto da classe Ponto para um objeto cout, como fazemos com qualquer tipo bsico. O mesmo princpio pode ser utilizado para a sobrecarga do operador >> associando um objeto da classe istream (cin) a um objeto da classe Ponto. Podemos verificar o emprego desta funo sobrecarregada atravs da instruo abaixo, que imprime na tela uma string de caracteres e, em seguida, os dados de um objeto Ponto:
cout << "\n p1 = " << P1;

Entretanto,uma dvida surge, o que acontece na linha de cdigo abaixo:


cout << "\n pf = " << Pf;

Onde Pf um objeto da classe PFloat mas no sobrecarregamos o operador << para receber como segundo parmetro um objeto da classe PFloat. Neste caso, o programa utiliza a funo de converso de objeto PFloat em objetos do tipo Ponto definida acima, para converter este objeto e utilizar a funo operadora << definida para objetos do tipo Ponto. Este exemplo, mostra a importncia e flexibilidade das converses de tipos.

4.15.6

Exerccios

15.1 Acrescente a classe Ponto a sobrecarga dos operadores: menos unrio (-), menos binrio (-), multiplicao (*), diviso (/), mdulo (%), as operaes aritmticas de atribuio e as operaes lgicas. 15.2 Crie uma classe que defina um nmero complexo (x + yi, onde x e y so do tipo float e i a raiz quadrada de 1). Defina, todos os operadores aritmticos, de bits e lgicos para esta classe. Sobrecarregue os operadores << e >> da classe stream, para a leitura/escrita de objetos desta classe. Crie uma outra classe para a representao de nmeros complexos no plano polar. Crie funes de converso, para que os objetos das duas classes sejam equivalentes. 15.3 Crie uma classe para representar strings. Reimplemente os operadores aritmticos, de atribuio e lgicos para o contexto desta classe. Crie funes conversoras dos tipos bsicos (int, char, float, ...) para objetos desta classe. Sobrecarrrege o operador [] para controlar o acesso a elementos individuais da classe string e crie uma funo que converta objetos da classe string em um ponteiro do tipo char. 15.4 Inclua uma sobrecarga do operador de chamada funo () na classe string anterior. O seu prottipo o seguinte:
void operator ()(int n, char ch);

Esta sobrecarga atribui o caracter ch ao ensimo caracter da cadeia. Escreva um programa de teste. 15.5 Crie uma classe para representar as cores (class Cor). Sobrecarregue os operadores aritmticos e relacionais para esta classe. Utilize o princpio, que a soma de duas cores uma cor misturada com metade de cada uma das cores anteriores. Defina as outras funes aritmticas. Utilize os operadores para os objetos cout e cin, para ler e escrever dados desta classe.
Marcelo Ricardo Stemmer
146

Informtica Industrial I

DAS/UFSC

4.16 Herana
Nos captulos anteriores definimos que classe representa um tipo de objeto. Ento, quando modelamos um ambiente atravs da orientao a objetos, criamos uma classe para cada tipo de objeto presente e modelado no ambiente. Entretanto, existem alguns tipos (classes) de objetos que possuem caractersticas semelhantes com outros tipos (classes) de objetos. Por exemplo, quando estamos modelando o funcionamento de um banco, podemos definir como objetos do modelo o cliente que chega na agncia e os funcionrios do banco. Ao modelarmos estas duas entidades, percebemos que ambas possuem determinadas caractersticas em comum; ambas entidades so seres humanos. Por serem pessoas, ambas as entidades contero necessariamente a descrio de uma pessoa mas os seus dados especficos. Para no representar duas vezes o elemento pessoa, uma na entidade cliente e outra na entidade funcionrio, criamos ento uma entidade separada chamada pessoa e descrevemos atravs desta a entidade pessoa. Aps a definio desta nova entidade, dizemos que as classes funcionrios e clientes herdam da classebase pessoa todas as caractersticas que definem um ser humano no nosso modelo. Na Figura 27 apresentamos a diferena entre as duas modelagens.
Classe
Funcionrio C D E

Classe
Cliente F Pessoa A B G

Pessoa A B

Classe-Base
Pessoa A B

Herana
Funcionrio C D E Cliente F G

Classes Derivadas

Figura 27 - Modelagem aplicando-se o princpio da Herana.

O processo de hierarquia est presente quando dividimos classes em sub-classes, mantendose o princpio de que cada subclasse herda as caractersticas da classe da qual foi derivada. Alm das caractersticas herdadas, cada subclasse tem suas caractersticas particulares. Em programao orientada a objetos, o conceito de subclasse ou classes derivadas chamado de herana. Em C++, a classe de origem chamada classe-base e as classes que compartilham as caractersticas de uma classe-base e tm outras caractersticas adicionais so chamadas de classes derivadas. Em C++, definimos uma classe-base quando identificamos caractersticas comuns em um grupo de classes. Com o princpio da herana, alm de precisarmos modelar somente uma vez a entidade pessoa, o nosso modelo ainda ganha em flexibilidade e em organizao do projeto. Suponha que neste modelo voc tenha que futuramente incluir a entidade acionista no modelo do banco. Bom, considerando que todo acionista tambm um ser humano, basta definir que a classe acionista ser
Marcelo Ricardo Stemmer
147

Informtica Industrial I

DAS/UFSC

derivada da classe-base pessoa, herdando todas as suas propriedades (mtodos e atributos), e adicionar a classe acionista as suas propriedades particulares. Podemos ainda refinar o modelo acima, criando diferentes classes para modelar diferentes tipos de clientes. Podemos criar uma classe para modelar os clientes que so universitrios. Esta classe seria um refinamento da classe cliente e, por isso, representamos esta entidade como uma classe derivada da classe cliente. Neste sentido, somente precisamos adicionar as propriedades particulares da classe cliente-universitrio como: o nmero de matrcula, o nome do curso e a data prevista para a formatura. Uma classe que derivada de uma classe-base pode, por sua vez, ser a classe-base de outra classe. Outro aspecto importante a reutilizao do programa. Suponha que amanh aparea um projeto para modelarmos uma clula de produo de uma fbrica. Neste modelo, precisamos modelar pessoas com diferentes propriedades: engenheiros, gerentes e funcionrios. Neste caso, podemos utilizar a nossa classe-base pessoa para definir estas trs novas classes, ganhando assim em tempo de projeto. Se recebermos um outro novo projeto para representar uma padaria, poderemos ento aproveitar diversas entidades do nosso modelo como as classes pessoa, cliente, funcionrio e cliente-universitrio. Diminuindo, assim, consideravelmente o tempo deste projeto. Voc pode ento criar uma biblioteca com todas as classes definidas que podero vir a ser o ncleo de muitos programas. Desta forma, voc ter grandes vantagens em termos de reutilizao e baixo custo de projeto.O uso de uma biblioteca de classes oferece uma grande vantagem sobre o uso de uma biblioteca de funes: o programador pode criar classes derivadas de classes-base da biblioteca. Isto significa que, sem alterar a classe-base, possvel adicionar a ela caractersticas diferentes que a tornaro capaz de representar exatamente o que desejamos. A facilidade com que classes existentes podem ser reutilizadas sem ser alteradas um dos maiores benefcios oferecidos por linguagens orientadas a objetos. O processo de herana vai alm da derivao simples. Uma classe derivada pode herdar caractersticas de mais de uma classe-base. Classes derivadas no esto limitadas a herana nica. Sempre que estivermos modelando um ambiente, seja este real ou abstrato, precisamos fazlo da forma mais genrica possvel. Quando mais genrico for o modelo, mais flexvel ser o nosso sistema e maior ser a reusabilidade e expansibilidade do nosso sistema. Modelar um sistema significa representar todas as propriedades importantes deste e no descrever este da maneira mais detalhada possvel. No exagere no nvel de detalhe do seu modelo. Isto diminuir a flexibilidade do seu modelo, aumentar o tempo de projeto, aumentar a quantidade de erros, diminuir a velocidade do programa e aumentar o tamanho deste. A orientao a objetos realmente muito poderosa, permitindo-nos a construo de projetos flexveis, permitindo a reutilizao de partes do modelo e do cdigo bem como a fcil expanso do sistema. Entretanto, a eficincia do seu programa orientado a objetos depende diretamente da qualidade do seu modelo. Modelos enxutos e bem definidos, geram programas velozes e flexveis. Modelos enormes e obscuros, geram programas gordos e complexos, cheios de erros, ilegveis e que no podem ser reaproveitados. Tenha conscincia ao modelar um sistema e bom-senso para definir as classes e as suas relaes. O bom entendimento da metodologia orientada a objetos, permitir que voc modele adequadamente um sistema qualquer.

4.16.1

Derivando uma Classe

Agora mostraremos como podemos implementar em C++ a criao de uma classe base e a sua derivao criando uma nova classe. Aqui, apresentaremos na forma de um exemplo a sintaxe empregada em C++. Como exemplo, vamos modelar a classe Pessoa apresentada como exemplo acima e a classe cliente, derivada da classe Pessoa.
// Exemplo de classes derivadas ... #include <iostream.h> #include <string.h>
Marcelo Ricardo Stemmer
148

Informtica Industrial I

DAS/UFSC

#define

Nome_Size

80

class Pessoa { protected: char * int long int

Nome; Idade; RG;

public: Pessoa(); Pessoa(char * aNome, int aId = 0, long int aRG = 0); Pessoa(Pessoa const & aP); ~Pessoa(); char const * GetNome() const { return Nome; } int GetIdade() const { return Idade; } long int GetRG() const { return RG; void GetData(); }; Pessoa::Pessoa() { Nome = new char[Nome_Size]; Idade = 0; RG = 0; } Pessoa::Pessoa( char * aNome, int aId, long int aRG) { Nome = new char[Nome_Size]; strcpy( Nome, aNome); Idade = aId; RG = aRG; } Pessoa::Pessoa(Pessoa const & aP) { Nome = new char[Nome_Size]; strcpy( Nome, aP.GetNome()); Idade = aP.GetIdade(); RG = aP.GetRG(); } Pessoa::~Pessoa() { if(Nome != 0) { delete Nome; Nome = 0; } } void Pessoa::GetData() { cout << "\nNome : "; cin.getline( (char *)Nome, Nome_Size); cout << "Idade : "; cin >> Idade; cout << "RG : ";
Marcelo Ricardo Stemmer
149

Informtica Industrial I

DAS/UFSC

cin }

>> RG;

ostream & operator <<(ostream & OS, Pessoa & const P) { OS << "\n\n Dados Pessoais ---------------" << "\n Nome : " << P.GetNome() << "\n Idade : " << P.GetIdade() << "\n RG : " << P.GetRG(); return OS; } class Cliente : public Pessoa { protected: int Conta; int Saldo; public: Cliente(); Cliente(char * aNome, int aConta = 0, int aId = 0, long int aRG = 0, int aSaldo = 0); int GetConta() const { return Conta; } int GetSaldo() const { return Saldo; } void GetData(); }; Cliente::Cliente() : Pessoa() { Conta = 0; Saldo = 0; } Cliente::Cliente(char * aNome, int aConta, int aId, long int aRG, int aSaldo) : Pessoa(aNome, aId, aRG) { Conta = aConta; Saldo = aSaldo; } void Cliente::GetData() { Pessoa::GetData(); cout << "Conta : "; cin >> Conta; cout << "Saldo : "; cin >> Saldo; } ostream & operator <<(ostream & OS, Cliente & const C) { OS << Pessoa(C); OS << "\n Conta : " << C.GetConta() << "\n Saldo : " << C.GetSaldo(); return OS; } void main() { Pessoa P1("Carlos", 18, 1315678);
Marcelo Ricardo Stemmer
150

Informtica Industrial I

DAS/UFSC

Cliente C1, C2("Pedro", 1234, 17, 123432); C2.GetData(); C1.Pessoa::GetData(); Pessoa P2 = P1; Pessoa P3 = C1; cout << P1 << P2 << P3; cout << C1 << C2; }

Para derivar uma nova classe de uma classe j existente, basta indicar o nome da classe-base aps o nome da nova classe, separado por dois-pontos (:). O nome da classe-base pode ser precedido da palavra public ou da palavra private.
class Cliente : public Pessoa

Esta declarao indica que a classe Cliente derivada da classe Pessoa. A classe Cliente incorpora todos os membros da classe Pessoa, alm de seus prprios membros. Nem sempre queremos criar objetos da classe-base. Muitas vezes declaramos classes somente para que estas sirvam como uma classe-base para um conjunto de classes derivadas. Classes usadas somente para derivar outras classes so geralmente chamadas classes abstratas, o que indica que nenhuma instncia (objeto) delas criado. Entretanto, o termo abstrato tem uma definio mais precisa quando usado com funes virtuais, apresentado no prximo captulo.

4.16.2

Dados Protected

Observe que a parte pblica da classe-base est disponvel classe derivada e a qualquer objeto dessa classe. Qualquer membro pblico da classe-base automaticamente um membro da classe derivada. Entretanto, nenhum membro privado da classe-base pode ser acessado pela classe derivada. Por isso, criou-se os membros protected. Membros protected so semelhantes a membros private, exceto pelo fato de que so visveis a todos os membros de uma classe derivada. Observe que membros protected no podem ser acessados por nenhum objeto declarado fora dessas classes. Sempre que voc escrever uma classe que pode vir a ser uma classe-base de outras classes, declare como protected os membros privados necessrios s classes derivadas. Segundo este princpio, os dados definidos na classe-base Pessoa estaro disponveis a funes membro da classe Cliente pois foram definidas como protected. Entretanto, tero restries do tipo private para acessos fora da classe-base ou fora da classe derivada.

4.16.3

Construtores & Destrutores

Se nenhum construtor for especificado na classe derivada, o construtor da classe-base ser usado automaticamente. Observe os construtores da classe Cliente:
Cliente::Cliente() : Pessoa() { Conta = 0; Saldo = 0; } Cliente::Cliente(char * aNome, int aConta, int aId, long int aRG, int aSaldo) : Pessoa(aNome, aId, aRG) { Conta = aConta; Saldo = aSaldo; }

Marcelo Ricardo Stemmer

151

Informtica Industrial I

DAS/UFSC

Estes construtores tm uma sintaxe no familiar: os dois-pontos seguidos do nome da funo construtora da classe-base. Isto causa a chamada ao construtor sem argumentos da classe Pessoa, quando um objeto criado sem valores de inicializao, e a chamada ao construtor com argumentos da classe Cliente, quando fornecemos valores para a inicializao do objeto. A instruo:
Cliente C2("Pedro", 1234, 17, 123432);

usa o construtor com argumentos da classe Cliente. Este construtor chama o construtor correspondente da classe-base, enviando os argumentos recebidos para o construtor da classe-base Pessoa que, por sua vez, inicializa o objeto. Note, que o construtor da classe derivada chama o construtor da classe-base e depois executa algumas rotinas para inicializar somente os dados especficos da classe-derivada. No nosso programa exemplo, a classe Pessoa tem um atributo do tipo ponteiro que alocado dinamicamente quando criamos um objeto e destrudo (liberado) quando destrumos este objeto. Para tal, inclumos a seguinte instruo nos construtores da classe:
Nome = new char[Nome_Size];

Ento, definimos um destrutor para a classe para liberar a memria alocada antes de destruir o objeto. Observe, que antes de liberarmos a memria vamos testar se o ponteiro atual vlido. Mas a classe Cliente no define nenhum destrutor. Isto implica que quando destruirmos um objeto da classe Cliente, o compilador ir utilizar o destrutor da classe-base, liberando assim a memria alocada.

4.16.4

Construtor de Cpia & Alocao Dinmica

O programa cria o objeto P2 e ento atribui a ele o contedo do objeto P1. O seguinte problema acontecer: quando voc atribui um objeto a outro, o compilador copia, byte a byte, todo o contedo de memria de um objeto no outro. Em outras palavras, ao membro Nome de P2 ser atribudo o contedo do membro Nome de P1. Entretanto, o membro Nome um ponteiro e, como resultado, P2.Nome e P1.Nome apontaro para a mesma localizao na memria. Desta forma, qualquer modificao na cadeia de caracteres de um dos objetos afetar diretamente o outro. Um problema mais srio ocorre quando os objetos envolvidos tm escopos diferentes. Quando o destrutor de P1 chamado, destruir a memria alocada e apontada por P1, destruindo portanto a mesma memria apontada por P2. Se P2 tentar acessar o contedo deste ponteiro, um erro fatal ser gerado. Para evitar que este erro acontea, implementamos o construtor de cpia para os objetos da classe Pessoa:
Pessoa(Pessoa const & aP);

Este construtor aloca um espao de memria para armazenar os seus dados e depois copia os valores contidos do objeto passado como argumento. Note que esta funo no copia o endereo contido em Nome, mas sim o valor apontado por este ponteiro. Evitando assim o problema descrito acima. Este construtor de cpia muito importante, geralmente utilizado na converso de outros objetos para este tipo ou na atribuio de objetos. Reimplemente este operador sempre que a sua classe contiver ponteiros com alocao dinmica como atributos.

4.16.5

Chamadas a Funes

O objeto C1 da classe Cliente usa a funo GetData() membro da classe Cliente, na instruo:
C1.GetData();
Marcelo Ricardo Stemmer
152

Informtica Industrial I

DAS/UFSC

O compilador sempre procurar primeiro pela funo na classe que define o objeto (no caso, Cliente). Se o compilador no encontrar esta funo ento ele ir procurar na classe-base da classe do objeto. Se ele encontrar em uma classe-base, o compilador executar a funo encontrada, seno ocorrer um erro. Podemos criar funes-membro de uma classe derivada que tenham o mesmo nome de funes-membro da classe-base. Isto faz com que a sintaxe da chamada a elas, por meio de um objeto, seja a mesma, independentemente de tratar-se de um objeto da classe-base ou da classe derivada. A funo GetData() est definida com o mesmo prottipo tanto na classe-derivada quanto na classe-base, ento qual das verses da funo ser utilizada pelo compilador? A regra a seguinte: Se duas funes de mesmo nome existem uma na classe-base e outra na classe derivada, a funo da classe derivada ser executada se for chamada por meio de um objeto da classe derivada.Se um objeto da classe base criado, usar sempre funes da prpria classe-base pois no conhece nada sobre a classe derivada. Para que uma funo da classe derivada, com mesmo nome de uma funo da classe-base, possa acessar a que est na classe-base, necessrio o uso do operador de resoluo de escopo (::): Pessoa::GetData(); Esta instruo executa a funo GetData() da classe-base dentro da definio desta funo na classe-derivada. Sem o uso do operador de resoluo de escopo, o compilador executar a funo GetData() da classe-derivada e o resultado ser uma seqncia infinita de chamadas recursivas. O operador de resoluo de escopo permite que se especifique exatamente qual a classe da funo que queremos executar.
C2.GetData(); C1.Pessoa::GetData();

A diferena das instrues acima que para o primeiro objeto, estaremos utilizando a verso da funo GetData() definida na classe derivada e para o segundo objeto estaremos utilizando a verso da funo definida na classe-base. A distino entre as duas chamadas feita pelo operador de resoluo de escopo (::).

4.16.6

Herana Pblica e Privada

Declaramos a classe derivada Cliente especificando a palavra public:


class Cliente : public Pessoa

A declarao public indica que os membros pblicos da classe-base sero membros pblicos da classe derivada e os membros protected da classe base sero tambm membros protected da classe derivada. Os membros pblicos da classe-base podem ser acessados por um objeto da classe derivada. A declarao private pode ser usada no lugar de public e indica que tanto os membros pblicos quanto os protegidos da classe-base sero membros privados da classe derivada. Estes membros so acessveis aos membros da classe derivada, mas no aos seus objetos. Portanto, um objeto da classe derivada no ter acesso a nenhum membro da classe-base. Os membros privados da classe-base sero sempre inacessveis fora da classe-base. Nenhuma classe derivada pode acessar um membro privado de uma classe base. Geralmente, a derivao privada raramente usada. Mas h momentos em que a derivao privada desejvel. Por exemplo, imagine que voc tenha uma funo da classe-base que trabalha

Marcelo Ricardo Stemmer

153

Informtica Industrial I

DAS/UFSC

perfeitamente com objetos da classe base, mas gera resultados errados quando usado com objetos da classe derivada. A derivao privada neste caso uma soluo bem elegante.

4.16.7

Converses de Tipos entre Classe-Base e Derivada

Visto que Cliente um tipo de Pessoa, faz sentido pensar em converter um objeto da classe Cliente num objeto da classe Pessoa. C++ permite a converso implcita de um objeto da classe derivada num objeto da classe-base. Por exemplo:
Pessoa P3 = C1; // C1 um objeto da classe Cliente

Todos os membros da classe-base P3 recebem os valores dos membros correspondentes do objeto C1 da classe derivada. Aqui, o construtor de cpia da classe Pessoa evitar que um erro ocorra devido a ponteiro presente na classe. Este construtor utilizado para converter o objeto da classe derivada em um objeto da classe base sem que ambos objetos contenham o mesmo endereo no ponteiro e venham a causar um erro de acesso memria. Entretanto a atribuio inversa no vlida, no podemos atribuir um objeto da classe-base a um objeto da classe derivada. Sobrecarregamos os operadores << associados a objetos da classe ostream, para facilitar a apresentao dos dados dos objetos de ambas as classes na tela. Perceba que na implementao da sobrecarga do operador << para o objeto da classe ostream e um objeto da classe Cliente, que utilizamos uma converso na instruo abaixo:
OS << Pessoa(C);

Esta converso converte temporariamente o objeto C da classe Cliente para um objeto da classe Pessoa. Isto causar a chamada do operador << definido para a classe Pessoa, imprimindo na tela os dados da classe Pessoa presentes no objeto da classe Cliente. Esta instruo opera como se estivssemos chamando uma funo da classe-base utilizando o operador de resoluo de escopo. Aqui no utilizamos o operador, mas convertemos o objeto da classe derivada, para um objeto da classe base antes de chamarmos a funo. O que tem o mesmo resultado.

4.16.8

Nveis de Herana

Uma classe por ser derivada de outra classe , que , por sua vez tambm uma classe derivada.
class X {}; class Y : public X {}; class Z : public Y {};

Neste exemplo, Y derivada de X, e Z derivada de Y. Este processo pode ser estendido para qualquer nmero de nveis, K pode ser derivada de Z, e assim por diante.

4.16.9

Herana Mltipla

Uma classe pode herdar as caractersticas de mais de uma classe. Este processo chamado de herana mltipla. A construo de hierarquias de herana mltipla envolve mais complexidade do que as hierarquias de herana simples. Esta complexidade diz respeito ao desenho da construo das classes e no a sintaxe de uso. A sintaxe de mltiplas heranas similar de uma nica herana. Eis um exemplo que representa os imveis a venda de uma imobiliria :
// Heranca Multipla

Marcelo Ricardo Stemmer

154

Informtica Industrial I

DAS/UFSC

#include #include #include #include

<iostream.h> <stdio.h> <iomanip.h> <string.h>

class Cadastro { private: char nome[30], fone[20]; public: Cadastro() { nome[0] = fone[0] = '\0'; } Cadastro(char n[], char f[]) { strcpy(nome, n); strcpy(fone, f); } void GetData() { cout << "\n\tNome: "; cin.getline(nome, 30); cout << "\tFone: "; cin.getline(fone, 20); } void PutData() { cout << "\n\tNome: " << nome; cout << "\n\tFone: " << fone; } }; class Imovel { private: char end[30], bairro[20]; float AreaUtil, AreaTotal; int quartos; public: Imovel() { end[0] = bairro[0] = '\0'; AreaUtil = AreaTotal = 0; quartos = 0; } Imovel(char e[], char b[], float au, float at, int q) { strcpy(end, e); strcpy(bairro,b); AreaUtil = au; AreaTotal = at; quartos = q; } void GetData() { cout << "\n\tEnd: "; cin.getline(end, 30); cout << "\tBairro: "; cin.getline(bairro, 20); cout << "\tArea Util: "; cin >> AreaUtil; cout << "\tArea Total: "; cin >> AreaTotal;
Marcelo Ricardo Stemmer
155

Informtica Industrial I

DAS/UFSC

cout << "\tNo. Quartos: "; cin >> quartos; } void PutData() { cout << "\n\tEnd : " << end; cout << "\n\tBairro : " << bairro; cout << "\n\tArea Util : " << setiosflags(ios::fixed) << setprecision(2) << AreaUtil << "\n\tArea Total : " << AreaTotal << "\n\tQuartos : " << quartos; } }; class Tipo { private: char tipo[20]; // Residencial, Loja, Galpao public: Tipo() { tipo[0] = '\0'; } Tipo(char t[]) { strcpy(tipo, t); } void GetData() { cout << "\n\tTipo : "; cin.getline(tipo, 20); } void PutData() { cout << "\n\tTipo: " << tipo; } }; class Venda : private Cadastro, public Imovel, public Tipo { private: float valor; public: Venda() : Cadastro(), Imovel(), Tipo() {valor = 0;} Venda(char n[], char f[], char e[], char b[], float au, float at, int q, char t[], float v) : Cadastro(n,f), Imovel(e,b,au,at,q), Tipo(t) { valor = v; } void GetData() { cout << "\n ...Proprietarios: "; Cadastro::GetData(); cout << "\n ...Imovel: "; Imovel::GetData(); Tipo::GetData(); cout << "\tValor R$ : "; cin >> valor; } void PutData() { cout << "\n ...Proprietario: "; Cadastro::PutData(); cout << "\n ...Imovel: "; Imovel::PutData();
Marcelo Ricardo Stemmer
156

Informtica Industrial I

DAS/UFSC

Tipo::PutData(); cout << "\n\tValor R$ : " << valor; } }; void main() { Venda C,V("Eduardo Mattos", "3203322", "Rua Rocha, 33", "Coqueiros", 50.0, 75.0, 2, "Comercial", 80000.0 ); cout << "\n\n* Imovel Para Venda : "; V.PutData(); cout << "\n\n Digite um Imovel para Vender!\n"; C.GetData(); C.PutData(); }

Atravs da declarao:
class Venda : private Cadastro, public Imovel, public Tipo { ... };

notificamos o compilador que a classe Venda derivada das classes Cadastro, Imovel e Tipo. Cadastro tem derivao do tipo privado enquanto as demais classes tm derivaes do tipo pblico. Muitas vezes podemos substituir uma herana por um objeto da classe-base. A escolha do mtodo que devemos aplicar depende muito do modelo adotado e do desempenho esperado. Uma boa modelagem pode definir claramente quais sero as classes criadas e como elas devero interagir. Os construtores da classe Venda so os seguintes:
Venda() : Cadastro(), Imovel(), Tipo() {valor = 0;} Venda(char n[], char f[], char e[], char b[], float au, float at, int q, char t[], float v) : Cadastro(n,f), Imovel(e,b,au,at,q), Tipo(t) { valor = v; }

Note que a definio de um construtor de uma classe com herana mltipla muito similar com o construtor de uma classe com herana simples. Ao chamar os construtores das classes base, devemos lembrar que os nomes dos construtores so colocados aps os dois-pontos e separados por vrgulas. A ordem de chamada a mesma da ordem em que eles aparecem escritos. Parmetros podem ser passados assim como em qualquer outro construtor. As funes GetData() e PutData() da classe Venda incorporam a chamada s funes correspondentes das classes Cadastro, Imovel e Tipo empregando o operador de resoluo de escopo (::) para efetuar a chamada das funes das classes base:
Cadastro::GetData(); Cadastro::PutData(); Imovel::GetData(); Imovel::PutData(); Tipo::GetData(); Tipo::PutData();

Alguns tipos de problemas podem aparecer em certas situaes envolvendo herana mltipla. O mais comum quando duas classes-base tm, cada uma delas, uma funo de mesmo nome (prottipo), enquanto a classe derivada destas duas no tem nenhuma funo com este nome. Quando a funo acessada por meio de um objeto da classe derivada, o compilador no reconhecer qual das duas estar sendo chamada. Para informar ao compilador qual das duas funes est sendo solicitada, devemos utilizar o operador de resoluo de escopo (::). Por exemplo, podemos chamar a funo PutData() da classe Imovel com um objeto da classe Venda atravs da instruo:
C.Imovel::PutData();

Marcelo Ricardo Stemmer

157

Informtica Industrial I

DAS/UFSC

Caso a classe derivada no contivesse esta funo, este seria o nico mtodo de acesso a esta funo sem causar um erro de ambigidade.

4.16.10 Exerccios
16.1 No incio comeamos discutindo a modelagem de um banco orientado a objetos. Termine o programa que modelas as pessoas que compem o ambiente banco : acionista, cliente, funcionrio, cliente-universitrios, pessoa-fsica, pessoa-jurdica, etc. 16.2 Crie uma classe Empresa capaz de armazenar os dados de uma empresa (Nome, End, Cidade, Estado, CEP, CGC, Fone e E-mail). Use a classe Empresa como base para criar a classe Restaurante. Inclua o tipo de comida, o preo mdio de um prato, funes para adquirir os seus dados e para imprim-los na tela. Sobrecarrega o operador ostream <<. 16.3 Imagine que voc deva escrever um programa para armazenar veculos. Primeiramente, crie a classe Motor que contm NumCilindro e Potencia. Inclua um construtor com argumentos com valores default que inicialize os dado com zeros e um construtor de cpia. Escreva a classe Veiculo contendo peso, velocidade mxima e preo. Crie a classe CarroPasseio usando as classes Motor e Veiculo como base. Inclua cor e modelo. Crie a classe caminhao derivada das classes Motor eVeiculo. Inclua a carga mxima, altura mxima e comprimento. Crie um programa para o controle de um estacionamento que tenha uma rea fixa e controle o acesso de veculos no estacionamento. Verifique se um veiculo pode ou no estacionar antes de permitir a entrada. Se puder, indique onde este deve estacionar. Reflita sobre o problema, crie um modelo e decida quais propriedades dos veculos devem ser descritas. Aceite as propriedades propostas como sugestes mas crie o seu prprio programa. 16.4 Um rob pode ser composto por trs tipos de motores : motor de corrente contnua, motor de passo e motor assncrono. Um rob pode conter juntas com movimento angular (geram uma variao no ngulo entre dois elos), transversal (geram um deslocamento linear do elo) ou juntas que no geram movimento nenhum, simplesmente ligam dois elos. Cada elo pode ser uma barra reta ou uma curva suave de 90 graus. Um rob pode ter uma garra para pegar objetos, uma garra para fazer operaes de soldagem e uma garra para fazer operaes de pintura. Modele um rob segundo as consideraes acima, definindo a geometria do rob e como ser o movimento deste. Crie um rob que seja capaz de pintar a parte superior de uma mesa, soldar em cima desta uma caixa. A mesa esta a 50 cm na frente do rob e a caixa est a 50 cm a direita do rob.

4.17 Funes Virtuais e Amigas


Neste captulo discutiremos tpicos avanados sobre classes. Cobriremos a definio e o uso de funes virtuais e funes amigas.

4.17.1

Funes Virtuais

Muitas vezes, quando derivamos um grupo de classes a partir de uma classe-base, certas funes-membro precisam ser redefinidas em cada uma das classes derivadas. Suponha o seguinte exemplo, onde temos uma classe base e duas classes derivadas. A funo print() est definida na classe base e redefinida nas classes derivadas. As nossas classes definem os tipos de clientes em um banco. Temos os clientes normais (classe-base) e clientes universitrios ou especiais.

Marcelo Ricardo Stemmer

158

Informtica Industrial I

DAS/UFSC

// Testando funcoes Virtuais #include <iostream.h> class Cliente { public: virtual void print() { cout << "\nCliente"; } }; class Universitario : public Cliente { public: void print() { cout << "\nCliente Universitario"; } }; class Especial : public Cliente { public: void print() { cout << "\nCliente Especial";} }; void main() { Cliente * p[3]; // matriz de ponteiros da classe-base Cliente B; Universitario D1; Especial D2; p[0] = &B; p[1] = &D1; p[2] = &D2; p[0]->print(); p[1]->print(); p[2]->print(); }

Planejamos agrupar um conjunto de objetos destas classes em uma lista nica. Isto , o nosso objetivo ter uma lista nica de clientes e diferenci-los pelos tipos de objetos que os definem. Um dos meios criar uma matriz de ponteiros para os diferentes objetos envolvidos. Qual seria o tipo da matriz tendo em vista que ela deve armazenar ponteiros para objetos de classes diferentes? A resposta est em como o compilador opera ponteiros em situaes deste tipo. Um ponteiro para um objeto de uma classe derivada de tipo compatvel com um ponteiro para um objeto da classe-base. Segundo este princpio, criamos um vetor de ponteiros da classe base e atribumos a ele endereos das classes derivadas, como voc pode observar acima. Podemos imprimir os dados da lista, atravs da chamada da funo print() :
for(int i = 0; i<10; i++) p[i]->print();

Observe que desejamos que funes completamente diferentes sejam executadas com por meio da mesma instruo de chamada. Se o ponteiro p[i] apontar para um cliente normal, a funo da classe base dever ser executada; se p[i] apontar para um cliente especial, a funo da classe de clientes especiais dever ser executada. A caracterstica de chamar funes membros de um objeto sem especificar o tipo exato do objeto conhecida como polimorfismo. A palavra polimorfismo significa assumir vrias formas. Em C++ indica a habilidade de uma nica instruo chamar diferentes funes e portanto assumir diferentes formas. Para que o exemplo anterior funcionasse corretamente, duas condies tiveram que ser introduzidas. Em primeiro lugar, todas as diferentes classes de clientes devem ser derivadas da mesma classe-base. Em segundo lugar, a funo print() deve ser declarada como virtual na classe-base. Apesar de termos fornecidos os endereos de objetos de classes derivadas, o compilador trata todos os endereos da lista de ponteiros como endereos da classe-base, ou seja, considera que

Marcelo Ricardo Stemmer

159

Informtica Industrial I

DAS/UFSC

os ponteiros apontam para objetos da classe base. Quando executamos uma funo utilizando este ponteiro,
p[i]->print();

a funo ser executada como se o objeto referenciado fosse da classe base.


p[i]->Cliente::print();

O compilador ignora o contedo do ponteiro p[i] e usa o seu tipo para identificar a funomembro a ser chamada. Para acessar objetos de diferentes classes usando a mesma instruo, devemos declarar as funes da classe-base que sero reescritas em classes derivadas usando a palavra-chave virtual. As instrues de chamada a funes no-virtuais so resolvidas em tempo de compilao e so traduzidas em chamadas a funes de endereos fixo. Isto faz com que a instruo seja vinculada a funo antes da execuo. Quando uma instruo de chamada a uma funo virtual encontrada pelo compilador, ele no tem como identificar qual a funo associada em tempo de compilao. Em instrues como a escrita acima, o compilador no conhece qual classe p[i] contm antes de o programa ser executado. Ento, a instruo avaliada em tempo de execuo, quando possvel identificar qual o tipo de objeto apontado por p[i]. Isto chamado de resoluo dinmica. A resoluo dinmica permite que uma instruo seja associada a uma funo no momento de sua execuo.O programador especifica que uma determinada ao deve ser tomada em um objeto por meio de uma instruo. O programa, na hora da execuo, interpreta a ao e vincula a ao funo apropriada. A resoluo dinmica envolve mais memria e tempo de execuo, entretanto aumenta a flexibilidade no projeto do software e permite criar bibliotecas de classes que outros programadores podem estender no tendo o arquivo-fonte. Uma funo virtual pura uma funo virtual sem bloco de cdigo ou o bloco de cdigo no contm nenhuma instruo. O propsito de uso de uma funo virtual pura me situaes em que a funo nunca ser executada e est presente somente para que seja redefinida em todas as classes derivadas. A funo serve somente para prover uma interface polimrfica para as classes derivadas. A funo print() pode ser definida como virtual pura da seguinte forma:
virtual void print() =0;

O sinal de igual (=) e o valor 0 no tm nenhum efeito aqui. A sintaxe (=0) usada somente para indicar ao compilador que esta uma funo virtual pura, e no tem corpo. Uma classe que no pode ser utilizada para criar objetos dita classe abstrata e existe somente para ser usada como base para outras classes. A classe que define uma funo virtual pura uma classe abstrata pois no se pode declarar nenhum objeto dela. Entretanto, um ponteiro para uma classe abstrata pode ser declarado para manipular objetos de classes derivadas. Toda classe que contm pelo menos uma funo virtual pura ou uma classe derivada que no redefine a funo virtual pura de sua classe-base abstrata.

4.17.2

Destrutores Virtuais

Se destrutores so definidos na classe-base e na classe derivada, eles so executados na ordem reversa qual o construtor executado. Quando um objeto da classe derivada destrudo, o destrutor da classe derivada chamado e em seguida o destrutor da classe-base chamado. Esta ordem no mantida quando um ponteiro para a classe-base contm um objeto de uma classe derivada. Se o operador delete aplicado a um ponteiro da classe-base, o compilador chama somente o destrutor da classe-base, mesmo que o ponteiro aponte para um objeto da classe derivada. A soluo declarar o destrutor da classe-base virtual. Isto faz com que os destrutores de todas as classes derivadas sejam virtuais, mesmo que no compartilhem o mesmo nome do destrutor
Marcelo Ricardo Stemmer
160

Informtica Industrial I

DAS/UFSC

da classe-base. Ento, se delete aplicado a um ponteiro para a classe-base, os destrutores apropriados so chamados, independentemente de qual tipo de objeto apontado pelo ponteiro.
class Base { public: }; virtual ~Base(); // destrutor virtual

A classe Base tem um destrutor virtual, mesmo sendo um destrutor que no faz nada. Sempre que voc escrever uma classe que tem uma funo virtual, ela deve ter um destrutor virtual mesmo que no necessite dele. A razo disto que uma classe derivada pode necessitar de um destrutor. Se um destrutor virtual est definido na classe-base, voc assegura que destrutores de classes derivadas so chamados na ordem necessria. Observe que, enquanto os destrutores podem ser virtuais, os construtores no devem ser.

4.17.3

Classe-Base Virtual

Alm de declarar funes virtuais, podemos usar a palavra virtual para declarar uma classe inteira. A necessidade de declarar uma classe virtual quando esta foi usada como classe-base para mais de uma classe derivada e dessas classes derivadas foi derivada outra por meio de herana mltipla. Uma classe-base no pode ser usada mais de uma vez numa mesma classe derivada. Entretanto, uma classe-base pode ser indiretamente usada mais de uma vez em classes derivadas. Observe a classe Super do exemplo abaixo:
#include <iostream.h> class Base { protected: int valor; public: Base(int n = 0) {valor = n;} virtual void Print() { cout << "\nValor : " << valor; } }; class Deriv1 : virtual public Base { public: Deriv1(int n = 0) : Base(n) { } }; class Deriv2 : virtual public Base { public: Deriv2(int n = 0) : Base(n) { } }; class Super : public Deriv1, public Deriv2 { public: Super(int n = 0) : Base(n) { } int RetValor() { return valor; } void Print() { cout << "\nValor do Super-Objeto : " << valor; } }; void main() { Base B(5); Deriv1 D1(10); Super S(343); B.Print(); D1.Print(); S.Print(); }

Neste caso, cada objeto da classe Super poderia ter dois sub-objetos da classe Base. Se um objeto da classe Super tentasse acessar dados ou funes da classe Base, ocorreria um erro de
Marcelo Ricardo Stemmer
161

Informtica Industrial I

DAS/UFSC

ambigidade. A declarao virtual nas classes Deriv1 e Deriv2 faz com que estas classes compartilhem uma nica classe-base. A classe Super s ter um sub-objeto da classe Base e no ter mais nenhum problema de ambigidade. Os construtores de classes-base so sempre executados antes do construtor da classe derivada. Os construtores de classes-base virtuais so chamados antes de qualquer construtor de classes-base no-virtuais.

4.17.4

Funes Amigas

O conceito de isolamento interno dos itens de uma classe, onde funes no-membros no teriam o privilgio de acesso aos dados privados ou protegidos desta classe, violado por um mecanismo oferecido por C++ que permite que funes no-membro, s quais foi dada uma permisso especial, tenham acesso parte interna da classe. Declarando uma funo como amiga, ela tem os mesmos privilgios de uma funo-membro, mas no est associada a um objeto da classe. No programa abaixo apresentamos a sintaxe das funes amigas:
// Uso de funcoes amigas #include <iostream.h> #include <strstrea.h> class Data; // Declara que existe esta classe class Tempo { private: long h, min, s; public: Tempo(long hh = 0, long mm = 0, long ss = 0) { h = hh; min = mm; s = ss; } friend char * PrintTime( Tempo &, Data &); }; class Data { private: int d, m, a; public: Data(int dd = 0, int mm = 0, int aa = 0) { d = dd; m = mm; a = aa; } friend char * PrintTime( Tempo &, Data &); }; char * PrintTime( Tempo & Tm, Data & Dt) // Funo global e amiga { char * temp = new char[50]; memset(temp, '\0', 50); strstream sIO(temp, 50, ios::out); sIO << "\n Relogio-> \t" << Tm.h << ":" << Tm.min << ":" << Tm.s; sIO << "\n Data-> \t" << Dt.d << "/" << Dt.m << "/" << Dt.a; return temp; } void main() { Tempo Tm( 15, 56, 4); Data Dt( 9, 5, 2000); char * str = PrintTime( Tm, Dt); cout << "\n" << str;
Marcelo Ricardo Stemmer
162

Informtica Industrial I

DAS/UFSC

delete str; }

Neste exemplo, queremos que a funo PrintTime() tenha acesso aos dados privados da classe Tempo e Data. Desta forma, usamos a palavra-chave friend na declarao da funo
friend char * PrintTime( Tempo &, Data &);

Esta declarao pode ser colocada em qualquer posio da classe. No h diferena se for colocada na parte pblica ou na parte privada da classe. Um objeto Tempo passado como argumento funo PrintTime(). Este argumento necessrio pois, mesmo quando se d a uma funo amiga o privilgio de acesso aos dados privados da classe, ela no parte daquela classe, devendo ser informada sobre qual objeto agir. A funo PrintTime() cria um objeto da classe strstream. Este objeto atua como se fosse um objeto cout, entretanto em vez de enviar os dados para a sada padro (tela), ele armazena estes dados no buffer de caracteres fornecidos ao seu construtor. Esta uma das formas mais fceis para converter dados de uma classe para texto (ASCII) e armazenar estes dados em um buffer de caracteres. Note que operamos sob o objeto criado assim como operamos com o objeto cout. O mesmo princpio pode ser empregado para a leitura de dados armazenados em um buffer de caracteres, operando-se como se estivssemos utilizando o operador cin. Funes amigas so muito empregadas quando sobrecarregamos os operadores << e >> associados aos objetos cout e cin respectivamente. Desta forma definimos o operador << para imprimir os dados da classe e o operador >> para adquirir os dados da classe. Como muitas vezes desejamos que estes operadores tenham acesso aos membros privados da classe, ento devemos defini-los como funes amigas.
friend ostream & operator <<(ostream & OS, Tempo const & T); friend istream & operator >>(istream & IS, Tempo & T;

Todo e qualquer operador que queremos sobrecarregar como sendo uma funo global (i.e., recebe um parmetro se for unrio e dois se for binrio) e queremos permitir que este operador tenha acesso a membros privados e protegidos de uma dada classe, devemos definir este operador como sendo uma funo amiga. No nosso programa-exemplo acima, definimos que a funo PrintTime() amiga das classes Data e Tempo. Para tal, precisamos declarar nas duas classes que esta funo amiga da classe. Quando declaramos a funo na classe Tempo, estaremos declarando uma funo que recebe como parmetro um objeto da classe Data desconhecida at ento pelo compilador. Para evitar que o compilador gere um erro indicando que a classe no existe, devemos declarar no incio do arquivo que existe a classe Data que esta ser definida posteriormente. Fazemos isto atravs da instruo:
class Data;

4.17.5

Classes Amigas

Alm de ser possvel declarar funes independentes como amigas, podemos declarar uma classe toda como amiga de outra. Neste caso, as funes-membro da classe sero todas amigas da outra classe. A diferena que estas funes-membro tm tambm acesso parte privada ou protegida da sua prpria classe. Para modificar o programa anterior e declarar que a classe Data amiga da classe Tempo, basta retirarmos a declarao da funo amiga PrintTime() da classe Tempo e adicionarmos a declarao: friend class Data;

Marcelo Ricardo Stemmer

163

Informtica Industrial I

DAS/UFSC

Agora, se definirmos que a funo PrintTime() passa a ser uma funo da classe Data, ela automaticamente passar a ser amiga da classe Tempo e ter acesso a todos os membros desta classe. Uma funo ou classe amiga deve ser declarada como tal dentro da classe em que os dados sero acessados. Em outras palavras, quem escreve uma classe deve especificar quais funes ou classes iro acessar a sua parte privada ou protegida. Desta forma, um programador que no tem acesso ao cdigo-fonte da classe no poder criar uma funo amiga para esta classe. As funes amigas devem ser declaradas pelo autor da classe. Observe que a palavra chave friend oferece acesso em uma s direo. Se a classe A amiga da classe B, o inverso no verdadeiro. Uma funo operadora amiga deve receber no mnimo um argumento objeto. Em outras palavras, voc no pode criar uma funo operadora binria como operator +() que receba dois inteiros como argumentos. Esta restrio previne a redefinio de operadores internos da linguagem. Alguns operadores no podem ser definidos como funes amigas; devem ser definidos como funes-membro de classe. So eles: atribuio (=), acesso de membros de ponteiros (->), () e conversores de tipo.

4.17.6

Exerccios

17.1 Escreva as classes Animal, Vaca, Bufalo e Bezerro, sendo Vaca e Bufalo derivadas de Animal e Bezerro derivada de Vaca e de Bufalo. 17.2 Modele os elementos Veculos, Moto, Carro Esportivo, Carro de Luxo, Carro Popular, Perua, Carro Mil, Jipe, Caminho, Onibus e Caminhonete. Utilize a idia do exerccio 16.3. Crie um programa que controle uma revenda de carros. Tenha uma lista nica contendo todos os veculos a venda. Utilize o princpio de um vetor de ponteiros para a classe base e empregue exaustivamente os conceitos da derivao e de funes virtuais e amigas. Permita que o usurio insira algum veculo na lista, faa consultas, liste todos os veculos disponveis e retire um veculo da lista. 17.3 Define uma classe String que sobrecarrega os seguintes operadores para as mais variadas funes: (+), (==), (!=), (<), (>), (<=), (>=), (<<) e (>>). 17.4 Refaa os exerccios 16.1 e 16.2 empregando o princpio das funes amigas e virtuais.

4.18 Operaes com Arquivos Iostream


Neste captulo, veremos brevemente as facilidades de C++ para operaes de leitura e gravao em discos. Comearemos com uma breve descrio das classes usadas para executar esta tarefa, conhecidas como classes iostream. Em C++, os objetos stream so o ponto central das classes iostream. Um objeto stream pode ser pensado como um buffer para o recebimento ou envio de bytes. Desta forma, um arquivo em disco um objeto stream. O conceito de arquivo ampliado no sentido de considerar arquivos no somente os que existem em discos mas tambm o teclado, o vdeo, a impressora e as portas de comunicao. Por exemplo, o objeto cout representa o vdeo (recebimento de bytes) e o objeto cin representa o teclado (envio de bytes). As classes iostream interagem com esses arquivos. Diferentes objetos stream so usados para representar diferentes interaes com perifricos de entrada e sada. Cada stream associado a uma classe particular, caracterizada pelas suas funes de interface e pelos seus operadores de insero e extrao. Na Figura 28 apresentamos a hierarquia das classes iostream. Por exemplo, cout um objeto da classe ostream_withassign que derivada da classe ostream. Similarmente, cin um objeto da classe istream_withassign que derivada da classe istream. Objetos de destino de bytes usam o
Marcelo Ricardo Stemmer

164

Informtica Industrial I

DAS/UFSC

operador de insero <<, membro da classe ostream. Os objetos de origem de bytes usam o operador de extrao >>, membro da classe istream. Estas duas classes so derivadas da classe ios. Para descobrir os arquivos que definem estas classes, utilize o help do seu compilador pois a nova norma ANSI C++ definiu novos nomes para estes headers.

Figura 28 - Hierarquia das Classes Iostream do Compilador Borland C++ 4.5.

A classe ios a base para todas as outras classes. Ela contm vrias constantes e funesmembro para as operaes de leitura e impresso a todas as outras classes. As classes iostream e ostream so derivadas de ios e so dedicadas a leitura e impresso, respectivamente. Suas funes-membro implementam operaes formatadas ou no-formatadas em objetos stream. A classe istream contm funes como get(), getline(), read(), alm de outras. Contm ainda a sobrecarga do operador de extrao >>. J a classe ostream contm funes como put(), write(), alm de outras. Contm ainda a sobrecarga do operador de insero <<. Todo objeto istream ou ostream contm um objeto streambuf derivado. As classes istream e ostream trabalham em conjunto com a classe streambuf. A classe iostream derivada das classes istream e ostream por meio de herana mltipla. Desta forma, esta classe herda as capacidades tanto de leitura como de impresso. Outras classes podem ser criadas pelo usurio tendo como base istream e ostream. As classes istream_withassign e ostream_withassign so usadas para a entrada e a sada padro. Os objetos cin e cout so objetos destas classes. As classes istrstream, ostrstream e strstream so usadas na manipulao de buffers de dados: para leitura, para gravao e para leitura/gravao respectivamente. As classes ifstream, ofstream e fstream so usadas na manipulao de arquivos me disco para leitura, para gravao e para leitura e gravao respectivamente.

Marcelo Ricardo Stemmer

165

Informtica Industrial I

DAS/UFSC

4.18.1

Estudo de Caso

Vamos apresentar a leitura e escrita de arquivos a partir de um exemplo. O exemplo tratado a classe Pessoa definida nos captulos anteriores. A classe em si no apresenta nada de novo, somente sobrecarregamos os operadores de insero << e extrao >> de dados definidos para objetos da classe iostream. A sobrecarga destes operadores nos permite a escrita e a leitura automtica de dados da classe, utilizando-se estes operadores. O header fstream.h foi adicionado por causa das classes de manipulao de arquivos. Veja o exemplo abaixo.
// Exemplo da class fostream #include <iostream.h> #include <fstream.h> #include <iomanip.h> #include <string.h> #define Nome_Size 80 class Pessoa { protected: char * int long int

Nome; Idade; RG;

public: Pessoa(); Pessoa(char * aNome, int aId = 0, long int aRG = 0); Pessoa(Pessoa const & aP); ~Pessoa(); char const * GetNome() const { return Nome; } int GetIdade() const { return Idade; } long int GetRG() const { return RG; void GetData();

friend ostream & operator <<(ostream & OS, Pessoa const & P); friend istream & operator >>(istream & IS, Pessoa & P); }; Pessoa::Pessoa() { Nome = new char[Nome_Size]; Idade = 0; RG = 0; } Pessoa::Pessoa( char * aNome, int aId, long int aRG) { Nome = new char[Nome_Size]; strcpy( Nome, aNome); Idade = aId; RG = aRG; } Pessoa::Pessoa(Pessoa const & aP)
Marcelo Ricardo Stemmer
166

Informtica Industrial I

DAS/UFSC

{ Nome = new char[Nome_Size]; strcpy( Nome, aP.GetNome()); Idade = aP.GetIdade(); RG = aP.GetRG(); } Pessoa::~Pessoa() { if(Nome != 0) { delete Nome; Nome = 0; } } void Pessoa::GetData() { cout << "\nNome : "; cin.getline( (char *)Nome, Nome_Size); cout << "Idade : "; cin >> Idade; cout << "RG : "; cin >> RG; } ostream & operator <<(ostream & OS, Pessoa const & P) { OS << P.GetNome() << "\n" << P.GetIdade() << "\n" << P.GetRG(); return OS; } istream & operator >>(istream & IS, Pessoa & P) { IS.getline( (char *)P.Nome, Nome_Size); IS >> P.Idade; IS >> P.RG; return IS; } void main() { Pessoa Eu("Rodrigo", 20, 231123); // Escrevendo ofstream FOut("Teste.TXT", ios::out); FOut << Eu << "\n Um dia a casa cai! \n " << setw(12) << setprecision(3) << 12.2345; FOut.close(); // Lendo ifstream FIn; Fin.open("Teste.TXT", ios::in) Pessoa Vc;
Marcelo Ricardo Stemmer
167

Informtica Industrial I

DAS/UFSC

char Buffer[Nome_Size]; FIn >> Vc; cout << "\nVoce: \n" << Vc; while(FIn) //Enquanto nao acabar o arquivo { FIn.getline( Buffer, Nome_Size); cout << "\nBuffer : " << Buffer; } FIn.close(); }

Na funo main() que aparecem as novidades. Primeiro criamos um objeto Pessoa. Depois escrevemos este objeto e outros dados em um arquivo e depois prosseguimos com a leitura deste. Neste programa definimos um objeto chamado Fout da classe ofstream. Inicializamos este objeto com o nome do arquivo TESTE.TXT. Esta inicializao associa o objeto Fout ao arquivo em disco TESTE.TXT para gravao e j abre o arquivo. O segundo parmetro indica que o arquivo ser aberto para a escrita. Note que escrevemos os dados no arquivo da mesma forma que escrevemos os dados na tela com cout. Toda formatao e funo vlida para cout tambm pode ser aplicada a FOut. Desta forma, utilizamos o mesmo operador definido para escrever os dados da classe Pessoa na tela como em um arquivo. Esta facilidade advm do fato de cout e FOut serem ambos objetos de classes derivadas da classe ostream. Aps a escrita dos dados, devemos fechar o arquivo com a funo close(). neste momento que os dados sero salvos no arquivo. Se voc no fechar o arquivo, os dados somente sero salvos quando o objeto for destrudo e o arquivo, ento, ser fechado pelo destrutor do objeto. Para ler o arquivo, criamos um objeto da classe ifstream de nome Fin e associamos este objeto ao arquivo Teste.TXT atravs da funo open(). O segundo parmetro indica que este arquivo ser aberto para a leitura. Note que o construtor no abrir nenhum arquivo aqui, somente aps a chamada a funo open() que o arquivo estar aberto. Depois utilizamos a sobrecarga do operador >> para fazer a aquisio dos dados da classe Pessoa contido no referido arquivo e imprimir na tela. Aps termos lidos o dado da classe, prosseguimos lendo linha por linha do arquivo e escrevendo-a na tela at terminar o arquivo. Note que fazemos uso da funo getline(), que recebe um buffer como parmetro e adquire uma linha inteira do arquivo. Os objetos da classe ifstream tm um valor que pode ser testado para a verificao do fimde-arquivo. O objeto FIn ter o valor zero se o sistema operacional enviar ao programa o sinal de fim-de-arquivo e um valor no-zero caso contrrio. O programa verifica o trmino do arquivo no lao while. A funo eof() desta classe poderia ser empregada com o mesmo propsito. Aps lermos o arquivos, fechamos este atravs da funo close(). Todas as funes definidas para a leitura e escrita em C podem ser empregadas em C++. Estas funes foram incorporadas nas classes iostream. Verifique com o help do seu compilador as funes disponveis e verificar esta observao. Por exemplo, o funo put() foi adicionada a classe ostream, e pode ser acessada da forma:
cout.put(c); ou FOut.put(c);

O controle do formato da impresso e leitura pode ser executado por meio dos manipuladores e flags da classe ios. Estes mecanismos foram apresentados em 0.0.0 e se aplicam para todos os objetos streams.

Marcelo Ricardo Stemmer

168

Informtica Industrial I

DAS/UFSC

4.18.2

A funo Open()

Quando usamos um objeto da classe ofstream ou ifstream, necessrio associ-lo a um arquivo. Esta associao pode ser feita pelo construtor da classe ou usando a funo open(), membro da classe fstream, numa instruo aps a criao do objeto com o construtor default. Tanto o construtor como a funo open() aceitam a incluso de um segundo argumento indicando o modo de abertura do arquivo. Este modo definido por bits de um byte, onde cada um especifica um certo aspecto de abertura do arquivo. A lista de modos definida na classe ios por meio de enum open_mode: Modos ios::in ios::out ios::ate ios::app ios::trunc ios::nocreate ios::noreplace ios::binary Descrio Abre para leitura (default de ifstream) Abre para gravao (default de ofstream) Abre e posiciona no final do arquivo leitura e gravao Grava a partir do fim do arquivo Abre e apaga todo o contedo do arquivo Erro de abertura se o arquivo no existir Erro de abertura se o arquivo existir. Abre em binrio (default texto).

Podemos trabalhar com arquivos no modo texto ou no modo binrio, assim como em C. Lembre-se que o fim de linha em modo texto representado por um nico caractere, enquanto em modo binrio representado por dois caracteres. Exemplos:
ifstream fin(Teste.txt, ios::in|ios::binary); fstream fio; \\ Arquivo para leitura e gravaao!!!! fio.open(Lista.dat, ios::in|ios::out|ios::ate);

4.18.3

Testando Erros

Situaes de erros na manipulao de arquivos podem ser previstas verificando-se a palavra (int) de status da classe ios. A palavra de status pode ser obtida pela funo rdstate(), membro da classe ios. Os bits individuais do valor retornado podem ser testados pelo operador AND bit-a-bit (&) e os seguintes valores enumerados: Bits ios::goodbit ios::eofbit ios::failbit ios::badbit Funo good() eof() fail() bad() Comentrio Nenhum bit setado. Sem erros Encontrado o fim-de-arquivo Erro de leitura ou gravao Erro irrecupervel

A funo clear(int status) modifica a palavra de status. Se usada sem argumento, todos os bits de erros so limpos. Do contrrio, os bits setados de acordo com os valores enumerados escolhidos e combinados pelo operador OR (|):
clear(ios::eofbit | ios::failbit);

4.18.4

Escrevendo e Lendo em Buffers de Caracteres

As classes iostream interagem com a memria pela mesma sintaxe com a qual interagem com arquivos de disco. Podemos ler e grava de e para buffers de caracteres na memria do computador. Veja o exemplo abaixo, onde criamos um objeto ostrstream para criar um buffer e
Marcelo Ricardo Stemmer
169

Informtica Industrial I

DAS/UFSC

adicionar dados neste buffer. Depois armazenamos o ponteiro deste buffer em uma varivel. Em seguida, criamos um objeto istrstream para ler dados do mesmo, passando para o seu construtor o ponteiro do buffer. Por fim, imprimimos os dados na tela.
// StrStream #include <iostream.h> #include <strstrea.h> void main() { ostrstream OS; // Cria buffer para a escrita OS << "123.45 \t" << 555.55 << "\t" << 333; OS << "\n\n Um dia voce enxergara a oportunidade que recebeu!"; OS << ends; char * ptr = OS.str(); double x, y; int i; istrstream IS(ptr); IS >> x >> y >> i; cout << x << '\t' << y << '\t' << i << '\n' << ptr; }

Note a semelhana da metodologia. O manipulador ends, usando neste exemplo, adiciona o terminador \0 cadeia de caracteres. Estas classes podem ser usadas para aproveitarmos os operadores << e >> para converter qualquer tipo de dado no formato texto ASCII e armazenar em um buffer de caracteres. Este buffer pode ser utilizado para transmitir estes dados para a tela do micro, ou para uma porta COM ou at para um outro processo via conexes TCP/IP da internet. Definindo o operador << e >> para toda classe, definimos um modo padro para a escrita/leitura dos dados de uma classe para um arquivo, um buffer, ou um canal de I/O qualquer. Esta uma ferramenta muito poderosa que no pode ser desprezada e, quando bem aproveitada, gera cdigo velozes, simples e com alta flexibilidade.

4.18.5

Imprimindo em Perifricos

Imprimir dados na impressora exatamente a mesma coisa que gravar dados num arquivo de disco. O DOS define o nome de alguns perifricos ligados ao computador. Qualquer um deles pode ser usado em nosso programa como nomes de arquivos. Basta criar um objeto do tipo fstream (ifstream, ofstream, fstream) e passar como nome do arquivo o nome do perifrico. Depois, toda operao feita sob este objeto, ir acessar diretamente o perifrico. A tabela seguinte descreve estes nomes: Nome CON AUX ou COM1 COM2 PRN ou LPT1 LPT2 LPT3 NUL Descrio Console (teclado e vdeo) Primeira porta serial Segunda porta serial Primeira porta paralela Segunda porta paralela Terceira porta paralela Perifrico Inexistente

Marcelo Ricardo Stemmer

170

Informtica Industrial I

DAS/UFSC

Exemplo:
ofstream oprn(PRN); ofstream ocom1(COM1); ifstream ilpt2(LPT2);

4.18.6

Exerccios

18.1 Refaa os exerccios 14.1, 14.2 e 14.3, salvando os dados em um arquivo. Utilize todos os conceitos apresentados neste captulo. 18.2 Escreva um programa para banco de dados de uma biblioteca, que tenha uma lista ligada de livros e estes dados sejam armazenados em um arquivo. Crie uma funo para retirar um livro do cadastro e apaga-lo do arquivo. 18.3 Escreva um programa que continue o anterio e pegue os dados de um livro deste cadastro, escreva estes dados em um buffer da memria e depois envie este buffer para ser impresso na impressora. 18.4 Escreva um programa que imprima os dados de um arquivo na tela, 20 linhas por 20 linhas. 18.5 Escreva um programa que converta arquivos criados no modo binrio em arquivos criados no modo ASCII. Crie outro programa que faa o contrrio. 18.6 Escreva um programa que imprima o tamanho de um arquivo em bytes. O nome do arquivo deve ser fornecido na linha de comando. 18.7 Escreva um programa que criptografa um arquivo usando o operador complemento bita-bit (~). Quando o programa executado para um arquivo j criptografado, o arquivo recomposto e volta ao original.

Marcelo Ricardo Stemmer

171

Informtica Industrial I

DAS/UFSC

5 Controladores Lgicos Programveis (CLP, PLC)


5.1 Introduo aos CLPs 5.1.1 Definio
Define-se como CLP um equipamento eletrnico digital que tem como objetivo implementar funes especficas de controle e monitorao sobre variveis de uma mquina ou processo por intermdio de mdulos de entrada e sada. Todas as funes disponveis devem poder ser programadas em uma memria interna e o hardware deve ser universal, podendo ser aplicado a todos os tipos de processos. Os CLPs atuais so baseados em microprocessadores ou microcontroladores. O principio de funcionamento idntico para todos os fabricantes: para exercer suas funes, um CLP processa sinais de entrada provenientes de botoeiras, chaves e sensores diversos e fornece sinais de sada que atuam sobre a mquina ou processo em questo. O CLP atende funes de seqnciamento e intertravamento eltricos por meio de comparaes, contagens, temporizaes e controle PID, em conformidade com um programa especfico armazenado em memria interna (Figura 29).
CLP E1 E2 Interfaces CPU Entradas ... En Memorias Saidas ... Sn S1 S2

...

PROCESSO

...

Figura 29 - Configurao bsica de um CLP.

5.1.2 reas de aplicao


Os CLPs encontram grande aplicao em quase todos os setores industriais envolvendo controle de processos, automao da manufatura, integrao de sistemas de automatizao, linhas de fabricao e montagem, automao predial, controle de subestaes de energia, onde quer que sejam requeridas funes de controle, seqnciamento e intertravamento de aes e superviso do andamento de alguma atividade. Algumas aplicaes usuais so:

Marcelo Ricardo Stemmer

172

Informtica Industrial I

DAS/UFSC

uso interno em mquinas-ferramenta, para funes de intertravamento e seqnciamento das operaes e controle de grandezas relevantes para a usinagem, tais como posio dos eixos, torque, velocidade de avano, acelerao e outras; uso da funo de controlador PID para controle de grandezas fsicas como posio, rotao, velocidade, temperatura, presso, vazo, fora, potncia e outras na indstria metal-mecnica, qumica, petroqumica, txtil, usinas de gerao de energia, etc; controle do seqnciamento e intertravamento das operaes em linhas de produo e montagem automatizadas, freqentemente substituindo lgicas de comando originalmente implementadas com rels.

5.1.3 Histrico
Os CLPs foram originalmente inventados com a inteno de substituir lgicas de comando implementadas por meio de rels. Foram inicialmente aplicados na indstria automobilstica, passando mais tarde a ter larga aplicao em todos os setores industriais. O interesse inicial da indstria automobilstica se deveu ao grande investimento necessrio na alterao da lgica de comando das linhas de montagem implementadas com rels a cada alterao do modelo de carro fabricado. O primeiro usurio foi a General Motors. Algumas datas importantes na evoluo do CLP so mostradas a seguir: 1968: projeto do primeiro CLP para a General Motors, baseado em componentes discretos; 1971: primeira aplicao de CLPs fora da indstria automobilstica; 1975: introduo do controlador PID analgico nos CLPs; 1977: realizao dos CLPs com microprocessadores em lugar de componentes discretos; 1978 em diante: CLPs ganham larga aceitao industrial; As principais vantagens dos CLPs sobre a lgica de rels so: reduo do tempo de implementao e alterao de lgicas de controle e intertravamento devida facilidade de programao e reprogramao; elevada confiabilidade; pequenas dimenses e peso reduzido; capacidade de comunicao com computadores e outros sistemas inteligentes (integrao); construo robusta, adequada a ambientes industriais; projeto modular, de fcil expanso.

5.2 Arquitetura dos CLPs


A Figura 30 apresenta a arquitetura interna bsica de um CLP. Todas as unidades so interligadas por meio de um barramento de endereos e um barramento de dados.

Marcelo Ricardo Stemmer

173

Informtica Industrial I

DAS/UFSC

Barramento de endereos

Clock

Processador

RAM

(EP)ROM

Barramento de dados

Interface serial

Entradas

Saidas

CLP

Terminal de programacao

Sensores (botoes, chaves, etc)

Atuadores (reles, contactores, etc)

Processo

Figura 30 - Arquitetura interna dos CLPs.

Os barramentos de dados e de endereos definem, respectivamente, o caminho de troca de informaes entre o processador e as demais unidades dos sistema e o endereo de acesso da cada unidade. Antes de enviar ou receber dados de qualquer dispositivo ligado ao barramento de dados, o processador central tem que selecionar o endereo correspondente deste dispositivo no barramento de endereos. Os CLPs geralmente so baseados em microcontroladores (micro-processadores com timers, DMA, I/O, etc, integrados no mesmo "chip"). Os tipos mais freqentemente utilizados so: 8031, 8051, 80188, 80196, 80535, NEC V25, entre outros. Alguns CLPs utilizam microprocessadores convencionais, como: Z80, 8085, 8088, etc. O programa de operao do CLP introduzido atravs de terminais de programao, que no ficam fixados no CLP exceto durante a entrada ou alterao de um programa. Estes freqentemente so equipamentos relativamente simples, dotados de teclado para entrada de dados e um display. Os terminais de programao mais sofisticados incluem tela de vdeo, gravador de EPROM e software grfico para programao e monitorao. Atualmente vem sendo cada vez mais usados computadores do tipo PC, Laptops e Notebooks para esta finalidade. O CLP construdo de forma modular, alojando em placas independentes os diversos componentes. Os mdulos de entrada, que constituem um sistema de aquisio de dados, filtram e codificam sinais digitais e analgicos provenientes de botes, chaves fim-de-curso, termopares, pressostatos, extensmetros, sensores de proximidade, "encoders", sinais de fontes de tenso ou corrente, etc. Os sinais com nveis de potncia mais elevados so isolados com opto-acopladores. Os mdulos de sada fornecem sinais digitais ou analgicos devidamente codificados para energizar os dispositivos de operao e sinalizao tais como contactores, solenides e atuadores diversos. As sadas podem ser ainda temporizadas, com regulagem para prover os retardos desejados. Os sinais de entrada e sada podem ser de corrente contnua ou alternada, em diferentes nveis de tenso e potncia. A Figura 31 apresenta um CLP com diversos mdulos de entrada e sada. Estes so montados em um "rack" da ao nas proximidades dos equipamentos que devero controlar. Os mdulos so acoplados entre si por meio de um barramento, que prov uma extenso dos barramentos internos de dados e endereos.

Marcelo Ricardo Stemmer

174

Informtica Industrial I

DAS/UFSC

Figura 31 - CLP com mdulos de expanso.

5.3 Formas de interfaceamento Homem/Mquina para CLPs


Para a utilizao do CLP em qualquer instalao industrial, necessrio prover uma forma de interfaceamento entre este e o operador humano, tanto para a operao "on-line" quanto "offline" do mesmo. Na operao "on-line", deve ser possibilitada a entrada ou alterao de dados e comandos e a superviso e visualizao do andamento do processo sob controle do CLP. Na operao "off-line" necessrio permitir a entrada, atualizao e correo dos programas de aplicao que devero rodar no CLP. A comunicao entre o CLP e o operador pode ser executada basicamente de 4 maneiras:

utilizando as entradas e sadas do prprio CLP; utilizando painis "inteligentes" dedicados; interligando o CLP a um Terminal de Programao (TP); interligando o CLP a um computador (usualmente PC).

Cada uma destas formas de interfaceamento Homem / Mquina tem suas vantagens e desvantagens e oferece diferentes possibilidades de troca de informaes e flexibilidade.

5.3.1 Interfaceamento por meio das Entradas e Sadas do CLP


O interfaceamento entre o operador e o CLP atravs de entradas e sadas digitais e analgicas do prprio CLP foi at pouco tempo o mtodo mais utilizado na indstria para comunicao durante a operao "on-line", apesar de sua inflexibilidade (Figura 32).

Figura 32 - Interfaceamento com operador via E/S do CLP.


Marcelo Ricardo Stemmer
175

Informtica Industrial I

DAS/UFSC

Esta tcnica utilizada para a entrada de dados, tais como valores de referncia para malhas de controle de temperatura em fornos industriais, controle de presso em caldeiras, controle da vazo de um determinado componente em uma vlvula de uma instalao qumica, etc, ou comandos do tipo ON/OFF, ligando ou desligando dispositivos comandados pelo CLP. Nesta forma de interao, os dados so introduzidos por meio de botes, chaves seletoras, potencimetros, etc, ligados entradas pr-definidas do CLP, cujo estado ser lido e levado em considerao pelo programa interno introduzido pelo operador no CLP. A mesma tcnica adotada para a superviso e visualizao do andamento do processo sendo controlado. Neste caso, a visualizao da operao feita por meio de lmpadas, LEDS, indicadores digitais ou analgicos, etc, conectados sadas pr-definidas do CLP. A desvantagem desta tcnica que qualquer alterao nas ligaes de entrada e/ou sada implica necessariamente em uma alterao correspondente no programa interno do CLP. Da mesma forma, uma alterao do programa, visando, por exemplo, uma otimizao, correo ou ampliao, pode implicar na necessidade de alterao da fiao externa, que interliga as entradas e sadas aos dispositivos citados (chaves, botes, LEDS, etc). Alm disso, as entradas e sadas utilizadas para o interfaceamento com o operador no podem ser aproveitadas para o interfaceamento com o processo a controlar.

5.3.2 Interfaceamento por meio de painis inteligentes


O desenvolvimento de mdulos de interface serial tipo RS-232C para CLPs viabilizou a utilizao dos chamados painis "inteligentes" para a entrada de dados e visualizao, baseados em microprocessadores (Figura 33). Alguns fabricantes do a este dispositivo simplesmente o nome de Interface. Estes equipamentos so compostos de um teclado simples, com tipicamente 9 teclas, um display de cristal lquido, usualmente de uma at trs linhas, uma pequena rea de memria RAM, uma EPROM, uma interface serial RS-232C e um microprocessador dedicado (8085, Z80, etc). Este equipamento conectado por meio da interface serial ao CLP e utilizado exclusivamente para a comunicao "on-line" entre o operador e o CLP, substituindo as ligaes rgidas adotadas na tcnica descrita anteriormente. Os painis inteligentes apresentam as seguintes caractersticas:

fcil introduo e visualizao de dados; dimenses reduzidas e portabilidade; cablagem necessria para a interligao com o CLP mnima (um cabo de interface serial, com 3 fios); fcil alterao do modo de operao do painel inteligente (por exemplo, alterando o significado de uma tecla ou a forma de apresentao dos dados no display) atravs de reprogramao da EPROM;

Da mesma forma que no interfaceamento por meio das entradas e sadas do CLP, os painis inteligentes so utilizados para comunicao "on-line", encontrando aplicaes tais como a introduo de parmetros e de valores de referncia para malhas de controle de temperatura e visualizao dos mesmos em fornos industriais ou a introduo de coordenadas da localidade para onde um pallet deve ser enviado em um sistema automtico de armazenamento e estocagem de materiais, entre centenas de outras possveis aplicaes.

Marcelo Ricardo Stemmer

176

Informtica Industrial I

DAS/UFSC

Figura 33 - Painel "Inteligente".

5.3.3 Interfaceamento por meio de Terminais de Programao (TP)


Os chamados terminais de programao (TP, tambm chamados Terminais Industriais TI), tem por finalidade principal permitir a introduo, alterao e depurao de programas de aplicao na memria do CLP. Os TPs foram concebidos para utilizao diretamente no cho de fbrica, nos locais onde os CLPs esto instalados. Em funo disto, os TPs so dispositivos portteis, de pequeno porte e peso e com bateria interna, de forma a garantir uma independncia da existncia de tomadas de energia nos locais de uso. Inicialmente, os TPs no passavam de painis inteligentes com maior capacidade de memria e com teclado e display melhores, baseados em placas dedicadas de microprocessadores (os chamados "single-board computers") e montados em pequenas valises. Atualmente verifica-se uma tendncia de substitui-los por PCs de pequeno porte (LapTops e Notebooks), como veremos no item seguinte (Figura 34).

Figura 34 - Terminais de Programao para CLP.

5.3.4 Interfaceamento por intermdio de computadores tipo PC / IC


Devido a reduo do custo dos computadores tipo PC, estes vem sendo cada vez mais utilizados como dispositivos de programao e visualizao para CLPs (ver Figura 34). Alm disto,
Marcelo Ricardo Stemmer
177

Informtica Industrial I

DAS/UFSC

a crescente reduo das dimenses e peso dos modernos Laptops e Notebooks torna sua aplicao em campo, diretamente no cho de fbrica, cada vez mais vantajosa. Modernos pacotes de software para CLPs em PCs incluem as possibilidades de: programao grfico-interativa; armazenamento de dados e programas do CLP em arquivos no disco do PC; visualizao do andamento do processo controlado pelo CLP na tela do PC (sistema supervisrio); entrada de dados e parmetros "on-line" para o CLP por intermdio do PC, incluindo a possibilidade de realizao de clculos complexos no PC e o envio dos resultados ao CLP; gerao de relatrios e grficos relativos ao andamento dos processos controlados pelo CLP no PC;

5.4 Mdulos de Entrada e Sada


Alm do mdulo bsico contendo a CPU, memrias RAM e EPROM, interface serial e eventualmente um pequeno nmero de entradas e sadas, o CLP pode ser expandido pelo acrscimo de novos mdulos com entradas e sadas adicionais de diferentes tipos. Estes mdulos de E/S contm usualmente 2, 4, 8, 16 ou 32 circuitos montados em caixas isoladas contra poeira, leo, umidade, altas temperaturas (usualmente at 60C) e sobretenso (isolao galvnica). Os tipos mais usuais de mdulos de E/S so: - Mdulos de Entrada / Sada Analgicos: 110V / 220V AC (15%) sinal de tenso 0 a 5V DC / 0 a 10V DC/ 10V DC sinal de tenso 4 a 20mA / 0 a 20mA - sinal de corrente - Mdulos de Entrada / Sada Digitais: 0 ou 5V DC (TTL) 0 ou 12V DC -12 ou +12V DC 0 ou 24V DC - Mdulos de Comunicao: interfaces RS232C, RS422, RS423 ou RS485 interfaces para LANs (redes de computadores); gerao de relatrios: incluem interface para impressora; - Mdulos Especiais: controlador PID: usados no controle de temperatura, posio, vazo, presso, velocidade, etc. contadores de pulsos: usados na leitura de "encoders" digitais, medio de freqncia, etc. controle de motores de passo. Os mdulos de sada podem ser realizados com 3 tecnologias bsicas, conforme ilustrado na Figura 35: Sadas a rel: podem ser usadas em circuitos CA e CC, mas, como adotam comutao mecnica (rel NA), no permitem freqncias de chaveamento muito altas;

Marcelo Ricardo Stemmer

178

Informtica Industrial I

DAS/UFSC

Sadas a TRIAC: tambm podem ser usados em circuitos CA e CC, mas permitem comutao rpida; Sadas a Transistor coletor aberto: so usadas em circuitos CC e permitem comutao rpida.
optoacoplador
RELE NA i eletroima Contato NA

bobina

(a)

(b)

(c)

Figura 35 Sadas: (a) A rel; (b) A TRIAC; (c) a transistor coletor aberto.

Em funo do nmero total de entradas e sadas efetivamente ligadas a um CLP atravs dos diversos mdulos de expanso, pode-se classificar os CLPs em: pequenos: at 256 E/S, com custo da ordem de U$300 a U$5.000; mdios: 256 at 1024 E/S, com custo da ordem de U$5.000 a U$30.000; grandes: mais de 1024 E/S, com custo da ordem de U$30.000 at aproximadamente U$80.000.

5.5 Organizao interna de memria


Os CLPs utilizam memria SRAM ou DRAM protegida por baterias para impedir a perda dos programas de aplicao e dos dados e parmetros em caso de falta de energia de alimentao. Memria EPROM e mais recentemente memria flash (EAPROM) utilizada para os programas "permanentes", como o monitor do CLP, ou programas de aplicao que no devero sofrer alteraes freqentes. A rea de memria do CLP usualmente subdividida como mostra a tabela a seguir. Grupo Utilizao Memria do Sistema Monitor do CLP rea de Trabalho do Monitor Memria de Aplicao Tabela de E/S Tabela de Dados Programa de Aplicao
Marcelo Ricardo Stemmer
179

Informtica Industrial I

DAS/UFSC

O Monitor uma espcie de "sistema operacional" simplificado do CLP, que permite a inicializao deste aps ligar (incluindo a execuo de auto-testes), a comunicao do CLP com dispositivos perifricos (tais como um TP, um painel inteligente, um PC ou uma impressora) e o carregamento e superviso dos programas de aplicao. O monitor, por no sofrer alteraes freqentes (e s por parte do fabricante do CLP), armazenado em memria EPROM. A rea de trabalho do monitor o espao de memria RAM onde so armazenados temporariamente os dados e variveis utilizados para clculos ou tarefas internas do monitor. A tabela de E/S uma rea de memria RAM onde so armazenados os valores atuais das entradas e sadas do CLP. Estes valores so constantemente atualizados em ciclos de varredura. A tabela de dados uma rea de RAM que inclui os dados e variveis utilizados no programa de aplicao, tais como valores atuais de contadores, temporizadores, constantes, etc. Estas variveis e constantes utilizadas pelos programas aplicativos so usualmente designadas por smbolos alfanumricos, compostos de uma ou mais letras indicando o tipo de dado (entrada, sada, memria, constante, etc.) e por nmeros que, no caso das entradas e sadas, indicam o mdulo e a porta correspondentes, como indicado na Figura 36. No exemplo, S0001.1 designa uma sada pertencente ao mdulo 0001, porta 1. As constantes (KM), variveis auxiliares (A) e operandos memria (M) no tem nmero de mdulo ou porta, pois no se referem a entradas ou sadas fsicas do CLP.
RAM Tabela I/O

Tabela Sada Tabela Entrada Dados aplicao

S0001.1 E0002.1 A0001 KM09.81 M0001

Figura 36 - Tabelas de E/S e de dados.

Finalmente, a rea de programas de aplicao contm as instrues seqenciais de controle definidas pelo usurio, armazenadas usualmente em RAM. Estes programas podem opcionalmente ser armazenados em EPROM ou EEPROM, caso as alteraes esperadas sejam pouco freqentes.

5.6 Programao de CLPs 5.6.1 Introduo


Os programas de um CLP so sempre executados de forma cclica (isto , em "loop"): aps a execuo da ltima instruo, o CLP reinicia automaticamente a execuo a partir da primeira linha de programa. Cada execuo completa das linhas que compe uma lgica programada no CLP chamada um ciclo de varredura. Durante um ciclo de varredura, todas as entradas so lidas e seu estado copiado na rea de memria reservada tabela de entradas. Da mesma forma, em cada ciclo a tabela de sadas varrida e seu contedo copiado nas sadas fsicas do CLP. Desta forma, os tempos de execuo dos programas de aplicao apresentam uma variao mnima. O fluxograma da Figura 37 representa a operao bsica dos ciclos de varredura. Durante o carregamento do programa aplicativo no CLP, a varredura de entradas e sadas (input e output scan, na Figura 37) esto desabilitadas, e o CLP no se encontra no Run Mode (modo execuo). Estas funes so habilitadas pelo programa monitor do CLP somente quando
Marcelo Ricardo Stemmer
180

Informtica Industrial I

DAS/UFSC

houver um programa de aplicao vlido na memria de trabalho e o CLP estiver corretamente configurado. O CLP necessita ser configurado antes da utilizao. A configurao feita atravs do carregamento de um arquivo especial de configurao, contendo as seguintes informaes: Descrio do barramento de Mdulos de E/S: nmero e tipo das entradas e sadas; Descrio dos operandos: nmero e tipo dos operandos e suas caractersticas (p.ex. : retentividade); Parmetros gerais: tipo de CPU, endereo em rede, perodo de interrupes, etc. Parmetros de Comunicao em Rede: taxa de transmisso, paridade, etc Aps o carregamento do arquivo de configurao, pode-se realizar o carregamento do programa de aplicao .na memria de trabalho do CLP. O programa aplicativo desenvolvido dentro de um ambiente de desenvolvimento fornecido pelo fabricante do CLP e que roda no TP (usualmente um computador tipo PC ou IC).
Preparao da verredura e atualizao dos timers N

Housekeeping

IO Enabled

Input Scan

Run Mode

User Program

IO Enabled

Output Scan

Programmer Communication System Communications User Programm Checksum

Comunicao com o TP, se conectado Comunicao com outros equipamentos via rede, se houver

Figura 37 O ciclo de varredura de um CLP.


Marcelo Ricardo Stemmer
181

Informtica Industrial I

DAS/UFSC

A programao de um CLP a maneira pela qual o usurio define as relaes existentes entre os sinais de entrada e de sada. possvel identificar na maior parte dos CLPs existentes no mercado trs formas mais difundidas de programao:

Programao a partir de operadores lgicos (ou "Instruction List" - IL): a lgica de comando representada na forma de operadores booleanos do tipo AND, OR, XOR, NOT, etc. As linguagens de programao deste tipo se assemelham bastante com as linguagens de mquina de microprocessadores (assembly) . Se a lgica foi originalmente implementada com rels (situao freqentemente encontrada na prtica) preciso obter a funo lgica booleana associada, a partir da qual gerado o programa; Programao baseada no Diagrama de Escada (ou "Ladder Diagramm" - LD): esta linguagem foi criada para facilitar a implantao no CLP de lgicas originalmente realizadas com rels. A programao realizada de forma grfico-interativa e o programa resultante tem a forma dos chamados "diagramas de escada" ou "diagramas de rels", que sero apresentados mais adiante; Programao em GRAFCET (ou "Sequential Function Chart" - SFC): a linguagem GRAFCET (GRAFo de Comando Etapa-Transio) representa um mtodo moderno de programao baseado na tcnica das redes de Petri, que a torna mais adequada que as anteriores para a implementao de lgicas complexas. A linguagem permite simultaneamente a programao e a verificao da correo lgica do programa (validao).

Qualquer que seja a tcnica de programao adotada, o programa de aplicao traduzido pelo terminal de programao ou PC na linguagem de mquina do processador utilizado no CLP e carregada neste via interface serial. Para elaborar a lgica de comando a ser implementada, faz-se uso da lgebra booleana. A implementao prtica das expresses booleanas pode ser feita por Hardware, usando portas lgicas digitais ou rels, ou por meio de Software, que a tcnica usada nos CLPs. Os dois primeiros tipos de linguagens de programao que examinaremos so fortemente baseadas na converso das expresses lgicas booleanas em programas para o CLP. Em funo disto, faremos a seguir uma breve reviso de lgebra de Boole.

5.6.2 Reviso de lgebra booleana


Os sistemas digitais tem como bloco construtor bsico as chamadas portas lgicas binrias. A lgebra booleana uma forma de lgica simblica que mostra como estas portas lgicas operam. Todas as portas lgicas operam com dois nveis bsicos de tenso, denominados genericamente como nvel "baixo" e nvel "alto", cujos valores reais podem ser de 0V e +5V, -5V e +5V, +12V e 12V, 0V e +24V, etc. Na lgebra booleana, ao contrrio da lgebra convencional, uma varivel pode assumir somente dois valores possveis, correspondentes a tenso "baixa" e a tenso "alta" das portas lgicas, representados por "0" e "1", respectivamente. Existem trs combinaes bsicas entre variveis lgicas booleanas: a Conjuno (funo lgica "E"), a Disjuno (funo lgica "OU") e a Negao (funo lgica "NO"). Estas combinaes so utilizadas para representar expresses booleanas da forma: Conjuno: y = x1.x2, que lida como y igual a x1 E x2. A conjuno pode ser representada na forma de uma "tabela de verdade", que expressa os possveis valores da varivel de sada para todos os valores possveis das variveis de entrada. A tabela da verdade para a conjuno a seguinte:

Marcelo Ricardo Stemmer

182

Informtica Industrial I

DAS/UFSC
x1 0 0 1 1 x2 0 1 0 1 y 0 0 0 1

Disjuno: y = x1 + x2, que lida como y igual a x1 OU x2. Da mesma forma que a conjuno, a disjuno pode ser expressa na forma de uma tabela da verdade:
X1 0 0 1 1 x2 0 1 0 1 y 0 1 1 1

Negao: y = x 1, que lida como y igual a NO x. A tabela da verdade :


x 0 1 y 1 0

Para calcular o resultado de expresses lgicas booleanas mais complexas, onde vrias das combinaes bsicas citadas podem ser utilizadas, foram definidos por Boole os seguintes teoremas (hoje conhecidos como leis de Boole): - leis comutativas: x1.x2 = x2.x1 (1.a) x1+x2 = x2+x1 (1.b) - leis distributivas: x1.(x2+x3) = x1.x2+x1.x3 (3.a) x1+x2.x3 = (x1+x2).(x1+x3) (3.b) - leis da absoro: x1.(x1+x2) = x1 (4.a) x1+x1.x2 = x1 (4.b) - leis da negao: x. x = 0 2 (6.a) x + x = 14 (6.b) (x)= x6 (6.c) - Negao simples: 0 = 1 7 (9.a) 1 = 0 8 (9.b) - tautologia: x.x = x (5.a) x+x = x (5.b) - Leis de "De Morgan" x1 . x2 = x1 + x2 3 (7.a) x1 + x 2 = x1.x2 5 (7.b) - leis associativas: x1.(x2.x3) = (x1.x2).x3 (2.a) x1+(x2+x3) = (x1+x2)+x3 (2.b)

- Operaes com 0 e 1: x.1 = x (8.a) x.0 = 0 (8.b) x+0 = x (8.c) x+1 = 1 (8.d)

Marcelo Ricardo Stemmer

183

Informtica Industrial I

DAS/UFSC

A implementao prtica de lgicas combinacionais booleanas freqentemente realizada por meio de tabelas da verdade, que exprimem o comportamento desejado das sadas do sistema para um dado conjunto de valores de entrada. A partir desta tabela da verdade obtida a expresso booleana que a representa. O processo de obteno da expresso booleana a partir da tabela de verdade se compe de trs passos: Passo 1: procura-se na tabela da verdade todas as linhas cujas sadas tenham valor lgico 1; Passo 2: para cada uma destas linhas obtm-se a conjuno ("E") de todas as variveis de entrada, representando as entradas com valor lgico 1 por xi e as com valor lgico 0 por xi ; Passo 3: finalmente, a expresso booleana procurada dada pela disjuno ("OU") das expresses parciais obtidas no passo anterior. A expresso booleana assim obtida dita "de termos mnimos". O processo acima pode ser visualizado no seguinte exemplo. Dada a tabela da verdade abaixo:
Linha 1 2 3 4 5 6 7 8 x1 0 0 0 0 1 1 1 1 x2 0 0 1 1 0 0 1 1 x3 0 1 0 1 0 1 0 1 y 0 0 1 0 1 0 1 0

Passo 1: As linhas cujas sadas tem valor lgico 1 so a 3, a 5 e a 7 Passo 2: obtemos as seguintes expresses parciais: Linha 3: x1.x 2 .x 3 Linha 5: x1 .x 2.x 3 Linha 7: x1 .x2 .x3 Passo 3: a funo procurada (expresso booleana de termos mnimos) dada pela disjuno das expresses acima, isto : y = x1.x 2 .x 3 + x1 .x 2.x 3 + x1 .x 2 .x 3 .

As leis de Boole podem agora ser utilizadas para simplificar a expresso obtida. Usando as leis 3.a, 6.b, 8.a e 3.b sobre a equao anterior, obtemos: y = ( x1 + x2 ).x3 . O mesmo resultado pode ser obtido de forma mais fcil por meio de uma ferramenta de apoio conhecida como Diagrama de Karnaugh [10], que no abordaremos aqui. A implementao prtica das expresses booleanas pode ser feita por Hardware, usando portas lgicas digitais ou rels, ou por meio de Software, que a tcnica usada nos CLPs. Os dois primeiros tipos de linguagens de programao que examinaremos so essencialmente baseadas na converso das expresses lgicas obtidas da forma acima descrita em programas para o CLP.

Marcelo Ricardo Stemmer

184

Informtica Industrial I

DAS/UFSC

5.6.3 Instruction List (IL) 5.6.3.1 Introduo

A linguagem IL define uma srie de mnemnicos semelhantes a linguagem "assembly" (linguagem de mquina dos microprocessadores), que representam as operaes lgicas booleanas e comandos de transferncia de dados. At bem recentemente cada fabricante oferecia seu prprio conjunto de mnemnicos, mas agora estes sero padronizados pela norma IEC 1131 sob o nome de IL (Instruction List, lista de instrues).

5.6.3.2

Elementos bsicos

Um possvel repertrio bsico de comandos poderia ter a seguinte forma: - E <operando> : executa uma operao lgica "E" entre o acumulador do microprocessador do CLP e o operando indicado como parmetro; - EN <operando> : executa uma operao lgica "E" entre o acumulador e a negao do operando; - OU <operando> : executa uma operao lgica "OU" entre o acumulador e o operando indicado como parmetro; - OUN <operando> : executa uma operao lgica "OU" entre o acumulador e a negao do operando; - CAR <operando> : carrega contedo do operando no acumulador (este operando pode ser, por exemplo, uma entrada do CLP); - CARN <operando> : carrega contedo negado do operando no acumulador; - S <operando> : seta operando em 1, se o contedo do acumulador for 1 (este operando pode ser, por exemplo, uma sada do CLP); - R <operando> : reseta operando em 0, se o contedo do acumulador for 1; - ARM <operando> : armazena contedo do acumulador no operando indicado; - ARMN <operando> : armazena contedo negado do acumulador no operando indicado; - TEM <valor> : executa um retardo com temporizao definida pelo valor indicado. Uma linguagem completa inclui ainda mnemnicos para realizar comparaes do tipo >, <, =, >=, <=, deslocamentos (shifts) esquerda e direita, contadores, definio de variveis, etc. Os comandos propostos acima podem ser utilizados para a programao de uma lgica de comando implementada originalmente com portas lgicas digitais, como a apresentada na Figura 38. As equaes booleanas equivalentes so tambm mostradas na figura.
X2 And X3 Or S1=(X2.X3+X4).X1 S2=S3=S1.X5

X4

Not

S1 And

X1

S1 And X5 Not

S2

S3

Figura 38 - Lgica de comando com portas lgicas digitais.

Marcelo Ricardo Stemmer

185

Informtica Industrial I

DAS/UFSC

O programa para implementar estas equaes no CLP teria a seguinte forma: CAR x2 ; coloca x2 no acumulador E x3 ; acumulador = acumulador AND x3 OUN x4 ; acumulador = acumulador OR NOT x4 E x1 ; acumulador = acumulador AND x1 ARM s1 ; armazena acumulador em s1 EN x5 ; acumulador = acumulador AND NOT x5 ARM s2 ; armazena acumulador em s2 ARM s3 ; armazena acumulador em s3 Um exemplo prtico de linguagem baseada em operadores lgicos booleanos a STEP-5, da Siemens AG. Alguns comandos bsicos desta linguagem esto representados na tabela a seguir a ttulo de exemplo. Uma referncia completa pode ser encontrada em [9]. Observe que os mnemnicos esto em alemo.
Grupo operadores lgicos Operao U UN O ON S R S R FR ZV ZR P PN SU RU L T LC = < > >< <= >= + x : SPA SPB SLW SRW RLD RRD Descrio lgico E (Und) lgico E NO (Und Nicht) lgico OU (Oder) lgico OU NO (Oder Nicht) Seta E/S/Varivel Reseta E/S/Varivel Seta contador Reseta contador libera contador (Freizesten) contagem p/ frente contagem p/ trs Testa se bit = 1 (Pruefen) Testa se bit = 0 Seta incondicional Reseta incond. Carrega (Laden) Transfere (Transferieren) Carrega codificado igual menor maior diferente menor ou igual maior ou igual adiciona subtrai multiplica divide Pula absoluto (Springe Absolut) Pula condicional (Springe Bedingt) Desloca a esquerda Desloca a direita rotaciona a esquerda rotaciona a direita

Memria Contadores

teste de bits

carregar e transferir

Comparaes

operaes matemticas

Pulos Deslocamento

5.6.3.3

Exemplo de programao em IL

Deseja-se implementar uma parte da lgica de comando de uma furadeira em IL, conforme mostrado na Figura 39. Definem-se as seguintes entradas e sadas para executar o comando:

Marcelo Ricardo Stemmer

186

Informtica Industrial I

DAS/UFSC

Ponto de partida

Ponto de reduo

Profundidade de perfurao

Figura 39 - Comando de uma furadeira.

Sinais de Entrada: - x1: comando de partida (operador); - x2: furadeira na posio de partida; - x3: ponto de reduo alcanado; - x4: profundidade de perfurao alcanada. Sinais de Sada: - y1: ligar/desligar avano rpido; - y2: ligar/desligar avano lento com rotao; - y3: ligar/desligar retrocesso rpido. A operao bsica a seguinte: se a furadeira estiver na posio de partida (x2) e um comando de partida (x1) foi dado, ligar avano rpido (y1) at atingir o ponto de reduo (x3). Neste ponto, desligar o avano rpido (y1) e ligar o avano lento com rotao (y2). Ao atingir a profundidade de perfurao desejada (x4), desligar o avano lento com rotao (y2) e ligar o retrocesso rpido (y3), at retornar a posio de partida (x2). A lgica de comando acima, aps convertida em programa (IL), tem a forma seguinte: CAR x1 E x2 S y1 CAR y1 E x3 R y1 S y2 CAR y2 E x4 R y2 S y3 CAR y3 E x2 R y3 ; SE comando de partida ; E posio de partida ; ENTO liga avano rpido ; SE avano rpido ligado ; E ponto de reduo atingido ; ENTO desliga avano rpido ; e liga avano lento com rotao ; SE avano lento com rotao ligado ; E profundidade de perfurao atingida ; ENTO desliga avano lento com rotao ; e liga retrocesso rpido ; SE retrocesso rpido ligado ; E posio de partida atingida ; desliga retrocesso rpido

Marcelo Ricardo Stemmer

187

Informtica Industrial I

DAS/UFSC

5.6.3.4

Vantagens e desvantagens da tcnica

Como vantagens desta forma de programao temos: correspondncia entre comandos da linguagem e as instrues assembly do processador, facilitando uma estimativa do tempo de execuo do programa; documentao mais compacta do que a equivalente com rels. Como desvantagens, podemos citar: necessidade de familiarizao do operador com lgebra booleana; necessidade de uma certa familiarizao com programao em assembly; alteraes trabalhosas nas lgicas j implementadas.

5.6.4 Ladder Diagramm (LD) 5.6.4.1 Introduo

A lgica de controle a rels costuma ser representada, nos meios industriais, por um padro caracterstico conhecido como "Diagrama de Escada" ou "Diagrama de Rels". Um diagrama de escada corresponde associao de elementos de entrada e sada, que representam alguma funo lgica de controle. Como muitos engenheiros e tcnicos estavam acostumados a trabalhar com lgica de reles, foi criada uma linguagem para CLP que procura simular um diagrama de reles real, como veremos a seguir.

5.6.4.2

Elementos bsicos do LD

Os diagramas de escada baseiam-se fundamentalmente em trs smbolos bsicos (Figura 40), representando:

Rels Normalmente Abertos (NA), que mantm os contatos de sada abertos (OFF) enquanto no houver corrente na bobina de entrada; Rels Normalmente Fechados (NF), que mantm os contatos de sada fechados (ON) enquanto no houver corrente na bobina de entrada; as Bobinas propriamente ditas, que correspondem a sinais de sada.
RELE NA RELE NF

eletroima Contato NA

eletroima Contato NF

bobina

bobina

Rele NA

Bobina Rele NF

Figura 40 - Rels e elementos bsicos de Diagramas de Escada.

Marcelo Ricardo Stemmer

188

Informtica Industrial I

DAS/UFSC

Os rels NA e NF correspondem variveis de entrada do CLP, enquanto as bobinas representam elementos de sada do mesmo. A cada elemento no diagrama de escada usualmente associado um identificador composto por letras e nmeros. Alm destes elementos bsicos, existem representaes prprias para temporizadores, contadores e outros elementos especiais de entrada e sada. Uma funo lgica "E" representada pela associao em srie de rels, conforme mostrado na Figura 41.a. Nesta situao, somente haver sinal na sada do conjunto (estado lgico "1") quando as bobinas de entrada de ambos os rels estiverem ativadas (isto , tiverem tambm um estado lgico "1"). Esta associao representada em Diagrama de Escada da forma mostrada na Figura 41.b.
Es Ss Ss Saida = 1 Se Ec1 = 1 E Ec2 = 1

a) Ec Ec

RELE 1

RELE 2

b) RELE 1 RELE 2

Figura 41 - Lgica "E": (a) com rels; (b) em diagrama de escada.

De forma anloga, uma funo lgica "OU" representada pela associao em paralelo de rels, conforme a Figura 42.a. Aqui teremos sinal na sada do conjunto (lgico "1") quando ao menos uma das bobinas dos rels estiver ativada (tambm lgico "1"). A representao equivalente em Diagrama de Escada mostrada na Figura 42.b.

Es

Ss

Saida = 1 Se Ec1 = 1 OU Ec2 = 1

Ec a) RELE 1 b) RELE 1

RELE 2

Ec

RELE 2

Figura 42 - Lgica "OU": (a) com rels; (b) em diagrama de escada.

Marcelo Ricardo Stemmer

189

Informtica Industrial I

DAS/UFSC

Um rel NF indica uma negao do sinal de entrada correspondente, uma vez que haver sinal na sada do mesmo (lgico "1") quando no houver sinal na bobina de entrada (lgico "0"). Uma bobina ligada em srie com um conjunto de rels indica que um determinado sinal de sada ser ativado quando os rels associados permitirem a passagem de corrente at a referida bobina, ativando um elemento externo (Figura 43).
Es Ss

Es

Ss

Ss

Ec

a)
Ec Ec

RELE 3

RELE 1

RELE 2

b)
RELE 1 RELE 2 Bobina

Figura 43 - Ligao em srie de uma bobina. (a) Rels; (b) Diagrama Escada.

5.6.4.3

Estrutura de um programa em LD

A linguagem de programao baseada no diagrama de escada (LD) composta por um conjunto de smbolos grficos, como os mostrados na Figura 44, com os quais possvel representar uma grande variedade de estruturas. Os smbolos so interligados entre si para representar lgicas. O nmero de instrues simblicas que podem fazer parte de cada lgica varia muito de um modelo de CLP para outro.
Abertura de ramo paralelo Entrada, Rele NA Fechamento do ultimo ramo paralelo aberto Entrada, Rele NF Rele de Pulso Saida, Bobina

Saida complementada, Bobina

Temporizador

Figura 44 - Exemplos de smbolos grficos do Diagrama de Escada (LD)

Um programa em LD composto de uma ou mais lgicas, que so sempre colocadas entre uma barra vertical de entrada (sempre a esquerda do diagrama) e uma barra vertical de sada (sempre a direita do diagrama). Estas barras representam barras de energia, sendo que o fluxo simulado de corrente eltrica vai sempre somente da barra esquerda para a direita, no havendo portanto, como em um circuito a reles real, caminhos de fuga de corrente.
Marcelo Ricardo Stemmer
190

Informtica Industrial I

DAS/UFSC

Assim, os elementos de uma linguagem de rels so geralmente dispostos sobre uma matriz com nmero limitado de clulas (Figura 45), que podem ser:

barras de alimentao: barras verticais, uma em cada extremo da matriz, simulando as linhas de alimentao do circuito; ligaes horizontais: representam ligaes eltricas entre clulas, transferindo o estado lgico de uma clula a outra; ligaes verticais: permitem interligar clulas em paralelo, definindo uma funo "OU" do estado lgico destas; instrues e operandos, que podem ser: elementos de deciso: contatos NA e NF que refletem o estado lgico das entradas do CLP; elementos de operao: bobinas dos rels, cujos estados lgicos so alterados em funo do resultado da lgica e jogados nas sadas; blocos de funo: grande variedade de elementos adicionais, definindo funes como contadores, operaes aritmticas, seqnciadores, bobinas auxiliares, reles de pulso, etc.

1 Barra de Entrada (esquerda) 2 3

4 5 6

...

Barra de Sada (direita) Clulas com elementos de deciso, operao ou

Figura 45 - formato de uma lgica.

Cada lgica processada coluna por coluna, na seqncia mostrada pela numerao colocada dentro das clulas na Figura 45. Programas compostos de vrias lgicas so executados de cima para baixo, uma lgica aps a outra, e repetidos ciclicamente aps a execuo da ltima lgica. A ttulo de exemplo, a lgica de comando apresentada anteriormente para o circuito lgico digital (Figura 38) seria representada em Diagrama de Escada conforme mostra a Figura 46. O programa correspondente para CLP seria composto de 2 lgicas.

X1
lgica 0

X2

X3

S1

X4 S2
lgica 1

S1 = (x2.x3+x4).x1 S2 = S3 = S1.x5

S1

X5 S3

Barra Entrada

Barra Saida

Figura 46 - Exemplo de Diagrama de Escada.


Marcelo Ricardo Stemmer

191

Informtica Industrial I

DAS/UFSC

Para a entrada do programa sob a forma de Diagrama de Escada no CLP, o terminal de programao pode possuir um teclado dedicado com os smbolos acima indicados ou permitir a programao por meio de recursos grficos de edio no vdeo. Esta ltima opo vem sendo preferida nos anos recentes, pois adequada para a programao usando um computador tipo PC ligado ao CLP.

5.6.4.4

Operandos e Instrues de LD

Os operandos identificam variveis e constantes utilizadas no programa aplicativo. Exemplos de operadores so os pontos de entrada e sada e as memrias contadoras. Existem 3 tipos bsicos de operandos: operandos simples: contm o valor atual de uma entrada (rel), sada (bobina) ou posio de memria (rel auxiliar ou nmero real de ponto flutuante) do CLP. So identificados no programa por cdigos alfanumricos. Ex.: E0002.3 (entrada 3 do bloco 0002) ou S0001.4 (sada 4 do bloco 0001); operandos constantes: so utilizados para definir valores fixos durante todo o programa. So tambm identificados no programa por meio de cdigos alfanumricos. (Ex.: KM+9.81 ou #9.81); operandos tabela ou vetor: so arranjos (arrays) de operandos simples. So identificados de forma semelhante aos casos anteriores. Ex.: TM0026. A maioria dos CLPs atuais permite a definio de alguns operandos como retentivos, isto , que tem seu valor conservado mesmo aps o desligamento do CLP ou queda de energia. As instrues so utilizadas para executar determinadas tarefas por meio de leitura e/ou alterao do valor dos operandos j vistos. As instrues podem ser subdivididas em grupos, como segue: rels: leitura de valores de contatos e ajuste de valores de bobinas; movimentadores: movimentam entrada para memria, memria para sada, etc.; aritmticas: permitem somar, subtrair, multiplicar e dividir operadores; binrias: operaes E, OU e OU exclusivo entre operadores; contadores: operaes de contagem simples (incremental), contagem bidirecional (incremental / decremental) e temporizao (delay); converso: operaes de converso A/D, D/A, Binrio/Decimal e Decimal/Binrio; teste: operaes de comparao (igual, maior, menor, etc); comunicao: envio e recepo de mensagens via rede; Todas estas instrues tem sua representao grfica em LD. Veremos a seguir exemplos de algumas delas. Para uma referncia completa recomendamos a leitura do manual prprio do fabricante do CLP em uso. - Instrues tipo Rel: As instrues mais usuais sobre rels (NA e NF) j foram exemplificadas anteriormente.

Marcelo Ricardo Stemmer

192

Informtica Industrial I

DAS/UFSC

Um tipo til de instruo rel ainda no mencionada o rel de pulso. O rel de pulso coloca a sada em 1 durante um nico ciclo de varredura do programa quando a sua entrada passa de 0 para 1. Veremos uma aplicao disto mais a frente. As bobinas podem ser de 4 tipos bsicos diferentes: bobina simples: seu estado sempre igual ao resultado da lgica que a antecede (0 se linha desenergizada e 1 se linha energizada); bobina liga: seu estado vai para 1 se o resultado da lgica que a antecede for verdadeiro (linha energizada); caso contrrio, no ocorre nada; bobina desliga: seu estado vai para 0 se o resultado da lgica que a antecede for verdadeiro (linha energizada); caso contrrio, no ocorre nada; bobina de salto: no realmente uma sada, como as demais, mas uma forma de implementar um salto (jump) na seqncia de execuo do programa. Este tipo de bobina associado a uma constante, que indica quantas lgicas devem ser puladas se a bobina de salto for ativada. - Instrues tipo Contador: A instruo tipo Contador Simples (unidirecional) requer 2 operadores, 2 sinais de entrada e 2 de sada (Figura 47). Um dos operadores armazena o valor da contagem enquanto o outro define um valor limite para a mesma (este limite uma constante). Se houver um sinal lgico 1 na entrada habilita, cada transio de 0 para 1 na entrada incremento aumenta o valor do contador em 1. A contagem para quando o limite definido pelo outro operando atingido. Quando isto ocorre, a sada limite atingido vai para 1. A sada limite no atingido oposta a anterior.

incremento op1: contagem

limite atingido

habilita

op2: limite (cte)

limite no atingido

Figura 47 - Contador simples.

A instruo tipo Contador Bidirecional (incremental / decremental) pede 3 operadores, 3 sinais de entrada e 3 de sada (Figura 48). O primeiro operador define o valor da contagem. O segundo operador define o passo da contagem (valor do incremento ou decremento). O terceiro operador contm o valor limite superior de contagem (o valor limite inferior sempre zero). Se houver um sinal lgico 1 na entrada habilita, cada transio de 0 para 1 na entrada incrementa faz com que o operando contador seja incrementado em um passo. Uma transio de 0 para 1 na entrada decrementa tem o efeito oposto. A sada limite superior ativada quando o primeiro operando (contador) assume valor igual ao terceiro operando (limite de contagem). A sada limite inferior ativada quando o contador chega em zero. A sada no limite mantida ativada enquanto nenhum dos limites atingido.

Marcelo Ricardo Stemmer

193

Informtica Industrial I

DAS/UFSC

incrementa decrementa op1: contagem op2: passo habilita op3: limite (cte)

limite superior no limite

limite inferior

Figura 48 - Contador Bidirecional.

Uma instruo semelhante utilizada para gerar delays. Para implementar um atraso, utilizase uma instruo temporizadora. O Temporizador ativa (i., coloca em 1) a sada tempo atingido T segundos (ou outra unidade de tempo especificada pelo fabricante) aps a ativao de sua entrada libera (Figura 49) . necessrio energizar tambm a entrada habilita, seno o contador de tempo zerado. Usualmente as entradas libera e habilita so conectadas juntas.

libera op1: contagem tempo

tempo atingido

habilita

op2: tempo limite

tempo no atingido

Figura 49 Temporizador.

- instrues aritmticas: A soma requer 3 operandos: 2 deles contm as parcelas a serem somadas e o terceiro contm o resultado da soma (Figura 50). A operao s realizada quando a entrada habilita ativada. A sada estouro ativada se a soma maior do que a capacidade do terceiro operando. A multiplicao muito semelhante, usando tambm 3 operandos: o primeiro o multiplicando, o segundo o multiplicador e o terceiro o resultado. Tambm so usadas as mesmas sadas que na soma.
habilita MUL / SOM op1: parcela 1 op2: parcela 2 op3: resultado estouro cpia entrada

Figura 50 - Soma e Multiplicao.


Marcelo Ricardo Stemmer

194

Informtica Industrial I

DAS/UFSC

A subtrao tambm pede 3 operandos: 2 contendo as parcelas da subtrao e o terceiro contendo o resultado (Figura 51). So usadas 3 sadas, que indicam o sinal do resultado. A operao s realizada quando a entrada habilita ativada.
habilita SUB op1: parcela 1 op2: parcela 2 op3: sub op1-op2 res < 0 res >0 res = 0

Figura 51 Subtrao.

A diviso pede 4 operandos: o dividendo, o divisor, o quociente e o resto (Figura 52). A operao s se realiza quando a entrada habilita ativada. A sada diviso por zero ativada se o divisor (segundo operando) for zero. Neste caso, o resto ser colocado em zero.

habilita

DIV op1: dividendo op2: divisor op3: quociente op4: resto

cpia entrada

diviso por zero

Figura 52 Diviso.

- instrues binrias: As operaes binrias AND, OR e XOR (OU EXCLUSIVO) pedem 3 operandos: 2 operandos contendo os valores a combinar e um terceiro contendo o resultado (Figura 53). Assim, o terceiro operando conter (Op1 AND Op2), (Op1 OR Op2) ou (Op1 XOR Op2), conforme a escolha. A operao s realizada se a entrada habilita estiver ativada.
habilita AND/OR/XOR op1 op2 op3: resultado cpia entrada

Figura 53 - Operaes OR, XOR, AND.

Marcelo Ricardo Stemmer

195

Informtica Industrial I

DAS/UFSC

5.6.4.5

Diagramas equivalentes

Alguns diagramas no podem ser representados diretamente com este tipo de simbologia. Tais diagramas so os que apresentam diversos caminhos para acionar uma determinada sada. Um exemplo desta situao apresentado na Figura 54.

X1

X2

S1

X5 X3 X4

S1 = (X1.X2)+ (X1.X5.X4)+ (X3.X4)+ (X3.X5.X2)

Barra Entrada

Barra Saida

Figura 54 - Diagrama no representvel no CLP.

Em tais situaes, o programador deve converter a estrutura proibida para uma equivalente que possa ser representada utilizando os recursos da linguagem. Tais transformaes geralmente resultam em um diagrama com mais elementos do que o original. Para o exemplo anterior, a representao equivalente mostrada na Figura 55, que apresenta as mesmas equaes booleanas que as do diagrama original.

X3

X5

X2

S1 S1 = (X3.X5+X1).X2+ (X1.X5+X3).X4 S1 = (X1.X2)+ (X1.X5.X4)+ (X3.X4)+ (X3.X5.X2)

X1 X1 X5 X4

X3

Barra Entrada

Barra Saida

Figura 55 - Diagrama equivalente ao exemplo anterior.

Marcelo Ricardo Stemmer

196

Informtica Industrial I

DAS/UFSC

5.6.4.6

Exemplos de programao em LD

- Exemplo 1: Comando de uma Sinaleira Deseja-se implementar o comando de uma sinaleira que controla o trfego em um cruzamento de duas ruas de mo nica por meio de um CLP, conforme mostra a Figura 56.

CLP

Figura 56 - Cruzamento com sinaleiras.

A seqncia de comando a implementar a apresentada na tabela abaixo. Estado 1 2 3 4 Sinaleira A Vermelho Vermelho Verde Verde/ Amarelo Sinaleira B Verde Verde/ Amarelo Vermelho Vermelho Temporizao 40 seg. 10 seg. 40 seg. 10 seg.

As conexes correspondentes s entradas e sadas no CLP so mostradas na tabela a seguir. Nmero da E/S no CLP Entrada 0 Sada 10 Sada 11 Sada 12 Sada 15 Sada 16 Sada 17 Funo na sinaleira Habilita Sinaleiras Sinaleira A Vermelha Sinaleira A Amarela Sinaleira A Verde Sinaleira B Vermelha Sinaleira B Amarela Sinaleira B Verde Conexo Externa Chave ON/OFF Lmpada Lmpada Lmpada Lmpada Lmpada Lmpada

Para o exemplo em estudo, o diagrama em escada equivalente (LD) a ser programado no CLP mostrado na Figura 57.

Marcelo Ricardo Stemmer

197

Informtica Industrial I

DAS/UFSC

Observe que teremos basicamente uma lgica para cada um dos quatro estados da tabela 3, acrescidos de duas lgicas adicionais para o inicio de operao (quando a sinaleira ligada) e para o trmino de operao (quando a sinaleira desligada). No nosso exemplo, a sinaleira foi programada para ir para o estado 1 no momento em que for ligada (indicado como partida na Figura 57). Nesta aplicao, alm dos rels NA e NF e bobinas liga e desliga, foram utilizados temporizadores, ajustados com os tempos desejados de durao de cada estado, e um rel de pulso (PLS), que pode ser visto na lgica 1. O rel de pulso impede que a lgica 1 seja repetida em cada ciclo de varredura (o que seria indesejvel, pois ela s deve ser executada na partida). O rel de pulso mantm a sada em 1 somente durante o ciclo de varredura imediatamente aps o ligamento da sinaleira, mesmo que a chave conectada a entrada E0 do CLP continue ligada, produzindo assim o efeito desejado. Lembre-se que o programa representado pelo diagrama de escada da Figura 57 ser executado de forma cclica, retornando a primeira lgica aps cada ciclo de varredura (cuja durao de apenas alguns milissegundos). Desta forma, todas as lgicas que compe e programa sero executadas milhares de vezes enquanto a sinaleira passa uma nica vez pelos 4 estados previstos. E0 S10 S17 S10 S12 S15 S17 S16 S15 S16 S17 S10 S12 S11 Estado 4
L D D D L

P LS

L L D

P artida (Estado 1)

E0
D D D

Estado Desligado

S17 40s S16 10s

Estado 2

L D D D L

Estado 3

S12 40s S11 10s

S10 S11 S12 S15 S17 Estado 1

Figura 57 - Diagrama de Escada para o comando da sinaleira.

Marcelo Ricardo Stemmer

198

Informtica Industrial I

DAS/UFSC

- Exemplo 2: Comando de um Estacionamento Um estacionamento composto de 2 andares, com 10 vagas para carros em cada andar. A quantidade de carros em cada andar controlada atravs das fotoclulas FC1 at FC4. A entrada do estacionamento controlada por uma sinaleira com uma lmpada verde L1 e uma lmpada vermelha L2, que s permite a entrada de um carro caso haja ao menos uma vaga no estacionamento. Uma segunda sinaleira indica se h vagas no trreo. Se houver vagas, a lmpada verde L3 acende; seno, a lmpada vermelha L4 acende e o carro tem que se dirigir ao primeiro andar. O acesso ao primeiro andar tambm controlado por uma sinaleira com uma lmpada verde L5 e uma lmpada vermelha L6. A operao transcorre da seguinte forma: quando um veculo entra no estacionamento, a fotoclula FC1 ativada e a quantidade de veculos no andar trreo incrementada em 1, bem como a quantidade total de carros no estacionamento. Se um veculo sobe ao primeiro andar, a fotoclula FC2 ativada e o nmero de veculos no trreo decrementado em 1 enquanto o nmero de veculos no primeiro andar incrementado em 1. Se o nmero de carros no primeiro andar chega a 10, a lmpada vermelha L6 acende e a subida de novos veculos impedida. Se um veculo do primeiro andar deseja sair do estacionamento, a fotoclula FC3 ativada e o nmero de carros no primeiro andar novamente decrementado, bem como o nmero total de carros no estacionamento. Se um veculo estacionado no trreo deseja sair, a fotoclula FC4 ativada e o nmero de carros do trreo bem como o nmero total de carros no estacionamento so decrementados em 1. O contador de carros pode ser resetado por meio do boto C0. O esquema do estacionamento apresentado na Figura 58. As ligaes de entrada e sada no CLP so indicadas na Figura 59. A tabela a seguir apresenta as entradas e sadas do CLP envolvidas nesta aplicao, elucidando suas funes.

primeiro andar

FC3 L6 L5

FC2

FC1 L4 L3 FC4 Sada Trreo Entrada L2 L1

Figura 58 - Esquema do estacionamento a ser controlado.

Marcelo Ricardo Stemmer

199

Informtica Industrial I

DAS/UFSC

C0

FC1

FC2

FC3

FC4

E0

E1

E2

E3

E4

Entradas do CLP Sadas do CLP


S0 S1 S2 S3 S4

+24V

S5

L1

L2

L3

L4

L5

L6

Figura 59 - Conexes de Entrada e Sada no CLP.

Entrada / Sada E0 E1 E2 E3 E4 S0 S1 S2 S3 S4 S5

Ligao externa C0 FC1 FC2 FC3 FC4 L1 L2 L3 L4 L5 L6

Comentrios Chave Resetar contador Fotoclula Entrada Fotoclula Subida Fotoclula Sada, 1o. Pav. Fotoclula Sada, Trreo Sinaleira Entrada, Verde Sinaleira Entrada, Verm. Sinaleira Trreo, Verde Sinaleira Trreo, Verm. Sinaleira 1o. Pav., Verde Sinaleira 1o. Pav., Verm.

O programa em LD para o problema apresentado mostrado na Figura 60. Observe que so utilizados aqui 3 contadores incrementais/decrementais. O primeiro deles conta os veculos no andar trreo, o segundo conta os veculos no primeiro andar e o terceiro um totalizador, contando os veculos no estacionamento como um todo. Observe que aqui estamos usando bobinas simples.

5.6.4.7

Vantagens e desvantagens da tcnica

As vantagens desta tcnica de programao so: possibilidade de uma rpida adaptao do pessoal tcnico, uma vez que a forma de descrio da lgica se assemelha muito aos diagramas eltricos convencionais e lgicas com rels; possibilidade de aproveitamento integral do raciocnio lgico utilizado na elaborao de um comando feito anteriormente com rels; fcil recomposio do diagrama original a partir do programa de aplicao; fcil visualizao dos estados das variveis sobre o diagrama de escada, permitindo depurao lgica e manuteno do software mais rpidas; fcil documentao; representao dos smbolos do diagrama de escada padronizados de maneira idntica nas normas NEMA ICS 3-304 e IEC 1131, mundialmente aceitas pelos fabricantes e usurios.

As vantagens citadas fazem desta tcnica de programao a mais difundida e aceita a nvel industrial atualmente. provvel que a tendncia de introduo de disciplinas de programao de microprocessadores nos currculos das engenharias conduza a uma preferncia futura por outras
Marcelo Ricardo Stemmer
200

Informtica Industrial I

DAS/UFSC

formas de programao. Programadores no familiarizados com a operao de rels tendem a ter dificuldades com esta linguagem.
E1
E0 = C0 E1 = FC1 E2 = FC2 E3 = FC3 E4 = FC4

S3
S0 = L1 S1 = L2 S2 = L3 S3 = L4 S4 = L5 S5 = L6

E2
E4

D MAX = 10

E0

S3

S2

E2 E3

S5

D MAX = 10

E0

S5

S4

E1 E3
E4

S1

D MAX = 20

E0

S1

S0

Figura 60 - Programa em LD para o estacionamento.

5.6.5 Grafos de Comando Etapa-Transio (GRAFCET, SFC) 5.6.5.1 Introduo

Para a programao de lgicas de comando mais complexas, uma linguagem de mais alto nvel do que as apresentadas anteriormente se faz necessria. O resultado de esforos neste sentido foi a definio da linguagem GRAFCET pela AFCET (Association Franoise pour la Cyberntique Economique e Technique, Paris). A linguagem uma adaptao da tcnica de Redes de Petri e permite uma visualizao dos estados pelos quais o sistema a comandar deve passar para realizar uma dada operao. Esta linguagem tambm conhecida como Sequential Function Chart (SFC).

Marcelo Ricardo Stemmer

201

Informtica Industrial I

DAS/UFSC

5.6.5.2

Elementos bsicos do GRAFCET

Um grafo de comando etapa-transio constitudo dos seguintes elementos: - Etapas: correspondem a uma situao na qual o comportamento de todo ou parte do sistema invariante em relao as suas entradas e sadas. Assim, as etapas representam um estado parcial do sistema. Duas representaes so utilizadas para as etapas: a do GRAFCET original (GO, esquerda na Figura 61), semelhante a adotada em redes de Petri, e a do GRAFCET normalizado (GN, direita na Figura 61), cuja representao grfica no computador mais fcil. Uma etapa pode estar ativada ou desativada em um dado momento. Representa-se a ativao de uma etapa colocando uma ficha ("token") em seu interior. A representao grfica da ficha feita por meio de um ponto (Figura 61.b). O estado global de um sistema em um dado momento dado pelo conjunto de etapas ativadas. O conjunto de etapas ativadas constitui a "marcagem" do grafo.

a)

(GO)

(GN)

b)

(GO)

(GN)

Figura 61 - Etapa (a) desativada; (b) ativada.

- Aes: uma ao sempre associada uma etapa e s pode ser executada quando a etapa estiver ativada. A execuo de uma ao pode estar condicionada a uma funo lgica de variveis de entrada do CLP ou ao estado ativo ou inativo de outras etapas. Uma ao esta usualmente relacionada ativao ou desativao de sadas do CLP. Sua representao mostrada na Figura 62. Aes simples, como ativar ou desativar uma sada, podem ser implementadas diretamente no grafo. Aes mais complexas podem se constituir de subrotinas completas, que podem inclusive ser implementadas em outras linguagens, como IL ou LD.
(GO) Se porta aberta: acender lampada

a)

(GN) b) Acender lampada

Figura 62 - Aes (a) condicionais; (b) incondicionais.

- Transies: indicam a possibilidade de evoluo entre etapas. A cada transio associada uma condio lgica chamada receptividade, descrita ao lado do smbolo da transio. A transio

Marcelo Ricardo Stemmer

202

Informtica Industrial I

DAS/UFSC

representada graficamente por uma barra com a receptividade indicada ao lado desta, conforme a Figura 63. A receptividade em geral uma funo associada ao estado das entradas do CLP.

Contato C1 fechado (C1) Contato C1 fechado e C2 aberto (C1.C2)


Figura 63 - Transies e suas receptividades.

Uma receptividade especial a que manipula a varivel tempo. Neste caso, a representao mostrada na Figura 64. Um exemplo deste tipo de receptividade apresentado na Figura 65.

En

t/<etapa origem>/<tempo>

Tn En+1

Figura 64 - Receptividade tempo.

t/6/10s

T3 7

Figura 65 - Exemplo de receptividade tempo.

Marcelo Ricardo Stemmer

203

Informtica Industrial I

DAS/UFSC

Caso no haja condio associada a receptividade, esta chamada de "receptividade incondicional", que representada conforme a Figura 66.

=1

Figura 66 - Receptividade incondicional.

- Arcos: ligam sempre uma transio uma etapa ou uma etapa uma transio. Sua representao grfica mostrada na Figura 67. Os arcos podem ser de entrada ou de sada, isto , arcos que entram ou saem de etapas (Figura 68) ou de transies.
Etapa arco Trans.

arco

Figura 67 - Arcos (GO).

arcos de entrada

(GO)

(GN)

arcos de saida

Figura 68 - Arcos de entrada e sada.

5.6.5.3

Regras de Evoluo do GRAFCET

Cinco regras definem a evoluo do estado (ou marcagem) do GRAFCET:

Marcelo Ricardo Stemmer

204

Informtica Industrial I

DAS/UFSC

- Regra 1: As etapas ativadas na condio inicial devem ser assinaladas com um duplo circulo (GO) ou duplo quadrado (GN), conforme mostra a Figura 69. As etapas usualmente so numeradas a partir daquela que representa a condio inicial (que recebe o nmero 1).

(GO)

(GN)

Figura 69 - Condio inicial do grafo.

- Regra 2: Uma transio ser vlida se todas as etapas de entrada desta estiverem ativadas. Se a transio vlida e a receptividade a ela associada verdadeira, a transio dita disparvel. O "disparo" (definido a seguir), nestas circunstncias, obrigatrio. - Regra 3: "Disparar" uma transio consiste em ativar todas as etapas de sada da transio e desativar todas as etapas de entrada (Figura 70 e Figura 71).

a)

b)

Figura 70 - Disparo simples (a) antes; (b) depois.

a)

b)

Figura 71 - Disparo mltiplo (a) antes; (b) depois.

Marcelo Ricardo Stemmer

205

Informtica Industrial I

DAS/UFSC

- Regra 4: Vrias transies simultaneamente disparveis no grafo devero ser efetivamente disparadas no mesmo instante. - Regra 5: Se uma etapa deve ser desativada e ativada simultaneamente, ela permanece ativada (Figura 72).

Figura 72 - Etapa com realimentao.

5.6.5.4

Estruturas lgicas em GRAFCET

Diversas estruturas lgicas complexas podem ser representadas em GRAFCET, conforme mostrado a seguir. Uma estrutura lgica "OU" pode aparecer sob a forma de uma divergncia (Figura 73), correspondendo a uma estrutura de software do tipo: "SE (estado = x E C1 verdadeira) ENTO (passe ao estado y) SENO SE (estado = x E C2 verdadeira) ENTO (passe ao estado z)".

(GO)

(GN)

C1

C2

C1 b)

C2

a)

Figura 73 - Divergncia em OU (a) GO; (b) GN.

Uma convergncia em "OU" (Figura 74) corresponde, por sua vez, a uma estrutura de software do tipo: "SE (estado = x E C1 verdadeira) OU (estado = y E C2 verdadeira) ENTO (passe ao estado z)".

Marcelo Ricardo Stemmer

206

Informtica Industrial I

DAS/UFSC

C1 C1 C2

C2

(GO)

(GN)

a)

b)

Figura 74 - Convergncia em OU (a) GO; (b) GN.

Uma divergncia em "E" (Figura 75) eqivale a uma estrutura de software do tipo: "SE (estado = x E C1 verdadeira) ENTO (passe aos estados y E z)".

C1 (GO) C1 (GN)

a)

b)

Figura 75 - Divergncia em E (a) GO; (b) GN.

Finalmente, uma convergncia em "E" (Figura 76) eqivale a estrutura: "SE ((estado = x E y) E (C1 verdadeira)) ENTO (passe ao estado z)".

Marcelo Ricardo Stemmer

207

Informtica Industrial I

DAS/UFSC

C1 (GO) C1 (GN)

a)

b)

Figura 76 - Convergncia em E (a) GO; (b) GN.

5.6.5.5

Anlise e validao do GRAFCET

Um dos aspectos mais interessantes desta linguagem de programao para CLP a possibilidade oferecida por ela de realizar uma verificao de correo lgica das especificaes, baseada em certas propriedades bsicas que um grafo correto deve apresentar. O que veremos a seguir apenas uma breve introduo ao aspecto de anlise e validao do GRAFCET. Um estudo mais detalhado do assunto pode ser encontrado na vasta literatura disponvel sobre Redes de Petri, de onde esta tcnica de programao derivada. Um grafo correto em GRAFCET deve possuir as seguintes 5 propriedades: Grafo Limitado e Seguro: quando o nmero de fichas contido em qualquer etapa inferior a um dado limite para qualquer marcagem possvel, o grafo dito limitado. Se este limite 1, o grafo dito seguro. Uma etapa onde possam se acumular fichas em nmero ilimitado indicativo de um erro de especificao. Grafo Reinicializvel: quando, para qualquer marcagem acessvel atingida a partir da marcagem inicial, existe uma seqncia de disparo que permita o retorno a marcagem inicial, o grafo dito reinicializvel. Grafo Vivo: quando, para qualquer marcagem acessvel M e qualquer transio T, existe uma seqncia de tiro disparvel a partir de M que inclua T, o grafo dito vivo. Isto eqivale a dizer que no podem haver ramos do grafo por onde a ficha jamais passa. Grafo Determinsta: um grafo dito determinista quando todos os possveis conflitos nele contidos esto resolvidos de forma inequvoca. Duas transies so ditas em conflito se existe uma marcagem acessvel que sensibilize as duas ao mesmo tempo, de forma que o disparo de uma delas impea o da outra, como na Figura 77.

Marcelo Ricardo Stemmer

208

Informtica Industrial I

DAS/UFSC

Figura 77 Transies A e B em Conflito.

Um conflito dito resolvido se as etiquetas associadas s transies envolvidas no permitam nunca o valor verdade para as duas simultaneamente, como ilustrado na Figura 78.

[C1, ]

[C1, ]

IF (C1=TRUE) THEN Ao1 ELSE Ao2;

Ao1

Ao2

Figura 78 Conflito resolvido (estrutura tipo IF - THEN - ELSE).

Grafo Determinado: um grafo dito determinado se s h aes que possam ser executadas simultaneamente associadas a etapas paralelas. Duas etapas so ditas paralelas se existe uma marcagem acessvel que ative as duas mesmo tempo, como mostrado na Figura 79.

Figura 79 Etapas A e B em Paralelo

Marcelo Ricardo Stemmer

209

Informtica Industrial I

DAS/UFSC

O grafo da Figura 80.a exemplifica uma situao em que so associadas aes incompatveis entre si a etapas paralelas. Em uma das etapas definiu-se a ao de ler o valor de uma varivel x, enquanto na outra definiu-se a ao de escrever um novo valor para a mesma varivel. Como as duas etapas podem ser ativadas simultaneamente, nada impede que as duas aes sejam executadas ao mesmo tempo, o que no caso geraria um erro (leitura e escrita simultneas de uma mesma rea de memria). Isto corresponde a uma situao tpica de automao onde um intertravamento se faz necessrio, como ilustrado na Figura 80.b.

C1

C1

[escrever x]

[lr x]

[escrever x]

[lr x]

a)

b)

Figura 80 (a) Grafo no Determinado; (b) Grafo determinado via intertravamento.

Na anlise do GRAFCET, caso qualquer uma das cinco propriedades bsicas acima esteja faltando, de se supor que ocorreu um erro srio de especificao e o programa deve ser revisto. Hoje j esto disponveis programas de computador capazes de realizar automaticamente uma verificao de algumas destas propriedades, facilitando enormemente a tarefa de validao de software. A maioria destas ferramentas, no entanto, foi elaborada para redes de Petri e no especificamente para GRAFCET.

5.6.5.6

Exemplo de programao em GRAFCET

Deseja-se realizar o comando de um sistema de transporte de peas em Pallets que inclui um AGV (Automatic Guided Vehicle). O AGV deve transportar pallets do porto A ao porto B, conforme mostrado na Figura 81. Enquanto um pallet carregado no AGV no porto A, um rob remove o pallet anterior do porto B (caso haja algum).

Marcelo Ricardo Stemmer

210

Informtica Industrial I

DAS/UFSC

FMC

Correia Entrada

Robo

PB

Correia Saida
Pallet PA

AGV
FC

Porto A

Porto B
Figura 81 - Sistema de transporte com AGV.

A operao comandada por um CLP atravs dos seguintes sinais de entrada e sada: Sinais de Entrada: (Sensores) - PA = Pallet em A - PB = Pallet em B - FC = Fim de carregamento do Pallet no AGV - A = AGV no porto A - B = AGV no porto B Sinais de Sada: (Atuadores) - D = AGV se desloca para a Direita - E = AGV se desloca para a Esquerda - S = AGV parado (Stop) - CP = Carrega Pallet no AGV - DP = Descarrega Pallet do AGV - RP = Remove Pallet (Rob) O GRAFCET que realiza o comando pretendido representado na Figura 82.

Marcelo Ricardo Stemmer

211

Informtica Industrial I

DAS/UFSC

1
PA

S .E

2
FC

CP

4 3
A B PB

D 6

CP
PB

RP
PB

S .D 7
=1

RP

8
PB

DP

E .D P .R P . S

Figura 82 - GRAFCET (GN) para o comando do sistema de transporte.

O GRAFCET pode ser programado com o auxlio de recursos grfico-interativos ou por meio de uma linguagem textual que descreva o grafo.

5.6.5.7

Vantagens da tcnica

As principais vantagens do uso do GRAFCET so:


simplicidade de interpretao; abrangncia, podendo representar a maioria dos sistemas de controle lgico industriais; formalizao rigorosa, permitindo anlise e documentao precisas; facilidade de decomposio do sistema em subsistemas funcionais; facilidade de representao de sistemas com paralelismos; capacidade de uso em vrios nveis de interpretao.

5.7 Normas Relevantes Para CLPs


Diversas entidades internacionais preocupam-se com a criao e o aperfeioamento de normas especficas sobre CLPs. Algumas normas que merecem ateno so listadas a seguir [3]:

NEMA (National Electrical Manufacturers Association) ICS 1-109 "tests and test procedures": define uma srie de testes aplicveis a nvel de projeto, produo e aplicao de CLPs; NEMA ICS 2-230 "Components for solid-state logic systems": descreve testes e equipamentos para verificao de imunidade a rudo;
212

Marcelo Ricardo Stemmer

Informtica Industrial I

DAS/UFSC

IEEE std 518-1977 "Guide for installation of electrical equipment to minimize electrical noise inputs to controllers from external sources": contm um estudo sistemtico sobre rudos, suas fontes e mtodos de reduo; NEMA ICS 3-304 e IEC 1131: so as normas mais completas sobre CLPs, abordando problemas de confiabilidade, redundncia, recuperao de falhas, sistemas de comunicao, entre outros. Elas enumeram estruturas, tipos de programao e subsistemas para CLPs, estabelecem parmetros mximos e mnimos de operao, dentro dos quais os CLPs devem funcionar sem apresentar defeitos, e descrevem testes padronizados para caracterizar e verificar as especificaes dos fabricantes. A norma IEC 1131 padroniza 5 linguagens para CLP: IL, LD, GRAFCET, ST (Structured Text, semelhante a Pascal) e FBD (Functional Block Diagram, que transforma um desenho de um diagrama de blocos com portas AND, OR, XOR, etc, da lgica digital em programa de CLP).

5.8 Interligao de CLPs Utilizando Redes de Comunicao


A padronizao dos canais de comunicao entre CLPs e outros equipamentos inteligentes de automao tem adquirido grande importncia, em vista da tendncia de integrao total de todos os nveis hierrquicos de automao verificada aps a introduo da filosofia CIM (Computer Integrated Manufacturing). Diversos fabricantes de componentes para automao industrial, incluindo a maioria dos CLPs, j fornecem interfaces para rede em seus produtos (Figura 83). Entre as redes mais difundidas a este nvel hierrquico de automao esto os sistemas BITBUS, PROFIBUS, FIP, INTERBUS-S, CAN, SERCOS, LON, TOKEN-RING e ETHERNET, s para citar alguns poucos exemplos. Muitos fabricantes oferecem redes "proprietrias" para esta finalidade (redes com tecnologia prpria). A tendncia dominante, no entanto, a de procurar seguir um dos vrios sistemas atualmente propostos para padronizao de redes para cho de fbrica (FIP, PROFIBUS, ISA-SP50, etc.).

Figura 83 - CLP com mdulo para interligao em rede.

Uma das possveis reas de aplicao de CLPs interligados por uma rede de comunicao a realizao de um SDCD (Sistema Digital de Controle Distribudo), usado para o controle e superviso de sistemas complexos envolvendo grande nmero de grandezas, tais como refinarias, usinas eltricas, plantas qumicas, etc. Aqui, um computador ligado rede toma as decises centrais e vrios CLPs ligados a ele via rede interagem com o ambiente a ser controlado e supervisionado por meio de seus mdulos de entrada e sada (Figura 84). Outra importante aplicao de mdulos de rede para CLP a interligao destes com Sistemas Supervisrios, que rodam em computadores tipo PC e permitem visualizar na tela do mesmo o andamento do processo sendo controlado pelo CLP. Exemplos de tais programas
Marcelo Ricardo Stemmer
213

Informtica Industrial I

DAS/UFSC

supervisrios so o FIX (verses SCADA e MMI), InTouch, Genesis, Unisoft, Elipse 21, entre outros. A maioria dos fabricantes de CLP oferece drives especficos de seu produto para estes softwares. Os fabricantes atuais de CLP oferecem algumas instrues adicionais para permitir o desenvolvimento de programas aplicativos que faam uso do acesso a rede. As instrues mais usuais so as de leitura e escrita de operandos em outros CLPs conectados rede. A sintaxe de tais comandos ainda varia de fabricante para fabricante, mas dever passar por um processo de padronizao em breve (a IEC j est realizando estudos neste sentido).

Rede de comunicao

Mdulo de Interface para rede

...
CLP1 CLP2 CLPn

Figura 84 - SDCD com CLPs interligados via rede.

5.9 O Mercado de CLPs no Brasil


No Brasil, mais de 20 empresas esto produzindo CLPs, com as mais variadas especificaes. Enquanto alguns fabricantes desenvolveram tecnologia prpria, grande parte deles adota tecnologia importada. Algumas caractersticas bsicas de produtos dos principais fabricantes so mostradas na tabela a seguir [1]. O mercado de CLPs no Brasil, apesar de enfrentar uma queda no volume de vendas nos anos de 1990 e 1991, vem apresentando desde ento um franco crescimento. Segundo um estudo publicado pela SOBRACON [11], passou-se de um volume de vendas de 27,8 milhes de dlares em 1986 para 61,5 milhes de dlares em 1992 (Figura 85). O nmero de unidades vendidas cresceu de 3.324 em 1990 para 5.579 em 1992, indicando uma boa recuperao do setor aps a crise de 1990/91. O mesmo estudo indica ainda que 69,14% das empresas usurias de componentes para automao industrial utilizam CLPs. 44,44% dos CLPs instalados so de pequeno porte, 28,40% so de mdio porte e 19,75% so de grande porte. Os restantes 7,41% dos usurios no respondeu a pergunta. Com relao as aplicaes mais comuns, o estudo mostra que 42,67% dos CLPs instalados so usados na rea de controle de processos, 40,00% na rea de manufatura, 4,00% so usados em ensino e 2,68% na integrao de sistemas de automatizao industrial. Os restantes so aplicados em reas diversas como controle de demanda, laboratrios de teste, linhas de fabricao de mquinas, automao predial e controle de subestaes de energia. Alm disso, 48,70% dos CLPs usados so de fabricao nacional.
Marcelo Ricardo Stemmer
214

Informtica Industrial I
70

DAS/UFSC

F a t u r a m e n t o

60 50 40 30 20 10 0 1986 1987 1988 1989 1990 1991 1992 U$ milhes

ANO

Figura 85 - Faturamento do setor de CLPs no Brasil (1986-1992).


Fabricante ATOS Modelo (exemplos) MPC-504 MPC-514 MPC-264 AL-1000 AL-600 CAMCON-80 CAMCON-100 CPC-1000 CA-1200 MPI-256 MPI-4096 D-20 CP/DIG-80 CP/DIG-80-10 1484 PLC90-30 modelo 311 PLC90-30 modelo 331 Geotron CLP HSC-1000 MPC-85 MPC-130 Simatic S5 Simatic S7 CLP2mini CLP2/20 CLP-16 CLP-40 CLP-80 PS-22 CP-80 Vilogic-500 CPW-A500 CPW-A200 CPW-A100 E 20 32 16 32 16 26 S 12 16 16 32 8 20 Max E+S 32 48 128 256 256 256 Mem. Proc. 8040 8040 8035 8031 80C32

ALTUS (Bosch) BCM Cambridge Chronos Contrap CGR Digicon

16K

16

16

Engeletro FANUC (GE) Geotron Herge Italvolt Siemens Allen-Bradley Pulse

12 256 256 4 320 512

8 256 256 4 320 512

220 256 4096 40 512 512 512

32K 8K 16K 2K 4K 8K 3K 8K 16K 14K 3K

Z80-2

8085 8085 80188 80188 8085 8085 8748

512 512 128

Mller SCI Villares WEG (AEG)

8 8 8 8 8 256 12 12

8 8 8 8 8 256 12 12

128 896 16 40 80 288 256 512 4096 336 336

1K 8K 4K 4K 4K 4K 12K 1K 8K 8K

8080A 8086

Marcelo Ricardo Stemmer

215

Informtica Industrial I

DAS/UFSC

6 Sensores e Atuadores Inteligentes


A introduo de p e c em sistemas de sensoreamento a atuao tornou possvel a realizao de uma srie de funes de forma distribuda. Tais funes eram realizadas anteriormente em uma unidade central de processamento.

6.1 Sensores Inteligentes


As principais tarefas executadas por sensores nos diversos setores industriais esto representadas de forma genrica na Figura 86.
Fora Dilatao Estrutura ... Verificao da Geometria Verificao da funo controle de sistemas superviso de sistemas

Verificao do material Aquisio de dados de qualidade

Comprimento Angulo Diametro Superficie Forma ... Potncia Rotao Fora Presso Temperatura ...

Tarefas de sensores na Produo Aquisio de dados de estado

Posio Angulo Fora Rotao Torque Dilatao Presso Temperatura Corrente ... Forma Cr Cdigo Massa Dimens. ...

de peas Identificao de ferramentas

Figura 86 - Grandezas a medir na automao.

A complexidade requerida de um sensor depende da tarefa a que est destinado. Modernos sistemas de sensoreamento inteligentes permitem uma configurao flexvel. Entre as possveis funes a serem realizadas por sensores inteligentes, temos: aquisio de dados utilizando transdutores j disponveis digitalizao e codificao dos dados filtragem digital de sinais compactao de informaes e eliminao de redundncias calibrao do sensor superviso de valores limite correo automtica de erros sistemticos (no linearidade, dependncias de temperatura (Drift), etc. clculo de grandezas derivadas do valor medido (valor mdio, desvio padro, etc.)

A programao destas funes no sensor inteligente pode ser feita por meio de gravao de uma EPROM ou atravs de carregamento de programa (downloading) via interface de comunicao. Uma opo em estudos a introduo de um sistema operacional para sensores, que inclui uma srie de funes padronizadas, que podem ou no ser utilizadas em um dado sensor. Um tal sistema operacional teria as seguintes funes bsicas:
Marcelo Ricardo Stemmer
216

Informtica Industrial I

DAS/UFSC

controle de hardware: comando das entradas, conversores, temporizao, etc... administrao e processamento de dados: armazenamento local, converso de formato, acesso s funes de uma biblioteca, etc... comunicao com o mundo exterior: interface para rede com protocolo de comunicao padronizado (rede tipo FieldBus) Apesar da grande variedade de transdutores existentes, a maioria destes converte a grandeza fsica medida em um dos seguintes sinais eltricos: entradas binrias ou digitais: TTL, 0-12V, 0-24V (encoders, chaves fim-de-curso, rels, botoeiras, etc.) entradas analgicas: 0-20mA, 4-20mA, 0 a 5V, 5V, 0 a 10V, 10V (usando conversores analgico/digital) A configurao bsica de um sensor inteligente mostrada na Figura 87.

Adaptao periferia Fim-de-curso botoeira ... Contador Fora Presso ... Temperatura entradas analgicas (MUX) ROM RAM entradas digitais CPU

Sensor virtual

DPRAM

coproc. comunicao (Layer 2)

Interface serial

BUS

Figura 87 - Configurao bsica de um Sensor inteligente.

6.2 Atuadores Inteligentes


Atuadores convertem sinais eltricos de corrente ou tenso em outras grandezas fsicas como: velocidade fora presso rotao/translao temperatura, etc.

Marcelo Ricardo Stemmer

217

Informtica Industrial I

DAS/UFSC

Os sinais convertidos so utilizados para afetar o comportamento de um dado sistema, como: aumentar ou diminuir a vazo num cano aumentar ou diminuir a temperatura em um forno industrial aumentar ou diminuir a velocidade de avano ou de corte de uma mquina-ferramenta A maioria dos atuadores podem ser comandados com um dos seguintes sinais eltricos: sadas digitais: TTL, 0-12V, 0-24V (rels, etc.) sadas analgicas: 0-20mA, 4-20mA, 0 a 5V, 5V, 0 a 10V, 10V (servo-vlvulas, motores DC, etc.) sadas PWM (Pulse Width Modulation): motores AC, motores de passo, etc. A configurao bsica semelhante a de um sensor inteligente (Figura 88).

Reles

adaptao periferia sadas digitais

Atuador virtual

Motor DC sadas analgicas Servovlvula Motor AC e de passo ROM RAM CPU DPRAM

coprocessador comunicao (Layer 2)

interface serial

BUS

PWM

Figura 88 - Configurao bsica de um Atuador Inteligente.

Marcelo Ricardo Stemmer

218

Informtica Industrial I

DAS/UFSC

7 Anexo I Trabalhos em C/C++ Trabalho 1


Crie um programa que desenhe na tela o seu quadro de horrios deste semestre.

Trabalho 2
A decomposio LDU uma decomposio famosa de matrizes aplicada para calcular inversas de matrizes e resolver problemas de equaes lineares. Utilize o programa 9.1 e crie um programa que calcule a decomposio LDU de uma matriz, preferencialmente, com pivotamento.

Trabalho 3
Crie um programa que faa o controle de cadastro de usurios e controle de alocao para uma locadora de fitas de vdeo. Utilize uma classe para os clientes e outra para as fitas, e empregue o mtodo da lista ligada para gerenciar um vetor dinmico. O usurio de poder incluir/retirar um cliente ou uma fita, fazer uma pesquisa, pedir a lista de clientes e a lista de fitas ou alterar algum parmetro destas.

Trabalho 4
Tema livre, a ser proposto pelos alunos e apresentado ao professor (em equipe).

Marcelo Ricardo Stemmer

219

Informtica Industrial I

DAS/UFSC

8 Anexo II Trabalho de CLP


MISTURADOR AUTOMTICO DE TINTAS Um misturador automtico para duas cres de tintas deve ser comandado por meio de um CLP. A operao transcorre da seguinte forma: aps pressionar o boto de partida C0 (botoeira que mantm contato somente enquanto pressionada), a lmpada H0 acende, indicando inicio de operao, a vlvula Y1 abre e a bomba M2 ligada. Quando o nvel da primeira tinta no recipiente de mistura atinge o sensor B1, a vlvula Y1 fechada e a vlvula Y2 aberta, misturando a segunda tinta ao contedo do recipiente. Quando o nvel total de tinta atinge o sensor B2, a vlvula Y2 fechada, a bomba M2 desligada e o misturador M1 ativado. Aps 6 segundos o misturador M1 e a lmpada H0 so desligados e a tinta j homogeneizada pode ser removida (manualmente). O misturador pode ser desligado em qualquer ponto da operao por meio do boto de parada de emergncia C6, pelos sensores trmicos F1 ou F2 ligados aos motores do misturador e da bomba, respectivamente, ou pelo sensor B4, que indica enchimento total do recipiente de mistura. A Figura 89 apresenta o esquema do misturador. As ligaes no CLP so apresentadas na Figura 90. A tabela a seguir mostra os sinais de entrada e sada utilizados e descreve seu uso nesta aplicao. Elabore o programa de comando do misturador no CLP, usando Diagramas de Escada.
Boto de Partida C0

Lmpada de operao H0

Boto de Emergncia C6 Misturador M1 com sensor F1 Bomba M2 com sensor F2

Vlvula Y1

Vlvula Y2

sensor nvel B4 sensor nvel B2 sensor nvel B1

Tinta 1

Tinta 2

hlice do misturador

Figura 89 - Misturador de Tintas (2 cres).

Marcelo Ricardo Stemmer

220

Informtica Industrial I

DAS/UFSC

C0

B1

B2

B4

C6

F1

F2

E0

E1

E2

E3

E4

E5

E6

Entradas do CLP

+24V

Sadas do CLP
S0 S1 S2 S3 S4

H0

Y1

Y2

M1

M2

Figura 90 - Conexes de Entrada e Sada no CLP

Entrada / Sada E0 E1 E2 E3 E4 E5 E6 S0 S1 S2 S3 S4

Ligao externa C0 B1 B2 B4 C6 F1 F2 H0 Y1 Y2 M1 M2

Comentrios Chave Partida Sensor de nvel Sensor de nvel Sensor de nvel Chave Parada Emergncia Sensor trmico Misturador Sensor trmico Bomba Lmpada de operao Vlvula tinta 1 Vlvula tinta 2 Motor Misturador Motor Bomba

Marcelo Ricardo Stemmer

221

Informtica Industrial I

DAS/UFSC

9 Bibliografia
9.1 CLP
[1] Stemmer, C. E. : "Equipamentos de automatizao da manufatura". Anais do II CONAI, 1985. [2] Lcio e Silva, J.J.; Foot Filho, D. : "Controladores lgicos programveis: aplicaes na manufatura". Anais do VI Seminrio de Comando Numrico no Brasil, 1986. [3] Gerbase, L. F. : "Tendncias atuais na normalizao de controladores lgicos programveis". Anais do II CONAI, 1985. [4] Cugnasca, C.E.; Del Bianco F., O.; Moscato, L.A : "Mtodos de programao de controladores lgicos programveis". Anais do II CONAI, 1985. [5] Rillo, H.; Costa Rillo, A.H.R.; Cirelli, S.; Zilinskas, W.: "Controlador programvel por grafos de comando etapa-transio (GRAFCET)". Anais do II CONAI, 1985. [6] Weck, M. : "Werkzeugmaschinen". Band 3, VDI-Verlag, Dsseldorf, Alemanha, 1989. [7] Blanchard, M. : "Comprendre maitriser et appliquer le GRAFCET". Cepadues Editions, Toulouse, Frana, 1979. [8] De Oliveira, J.C.P. : "Controlador Programvel". Makron-Books do Brasil Editora, So Paulo, 1993. [9] Berger, H. : "Programmieren von Funktionsbausteinen in STEP5". Siemens AG, Berlin e Munique, Alemanha, 1986. [10] SOBRACON : "Guia Brasileiro de Automatizao Industrial 1992". [11] Webb, John et all: Programmable Logic Controllers: Principles and Applications. 4th edition, Prentice-Hall, 1998. [12] Stenerson, Jon : Fundamentals of Programmable Logic Controllers, Sensors and Communications. 2nd edition, Prentice-Hall, 1999. [13] Peter Rohner : Automation With Programmable Logic Controllers, MacMillan, 1996. [14] Simpson, Colin : Programmable Logic Controllers. Prentice Hall . [15] Mandado, Enrique : Programmable Logic Devices and Logic Controllers. Prentice Hall . [16] K. Clements-Jewery, W. Jeffcoat : The Plc Workbook : Programmable Logic Controllers Made Easy. [17] W. Bolton : Programmable Logic Controllers : An Introduction .
Marcelo Ricardo Stemmer
222

Informtica Industrial I

DAS/UFSC

[18] Robert F. Filer, George Leinonen : Programmable Controllers and Designing Sequential Logic. Saunders College Publishing Series in Electronics Technology. [19] George L., Jr. Batten, George J. Batten : Programmable Controllers : Hardware, Software, and Applications. [20] Frank D. Petruzella: Programmable Logic Controllers.

9.2 C/C++
[1] Booch, G.; Jacobson, I. e Rumbaugh, J.: The Unified Software Development Process, ed. Addison Wesley Longman, January of 1999. [2] Booch, G.; Jacobson, I. e Rumbaugh, J.: The Unified Modelling Language User Guide, Ed. Addison Wesley-Logman, 1999. [3] Borland C++: Programmers Guide, Borland International, USA, 1994. [4] Borland C++: Users Guide, Borland International, USA, 1994. [5] Douglass, B. P.: Real-Time UML : Developing Efficient Objects for Embedded Systems, ed. Addison Wesley Longman, August of 1998. [6] Mizrahi, Victorine Viviane.: Treinamento em Linguagem C Curso Completo, Mdulo 1, Ed. Makron Books do Brasil, So Paulo,1990. [7] Meyer, Bertrand .: Object-Oriented Software Construction. Ed. Prentice Hall. [8] Mizrahi, Victorine Viviane.: Treinamento em Linguagem C++ - Mdulo 1 e 2, Ed. Makron Books do Brasil, So Paulo, 1994. [9] Montenegro, Fernando; Pacheco, Roberto: Orientao a Objetos em C++, Ed. Cincia Moderna, Rio de Janeiro, 1994. [10] Petzold, Charles: Programming Windows 95, Microsoft Press, Washington, 1996. [11] Reidorph, Kent: Teach Yourself Borland C++ Builder 3 in 21 Days, Sams Publishing, Indianapolis, USA, 1998. [12] Rumbaugh, J.; Blaha, M.; Premerlan, W.: Eddy, F. e Lorensen, W.: Object-Oriented Modelling and Design . Ed. Prentice Hall. [13] Stevens, W. R..: Programmieren von Unix-Netzen Grundlagen, Programmierung, Anwendung, Ed. Hanser and Ed. Prentice-Hall, 1992. [14] Swan, Tom: Programao Avanada em Borland C++ 4 Para Windows, Ed. Berkeley Brasil, So Paulo, 1994.

Marcelo Ricardo Stemmer

223

Informtica Industrial I

DAS/UFSC

9.3 Hot Sites


http://www.developer.com http://www.borland.com/ http://msdn.microsoft.com/resources/devcenters.asp http://search.microsoft.com/us/dev/ http://www.rational.com/uml/ http://www.togethersoft.com/together/togetherC.html http://world.isg.de/world/ http://www.popkin.com/services/enterprise/uml/uml.htm http://www.ee.cooper.edu/resource/docs/linux/LDP/lpg/node1.html http://www.geog.leeds.ac.uk/staff/i.turton/unix/course.html http://www.geog.leeds.ac.uk/staff/i.turton/unix/course.html

Marcelo Ricardo Stemmer

224

Você também pode gostar