Вы находитесь на странице: 1из 63

UNIVERSIDADE DE SANTO AMARO

Sistemas de Informao

Desenvolvimento de Sistemas

Eugnio Akihiro Nassu

Universidade de Santo Amaro

Eugnio Akihiro Nassu

Desenvolvimento de Sistemas Sistemas de Informao E a D

So Paulo 2009

Eugnio Akihiro Nassu

Desenvolvimento de Sistemas Sistemas de Informao E a D

Apostila da Disciplina Estruturas de Dados E a D Curso: Bacharelado em Sistemas de Informao

So Paulo 2008

1 Introduo
Nesta apostila, trataremos dois aspectos fundamentais no desenvolvimento de sistemas, primeiro, apresentaremos a anlise estruturada, parte importante para a modelagem dos sistemas. Depois iniciaremos a linguagem C, bsica para a programao. Todas as linguagens modernamente usadas so baseadas na linguagem C, da sua importncia. Atualmente, outra forma bastante usada para anlise e modelagem de sistemas a anlise e modelagem Orientada a Objetos, que objeto de outras disciplinas, assim como a programao Orientada a Objetos. Esta apostila dividida em duas grandes partes, uma dedicada anlise estruturada e a segunda uma introduo linguagem de programao C.

2 Anlise Estruturada de Sistemas


O mtodo da anlise estruturada baseia-se em princpios da programao estruturada: Diviso do problema em parte/sub-partes, que facilitem a especificao correta e completa do sistema. Abordagem top-down com refinamentos sucessivos, ou seja, parte de uma viso bem geral e vai aumentando o nvel de detalhe sucessivamente. Para exemplificar a anlise top-down com uma atividade do mundo real, pode-se pensar em uma planta de uma casa. A fase de nvel mais alto envolve a escolha de terreno, localizao, etc. Depois se pode partir para uma planta baixa, sem detalhamento. Depois so inseridas as conexes de fios, gua, telefone, etc. No final, o pessoal que constri a casa chega ao nvel de detalhe mais fino, onde cada tijolo vai formando a casa. H na literatura diversas verses do mtodo de anlise: Tom De Marco (1979) Page-Jones (1980) Gane & Sarson (1982)

2.1 Tcnicas de Representao


Nesta seo, apresentaremos os principais elementos para representao dos sistemas, a saber: Diagrama de Fluxo de Dados Descrio dos Processos Dicionrio de Dados
3

Detalharemos cada um deles nas sees seguintes.

2.1.1 Diagrama de Fluxo de Dados (DFD)


O Diagrama de Fluxo de Dados mostra como os dados da aplicao sendo modelada percorrem o sistema. Ele representado atravs de um diagrama para melhor visualizao.

2.1.1.1 Componentes de um DFD


Os componentes de um DFD so: Entidade Externa: Um produtor ou consumidor de informaes que resida fora dos limites do sistema a ser modelado. Processo: Um transformador de informaes que resida dentro dos limites do sistema a ser modelado. Fluxo de Dados: Compreende um elemento de dados ou estrutura de dados, que trafegam entre os processos e entidades. A seta indica a direo do fluxo de dados. Depsito de Dados: Um repositrio de dados que so armazenados para serem usados em um ou mais processos; pode ser simples (buffer, fila, etc.) ou mais complexo (banco de dados).

2.1.1.2 Notaes do DFD


A figura 1 mostra as notaes grficas de um DFD.

Yourdon, DeMarco

Entidade Externa

Processo

Depsito de Dados

Fluxo de Dados

Gane & Sarson

Entidade Externa

Processo

Depsito de Dados

Fluxo de Dados

Figura 1

As figuras 2 e 3 mostram exemplos de um DFD simples, um em cada notao.

D1 E1 CLIENTES

F4 F2
P1 Receber Pedidos F1 - Pedidos Recebidos F2 - Pedidos Invlidos

F5

F1

F3

F3 - Inf. de Pagamento F4 - Detalhes de Pedidos F5 - Detalhes de Remessa de Pedidos

Figura 2

D1 E1 CLIENTES F2 F4 F5

P1
F1 Receber Pedidos F1 - Pedidos Recebidos F2 - Pedidos Invlidos F3 - Inf. de Pagamento F3 F4 - Detalhes de Pedidos F5 - Detalhes de Remessa de Pedidos

Figura 3

2.1.1.3 Estudo de Caso: Sistema de Alarme Residencial


O software SafeHome possibilita que o dono da casa configure o sistema de segurana quando ele for instalado, monitora todos os sensores ligados ao sistema de segurana e interage com o dono da casa por meio de um teclado (key pad) e teclas de funo contidas no painel de controle do SafeHome ilustrado na Figura 6.6. Durante a instalao, o painel de controle do SafeHome usado para programar e configurar o sistema. A cada sensor atribudo um nmero e um tipo, uma senha mestra programada para armar e desarmar o sistema e nmeros telefnicos so introduzidos para serem discados quando ocorrer um evento sensor. Quando um evento sensor sentido pelo software, ele dispara um alarme sonoro ligado ao sistema. Aps um tempo de espera, que especificado pelo dono da casa durante as atividades de configurao do sistema, o software disca um nmero telefnico do servio de monitorao, oferece informaes sobre o local, registrando a natureza do evento que foi detectado. O nmero ser novamente discado a cada 20
6

segundos at que a ligao telefnica seja completada. Todas as interaes com o SafeHome so gerenciadas por um subsistema de interao com o usurio, que l a entrada fornecida pelo teclado e pelas chaves de funo, exibe mensagens de prompting e informaes sobre o status do sistema no mostrador de cristal lquido (LCD). A interao com o teclado assume a forma exibida na figura 4

of

awa

stay

SAFEHOME

1
ma

2
test

3
bypas

4
instant

5
co

6
chim

alarm check fire

away stay instant bypass not ready

7
read

8 0
panic

9 #

armed

power

Figura 4 Na figura 5 exibido um DFD no nvel de contexto. 7

Linha telefnica

Comandos e dados do usurio

Display do painel de

Informaes de display

controle

Software SafeHom Tipo de alarme

Alarme

Status

do

sensor

Tons de nmeros telefnicos

Painel de controle

SENSOR

Figura 5 Na figura 6 exibido um DFD com mais detalhes. Note que as entidades externas so as mesmas, e detalhamos melhor o processamento dos comandos do sistema. Assim, a anlise se aproxima cada vez mais da linguagem de programao, que deve ser um dos ltimos estgios do desenvolvimento.

Painel de Controle

Dados e comandos do Usurio Configurar Sistema Interagir com o Usurio Pra/ Inicia Solicitao de Configurao Ativar/ Desativar Sistema Mensagem Ativada/Desativada Senha vlida Dados de Configurao Exibir Mensagens e Status Dados de Configurao Informao de configurao

Subsistema de Interao com o Usurio

Dados de Configurao

Senha

Display de Controle do Painel

Processar Senha

Informaes para o Display

Alarme Informaes do sensor Status do sensor Sensores Monitorar Sensores Tipo de alarme Tons de Nmero Telefnico Linha Telefnica

Figura 6 - DFD de nvel 1 para o SafeHome Na figura 7 detalhado especificamente o processo de monitorar sensores.

Formatar para o Display

Informaes do Sensor

Informaes de Configurao Dados de Configurao

Tipo de Identificao e Localizao do sensor Gerar Sinal de Alarme Dados de Alarme Tipo de Alarme

Tipo de Identificao do sensor Ler Sensores Status de Sensor

Avaliar contra o Planejamento

Nmero Telefnico

Discar Nmero Telefnico

Tons de Nmeros Telefnicos

Figura 7 - DFD de Nvel 2 que refina o Processo Monitorar Sensores


Finalmente na figura 8 mostrado um diagrama de nvel 3, mais detalhando do mesmo processo
Informaes do Sensor

Status do sensor Ler Sensores Parmetro de ID do sensor Adquirir Inf. de Resposta

Inf. de configurao
Dados de configurao Formatar Display Tipo de ID e Localizao Formatados Adquirir Condies de Alarme Dados do alarme Selecionar Nro Telefnico Nmero Telefnico Configurar Ligao c/ a Rede Telefnica

Tipo de ID e Localizao Formatados

Informaes sobre codificao do alarme, ID do sensor e timing

Gerar Impulsos p/ a Linha Tipo de Alarme

Lista de Nmeros

Tons de Nro Telefnico Gerar Sinal de Alarme

Figura 8 DFD de Nvel 3 que refina mais o Processo Monitorar Sensores 10

2.1.2 Descrio dos Processos


Aps a preparao dos DFDs, h necessidade de se definir cada processo criado. Aqui apresentado a Tcnica de Descrio de Processos em Portugus Estruturado que a forma mais popular de descrio das funes do sistema. O portugus estruturado uma descrio um pouco mais prxima das linguagens de programao, mas totalmente independente da linguagem que ser utilizada no sistema. Sua sintaxe um pouco mais aberta, e uma linguagem em que a inteno ainda no ser executada no sistema, mas sim apenas descrever como o cdigo que ainda ser elaborado deve se comportar. Suas principais caractersticas incluem: portugus - vocabulrio reduzido sintaxe simplificada identao So empregadas as mesmas construes da programao estruturada: Sequncia Deciso Iterao Cada construo sera detalhada e exemplificada: A) Sequncia: construo onde uma tarefa seguida por outra, incondicionalmente. Exemplo: Subtrair o valor (R$) retirado do valor total Gravar detalhes da transao no arquivo de totais Liberar o dinheiro B) Seleo: Aplica-se quando a realizao de uma tarefa (parte da funo) est condicionada a uma outra tarefa/situao. Exemplos: Se a conta tem saldo suficiente processar a retirada do R$ Seno informar que o saldo insuficiente Se a conta do cliente tem saldo suficiente processar a retirada do R$ Seno se a conta pode ultrapassar o limite checar se o limite permitido suficiente gravar detalhes da retirada
11

liberar o R$ Seno informar que o saldo insuficiente

C) Iterao: Aplica-se quando uma tarefa (parte da funo realizada repetidamente. Exemplo: Para cada cliente Para cada moeda Se a moeda vlida Somar valor da moeda a valor total inserido Atualizar display Se total inserido suficiente p/ a bebida selecionada Liberar o copo Dispensar a bebida Seno rejeitar a moeda Fim Fim O nvel de formalismo do Portugus Estruturado pode variar, de acordo com: A fase de desenvolvimento do software O interesse da empresa/equipe

Pouco formalismo a principal deficincia da tcnica.

2.1.3 Dicionrio de Dados


No Dicionrio de Dados so definidos e detalhados todos os componentes dos Diagramas de Fluxo de Dados: Entidades Externas Processos Depsitos de Dados Fluxos de Dados Estruturas de Dados Elementos de Dados

Para tanto so empregados Formulrios apropriados. Como Exemplo de Dicionrio de Dados mostraremos os formulrios corresponentes para a parte do sistema representada no DFD na figura 9
12

D1 E1 CLIENTES F2 F4 F5

P1
F1 Receber Pedidos F1 - Pedidos Recebidos F2 - Pedidos Invlidos F3 - Inf. de Pagamento F3 F4 - Detalhes de Pedidos F5 - Detalhes de Remessa de Pedidos
Figura 9

ENTIDADE EXTERNA
Entidade Externa: E1 - Cliente Descrio: Clientes que encaminham pedidos de compra Fluxos de Dados de Entrada: F2 - Pedidos Invlidos Fluxos de Dados de Sada: F1 - Pedidos Quantidade: 500 clientes Tipos/Classes: Clientes so classificados em 3 categorias, de acordo com informaes cadastrais, volume e frequncia de compra e histrico de pagamentos anteriores Observaes:
13

PROCESSO
Processo: P1 - Receber Pedidos Descrio: Verificao dos pedidos recebidos, identificando os que no podem ser atendidos Entradas Descrio Sadas F2 - Pedidos no Atendidos F3 - Informaes de pagamento

Obter itens do pedido F1 - Pedidos Para cada item Se no houver estoque Enviar aviso de no atendimento de pedido p/ o cliente Seno prosseguir no atendimento do pedido

Observaes: A especificao funcional completa do processo est na Sesso 7.2 do Documento de Requisitos

DEPSITO DE DADOS
Depsito de Dados: D1 - Pedidos Recebidos Descrio: Todos os pedidos recebidos na semana Entradas F4 - Detalhes dos Pedidos
Contedo Pedido Identificao-pedido Detalhes-clientes Detalhes-produtos

Sadas F5 - Detalhes de Remessa dos Pedidos

Observaes: Descrio dos contedos do depsito de Dados esto no Anexo 1


14

FLUXO DE DADOS
Fluxo de Dados: F2 - Pedidos que no podem ser atendidos
Origem: P1 - Verificar Pedidos Destino: E1 - Clientes Descrio: Detalhes de cada item de cada pedido que no pode ser atendido, ou porque no h estoque disponvel no momento ou porque o item deixou de ser comercializado Estruturas de Dados Includas Pedido Identificao do pedido Detalhes do cliente Detalhes do item Causa do no atendimento Volume de Informao Item com estoque no disponvel: 20/semana Item no maiscomercializado: 5/semana No h previso de crescimento

Observaes:Em um pedido, apenas parte dos itens solicitados podem aparecer no Fluxo de Dados F2.

ESTRUTURA DE DADOS
Estrutura de Dados: Pedido Descrio: Estrutura de dados representando um pedido de compra de um cliente, contendo um ou mais itens Identificao do Pedido Data do pedido [Nro do pedido do cliente] Detalhes do Cliente Nome, Endereo Carto de Crdito Detalhes do Pedido Item/qtde/valor Fluxos de Dados Relacionados F1 - F2 - ........... Informao de Volume Atual: 100/dia Previsto (prx. Semestre): 150/dia

Observaes: Informaes dos Clientes constam das Fichas de Cadastro

15

ELEMENTO DE DADOS
Elemento de Dados: Cdigo do Estado Brasileiro Descrio: Cdigo composto de 2 letras, 1 para cada est. Tipo: (A AN N) - Alfabtico SE Discreto Valor Significado AM Amazonas SP So Paulo PA Paran Total 25 SE Contnuo Limite de Variao dos Valores Valores Tpicos Significado dos valores Tamanho - 2 caract.

Estruturas de Dados Relacionadas: End. do Cliente, End. do Fornecedor Observaoes: (outras informaes)

2.2 Processo de Utilizao do Mtodo


O processo de anlise segue os seguintes passos: 1. Anlise Detalhada do Problema 2. Preparao do DFD Geral (Diagrama de Contexto) 3. Preparao dos DFDs Detalhados (nveis 1 e 2) 4. Descrio da Lgica dos Processo 5. Preparao do Dicionrio de Dados Como exemplo de Aplicao do Mtodo "Anlise Estruturada" usaremos um Sistema de Atendimento de Pedido.

16

DADOS DOS SOFTWARES

detalhes dos softwares

pedido CLIENTE nota fiscal situao de crdito processar pedido

DADOS DOS CLIENTES

Diagrama de Fluxo de Dados - Nvel 1

17

DADOS DOS SOFTWARES

FORNECEDORES DE SOFTWARE

detalhes dos softwares detalhes dos softwares a serem providenciados verificar se o pedido vlido endereo, telefone

pedido CLIENTE

situao de crdito

solicitar produtos ao fornecedor

DADOS DO CLIENTE

PEDIDOS PENDENTES nota fiscal preparar pedidos detalhes dos softwares disponveis

Diagrama de Fluxo de Dados - Nvel 2

18

DADOS DOS SOFTWARES

FORNECEDORES DE SOFTWARE

detalhes dos softwares detalhes dos softwares a serem providenciados verificar se o pedido vlido endereo, telefone

pedido CLIENTE

situao de crdito

solicitar produtos ao fornecedor

DADOS DO CLIENTE

PEDIDOS PENDENTES

nota fiscal preparar pedidos detalhes dos softwares disponveis

Diagrama de Fluxo de Dados - Nvel 3 A partir destes diagramas, fica facilitado a elaborao da descrio do sistema e dos dicionrios de dados,

que descrevem os elementos contidos no DFD.

19

3 Linguagem C
A partir desta seo, apresentaremos a linguagem C, muito importante para o desenvolvimento de sistemas, sendo uma das linguagens mais usadas e base para muitas das linguagens modernas.

3.1 Introduo e Histrico


A linguagem C surgiu no incio dos anos 70 para o desenvolvimento do UNIX. O seu criador Dennis Richie, que na poca trabalhava na ATT & Bell Labs. O mesmo laboratrio tinha criado uma outra linguagem chamada "B", e a linguagem C herdou algumas de suas caractersticas. Tendo sido criada para escrever sistemas operacionais uma linguagem bastante poderosa, com recursos para manipulao do sistema em baixo nvel. Obviamente com esse poder possvel escrever qualquer tipo de aplicativo com C, mas ela e a sua sucessora, C++ so usadas para desenvolvimento de sistemas operacionais, software bsico como sistemas de bancos de dados, compiladores e ambientes de desenvolvimento.

3.2 C ou C++
Nesta apostila, trabalharemos especificamente com a linguagem C. Os compiladores disponveis atualmente em geral so de C++ ou de C e C++. Os programas na linguagem C permitem algumas construes invlidas na linguagem C++, mas em geral os programas funcionam da mesma forma. Nos ambientes de desenvolvimento utilizados, procure sempre dar extenso .C para seus cdigos fonte, e no .CPP que usado para os programas em C++. C++ uma linguagem derivada da linguagem C que possui caractersticas de orientao a objetos, mas seus comandos bsicos so os da C, portanto um passo no aprendizado usar a linguagem C. Sempre que possvel usaremos o padro ANSI C. ANSI uma entidade padronizadora dos Estados Unidos (como a ABNT no Brasil). Usando o ANSI C, podemos estar seguros que o programa poder ser compilado e executado na maioria dos sistemas operacionais.

Uma sugesto para estudo ao digitar os programas exemplo, realmente digit-los, evitando usar o recurso de copiar e colar. Assim, o estudante ter maior contato com a ferramenta de programao e passar por alguns erros de digitao, o que comum na vida real. Os programas podem conter pequenos erros, mesmo aps a reviso. Comentrios sobre erros ou partes obscuras so sempre bem vindos.

3.3 Identificadores e palavras-chave


Palavras-chave de uma linguagem so aquelas correspodentes a comandos ou a elementos essenciais. Elas no podem ser utilizadas para outra finalidade exceto para aquela que foram definidas. Devemos conhecer as
20

palavras-chave da linguagem para utiliz-las em locais indevidos. As palavras chave da linguagem C so exibidas a seguir: auto double int struct break else long switch case enum register typedef char extern return union const float short unsigned continue for signed void default goto sizeof volatile do if static while Veremos o uso da maioria das palavras durante o curso. Por enquanto importante conhecer as palavras reservadas para no definir elementos com esses nomes. Observe que todas elas so escritas com letras minsculas. A linguagem C diferencia maisculas e minsculas. Assim, por exemplo, "Auto" no uma palavra reservada, bem como "AUTO", "aUtO" ou "altO". Identificadores so palavras que do nomes a elementos definidos pelo programador. Como j explicado anteriormente, identificadores no podem ser palavras-chave, tambm conhecidas como reservadas. Elas possuem a seguinte regra de formao: Podem conter letras (a-z, A-Z sem acentos), dgitos (0-9) ou o caractere sublinhado ("_"). Devem comear com letras ou com o sublinhado, nunca por um dgito. Dependendo do compilador usado, so diferenciados entre si pelos primeiros trinta e dois (32) caracteres. Existem convenes para criao de identificadores. Falaremos sobre elas medida que formos definindo elementos. Mas essas so apenas convenes, definidas para facilitar a leitura dos programas.

3.4 Tipos de Dados Bsicos


Um tipo de dado classifica um dado a ser usado pelo programa. Os dados podem ser do tipo inteiro, correspondente a um nmero inteiro, tipo real, correspondente a um nmero real, caractere, correspondente a uma letra ou smbolo no caso do computador. Podemos ainda ter tipos texto, para armazenar seqncias de caracteres e tipos booleanos, que possuem valor verdadeiro ou falso. Na linguagem C existem os seguintes tipos bsicos: int - nmeros inteiros char - caracteres float - nmeros reais, preciso simples double - nmeros reais, preciso dupla
21

void - indica ausncia de tipo, no usado propriamente como um tipo.

Na linguagem C no existe um tipo booleano nativo. Quanto ao uso de memria isso depende da plataforma em que se est fazendo o desenvolvimento, pois a linguagem C altamente aderente ao sistema operacional usado. Podemos usar as seguintes convenes: int - 2 palavras do computador char - 1 palavra do computador float - 4 palavras do computador double - 8 palavras do computador.

Sendo assim, se o computador em questo for de 32 bits, o tipo int usar 2 vezes 32 = 64 bits. Existe um operador especfico para descobrir o tamanho dos tipos de dados, o sizeof. Ele um operador til para operaes de memria, veremos seu uso adiante.

3.5 Modificadores de Tipos de Dados


Podemos modificar os tipos bsicos atravs dos modificadores. So eles: short - indica um tipo pequeno long - indica tipo aumentado signed - indica tipo com sinal unsigned - indica tipo sem sinal Esses modificadores podem ser aplicados em alguns tipos. Na tabela a seguir, mostramos os tipos disponveis no padro ANSI:

unsigned char signed char unsigned int signed int short int unsigned short int signed short int long int signed long int unsigned long int long double O int pode ser omitido, sendo considerado como padro na ausncia de tipo modificado. No tipo int, as
22

declaraes short e signed so redundantes, uma vez que representam os padres do tipo. O tipo long double est presente em algumas implementaes de compiladores. Um dos usos mais relevantes do modificador de sinal no tipo char, uma vez que em alguns compiladores o seu padro sem sinal.

3.6 Variveis
Uma varivel uma regio de memria associada a um tipo e a um nome, que um identificador vlido. Uma varivel pode armazenar um valor e ser modificada, sendo esse o motivo de seu nome. Na linguagem C obrigatria a declarao de nome e tipo antes do uso de qualquer varivel. A declarao de uma varivel deve ser feita no incio de um bloco. Um bloco um trecho de cdigo entre os marcadores de blocos abre chaves e feha chaves ("{" e "}"). O formato da declarao :

tipo lista_de_variveis

onde a lista_de_variveis uma lista de indentificadores separados por vrgulas.

Exemplos:

int i, j, k; signed char ch; double altura, peso;

3.7 Constantes
Constantes so valores fixos que representam dados de um determinado tipo.

3.7.1 inteiros
int: 1 0 22000 -100 -214 long (terminados com a letra 'L'): 40000L -23L unsigned int (terminados com a letra 'U') : 1000U 50000 float (terminado com 'F'): 3.14F 6.02E23F double: 2.78 .123 9.67 -2.222
23

Nos nmeros reais, de ponto flutuante (float e double), quando temos um nmero entre -1 e 1 podemos omitir o zero. Por exemplo, .5 representa meio. (0.5 tambm pode ser usado sem problemas)

3.7.2 Notao Exponencial


Os nmeros reais aceitam uma notao especial, adequada para exibio de constantes muito grandes, a notao exponencial. A notao formada por duas partes, mostradas com um exemplo:

1E100

O nmero antes da letra 'E' (pode ser maiscula ou minscula) multiplicado por 10 elavado ao nmero depois da letra 'E'. No exemplo, temos 1 vezes 10 elevado a 100 (esse nmero conhecido como googol, inspirador do nome da famosa empresa de buscas). O expoente pode ser negativo:

1E-10 = 0.0000000001

3.7.3 Contantes octais


Os nmeros inteiros no padro so impressos e colocados na base numrica 10. A linguagem C aceita outras duas bases, sendo uma delas a octal. Um nmero est na base octal se ele for iniciado com zero. Portanto, em C, os zeros esquerda em uma constante so importantes.

Exemplos:

0111 igual ao nmero 73 0173 igual a 123 0999 um nmero invlido, pois na base octal os dgitos vo de 0 a 7.

3.7.4 Constantes hexadecimais


A outra base disponvel a base hexadecimal. Os nmeros em hexadecimal so iniciados com o prefixo 0x ou 0X (zero, depois uma letra 'X').

Para representar os dgitos maiores que 9, usamos as letras:


24

A - 10 B - 11 C - 12 D - 13 E - 14 F - 15

Ento:
0XCAFE 51966 0x11 17

Dica: a calculadora do Windows no modo cientfico converte nmeros em base 2, 8, 10 e 16. Essas bases foram escolhidas pois 8 so 3 bits e 16 so 4 bits.

3.7.5 Constantes caractere


As constantes caractere so colocadas entre apstrofos ('). Exemplos:
'a' '@'

importante diferenciar '1' de 1. Um representa o smbolo grfico, enquanto que o segundo representa o prprio nmero.

3.7.6 Strings (cadeias de caracteres)


As cadeias de caracteres representam texto. Elas so delimitadas pelas aspas ("). Exemplos: "Sistemas" "computador" "" "ABC"

Tambm devemos ressaltar que: 'A' bem diferente de "A" Uma apenas uma letra, enquanto a segunda uma palavra com uma letra. Esses valores no podem ser
25

confundidos. Alguns caracteres que no podem ser impressos so representados pelo cdigo de barra invertida. Para imprimir caracteres de aspas e apstrofo tambm usamos essa notao. A seguir, os caracteres de barra invertida:
\b retrocesso (backspace) \f alimentao de formulrio (form feed) \n nova linha \r retorno do carro \t tabulao (TAB) \" aspas \' apstrofo \0 caractere nulo \\ uma barra \v tabulao vertical \a beep \N constante octal (onde N um nmero na base 8) \xN constante hexadecimal (onde xN constante hexadecimal)

3.8 Operadores e Precedncia


A linguagem C possui muitos operadores, com vrios nveis de precedncia. A precedncia a ordem em que as operaes devem ser executadas em uma expresso. Por exemplo, em uma expresso envolvendo soma e multiplicao, a multiplicao tem precedncia maior, ou seja, deve ser executada primeiro. uma linguagem famosa por esse motivo. Alm dos operadores aritmticos bsicos, ele possui operadores lgicos, de bit e de atribuio. O uso de parnteses permitido para estabelecer uma ordem desejada de precedncia ou para deixar isso claro. 3.8.1

Comandos de Atribuio

O operador de atribuio simples o sinal '='. O lado esquerdo da atribuio deve ser uma varivel com valor modificvel. Nos exemplos, supomos que j existem variveis declaradas como na seo de exemplos de declarao de variveis:
i = 10; ch = 'A'; peso = 70.5;

A atribuio, alm de modificar o valor da varivel, tambm tem como resultado o valor atribudo. A
26

atribuio um operador com precedncia direita, o que permite construir o seguinte comando:
i = j = k = 0;

Aps esse comando, todas as variveis recebero o valor zero. Essa seqncia pode ser lida como:
i=(j=(k=0));

comum se referir a este comportamento a recursividade esquerda. 3.8.2

Operadores aritmticos

Os operadores bsicos esto presentes na linguagem C: + soma - subtrao * multiplicao / diviso

Alm desses, temos um operador para divises inteiras: % resto da diviso

Quando os operandos da diviso so nmeros inteiros, a diviso executada inteira:

4/3 resulta em 1 1/2 resulta em 0 1.0/2 resulta em 0.5, pois 1.0 um nmero do tipo double, no inteiro. 15/4 resulta em 3

O operador % fornece o resto da diviso:

4%3 resulta em 1 1%2 resulta em 1 15%4 resulta em 3

Os operadores / e % so de tal forma que:

(a/b) * b + (a%b) resulta em a


27

exemplo

(4/3)*3 + (4%3) resulta em 1*3 + 1 que igual a 4

A precedncia dos operadores *, / e % maior que a de + e -. Quando temos expresses com operadores de mesma precedncia, a ordem de execuo da esquerda para a direita (precedncia esquerda). Sendo assim, por exemplo:

2/2*3 resulta em 3. A diviso feita primeiro. Se quisermos que a multiplicao seja executada primeiro, necessrio usar parnteses:

2/(2*3) resulta em 0 (a diviso inteira, lembre-se). No caso da soma e subtrao, vale o mesmo princpio, mas os resultados no mudam. 3.8.3

Incremento e decremento

Em C so muito usados os operadores ++ e --, que aumentam ou diminuem respectivamente em 1 o valor de uma varivel. Esses operadores so chamados unrios, e podem ser prefixos ou posfixos. Quando prefixos, o incremento calculado antes da avaliao da expresso. Por exemplo:

x = 0; y = ++x;

Nesse caso, como o operador ++ prefixo, ele aplicado antes da atribuio. y recebe o valor 1, portanto.

Agora,

x=10; y=x--;

y receber o valor 10, pois o operador posfixo. O uso desse tipo de recurso deixa bastante obscura a avaliao da expresso, por esse motivo no recomendado usar os operadores de incremento e decremento dentro de expresses.

28

3.8.4 Lgica da Linguagem C


A linguagem C no possui tipo booleano. Em seu lugar, a linguagem possui a seguinte conveno: todo valor igual a zero considerado falso, enquanto qualquer valor diferente de zero considerado verdadeiro. Os operadores lgicos seguem essa definio, retornando zero ou valor diferente de zero. Os operadores lgicos so os de comparao: < menor que > maior que <= menor ou igual >= maior ou igual != diferente == igual a (dois smbolos de igual, um s representa a atribuio)

Temos ainda os conectores lgicos: && E lgico (and) || OU lgico (or) ! negao (not)

Esses operadores obedecem as regras das tabelas verdade a seguir: (V denota valor verdadeiro, ou seja, diferente de zero e falso igual a zero, conforme notao da linguagem C).
tabela verdade do && (and) x V V F F tabela verdade do || (or) x V V F F tabela verdade do ! (not) x V F !x F V y V F V F X || y V V V F y V F V F X && y V F F F

29

Os conectores lgicos tem precedncia menor que os comparadores. Exemplos de expresses:

salario > 400 salario >= 1000 && salario <= 2000 (note que no possvel fazer expresses como salario >= 1000 && <= 2000) nota < 0 || nota > 10

Podemos usar os parnteses caso haja alguma dvida na precedncia:

ano % 4 == 0 && (ano % 100 != 0 || ano % 400 == 0)

3.8.5

Operadores avanados - operadores de bit

Por ser uma linguagem voltada para sistemas operacionais, C possui diversos recursos para manipulao de bits, recurso muito til na programao de sistemas bsicos. Os operadores de bit da linguagem C so: ~ complemento & AND bit a bit | OR bit a bit ^ XOR (ou exclusivo) bit a bit << deslocamento esqueda >> deslocamento direita 3.8.5.1 Complemento Este operador inverte os bits de um nmero. Supondo que a varivel em questo use 16 bits, suponha que ela esteja com o valor igual a 171. Esse nmero em binrio :

10101011

Ento se

x = 171; y = ~x;
30

y receber o valor de x com todos os bits invertidos, ou seja 01010100 correspondente a 84:

171 -> 10101011 84 -> 01010100

3.8.5.2 Operador & Esse operador compara os bits de dois valores inteiros e aplica o AND em cada um dos bits. O and segue a tabela:
X 1 1 0 0 y 1 0 1 0 x&y 1 0 0 0

suposto novamente que o nmero possui no mximo 16 bits. Suponha ento (x e y so inteiros): x = 154; y = 127; z = x & y; Como 154 em binrio corresponde a 10011010 e 127 a 1111111, 10011010 01111111 --------- aplicando o & 00011010 que igual a 26. Portanto a varivel z recebe o valor 26. 3.8.5.3 Operador | Esse operador compara os bits de dois valores inteiros e aplica o OR em cada um dos bits. O and segue a tabela:
X 1 1 0 0 y 1 0 1 0 x|y 1 1 1 0

vamos supor novamente que o nmero possui no mximo 16 bits. suponha ento (x e y so inteiros):
31

x = 154; y = 126; z = x | y; como 154 em binrio corresponde a 10011010 e 126 a 1111110, 10011010 01111110 --------- aplicando o | 11111110 que igual a 254. Portanto a varivel z recebe o valor 254. 3.8.5.4 Operador ^ Esse operador compara os bits de dois valores inteiros e aplica o OR exclusivo em cada um dos bits. O and segue a tabela:
x 1 1 0 0 y 1 0 1 0 x^y 0 1 1 0

Nos exemplos suposto novamente que o nmero possui no mximo 16 bits.

suponha ento (x e y so inteiros):

x = 154; y = 126; z = x ^ y;

Como 154 em binrio corresponde a 10011010 e 126 a 1111110,

10011010 01111110 --------- aplicando o ^ 11100100 que igual a 228. Portanto a varivel z recebe o valor 228.

3.8.5.5 Operadores de deslocamento Os operadores de deslocamento movem os bits de um valor para a direita ou esquerda.
32

Suponha o techo de cdigo:

x = 19; y = x << 3;

O nmero 19 em binrio 10011. No deslocamento esquerda, so colocados zeros direita do valor 10011 100110 - um deslocamento 1001100 - dois deslocamentos 10011000 - trs deslocamentos

10011000 igual a 152 na base 10.

No deslocamento direita, os bits mais direita so descartados:

x = 19; y = x >> 2;

10011 1001 - um deslocamento 100 - dois deslocamentos

100 corresponde ao valor 4.

O deslocamento esquerda uma forma de se multiplicar o nmero por uma potncia de 2. Note que 19 * 8 = 152. E 8 corresponde a 2 elevado a 3, que o nmero de bits deslocados. Analogamente, o deslocamento a direita corresponde a uma diviso por potncias de 2. No exemplo, 19/4 igual a 4. Essas operaes so mais rpidas que a multiplicao e diviso tradicionais. Se o desempenho do seu programa for muito crtico, podem ser usadas essas solues para aumentar a velocidade.

3.8.6

Operador ?

O operador ? um operador que define seu resultado a partir do primeiro operando. Por exemplo: 33

x ? 1: 0 Para avaliar esta expresso, x avaliado primeiro. Se o seu valor for verdadeiro (diferente de zero), o resultado ser o valor entre o ? e os dois pontos (:). Caso contrrio o resultado ser o valor aps os dois pontos. Este operador usado no lugar de comandos condicionais, que veremos mais adiante.

3.8.7 Atribuies com operaes


Em qualquer programa, muito comum usar o valor da prpria varivel para calcular seu novo valor. Por exemplo: x = x + 2; y = y / 3; z = z % 10; Para abreviar essas operaes, C oferece as atribuies com operadores: x += 2; y /= 3; z %= 10; Essas trs linhas so exatamente equivalentes aos trs exemplos anteriores. As atribuies disponveis so: += -= *= /= %= &= |= ^= <<= >>=

3.8.8 Operador vrgula Podemos executar vrios comandos em seqncia usando o operador vrgula. O resultado final o resultado da ltima expresso:
34

x = 2+3, 1*3;

x receber o valor 3, resultado da segunda expresso.

3.9 Comandos de entrada e sada


O comando mais conhecido na linguagem C para sada o comando printf. Ele produz uma sada no dispositivo padro de sada, que no nosso caso em geral a tela do computador. Antigamente, o dispositivo padro poderia ser uma impressora. Futuramente poderemos ter outros tipos de telas ou interfaces mais modernas.

No seu formato mais bsico, o comando printf coloca na sada a cadeia de caracteres recebida:

printf( "Sistemas de Informao");

Porm, a cadeia serve na verdade como uma definio de formato. Podemos imprimir valores de variveis a partir do comando printf usando os cdigos de formato:

printf( "este o valor de x: %d", x );

O comando printf analisa a cadeia de formato, procurando por cdigos com o sinal de porcentagem (%). No exemplo, %d indica que ser colocado um valor inteiro na base 10. Ento, o printf espera um valor inteiro depois da cadeia de formato, no caso, x. O valor de x ser impresso no lugar do %d. Podemos colocar quantos valores forem necessrios na impresso:

printf( "%d + %d = %d", a, b, a + b );

Os cdigos de formato so os seguintes: %c caractere %d ou %i inteiro decimal %e notao exponencial usando e %E notao exponencial usando E %f nmero real %g use o menor entre %e ou %f
35

%G use o menor entre %E ou %f %o inteiro na base 8 %x inteiro na base 16 usando letras minsculas %X inteiro na base 16 usando letras maisculas %p ponteiro %% imprime um '%'

O tipo na cadeia de formato deve corresponder ao tipo da varivel ou constante na lista passada. Se houver diferena nos tipos, podem acontecer erros imprevisveis na execuo do programa. O mais comum a impresso de valores inesperados.

O comando de entrada o scanf. O scanf recebe uma cadeia de formato, para informar qual o tipo de dado que ser lido. O usurio do programa deve ento colocar pela entrada padro os dados esperados. Se o usurio digitar valores invlidos, como letras onde so esperados nmeros, o programa pode dar erros tambm imprevisveis. No scanf a cadeia de formato no deve ter outros caracteres alm dos cdigos de formato e espaos.

Os formatos so os mesmos do comando printf, porm se a possibilidade de informar nmero de casas decimais ou formato. Outra coisa importante que o scanf recebe o endereo da varivel que ser modificada. Para passar o endereo, devemos usar o operador prefixo &.

ex:

printf( "digite um nmero inteiro:" ); scanf( "%d", &x );

Se no usarmos o &, o valor da varivel no receber o valor digitado. Podemos ler vrios valores de uma vez:

printf( "digite 3 notas:" ); scanf( "%f %f %f", &nota1, &nota2, &nota3 );

Nesse caso, o usurio pode digitar as notas separadas por espaos ou apertando o "enter".

36

3.10 Programas seqenciais: Estrutura dos programas C


O cdigo fonte um arquivo de texto comum, puro onde escrito o programa na linguagem de programao desejada. Aps escrever o programa, devemos executar o compilador, que l o cdigo fonte e o transforma em um arquivo binrio. Esse arquivo binrio ento ligado (link) com as bibliotecas da linguagem C e outros mdulos do programa, formando um arquivo executvel. Vejamos como um programa simples em C (o popular "al mundo"):
1 2 3 4 5 6 7 #include <stdio.h> #include <stdlib.h> int main() { printf( "Ol" ); system( "PAUSE" ); return 0; }

As linhas 1 e 2 so declaraes de arquivos de incluso. Esses arquivos so "colados" no incio do programa, pois eles possuem declaraes importantes usadas pelos programas. No exemplo, o arquivo stdio.h possui a declarao do cabealho da funo printf, por esse motivo ela colocada. O stdlib.h possui a declarao da funo system. Ao contrrio do que muitos pensam, essas declaraes no so de bibliotecas. So arquivos fonte com declaraes de variveis, constantes, novos tipos de dados e de cabealhos de funes. As bibliotecas so arquivos com extenso .lib que j foram compiladas e so ajuntadas com o programa compilado.

Todo programa em C se inicia nessa funo com nome "main". A declarao indica que main tem como resultado um inteiro, e que ela no est esperando parmetros, pois os parnteses esto vazios.

Na linha 4, impressa na tela uma mensagem. Na linha 5 o comando faz com que o programa pare at que seja apertada alguma tecla. Se no for colocado, no compilador que utilizaremos a janela fechada logo que o programa finalizado, o que nos impede de ver os resultados. Na linha 6, definimos o resultado da execuo do programa. O cdigo 0 indica que o programa foi executado sem problemas. Nos sistemas operacionais baseados no unix (linux, solaris, entre outros), esses resultados so usados pelo sistema operacional. Por enquando, no h grande utilidade para esse valor. 3.10.1 Formatao Note que foram usados alguns deslocamentos e linhas em branco no programa de exemplo. O compilador ignora solenemente todos os espaos e linhas em branco. O programa a seguir equivalente, do ponto de
37

vista do compilador:
#include <stdio.h> #include <stdlib.h> int main() {printf("Ol");system("PAUSE");return 0;}

Note-se que o programa fica muito difcil de se ler. Nos blocos, usaremos dois espaos para deslocar comandos que estejam em um mesmo nvel de execuo. Recomandamos a leitura do site: http://www.ime.usp.br/~pf/algoritmos/aulas/layout.html Que tem uma excelente explicao sobre indentao e layout dos programas. 3.10.2 Comentrios Sempre que escrito cdigo que no seja claro deve-se explicar o que est sendo feito. Isso pode ser feito atravs de comentrios. Na linguagem C os comentrios so demarcados pelo '/*' e '*/'. Todo texto entre esses smbolos completamente ignorado pelo compilador. Comentar o programa til, especialmente para ajudar na manuteno do cdigo. Tambm no se deve fazer comentrios apenas por obrigao, eles devem ser claros e precisos.
1 2 #include <stdio.h> #include <stdlib.h> /* exemplo de comentrio */ /* o compilador no l o que est escrito aqui */ int main() { printf( "Ol" ); system( "PAUSE" ); return 0; }

3 4 5 6 7

3.11 Como desenvolver no ambiente DEV-C++


O DEV-C++ um ambiente integrado para desenvolvimento (Integrated Development Environment em ingls, IDE) gratuito para as linguagens C e C++. Ele pode ser obtido gratuitamente a partir do endereo:

http://www.bloodshed.net/dev/devcpp.html

3.11.1 Instalao
Basta executar o programa de instalao obtido na seo anterior. Sua instalao no difere de um programa comum. Ele possui uma verso em portugus, o que pode ser bastante til para muitos. Mesmo assim, algum conhecimento de ingls ainda necessrio, uma vez que nem todas as mensagens foram traduzidas para o
38

portugus..

3.11.2 Criando um programa Na primeira execuo, aceite todas as configuraes padro. Levar alguns instantes para analisar alguns arquivos, mas essas opes facilitaro a programao.

Para criar um programa, aperte control-N ou arquivo->novo->Arquivo Fonte. Podemos ento digitar um programa simples no editor:

Grave o arquivo. Aperte o disquete da barra de ferramentas, ou d control-s ou ainda Arquivo->salvar

IMPORTANTE: grave o arquivo como um arquivo C, no C++ (C source files). Ele ento ser reconhecido como programa em C, no em C++.

3.11.3 Executando
39

Nesta altura possvel compilar o programa, Executar se estiver compilado ou compilar e executar. Todas essas opes se encontram no menu Executar:

Ao executar o programa, aparece uma janela de comando do Windows, a mensagem impressa e impressa uma mensagem solicitando apertar alguma tecla. Ao ser apertada o programa encerrado.

40

3.11.4 Fazendo cpias do seu programa


Quando gravar o arquivo fonte, observe bem onde ele gravado. Para recuperar um programa em geral basta gravar o fonte, que em geral pequeno. No necessrio fazer cpias de segurana dos arquivos executveis e binrios.

3.12 Programas seqenciais


Vamos dar exemplos de alguns programas com comandos em seqncia.

Programa 1: faa um programa que l um nmero inteiro e imprime o nmero digitado:

Para elaborar o programa devemos seguir alguns passos:


41

1) Levantar as variveis que sero necessrias 2) Fazer a entrada de dados 3) Processar os dados 4) Imprimir a sada

1) Neste caso h a solicitao da digitao de apenas um nmero inteiro. Uma varivel inteira basta, portanto 2) Faremos a leitura desse nmero 3) No h processamento, uma vez que devemos apenas imprimir o nmero 4) Imprimiremos o nmero usando o printf Esta fase corresponde ao detalhamento da descrio do funcionamento do sistema, que foi abordado na primeira parte do curso. O cdigo est comentado com os passos correspondentes.
#include <stdio.h> #include <stdlib.h> int main() { /* passo 1 */ int n; /* passo 2 */ printf( "digite um nmero:" ); scanf( "%d", &n ); /* passo 3, vazio */ /* passo 4, imprime */ printf( "o nmero digitado foi: %d", n ); system("PAUSE" ); }

Programa 2: Faa um programa que l dois nmeros inteiros e imprime sua soma.

1) Vamos usar trs variveis: uma para cada nmero que deve ser lido e um para a soma. 2) fazer a leitura dos dois nmeros 3) calcular a soma 4) imprimir a soma
#include <stdio.h> #include <stdlib.h> int main() { /* passo 1 */ int a, b, soma; /* passo 2 */ printf( "digite dois nmeros:" ); scanf( "%d %d", &a, &b ); /* passo 3, calcula a soma */ soma = a + b; /* passo 4, imprime */ 42

printf( "o a soma : %d", soma ); system("PAUSE" ); }

Em todo o encerramento de comando, h o ponto-e-vrgula. Devemos tomar cuidado em algumas situaes para no colocar ponto-e-vrgulas demais no programa.

Em todos os programas, devemos nos certificar que os valores das variveis foram definidos ou digitados antes de efetuar qualquer operao com essas variveis. Para isso podemos usar a tcnica do teste de mesa, ou simulao.

Mais um exemplo, vamos fazer um conversor de temperatura. Os Estados Unidos adotam um sistema de temperaturas diferente do Brasil, os graus Farenheit. Para converter uma temperatura em graus Farenheit para graus Celsius podemos usar a frmula:

C = (F-32) *5 / 9

Onde F a temperatura em graus Farenheit. Sero necessrias ento variveis para as duas temperaturas.
#include <stdio.h> #include <stdlib.h> int main() { float F, C; printf( "digite a temperatura em graus Farenheit:" ); scanf( "%f", &F ); C = (F-32) * 5 / 9; printf( "%f em graus Celsius %f", F, C ); system("PAUSE" ); }

Uma operao muito comum em programao a troca de valores de variveis. Para tanto, torna-se necessrio o uso de uma varivel auxiliar para armazenamento de um dos valores. Podemos imaginar uma situao real para ilustrar esta situao: suponha que voc tem dois peixes, um em cada aqurio. Dois peixes no cabem no aqurio pois este pequeno e eles so peixes briges. Por algum motivo voc deseja trocar os peixes de aqurio, sem deixar algum peixe fora da gua. Para efetuar essa troca, seria necessrio ento um terceiro aqurio. Passamos um peixe(1) para o aqurio vazio, passamos o peixe(2) para o aqurio que ficou vazio e passamos o peixe(2) para o primeiro aqurio. Vamos mostrar um programa que l dois valores e troca o valor das variveis:
#include <stdio.h> #include <stdlib.h> int main() { 43

int x, y, temp; printf( "digite dois nmeros inteiros:" ); scanf( "%d %d", &x, &y ); printf( "antes da troca: x vale %d e y vale %d\n" , x, y ); temp = x; x = y; y = temp; printf( "depois da troca: x vale %d e y vale %d\n" , x, y ); system("PAUSE" ); }

3.13 Comandos de deciso simples (if)


Quando necessrio selecionar algum comando a ser executado atravs de uma condio, usado o comando if. A sintaxe do comando if a seguinte:

<> representa um trecho obrigatrio, e [] um trecho opcional.

if ( <condio> ) <comando1>; [else <comando2>;]

O funcionamento do if comea com a avaliao da condio, que pode ser qualquer expresso. Se expresso tiver resultado verdadeiro conforme a conveno de C, ou seja, valor diferente de zero, o <comando1> ser executado. Se houver clusula else no comando, que opcional, o <comando2> ser executado caso a expresso seja falsa, ou seja, tenha valor igual a zero.

Vejamos um exemplo de programa usando uma condio simples:


#include <stdio.h> #include <stdlib.h> int main() { int idade; printf( "digite sua idade:"); scanf( "%d", &idade ); if ( idade >= 18 ) printf("voc pode guiar."); system("PAUSE" ); }

Exemplo de sada:

digite sua idade: 20


44

voc pode guiar.

Outra execuo:

digite sua idade: 10

-------------------------------------

Apenas o comando seguinte ao comando if ser executado. Neste comando, e em todos os outros, podemos fazer um grupo de comandos que sero executados em um bloco, delimitado pelas chaves. Para evitar erros, muitos consideram uma boa prtica sempre usar as chaves, mesmo que seja executado somente um comando.

Vamos expandir o exemplo para que seja impressa uma mensagem caso a idade seja insuficiente.
#include <stdio.h> #include <stdlib.h> int main() { int idade; printf( "digite sua idade:"); scanf( "%d", &idade ); if ( idade >= 18 ) { printf("voc pode guiar."); } else { printf("voc no pode guiar."); } system("PAUSE" ); } Um exemplo de execuo desta verso: digite sua idade:10 voc no pode guiar.

3.13.1 Comandos de deciso aninhados (if..else if else if) Podemos escrever condies mais complexas usando uma seqncia de comandos if. Por exemplo, vamos supor que um aluno aprovado se tirar nota maior ou igual a 7. Entre 4 e 7, ele faz um exame, e abaixo de 4 ele ser reprovado.
#include <stdio.h> #include <stdlib.h> int main() { float nota; printf( "digite sua nota:"); scanf( "%f", &nota); 45

if ( nota >= 7 ) { printf("voc foi aprovado."); } else if ( nota >= 4 ) { printf("voc far exame."); } else { printf("voc est reprovado."); } system("PAUSE" ); }

Uma regra importante a lembrar que o else sempre pertence ao if declarado por ltimo. Isso ocorre quando temos uma condio dentro da outra:
#include <stdio.h> #include <stdlib.h> int main() { float nota; printf( "digite sua nota:"); scanf( "%f", &nota); if ( nota >= 7 ) if ( nota == 10 ) printf("parabns "); else if ( nota >= 4 ) { printf("voc far exame."); } else { printf("voc est reprovado."); } system("PAUSE" ); }

Nesse caso, o primeiro else corresponder ao segundo if, o que pode no ter sido a inteno inicial do programador. O uso de chaves resolve o problema, sendo mais um motivo para seu uso em todos os comandos if.
#include <stdio.h> #include <stdlib.h> int main() { float nota; printf( "digite sua nota:"); scanf( "%f", &nota); if ( nota >= 7 ) { if ( nota == 10 ) { printf("parabns "); } }else if ( nota >= 4 ) { printf("voc far exame."); } else { printf("voc est reprovado."); } system("PAUSE" ); }

3.14 Comandos de repetio fixa (for)


46

Uma das maiores utilidades do computador sua capacidade de efetuar tarefas repetitivas. A linguagem C oferece trs tipos de comandos de repetio. O comando for adequado para efetuar um nmero conhecido de repeties, embora isso no seja totalmente obrigatrio. A sintaxe do for a seguinte:

for ( <inicializao>; <condio>; <incremento> ) <comando>

O primeiro comando a ser executado a <inicializao>. Em geral so colocadas instrues que do os valores iniciais para as variveis usadas na repetio. Feito isso, a <condio> avaliada. Se ela for verdadeira (sempre obedecendo a conveno da linguagem C), <comando> executado. Se for falsa, o comando for encerrado, passando-se para a prxima instruo. Quando verdadeira, aps a execuo de <comando>, executada o cdigo em <incremento>. Em geral, valores das variveis so atualizados nessas instrues. Finalmente, a <condio> avaliada, e se ela continuar verdadeira <comando> executado novamente, caso contrrio encerra-se o for.

Vamos exibir um comando for simples, em um programa que imprime os nmeros de 1 a 10:
#include <stdio.h> #include <stdlib.h> int main() { int i; for ( i = 1; i <= 10; i++ ) printf( "%d\n", i ); system("PAUSE"); }

O uso de varives com nomes i, j e k para controle do comando for bastante usual.

Note que somente o comando seguinte ao for faz parte do lao de repetio. Caso haja mais de um comando, formamos um bloco com as chaves. Um erro bastante comum usar ponto-e-vrgula indevidamente:
#include <stdio.h> #include <stdlib.h> int main() { int i; for ( i = 1; i <= 10; i++ ); printf( "%d\n", i ); 47

system("PAUSE"); }

Nesse caso, o compilador considera que queremos repetir o comando vazio dez vezes. Somente no final mostrado o valor 11. Em todos os comandos considerada boa prtica sempre usar as chaves.

A seguir um exemplo de valores decrescentes:


#include <stdio.h> #include <stdlib.h> int main() { int i; for ( i = 10; i >= 1; i-- ) { printf( "%d\n", i ); } system("PAUSE"); }

Note que iniciamos o lao com um valor maior, a comparao foi invertida e o comando de incremento um decremento.

Podemos usar outros incrementos, por exemplo para imprimir somente os nmeros pares menores que 100:
#include <stdio.h> #include <stdlib.h> int main() { int i; for ( i = 0; i < 100; i += 2 ) { printf( "%d\n", i ); } system("PAUSE"); }

Via de regra, o comando de incremento deve modificar as variveis participantes da condio para que em algum momento ela se torne falsa. Se isso no acontecer, o programa pode entrar em lao infinito (loop infinito). No execute o programa a seguir, pois ele entra em loop infinito:
#include <stdio.h> #include <stdlib.h> int main() { int i; for ( i = 0; i < 100; i += 0 ) { printf( "%d\n", i ); } system("PAUSE"); } 48

Isso acontece pois o valor sempre ser 0, nunca sendo modificado, assim a condio sempre ser verdadeira. Devemos tomar extremo cuidado para que os programas no entrem em lao infinito. O operador vrgula pode ser usado caso seja necessrio fazer mais de uma operao nos componentes do for:
#include <stdio.h> #include <stdlib.h> int main() { int i, j; for ( i = 0, j = 0; i + j < 100; i++, j++ ) { printf( "%d\n" ); } system("PAUSE"); }

Tanto na inicializao como no incremento, as duas operaes so executadas.

Vejamos agora uma tcnica de programao, que denominaremos como varivel de acumulao. Suponha que desejamos efetuar a seguinte soma:
1+2+3+...+(n-1)+n

Podemos usar um lao for para efetuar essa operao, usando uma varivel que acumula os resultados. Na primeira iterao a varivel tem valor zero. Na segunda, somamos com 1, na segunda com 2, assim sucessivamente:
0 0+1 (0+1)+2 ((0+1)+2)+3 ...

No final, teremos a soma total dos nmeros. O programa que implementa essa soluo est a seguir:
#include <stdio.h> #include <stdlib.h> int main() { int i, n, soma; printf("digite o valor de n:"); scanf("%d", &n); soma = 0; for ( i = 1; i <= n ; i++ ) { soma += i; } printf("a soma dos nmeros de 1 a %d %d\n", n, soma ); system("PAUSE"); }

49

Na verdade, existe uma frmula simples que calcula essa soma:


soma = (( 1 + n ) / 2) * n;

Assim

nem

seria

necessrio

usar

um

lao.

3.15 Comandos de repetio (while) Um comando de lao mais genrico, onde no se conhece o nmero de iteraes. a sintaxe do comando while
while(<condio>) <comando>;

seguinte:

No incio do while, a <condio> avaliada. Se for verdadeira o comando executado, caso contrrio o while encerrado. Aps cada execuo, a condio avaliada novamente, completando o lao. A seguir exebido um programa que imprime os nmeros de 1 a 10 com o uso do while:
#include <stdio.h> #include <stdlib.h> int main() { int i; int i = 1; while ( i <= 10 ) { printf( "%d\n", i ); i++; } system("PAUSE"); }

Se o comando dentro do while for nico, as chaves so desnecessrias, mas como em todos os outros casos, recomendada.

Um bom exemplo de aplicao do lao while quando a parada depede da entrada do usurio. No programa a seguir, o lao continua at o usurio digitar um nmero negativo:
#include <stdio.h> #include <stdlib.h> int main() { int i; int i = 1; while ( i >= 0 ) { printf( "%d\n", i ); 50

printf( "digite um nmero negativo para encerrar:" ); scanf( "%d", &i ); } system("PAUSE"); }

3.16 Comando de repetio (do..while)


O comando while faz o teste da condio logo no incio do lao. Quando desejado que o lao seja executado
do <comando> while (<condio>);

pelo

menos

uma

vez,

pode

ser

usado

outro

comando,

do/while.

O comando executado uma vez, e a condio avaliada em seguida, desta vez de forma semelhante ao while. Se a condio for verdadeira, repete o comando, seno encerra o lao. O comando while pode se comportar da mesma forma, desde que se tenha certeza que a condio verdadeira antes do incio, sendo assim, o do/while tende a ser menos utilizado.

Uma das utilidades do comando do/while na validao de dados de entrada. No exemplo, exibido um programa que l uma nota vlida, entre zero e dez. Se a nota for invlida, uma nova entrada solicitada:
#include <stdio.h> #include <stdlib.h> int main() { float nota; do { printf( "Digite a nota:" ); scanf( "%f", &nota ); if (nota<0 || nota>10) { printf( "nota invlida, digite novamente:\n" ); } } while (nota<0 || nota>10) printf( "sua nota foi %f\n", nota ); system("PAUSE"); }

Como a entrada vai acontecer pelo menos uma vez, esse um caso bem apropriado para o uso deste comando. Ao fazer programas devemos tomar cuidado para que as entradas sejam sempre vlidas. O comando scanf no muito apropriado para essa tarefa, uma vez que digitando valores de texto onde se esperam nmeros ou vice-versa pode acarretar erros na execuo do programa consequentemente com sua interrupo. Mas podemos usar o do/while para amenizar o problema.
51

3.17 Comandos de controle do lao (break e continue) A linguagem C possui dois comandos para controle de execuo dos laos, o break e o continue. O break encerra o lao em que ele estiver contido, independente de qualquer condio:
#include <stdio.h> #include <stdlib.h> int main() { int i; for ( i = 1; i <= 10; i++ ) { if ( i == 5 ) { break; } printf( "%d\n", i ); } system("PAUSE"); }

Nesse caso, quando i chegar ao valor 5 ser executado o comando break, que encerrar o lao for em que ele est contido. O break usado em muitas situaes em que o lao j executou sua tarefa e no mais necessrio repetir seus comandos. O outro uso do break para encerrar o comando switch, que veremos em seguida.

O continue, por sua vez, fora a prxima execuo do lao, saltando os comandos restantes:
#include <stdio.h> #include <stdlib.h> int main() { int i; for ( i = 1; i <= 10; i++ ) { if ( i == 5 ) { continue; } printf( "%d\n", i ); } system("PAUSE"); }

Nesse exemplo, o comando continue executado quando a varivel i atinge o valor 5. Nesse exemplo, o comando printf saltado, passando para a prxima iterao do lao for, ou seja, no incremento e teste. O efeito no exemplo que somente o nmero 5 no ser impresso na sada padro.

3.18 Comando de deciso mltipla (switch..case)

52

Quando temos uma condio mltipla, podemos usar o comando switch. O comando tem algumas limitaes, pois as opes se limitam a valores inteiros. Vamos ver com um exemplo de programa que escreve os nmeros em forma de palavra:
#include <stdio.h> #include <stdlib.h> int main() { int n; printf( "digite um nmero:" ); scanf( "%d", &n ); switch( n ) { case 1: printf( "um" ); break; case 2: printf( "dois" ); break; case 3: printf( "trs" ); break; case 4: printf( "quatro" ); break; case 5: printf( "cinco" ); break; case 6: printf( "seis" ); break; case 7: printf( "sete" ); break; case 8: printf( "oito" ); break; case 9: printf( "nove" ); break; case 10: printf( "dez" ); break; } system("PAUSE"); }

O comando break logo aps cada opo essencial, pois na sua ausncia ocorre o chamado "fall-through" entre as opes. A partir da opo em que h a igualdade, todos os comandos sero executados at o encerramento do switch ou com o comando break. Ou seja, a opo considada somente para o incio das opes, sendo ignorado no restante.
#include <stdio.h> #include <stdlib.h> int main() { int n; printf( "digite um nmero:" ); scanf( "%d", &n ); switch( n case 1: case 2: case 3: ) { printf( "um" ); printf( "dois" ); printf( "trs" ); 53

case case case case case case case

4: printf( "quatro" ); 5: printf( "cinco" ); 6: printf( "seis" ); 7: printf( "sete" ); 8: printf( "oito" ); 9: printf( "nove" ); 10: printf( "dez" );

} system("PAUSE"); }

No exemplo, se for digitado "1", sero impressos todos os nmeros. Se for digitado "5", sero impressos todos os nmeros a partir de cinco.

Quando nenhuma das opes ocorrer, podemos colocar uma condio para isso, com o default:
int main() { int n; printf( "digite um nmero:" ); scanf( "%d", &n ); switch( n ) { case 1: printf( "um" ); break; case 2: printf( "dois" ); break; case 3: printf( "trs" ); break; case 4: printf( "quatro" ); break; case 5: printf( "cinco" ); break; case 6: printf( "seis" ); break; case 7: printf( "sete" ); break; case 8: printf( "oito" ); break; case 9: printf( "nove" ); break; case 10: printf( "dez" ); break; default: printf( "maior que dez" ); } system("PAUSE"); }

O exemplo a seguir usa o comando switch para dizer quantos dias tem o ms:
int main() { int mes; printf( "digite um ms:" ); scanf( "%d", &mes ); switch( n ) { case 1: case 3: 54

case case case case case

5: 7: 8: 10: 12: printf( "ms de 31 dias" ); break; case 4: case 6: case 9: case 11: printf( "ms de 30 dias" ); break; case 2: printf( "ms de 28 ou 29 dias" ); break; default: printf("ms invlido" ); } system("PAUSE"); }

Convm relembrar que as opes podem ser apenas do tipo inteiro.

3.19 Desvios (goto)

Existe um comando para desvio incondicional, o comando goto. Seu uso era muito freqente nas linguagens de programao mais antigas, e seu usa exagerado gerava programas com lgica extremamente confusa, conhecidas como "cdigo-macarro". Quando a programao estruturada prevaleceu, provou-se que o uso de goto sempre pode ser evitado. Assim, muitos autores e professores probem terminantemente o uso de desvios. Porm, em algumas situaes bastante especficas, o uso do goto pode ajudar a tornar o cdigo mais eficiente, pulando algumas partes de cdigo que no precisam ser executadas. Uma implementao de autmatos finitos (ref livro de compiladores do Setzer) tambm usa goto de maneira organizada. O comando goto desvia para um rtulo, identificador colocado no meio do cdigo que servir de ponto de desvio.
#include <stdio.h> #include <stdlib.h> int main() { float F, C; printf( "digite a temperatura em graus Farenheit:" ); goto final; scanf( "%f", &F ); C = (F-32) * 5 / 9; printf( "%f em graus Celsius %f", F, C ); final: system("PAUSE" ); }

Nesse programa, ao encontrar o goto seu fluxo automaticamente desviado para a instruo imediatamente seguinte ao rtulo, definido pelos dois pontos. Claro que nesse caso poderamos ter simplesmente omitido o
55

cdigo que foi pulado. Em geral, o goto est associado a comandos condicionais.

3.20 Comandos do pr-processador O pr-processador um programa que l o cdigo fonte e executa algumas operaes. Seus comandos so todos precedidos do caractere do jogo da velha (#).

3.20.1 incluso J vimos o comando de incluso ser usado em todos os exemplos. uma prtica de programao C colocar os arquivos de cabealho no topo do cdigo fonte. No usual, mas seria possvel colocar arquivos no meio de um programa.

Suponha que um arquivo tenha o seguinte contedo, e seu nome seja inclusao.c:
printf("vindo do arquivo de incluso");

Se o outro fonte tiver o seguinte comando:


#include <stdio.h> #include <stdlib.h> int main() { #include "inclusao.c" system("PAUSE" ); }

Nesse caso, o arquivo ser colocado no lugar do comando include. Essa prtica no recomendada, e os arquivos de incluso so normalmente colocados para os arquivos de cabealho. H mais uma diferena: Quando os arquivos vem entre os sinais '<' e '>', o arquivo procurado no diretrio padro de arquivos de incluso, configurado no ambiente de programao. Se o nome estiver entre aspas, ele ser procurado juntamente com o cdigo fonte sendo compilado.

3.20.2 Substituio: #define

O define usado para substituir uma cadeia por outra antes da compilao. Por exemplo
#define UM 1 56

Trocar todas as ocorrncias da cadeia "UM" por "1" Esse tipo de definio muito usada para definir constantes, nmeros que aparecem de algum lugar que trocados por uma palavra, ganham mais significado. exemplo
#define TAM_MAX 100

Pode definir o tamanho mximo de um vetor


int v[TAM_MAX];

Podemos usar as definies para definir outras constantes:


#define UM 1 #define DOIS UM+UM #define TRES UM+DOIS

Um exemplo definindo uma constante


#include <stdio.h> #include <stdlib.h> #define P "PAUSE" int main() { printf(P); system(P); }

Podemos usar o define para definir pequenos cdigos que do resultados, chamados funes. O exemplo a seguir calcula o valor absoluto de uma expresso.
#define ABS(a) (a)>0?(a):-(a)

Os parnteses so para que os resultados sejam corretos sejam quais forem os valores de a. Se fizermos
#define ABS(a) a>0?a:-a ABS(10-20) resultaria em 10-20<0?10-20:-10-20

Que no o valor esperado. Esse tipo de definio torna o cdigo bastante rpido, porm pode aumentar o tamanho do programa executvel. Dica: use o #define para declarar constantes na linguagem C.

57

3.21 Strings
Strings so cadeias de caracteres, que podem formar palavras, texto e caracteres especiais do computador. Em C, no temos um tipo "String" nativo como nas outras linguagens, so usados os vetores de caracteres para representar cadeias. Declaramos uma String colocando seu tamanho entre colchetes:
char nome[30];

A linguagem C usa um tipo de String em que o seu tamanho arbitrrio e seu final definido pela primeira apario de um caractere nulo ('\0'). Sempre devemos deixar um espao reservado para o caractere terminador. Sendo assim, a declarao do exemplo comporta uma cadeia com 29 caracteres, mais um para o terminador, totalizando os 30 da declarao.

Uma varivel desse tipo (na verdade um vetor) no pode ter seu valor modificado, ou seja:
nome = "Teste";

um comando que no funciona, pois o valor de nome no pode ser alterado. Mas seu contedo pode ser sim modificado. Para tanto, necessrio usar uma funo predefinida, o strcpy
strcpy( nome, "Teste" );

Faz o servio desejado. Existe uma outra forma de declarar uma varivel que contm uma cadeia:
char *nome1;

Essa varivel um ponteiro de memria, e esta pode ter seu valor alterado. Uma constante String pode ser atribuda varivel:
nome1 = "Teste2";

A desvantagem desse tipo de declarao que no podemos copiar contedos com o strcpy em nome1. Se atriburmos outro valor para a varivel:
nome1 = "Teste3";

A constante anterior ficar "perdida" na memria, ocupando espao que no pode mais ser reutilizado. Tal fenmeno conhecido como vazamento de memria. O vazamento de memria prejuducial ao sistema, pois ocupa memria que pode ser preciosa para a execuo dos programas que no pode mais ser recuperada.
58

Recomenda-se ento, o uso em formato de vetores de caracteres, no como ponteiro para caracteres.

Outra caracterstica das strings em C que no possvel comparar o contedo das strings atravs do comparador ==. necessrio usar a funo strcmp, que descreveremos a seguir.

3.21.1 Funes envolvendo cadeias de caracteres Existem vrias funes prontas para manipulao de Strings, listamos exemplos das mais importantes. Suas declaraes esto no arquivo de cabealho "string.h".

strcpy - copia o contedo de uma String em outra. Devemos nos certificar que o destino possui espao alocado
Ex: #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char nome[50], copia[50]; printf( "digite seu nome:" ); scanf( "%s", nome ); strcpy( copia, nome ); printf ("%s \n %s \n", nome, copia ); system("PAUSE"); }

suficiente

para

comportar

que

ser

copiado.

Note um detalhe. No scanf no usamos o '&' para leitura do nome, no caso de vetores isso no necessrio pois o nome do vetor j corresponde a seu endereo. strlen - esta funo retorna o comprimento da string:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char nome[50]; printf( "digite seu nome:" ); scanf( "%s", nome ); printf ( "%s tem %d caracteres", nome, strlen(nome) ); system("PAUSE"); } 59

strcmp - compara duas strings. Esta funo retorna um valor inteiro, dependendo da comparao lexicogrfica (ordem alfabtica) das strings:

retorna retorna

valor valor

negativo igual a

se zero

s1 se

s1

menor igual

que a

s2 s2

retorna valor positivo se s1 maior que s2


#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *s1 = "AAAAA", *s2 = "ZZZZZ", *s3 = "AAAAA"; printf ( "%s comparado com %s resulta em %d\n", s1, s2, strcmp(s1,s2) ); printf ( "%s comparado com %s resulta em %d\n", s2, s1, strcmp(s2,s1) ); printf ( "%s comparado com %s resulta em %d\n", s1, s3, strcmp(s1,s3) ); system("PAUSE"); }

Sempre bom lembrar que o comparador "==" no compara o contedo de strings, sendo necessrio o uso desta funo.

strcat - esta funo concatena strings:


#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char s1[50], s2[50]; strcpy( s1, "AAAAA" ); strcpy( s1, "ZZZZZ" ); printf ( "%s concatenado com %s resulta em %s\n", s1, s2, strcat(s1,s2) ); system("PAUSE"); }

O resultado armazenado na primeira string, ento para isso necessrio que ela tenha espao alocado suficiente.

gets - l uma string a partir do teclado.


#include <stdio.h> #include <stdlib.h> #include <string.h> 60

int main() { char nome[50]; printf("Digite seu nome:"); gets(nome); printf ( "ol %s\n", nome ); system("PAUSE"); }

puts - imprime uma String na sada padro. Esta funo coloca um caractere de final de linha automaticamente.
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char linha1[100], linha2[100], linha3[100]; printf("Digite a 1a. linha:"); gets(linha1); printf("Digite a 2a. linha:"); gets(linha2); printf("Digite a 3a. linha:"); gets(linha3); puts(linha1); puts(linha2); puts(linha3); system("PAUSE"); }

sprintf - permite a fomatao de uma string com o mesmo formato que usado na funo printf. bastante til na construo de mensagens e na formatao de nmeros.
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char linha[100]; sprintf( linha, "%.2f %s %d", 3.1, "teste", 4 ); puts( linha ); system("PAUSE"); }

3.22 Funes padro teis


getchar - l um caractere da entrada padro. atoi - converte uma string em nmero inteiro atof - converte uma string em nmero real

61

Funes matemticas abs - retorna o valor absoluto do nmero inteiro sqrt - retorna a raiz quadrada de um nmero real positivo. pow - pow( x, y ) retorna x elevado potncia y acos - retorna o arco-cosseno de um nmero asin - retorna o arco-seno de um nmero atan - retorna o arco-tangente de um nmero cos - retorna o cosseno de um arco em radianos sin - retorna o seno de um arco em radianos tan - retorna a tangente de um arco em radianos exp - retorna e elevado ao parmetro fornecido log - retorna o logaritmo do nmero na base e log10 - retorna o logaritmo do nmero na base 10 ceil - retorna o menor inteiro maior ou igual ao real dado floor - retorna o maior inteiro menor ou igual ao real dado

Vamos mostrar a seguir um programa que usa vrias das funes apresentadas:
#include <stdio.h> #include <stdlib.h> #include <math.h> int main() { int x = -1; float a = 4, b = 2, c = 3; printf( "abs(x) = %d\n", abs(x) ); printf( "sin(a) = %.5f\n", sin(a) ); printf( "pow( a, b ) = %.5f\n", pow(a,b)); printf( "sqrt(a) = %.5f\n", sqrt(a)); x = atoi( "123" ); printf( "%d\n", x ); system("PAUSE"); }

62