Vous êtes sur la page 1sur 113

Linguagem C para matemticos: Introduo

CSSIO DE ALCNTARA

UNIVERSIDADE FEDERAL DE UBERLNDIA


FACULDADE DE MATEMTICA

UBERLNDIA - MG
FEVEREIRO - 2015

Linguagem C para matemticos: Introduo

CSSIO DE ALCNTARA

Monograa apresentada por Cssio de Alcntara Faculdade de Matemtica da Universidade Federal de Uberlndia, como parte das
exigncias para concluso do curso de graduao em Matemtica - Licenciatura.

Orientador: Prof. SANTOS ALBERTO ENRIQUEZ REMIGIO, D.Sc.

UBERLNDIA - MG
FEVEREIRO - 2015

todos que me acompanharam nesta jornada.

Agradecimentos

Agradeo primeiramente ao meu pai Ednaldo de Alcntara e minha me Meire Aparecida de Alcntara, pelo apoio e compreenso.
minha namorada Tamara Melo Pereira, pelo companherismo e incentivo.
Ao meu orientador Santos Alberto Enriquez Remigio, pela pacincia, por ter acreditado em mim e disposto de seu tempo para me orientar para a realizao deste trabalho.
Ao professor e amigo Thiago Frana Naves, por ter me auxiliado com os programas.
Ao professor Lcio Borges de Arajo, pelos conselhos.
Ao meu amigo Dane Marques de vila pela ajuda.
A todos os meus colegas da graduao, pelo apoio e amizade.

Resumo

Este trabalho tem como objetivo introduzir aos alunos da graduao do curso de
matemtica a programao com a linguagem C, para isto apresentada uma breve introduo
linguagem, alguns compiladores gratuitos, dos quais utilizado o codeblocks, apresentada
uma explicao de cada tpico estudado, utilizando de analogias matemticas quando conveniente, e resolvido um conjunto de problemas matemticos usando-se esta linguagem para
axao. Tambm apresentada uma breve explicao sobre como resolver numericamente
um problema de valor de contorno (PVC) atravs do mtodo das diferenas nitas (MDF) e
o algoritmo de soluo para sistemas lineares tridiagonais baseado decomposio LU.
Ao nal do trabalho apresentado e resolvido um problema de valor de contorno
linear [1], onde aplicado boa parte do contedo aprendido no decorrer do texto sobre a linguagem C, alm de mostrar a aplicabilidade do MDF para soluo do PVC, que comprovado
ao observar os resultados.

Palavras-chave: linguagem C; codeblocks; problema de valor de contorno; mtodo


das diferenas nitas.

Sumrio
1

INTRODUO

12

1.1

12

OBJETIVO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

LINGUAGEM C

14

2.1

Compiladores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14

2.1.1

15

2.2

Usando o codeblocks . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . .

18

2.2.1

Comentrio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18

2.2.2

Pr-Processamento

. . . . . . . . . . . . . . . . . . . . . . . . . . .

19

2.2.3

Funo Principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

19

2.2.4

Bloco de Dados

. . . . . . . . . . . . . . . . . . . . . . . . . . . . .

20

2.2.5

Funes e Processos . . . . . . . . . . . . . . . . . . . . . . . . . . .

20

2.3

DIRETIVA INCLUDE E AS BIBLIOTECAS . . . . . . . . . . . . . . . . . . .

20

2.4

TRABALHANDO COM VARIVEIS . . . . . . . . . . . . . . . . . . . . . . .

22

2.4.1

O que varivel?

23

2.4.2

Declarao de Variveis

. . . . . . . . . . . . . . . . . . . . . . . . .

23

2.4.3

Tipos de Variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23

2.4.4

Atribuindo valores para as variveis

. . . . . . . . . . . . . . . . . . .

26

. . . . . . . . . . . . . . . . . . . . . .

28

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

28

Controle de Texto . . . . . . . . . . . . . . . . . . . . . . .

30

2.5

PRIMEIRO PROGRAMA EM LINGUAGEM C: ESTRUTURA BSICA

FUNES DE ENTRADA E SADA


2.5.1

Funes de Sada
2.5.1.1

2.6

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

2.5.2

Funes de Entrada

. . . . . . . . . . . . . . . . . . . . . . . . . . .

30

2.5.3

Mscara de dados

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

31

COMANDOS DE SISTEMA MS-DOS . . . . . . . . . . . . . . . . . . . . . .

34

ESTRUTURAS DE CONTROLE DE FLUXO

37

3.1

ESTRUTURA SELETIVA: IF E ELSE . . . . . . . . . . . . . . . . . . . . . .

37

3.1.1

Operadores Lgicos

. . . . . . . . . . . . . . . . . . . . . . . . . . .

38

3.1.2

Else If

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

42

3.2

ESTRUTURA SWITCH

. . . . . . . . . . . . . . . . . . . . . . . . . . . . .

44

3.3

ESTRUTURA DE REPETIO: FOR . . . . . . . . . . . . . . . . . . . . . .

46

3.3.1
3.4

ESTRUTURA DE REPETIO: WHILE


3.4.1

49

. . . . . . . . . . . . . . . . . . . .

58

Do While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

60

FUNES
4.1

63

Porque e Como Usar Funes

. . . . . . . . . . . . . . . . . . . . . . . . . .

63

Funes Sem Argumentos . . . . . . . . . . . . . . . . . . . . . . . .

64

4.1.1.1

Retornar Valores . . . . . . . . . . . . . . . . . . . . . . . .

65

4.1.2

Funes Com Argumentos . . . . . . . . . . . . . . . . . . . . . . . .

67

4.1.3

Prottipos de funes

. . . . . . . . . . . . . . . . . . . . . . . . . .

69

4.1.4

Recursividade

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

70

4.2

VARIVEIS LOCAIS E VARIVEIS GLOBAIS . . . . . . . . . . . . . . . . . .

73

4.3

BIBLIOTECA PADRO MATH.H . . . . . . . . . . . . . . . . . . . . . . . .

74

4.4

STRUCTS

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

83

4.4.1

Acessando os membros de uma estrutura . . . . . . . . . . . . . . . .

83

4.4.2

Typedef

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

86

PONTEIROS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

87

4.5.1

Declarao e Manipulao de Ponteiros . . . . . . . . . . . . . . . . .

87

4.5.2

Aritmtica de ponteiros

89

4.5.3

Alocao dinmica de memria

4.1.1

4.5

4.6

Vetores e Matrizes . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . .

90

4.5.3.1

Funo malloc . . . . . . . . . . . . . . . . . . . . . . . . .

90

4.5.3.2

Funo free

. . . . . . . . . . . . . . . . . . . . . . . . . .

91

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

99

ARQUIVOS
4.6.1

Abrir e fechar um arquivo

4.6.2

Ler e Escrever em arquivos

. . . . . . . . . . . . . . . . . . . . . . . .

99

. . . . . . . . . . . . . . . . . . . . . . . 101

RESOLVENDO UM PROBLEMA DE VALOR DE CONTORNO (PVC)


UTILIZANDO O MTODO DAS DIFERENAS FINITAS (MDF) E A LINGUAGEM C

103

5.1

Problema de Valor de Contorno e o Mtodo das Diferenas Finitas

5.2

Codicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

CONCLUSO

. . . . . . 103

112

Lista de Figuras
2.1.1 Compilador Codeblocks

. . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15

2.1.2 codeblocks: criando um novo arquivo . . . . . . . . . . . . . . . . . . . . . .

16

2.1.3 codeblocks: ambiente de desenvolvimento . . . . . . . . . . . . . . . . . . . .

16

2.1.4 codeblocks: boto compilar e executar

17

5.2.1 Resultados para n = 20

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

10

Lista de Tabelas
2.1

Palavras Reservadas

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

20

2.2

Bibliotecas Padro ANSI da Linguagem C . . . . . . . . . . . . . . . . . . . .

22

2.3

Tipos de dados em Linguagem C

. . . . . . . . . . . . . . . . . . . . . . . .

24

2.4

Operadores mais comuns da linguagem C . . . . . . . . . . . . . . . . . . . .

27

2.5

Controle de Texto

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

2.6

Mscaras de Dados

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

31

2.7

Mscara de dados especiais

. . . . . . . . . . . . . . . . . . . . . . . . . . .

32

2.8

Modicadores de mscara de dados . . . . . . . . . . . . . . . . . . . . . . .

32

2.9

Comandos de Sistema

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

34

3.1

Operadores Lgicos

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

39

4.1

Biblioteca math.h

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

75

4.2

Modos de Acesso a um Arquivo . . . . . . . . . . . . . . . . . . . . . . . . . 100

11

Captulo 1
INTRODUO
Ao longo do curso de graduao em matemtica na Universidade Federal de Uberlndia (UFU) possvel detectar certa diculdade dos alunos nas disciplinas que exigem conhecimento em linguagens de programao, o que leva o aluno a reprovar e, nos piores casos, decidir
abandonar o curso. Estas disciplinas, que so em sua maioria na rea de matemtica aplicada
computacinal, so extremamente importantes e necessrias para a formao do discente e so
muitas vezes prejudicadas, pois os professores acabam reservando um pouco da carga horria
total da disciplina para ensinar um pouco de programao aos alunos, o que no faz parte da
ementa.
Com o objetivo de introduzir os alunos da graduao do curso de matemtica na
programao com a linguagem C, utilizando de uma didtica de fcil entendimento e abordando
apenas alguns tpicos que so de fato teis para uma introduo, a presente monograa
apresenta uma reviso sobre a linguagem C e um conjunto de exemplos resolvidos usando-se
esta linguagem. No nal do trabalho encontra-se uma aplicao de parte da teoria ensinada,
onde resolvido um Problema de Valor de Contorno (PVC) utilizando o Mtodo das Diferenas
Finitas (MDF).
Para a elaborao deste material foi utilizado o sistema operacional Windows, mas o
que apresentado sobre a linguagem C funciona tambm no Linux, que mais utilizado pelos
alunos da graduao de matemtica na UFU.

1.1 OBJETIVO
Este trabalho tem como objetivo abordar alguns tpicos da linguagem C de programao para que um estudante de matemtica comece a criar seus programas, que pode ser usado
num futuro como material didtico para os alunos da graduao do curso de matemtica.
Sendo assim, os objetivos gerais so:

Ensinar alguns tpicos da linguagem C;

12

Mostrar exemplos do uso da linguagem C na soluo de alguns problemas matemticos;

Aplicar parte do que foi aprendido na soluo de um PVC usando o Mtodo das Diferenas Finitas.

13

Captulo 2
LINGUAGEM C
C uma linguagem de programao que foi criada em 1972, por Dennis Ritchie, nos
laboratrios Bell, com o objetivo principal de facilitar a criao de programas extensos com
menos erros. Muitas linguagens de programao foram infuenciadas pela linguagem C, dentre
elas podemos citar C++ e Java [3]. Para programar em linguagem C, alm de entender os
algortmos, o programador precisa de um compilador, que faz a traduo da linguagem de
programao para uma outra (binria) que o computador entenda e o execute.

2.1 Compiladores
Existem vrios compiladores dentre gratuitos e pagos. Para a realizao deste trabalho

foram feitos testes com duas plataformas IDE , o DEV-C++ e o Codeblocks (gura 2.1.1),
e foi optado por trabalhar com este ltimo, por possuir uma interface mais agradvel e ser
de fcil manuseio. Segue uma pequena lista de compiladores gratuitos que um programador
pode utilizar:

DEV-C++ - Plataforma IDE criada pela Bloodshed, tem suporte a projeto e boa
interface com o usurio. muito usado pelos alunos da graduao de matemtica na
UFU. Pode ser baixado no seguinte link: http://www.bloodshed.net/dev/devcpp.html.

GCC - Compilador utilizado pelo projeto GNU2 . padro ANSI C3 e nativo do sistema
4

operacional Linux . No possui interface com o usurio.


1 Programa

de computador que rene caractersticas e ferramentas de apoio ao desenvolvimento de software


com o objetivo de agilizar este processo.
2 Projeto lanado em 27 de setembro de 1983 por Richard Stallman com objetivo de criar um sistema
operacional, chamado GNU, baseado em software livre.
3 Em 1983, o instituto norte-americano de padres (ANSI) formou um comite, X3J11, para estabelecer uma
especicao do padro da linguagem C. Aps um processo longo e rduo, o padro foi completo em 1989
e raticado como ANSI X3.159-1989 "Programming Language C" que frequentemente referido como ANSI
C.
4 Linux um termo utilizado para se referir a sistemas operacionais que utilizem o ncleo Linux, que foi
desenvolvido pelo programador nlands Linus Torvalds, inspirado no sistema Minix. O seu cdigo fonte
est disponvel sob a licena GPL (verso 2) para que qualquer pessoa o possa utilizar, estudar, modicar e
distribuir livremente de acordo com os termos da licena.
14

Codeblocks - Plataforma IDE oriunda de projeto independente e criado com a colaborao de diversos desenvolvedores e programadores ao redor do mundo inteiro com
a inteno de ser uma soluo gratuita e de excelente qualidade.
os sistemas operacionais Windows, Linux e Mac.

Tem verses para

Pode ser baixado no seguinte link:

http://www.codeblocks.org/downloads.

Figura 2.1.1: Compilador Codeblocks

2.1.1

Usando o codeblocks

Para compilar e executar os programas deste trabalho, basta copiar os cdigos e seguir os
passos listados a seguir:
1. Crie um novo arquivo em branco clicando onde est indicado em vermelho na gura
2.1.2;
2. Cole o cdigo que foi copiado deste trabalho na rea indicada em vermelho na gura
2.1.3, que o local onde criamos os nossos algortmos;
3. Clique no boto indicado em vermelho na gura 2.1.4para compilar e executar o programa. O codeblocks vai pedir para salvar o programa antes, basta salvar no cheiro
desejado.

15

Figura 2.1.2: codeblocks: criando um novo arquivo

Figura 2.1.3: codeblocks: ambiente de desenvolvimento

16

Figura 2.1.4: codeblocks: boto compilar e executar

Vamos comear a aprender a programar em C a seguir.

17

2.2 PRIMEIRO PROGRAMA EM LINGUAGEM C: ESTRUTURA BSICA


O cdigo a seguir foi citado na primeira edio do primeiro livro de Ken Thomp-

son e Dennis Ritchie (K&R), intitulado de The C Programming Language [4]. K&R
pretendiam com este programa mostrar ao mundo uma linguagem inovadora, que era mais
produtiva e funcional, capaz de substituir as linguagens da poca (como o Assembly e o B). A
nalidade deste programa mostrar na tela uma mensagem dizendo Este eh o meu primeiro
programa em C e terminar o programa.

// O primeiro programa em C
/* Adaptado do programa original do livro The C Programming
Language de autoria de Ken Thompson e Dennis Ritchie */
# include < stdio .h >
int main ( void )
{
printf ( " Este eh o meu primeiro programa em C . " ) ;
return (0) ;
}
Apesar de no conter nenhuma frmula matemtica, este cdigo um bom ponto de
partida para nosso estudo da linguagem C. Nele possvel observar o bsico da estrutura de
um programa em C: comentrio, pr-processamento, funo principal, bloco de dados
e funes e processos. A seguir estudaremos cada elemento encontrado neste cdigo, assim
como introduzir outros elementos para que nossos programas quem cada vez mais ricos em
linguagem de programao.
A estrutura bsica de um programa na linguagem C, como visto anteriormente,
composta por: comentrio, pr-processamento, funo principal, bloco de dados e

funes e processos. Isto quer dizer, que apenas com estes cinco elementos possvel criar
programas em C. A seguir aprenderemos sobre cada um destes tpicos.

2.2.1

Comentrio
Comentrios so linhas no executadas. Isto quer dizer que o compilador no ir

executar as linhas comentadas de seu programa. Sua funo deixar o cdigo mais legvel e
para fazer anotaes importantes dentro do prprio cdigo, como por exemplo, anotar porque
voc usou uma lgica ao invs de outra, porque voc nomeou aquela varivel de tal forma,
etc.

Sintaxe:

18

// comentrio
ou

/* comentrio */
A diferena entre as duas sitaxes que na primeira o compilador ir entender como
comentrio tudo o que estiver na mesma linha que comeou com barras duplas (//) e na
segunda tudo o que estiver depois de /* e antes de */, podendo estar ou no na mesma linha.
Ento, para comentrios extensos aconselhado utilizar a segunda sintaxe e para comentrios
pequenos ca a critrio do programador.

2.2.2

Pr-Processamento
O pr-processamento, determinado pelo caractere # (sharp), uma das etapas mais

teis da programao em C. Nesta etapa o compilador examina o programa escrito e executa


as modicaes baseado nas diretivas

escolhidas pelo programador. Estas diretivas so co-

mandos que, assim como os comentrios, no so compilados, mas so executados antes do


processo de compilao, modicando o programa fonte.

As diretivas podem ser colocadas

em qualquer parte do programa, desde que no esteja na mesma linha do que outra diretiva
ou instruo, mas de praxe deix-las no incio do programa, pois facililta a organizao do
cdigo.
Existem vrias diretivas, estudaremos duas delas mais adiante, so elas: include e

dene.

Sintaxe:

# pre_processamento
Mais adiante voltaremos neste assunto detalhadamente.

2.2.3

Funo Principal
A funo principal (main) a primeira funo executada por todo programa em

C. Isto quer dizer que os blocos de comandos digitados dentro das limitaes da funo main
sero os primeiros a serem executados.

Existem vrias sintaxes para a funo main, neste

trabalho geralmente ser adotado a seguinte:

Sintaxe:

int main ()
{
bloco_de_dados
}
5 Construo

de algumas linguagens de programao que especica como o compilador ou montador deve


processar o cdigo fonte. Em alguns contextos, as diretivas so conhecidas como pragmas.
19

A expresso bloco_de_dados ser explicada a seguir.


Mais adiante estudaremos melhor o assunto funes, onde recordaremos a funo
principal (main).

2.2.4

Bloco de Dados
Os blocos de dados, determinado pelo abrir e fechar de chaves {}, so utilizados para

determinar todas as linhas de cdigo que devem ser executados de uma vez. Em um programa
pode haver quantos blocos de dados forem necessrios, desde que, para cada chave aberta

haja uma fechada.

Sintaxe:

{
bloco_de_dados
}

2.2.5

Funes e Processos
Dentro dos blocos de dados (isto , dentro das chaves) podemos ter funes, pala-

vras reservadas (ver Tabela 2.1) ou processos (operaes matemticas). Que so, basicamente, o que dene um programa. Sempre que forem utilizados, a linha deve terminar com
ponto e vrgula (;).

Sintaxe:

{
funao ;
}
No nosso primeiro programa foram utilizadas as funes printf e return.

Tabela 2.1: Palavras Reservadas


double
oat
unsigned
struct

auto

const

int

static

break

continue

else

for

void

case

default

enum

if

volatile

switch

long

signed

typedef

register

short

char

do

extern

goto

while

union

return

sizeof

2.3 DIRETIVA INCLUDE E AS BIBLIOTECAS


Como foi dito na seco anterior, uma das diretivas do pr-processamento o include.
Esta nos permite importar bibliotecas, que so conjuntos de funes, classes e variveis,
para nosso programa.

20

A utilizao das bibliotecas facilita o trabalho do programador, pois uma vez que
a funo j est pronta dentro de uma determinada biblioteca, basta import-la e utilizar a
funo desejada.
Por exemplo, digamos que o programador deseja mostrar uma mensagem na tela.
Ao invs de produzir uma funo que faa isso, ele s precisa importar uma biblioteca de

entrada e sada (I/O) e utilizar uma funo dela que execute tal procedimento.

Sintaxe:

# include < biblioteca_desejada .h >


Conforme dito anteriormente, necessrio o prexo # (sharp). Alm disso, o nome
da biblioteca deve ser seguido de ponto H (.h), a exteno do arquivo da biblioteca, e estar
entre os sinais menor (<) e maior (>).

Exemplo 1. Incluindo as bibliotecas stdio.h e stdlib.h.

// Exemplo de # include para as bibliotecas stdio e stdlib


# include < stdio .h >
# include < stdlib .h >
No decorrer deste trabalho aprofundaremos mais nossos estudos em algumas bibliotecas, em especial a biblioteca matemtica (math).
Na Tabela 2.2 teremos uma listagem das principais bibliotecas padro ANSI da linguagem C.

21

Tabela 2.2: Bibliotecas Padro ANSI da Linguagem C

Biblioteca

Descrio

<assert.h>

Implementa ajuda na deteco de erros em


verses de depurao de programas.

<complex.h>
<ctype.h>

Trata da manipulao de nmeros complexos.


Funes para converso de maisculas, minsculas
e outros tratamentos de caracteres.

<errno.h>
<fenv.h>

Teste de cdigos de erro reportados pelas funes de bibliotecas.


Dene vrias funes e macros para tratar de excees em
variveis do tipo ponto utuante.

<oat.h>
<inttypes.h>
<iso646.h>

Dene limites e preciso de variveis de ponto utuante.


Trata de converso precisa entre tipos inteiros.
Adiciona a possibilidade de programao usando
a codicao de caracteresde acordo com a ISO646.

<limits.h>

Constantes de propriedades especcas de implementao


da biblioteca de tipos inteiros.

<locale.h>

Especica constantes de acordo com a localizao especca.

<math.h>

Funes matemticas comuns em computao.

<setjmp.h>

Dene as macros setjmp e longjmp, para sadas no locais


e tratamento de execees.

<signal.h>

Implementa denies para receber e fazer o tratamento de sinais.

<stdarg.h>

Acesso dos argumentos passados para funes com parmetro varivel.

<stdbool.h>

Trata da denio para tipo de dados booleano.

<stdint.h>

Padres de denio de tipos de dados inteiros.

<stddef.h>

Padres de denies de tipos.

<stdio.h>

Tratamento de entrada/sada.

<stdlib.h>

Implementa funes para diversas operaes, incluindo converso,


alocao de memria, etc.

<string.h>
<tgmath.h>
<time.h>
<wchar.h>
<wctype.h>

Tratamento de strings.
Implementa facilidades para utilizao de funes matemticas.
Trata de tipos de data e hora.
Tratamento de caracteres para suportar diversas lnguas.
Contm funes para classicao de caracteres wide,

2.4 TRABALHANDO COM VARIVEIS


O assunto variveis causador de muitos erros quando se trata de programao por
ser fcil de confundir, caso elas no estejam bem estruturadas dentro do cdigo. Antes de
comear a falar sobre o assunto, vale lembrar que C uma linguagem case sensitive [3], o
que quer dizer que, em poucas palavras, distinguido maisculos de minsculos ( exemplo:
letra no igual a Letra, que no igual a LETRA).

22

2.4.1

O que varivel?
Variveis so endereos de mmoria no qual podemos atribuir ou mudar o valor.

Matematicamente falando, equivalente a trabalhar com funes, onde temos domnio e


imagem. Supondo uma funo que no possua domnio, ento no sabemos de onde esto
vindo os valores de entrada para a mesma. Precisamos dizer de onde esto vindo os valores
para podermos trabalhar com eles. O mesmo acontece na linguagem C: precisamos dizer o
domnio de nossas variveis para podermos trabalhar com elas.

Exemplo 2. A funo

y = f (x) =

1
. Falta algo para resolv-la? A resposta sim. Note
2x+1

que no foi informado o domnio da funo (assim como o contra-domnio). Sendo assim, no
sabemos quais valores podemos atribuir para a varivel

para obtermos os resultados.

Em C, o domnio o endereo de memria que vamos ordenar para o compilador


reservar para deteminada varivel. Este processo conhecido como declarao de variveis.

2.4.2

Declarao de Variveis
A declarao da varivel feita da seguinte maneira:

Especicar o tipo de varivel;

Nomear a varivel;
Alguns cuidados devem ser tomados ao se declarar uma varivel, como no duplicar

os nomes, lembrar-se do case sensitive, no comear uma varivel por nmero (mas pode
terminar) e tambm no usar espaos no nome da varivel, pois o compilador pode entender
que outra varivel depois do espao e acusar erro (para esta situao, costumeiro usar

underline (_) no lugar dos espaos).


Exemplo 3. Vejamos:
nome da varivel: 5x;
nome da varivel: resultado da equao.
Os exemplos acima esto errados. O primeiro poderia ser substitudo por x5 ou _5x
e o segundo pode ser substitudo por resultado_da_equao.

2.4.3

Tipos de Variveis
Conforme dito anteriormente, uma das etapas da declarao de variveis especicar

o tipo de varivel, que seria equivalente a especicar o domnio de uma funo. A linguagem
C aceita os tipos mais comuns de variveis alm da possibilidade de modicar o alcance. Na
Tabela 2.3 temos uma noo sobre os tipos de dados. Mas a seguir vamos falar sobre os que
sero mais usados no decorrer do texto.

23

Tabela 2.3: Tipos de dados em Linguagem C

Palavra chave

Signicado

Tamanho

Intervalo de valores

(em bytes)

aceitos

char

caracter

-128 a 127

signed char

caracter com sinal

-128 a 127

unsigned char

caracter sem sinal

0 a 255

int

inteiro

-32.768 a 32.767

signed int

inteiro com sinal

-32.768 a 32.767

unsigned int

inteiro sem sinal

0 a 65.535

short int

inteiro curto

-32.768 a 32 767

signed short int

inteiro curto com sinal

-32.768 a 32 767

unsigned short int

inteiro curto sem sinal

0 a 65.535

long int

inteiro longo

-2.147.483.648 a 2.147.483.647

signed long int

inteiro longo com sinal

-2.147.483.648 a 2.147.483.647

unsigned long int

inteiro longo sem sinal

0 a 4.294.967.295

oat

ponto utuante com

3.4 E-38 a 3.4E+38

1.7 E-308 a 1.7E+308

preciso simples
double

ponto utuante com


preciso dupla

long double

ponto utuante com

16

3.4E-4932 a 1.1E+4932

preciso dupla longo

Observao. O intervalo de valores aceitos da tabela acima pode variar de acordo com a
mquina do usurio.

Inteiro.
Declara-se como: int nomedavarivel
Como o nome sugere, int usado para variveis do tipo inteiro (Exemplo:

uma varivel de

16

bits (2 btyes) e tem o alcance entre

32768

2,58,100,2234).

+32767.

Flutuante.
Declara-se como: oat nomedavarivel
O tipo oat usado para variveis do tipo real ou decimal, tambm conhecido

como ponto utuante. uma varivel que tem uma preciso de


de memria e tem um alcance de

3.4E 36

3.4E + 36.

dgitos, consome

bytes

Uma observao importante que

usamos ponto (.) ao invs de vrgula (,) para escrever um nmero decimal.

Double.
Declara-se como: double nomedavarivel

Double uma melhoria do oat, basicamente o dobro de alcance, o que resulta


em um nmero mais preciso. Consome
a

bytes de memria e tem um alcance de

1.7E + 308.
24

1.7E 308

Caracter.
Declara-se como: char nomedavarivel
O tipo caracter usado para descrever um smbolo, tambm podendo ser um inteiro.

Ento, com o tipo char, podemos atribuir tanto a letra

quanto o nmero

2.

Vale ressal-

tar que os caracteres so baseados na tabela ASCII (que pode ser encontrada no endereo
http://187.7.106.14/marcelo/org_comp/tabelaASCII.pdf ), onde cada letra consome

bytes

de memria.

Void.
O tipo void usado quando queremos que algo retorne o valor nulo (ou vazio).

Vamos voltar a falar melhor sobre o tipo void mais adiante, quando entrarmos no assunto
procedimentos.
Tambm temos os seguintes modicadores de alcance:

Long.
Declara-se como: long tipodavarivel nomedavariavel

Long um modicador de alcance que dobra o nmero de bits que a varivel suporta,
fazendo com que o seu alcance aumente consideravelmente.

Pode ser usado para os tipos

int e double de variveis. Por exemplo o tipo int, que passa de

2147483648

32768

+32767

para

+2147483647.

Short.
Declara-se como: short tipodavarivel nomedavarivel

Short um modicador de alcance que divide por dois (2) o nmero de bits que a
varivel suporta, fazendo com que o seu alcance diminua. Pode ser usado para o tipo int de
varivel, que passa de

32768

+32767

para

32.768

32.767.

Unsigned.
Declara-se como: unsigned tipodavarivel nomedavarivel

Unsigned um modicador que usado quando queremos apenas valores positivos


para nossa varivel.

Com isto, temos um ganho na faixa positiva de valores que podemos

atribuir varivel declarada. Pode ser usado para os tipos int e char. Por exemplo o tipo int,
que passa de

32768

+32767

para

65535.

Signed.
Declara-se como: signed tipodavarivel nomedavarivel

Signed um modicador que usado para denir que a nossa varivel admite valores
positivos e negativos.

Pode ser usado para os tipos int e char.

Por padro, uma varivel

inteira do tipo signed.


Na Tabela 2.3 temos uma descrio detalhada de todas as combinaes possveis de
variveis e modicadores, assim como seus alcances e quantidade de memria.

25

2.4.4

Atribuindo valores para as variveis


Agora que aprendemos a declarar as variveis, aprenderemos a atribuir valores para

as mesmas.
A atribuio de valores s variveis indicada pelo sinal de igual (=). Sendo que a
varivel que vai receber o valor ca esquerda do sinal e o valor (ou resultado) ca direita.

Exemplo 4. Criar um programa que declara trs variveis inteiras e atribui valores para elas:

// Pr - processamento :
# include < stdio .h >
# include < stdlib .h >
// Funo principal :
int main () {
// Bloco de dados :
// Declarando variveis :
int a ;
int b ;
int c ;
// Atribuindo valores para as variveis :
a = 2;
b = 3;
c = a + b;
return 0;
}
Neste exemplo foram declaradas trs variveis (a,b e
atribudo valor
resultado de

para a varivel

a + b,

ento

a, 3

para a varivel

c)

do tipo int. Em seguida, foi

e para a varivel

o valor que o

c = a + b = 2 + 3 = 5.

A atribuio de valores s variveis se d de duas formas:

na inicializao ou

durante um processo.
Quando queremos que alguma varivel comee com um valor j estipulado, estamos
falando de declarao na inicializao.

E quando os valores so atribudos atravs de

clculos, estamos falando de um processo. Na Tabela 2.4 tem um descrio dos operadores
mais comuns.

26

Tabela 2.4: Operadores mais comuns da linguagem C

Operador

Descrio

Atribuio

Soma

Subtrao

Multiplicao

Diviso

Resto da diviso

++

Incremento

- -

Decremento

Vamos ver alguns exemplos:

Exemplo 5. Criar um programa que atribui valores na inicializao.

// Pr - processamento
# include < stdio .h >
# include < stdlib .h >
int main () {
// Atribuindo valores na inicializao :
int a = 45;
long int b = 123456789;
// Funo de sada de dados :
printf ( " % d " ,a ) ;
printf ( " % d " ,b ) ;
return 0;
}
Este cdigo atribui os valores

45

para a varivel

123456789

para

b.

Em seguida,

mostra na tela os valores para o usurio.


Observao. Veremos sobre o %d que foi utilizado na funo printf na seco
estudaremos mscara de dados. Idem para o %f do prximo exemplo.

Exemplo 6. Criar um programa que atribui valores durante um processo.

// Pr - processamento
# include < stdio .h >
# include < stdlib .h >
int main () {
// Declarando variveis :
int x ;
int y ;
float z ;

27

2.5.3,

quando

// Atribuindo valores para as variveis atravs de


processos :
x = 5 * 5 + 3;
y = x + 2;
z = y / 0.25;
// Funo de sada de dados :
printf ( " % d " ,x ) ;
printf ( " % d " ,y ) ;
printf ( " % f " ,z ) ;
return 0;
}
Este cdigo levemente mais complicado do que o primeiro.

A diferena que

primeiramente foi declarado que sero utilizadas duas variveis inteiras (x e

y)

e uma varivel

utuante (z ). Ento, foram criados processos para atribuir valores para estas variveis. Para
a varivel

x foi realizado o seguinte processo: x = 5 5 + 3 (l-se x igual a cinco vezes cinco

mais trs), logo

x = 25 + 3 = 28.

Perceba que foi feita a conta de multiplicao primeiro.

O compilador tem uma ordem de preferncia para realizar os clculos, que , basicamente, a
mesma que utilizamos nos clculos matemticos casuais. Mas, aconselhvel o programador
ter o hbito de usar parnteses para organizar os clculos em seus cdigos. Para a varivel

vai receber o valor que foi

com um acrscimo de duas unidades, ento

y = x + 2 = 28 + 2 = 30.

foi realizado o seguinte processo:


atribudo varivel
Para a varivel

y = x + 2,

isto quer dizer que

z foi realizado o seguinte processo: z = y/0.25, isto quer dizer que z vai receber

o valor que foi atribudo varivel

e dividir por dois, ento

z = y/0.25 = 30/0.25 = 120.

Em seguida so mostrados na tela os valores das variveis.

2.5 FUNES DE ENTRADA E SADA


Em alguns exemplos anteriores foi utilizado o comando printf vrias vezes. Trata-se
de uma funo de sada, assunto que trataremos primeiro nesta seco juntamente com

funes de entrada.

2.5.1

Funes de Sada
Funes de sada permitem, resumidamente, a comunicao entre a mquina e o

usurio (ou interface com o usurio). Por exemplo um programa no qual deseja-se calcular
a rea

de uma circunferncia de raio

R.

Com o que sabemos at agora, ns criaramos

um processo utilizando os operadores da Tabela 2.4 , para atribuir o valor, que ser o nosso
resultado, para uma varivel

A do tipo oat.

E o raio seria uma varivel tambm do tipo oat

com valor xo. O cdigo poderia ser:

28

// Pr - processamento
# include < stdio .h >
# include < stdlib .h >
int main () {
// Declarando variveis :
float A ;
float R = 2;
/* Criando o processo para atribuir o valor para a :
varivel A ( Area = 2* pi * R * R ) : */
A = (3.14) *( R ) *( R ) ;
return 0;
}
Perceba que, diferente dos programas anteriores, no foi utilizado o comando printf.
Ao executar o programa, ele faz os clculos e naliza. exatamente como foi escrito no cdigo.
Da surge a pergunta: Como vou saber o resultado?. Ou melhor: Como vou ver o resultado?. Ento surge a necessidade da utilizao de uma funo de sada, que permitir o
usurio ver o resultado.
As Funes de Sada so encontradas na biblioteca padro de entrada/sada: st-

dio.h. Trabalharemos apenas com a printf em nos programas deste trabalho.


Para utilizar a funo printf simples: basta iniciar uma linha com a funo printf,
especicar o que quer que aparea na tela para o usurio dentre dos parnteses () e colocar a
mensagem dentro de aspas ().

Sintaxe:

printf ( " digite sua mensagem " ) ;


Ainda no sabemos o suciente para mostrarmos o resultado para o usurio em todos
os programas.

Para isto precisamos falar sobre mscara de dados, que trataremos mais

adiante.

Exemplo 7. Criar um programa que faa aparecer a mensagem Ol na tela para o usurio.

# include < stdio .h >


# include < stdlib .h >
int main () {
// Aparecer mensagem Ola ! na tela :
printf ( " Ola ! " ) ;
return 0;
}

29

2.5.1.1

Controle de Texto
Os controles de texto so usados para melhorar a interface com o usurio. Assim

como quando escrevemos ns saltamos linhas, pargrafos, dentre outros para que o texto que
mais legvel e organizado.
Todos os comandos de controle de texto so determinados pela barra invertida (\).
Como podemos ver na Tabela 2.5, cada letra determina uma ao.
Geralmente ns usaremos apenas os comandos de saltar linha e de adicionar ta-

bulao.

Tabela 2.5: Controle de Texto

Comando

Ao

\n

Salta uma linha

\t

Adiciona uma tabulao

\a

Adiciona um bip

\b

Volta um caracter

\r

Volta uma linha

Exerccio 8. Criar um programa que utiliza o comando \n:

# include < stdio .h >


# include < stdlib .h >
int main () {
// Usando o comando de saltar linha \ n depois de cada
printf :
printf ( " A area de um quadrado eh determinada por : \ n " ) ;
printf ( " L ^ 2\ n " ) ;
return 0;
}

2.5.2

Funes de Entrada
Voltemos a falar sobre o programa do clculo da rea de uma circunferncia de raio

R.

Com o programa que zemos, conseguimos calcular a rea de uma circunferncia de raio

2.

Mas, e se quisssemos mudar o valor do raio? Seria necessrio abrir o cdigo e mudar o

valor atribuido para a varivel

R sempre que quisssemos calcular a rea de uma circunferncia

diferente. Para este programa no algo difcil de se fazer, mas em um programa maior e
mais complexo no muito interessante car fazendo tal procedimento.

Para isto usamos

as funes de entrada, que devem ser usadas em conjunto com as funes de sada
do seguinte modo: Voc pede para o usurio digitar uma entrada com uma funo de sada
(printf ), ento uma funo de entrada vai armazenar em alguma varivel o que o usurio
digitou.

30

Assim como as funes de sada, as funes de entrada de C so encontradas na


biblioteca padro de entrada/sada: stdio.h. Trabalharemos apenas com a funo scanf em
nossos programas.
Para utilizar a funo scanf simples: basta indicar o endereo da varivel que vai
receber o valor digitado nela precedido de um e comercial (&) e uma mscara de dados.

Sintaxe:

scanf ( " mascara_de_dados " ,& endereo_da_variavel ) ;


Ateno: Qualquer tecla que se aperte no teclado considerado uma entrada, inclusive as teclas SPACE e ENTER. Isto quer dizer que, se digitarmos um nmero e, em seguida,
apertarmos ENTER, alm de armazenar o nmero, o ENTER tambm car armazenado, o
que poder atrapalhar entradas de dados futuras.
Falaremos sobre mscara de dados antes de ver exemplos de funes de entrada.

2.5.3

Mscara de dados
Para trabalhar com funes de entrada e sada de dados precisamos utilizar

mscaras de dados. Estas so usadas para denir entradas e sadas de dados em C. Basicamente, uma mscara de dados demonstra ao programa que tipo de converso deve ser
adotado para converter os bytes armazenados em uma varivel.
Exemplicando, se pretendemos entrarmos com uma varivel do tipo oat e utilizarmos uma mscara de int, o algortmo vai ler apenas os dois primeiros bytes, pois uma varivel
inteira tem

bytes e uma utuante tem

bytes. Ento o correto utilizar uma mscara de

oat.
Todos os comandos de mscara de dados so determinados pelo simbolo de porcen-

tagem (%). Como podemos ver na Tabela 2.6, onde so listadas as mscaras.

Tabela 2.6: Mscaras de Dados

Mscara

Tipo de dado

%d

int

Descrio
Mostra um nmero inteiro

%c

char

Mostra um caracter

%f

oat

Mostra um nmero decimal

%lf

double

Mostra um nmero decimal com preciso alta

%i

int

%ld

long int

Mostra um nmero inteiro

%e

oat ou double

Mostra um nmero exponencial (nmero cientco)

%E

oat ou double

Mostra um nmero exponencial (nmero cientco)

%o

int

Mostra um nmero inteiro em formato octal

%x

int

Mostra um nmero inteiro em formato hexadecimal

%X

int

Mostra um nmero inteiro em formato hexadecimal

%s

char

Mostra um nmero inteiro longo

Mostra uma cadeia de caracteres (string)

31

Existem algumas consideraes a se fazer sobre mscara de dados.

Por exemplo, se

quisermos que aparea o smbolo de porcentagem (%) na tela. Neste caso a mscara
de dados seria %%. Tambm podemos fazer algumas modicaes, como determinar a
preciso de uma varivel do tipo oat. Todas as consideraes sobre mscara de dados
esto nas Tabelas 2.7 e 2.8.

Tabela 2.7: Mscara de dados especiais

Mscara
%%

Descrio
Mostra o smbolo de porcentagem ( % ) na tela

\"

Mostra o smbolo de aspas (  ) na tela

\'

Mostra o smbolo de aspas simples ( ' ) na tela

Tabela 2.8: Modicadores de mscara de dados

Mscara

Modicao

Descrio

%d

%+d

%f

%."nmero"f

Mostra o sinal de positivo se houver

%o

%#o

Completa o nmero octal com zero

%x

%#x

Mostra indicador de Hexadecimal (0x).

O nmero que vier entre o ponto e o f ser o limite de sua preciso

Vamos fazer alguns cdigos para axar o contedo que aprendemos at agora.

Exemplo 9. Criar um programa que pea para que o usurio digite dois nmeros: um inteiro
e um utuante. Aps isso, mostrar na tela os nmeros digitados.

Soluo: Para este programa precisamos, primeiramente, declarar as variveis. Ento usaremos a funo printf para mostrar uma mensagem para o usurio digitar os dois nmeros, e
a funo scanf para l-las. Finalmente, usaremos novamente a funo printf para mostrar ao
usurio os nmeros digitados. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int a ;
float b ;
/* Utilizando as funes printf e scanf para que o usurio
digite os valores das variveis : */
printf ( " Ola ! Digite um numero inteiro . \ n " ) ;
scanf ( " % d " ,& a ) ;
printf ( " Agora digite um numero flutuante . \ n " ) ;
scanf ( " % f " ,& b ) ;
// Mostrando as variveis digitadas para o usurio :
32

printf ( " O numero inteiro digitado foi % d e o numero


flutuante foi % f " ,a , b ) ;
return 0;
}
Exemplo 10. Criar um programa que pea para que o usurio digite um nmero inteiro.
Ento fazer os seguintes clculos em cima do nmero digitado: incrementar uma unidade;
decrementar uma unidade; somar
por

unidades; subtrair

13

unidades; multiplicar por3; dividir

2.

Soluo: Este programa segue a mesma lgica do anterior. A diferena que sero declaradas
variveis para receber um valor para cada clculo realizado. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
// Declarando variveis :
int a ;
int b ;
int c ;
int d ;
int e ;
int f ;
float g ;
int h ;
printf ( " Ola ! Digite um numero inteiro . \ n " ) ;
scanf ( " % d " ,& a ) ;
// Atribuindo valores para as variveis atravs de
processos :
b = a + 1;
c = a - 1;
d = a + 5;
e = a - 13;
f = a * 3;
g = a / 2;
h = a % 2;
printf ( " O numero digitado foi % d .\ n " ,a ) ;
printf ( " Acrescido de uma unidade : % d .\ n " ,b ) ;
printf ( " Decrescido de uma unidade : % d .\ n " ,c ) ;
printf ( " Somado 5 unidades : % d .\ n " ,d ) ;
printf ( " Subtraido 13 unidades : % d .\ n " ,e ) ;
printf ( " Multiplicado por 3: % d .\ n " ,f ) ;
printf ( " Dividido por 2: % f .\ n " ,g ) .
printf ( " O resto da divisao por 2: % d " ,h ) ;
33

return 0;
}
Ao executar o programa, ir aparecer a mensagem Ola! Digite um numero inteiro..
Digitando

23 =

6, 22

o programa retornar

=1

2%2 = 0,

2, 2 + 1 = 3, 2 1 = 1, 2 + 5 = 7, 2 13 = 11,

respectivamente. Aparecer a mensagem O numero digitado

foi 2. Acrescido de uma unidade: 3. Decrescido de uma unidade: 1. Somado 5 unidades: 7.


Subtraido 13 unidades: -11. Multiplicado por 3: 6. Dividido por 2: 1. O resto da divisao por
2: 0.

2.6 COMANDOS DE SISTEMA MS-DOS


Os comandos de sistema podem ser muito teis para os cdigos criados por um
matemtico. Com eles possvel executar algumas tarefas, como criar uma pasta, vericar em
qual sistema operacional o programa est rodando, dentre outros. Para utilizar os comandos
de sistema precisamos da biblioteca stdlib.h (que sempre utilizamos em nossos programas at
ento).

Sintaxe:

system ( " comando " ) ;

Perceba que o comando est entre aspas.


string.

Isto porque ele

Vale ressaltar que boa parte destes comandos funciona tanto


em Windows quanto Linux.
A lista com alguns dos comandos de sistema so encontrados na Tabela 2.9.

Tabela 2.9: Comandos de Sistema

Comando

Descrio

cd PASTA

Abre uma pasta

cls

Limpa a tela

color XX

Mudar a cor da tela. XX um hexadecimal onde o primeiro


nmero a cor do fundo e a segunda a cor da letra.

copy ORIGEM DESTINO

Copia o arquivo de origem para o seu destino.

date/t

Mostra a data do sistema, sem alter-la.

dir

Exibe uma lista de arquivos e subpastas em

md PASTA

Cria uma pasta

mem

Mostra a memria utilizada e livre do sistema.

pause

Pausa o programa e solicita o pressionamento de


uma tecla para continuar.

time/t

Mostra a hora do sistema.

title NOME

Dene um nome para a janela.

ver

Mostra a verso do sistema operacional.

34

Exemplo 11. Criar um programa que reescreve o exemplo

11,

utilizando algumas funes

dos Comandos de Sistema.

# include < stdio .h >


# include < stdlib .h >
int main () {
// Declarando variveis :
int a ;
int b ;
int c ;
int d ;
int e ;
int f ;
float g ;
int h ;
// Mudando o ttulo da janela :
system ( " title EXEMPLO DOS COMANDOS DE SISTEMA " ) ;
printf ( " Ola ! Digite um numero inteiro . \ n " ) ;
scanf ( " % d " ,& a ) ;
// Atribuindo valores para as variveis atravs de
processos :
b = a + 1;
c = a - 1;
d = a + 5;
e = a - 13;
f = a * 3;
g = a / 2;
h = a % 2;
// Limpando a tela :
system ( " cls " ) ;
printf ( " O numero digitado foi % d .\ n " ,a ) ;
printf ( " Acrescido de uma unidade : % d .\ n " ,b ) ;
printf ( " Decrescido de uma unidade : % d .\ n " ,c ) ;
printf ( " Somado 5 unidades : % d .\ n " ,d ) ;
printf ( " Subtraido 13 unidades : % d .\ n " ,e ) ;
printf ( " Multiplicado por 3: % d .\ n " ,f ) ;
printf ( " Dividido por 2: % f .\ n " ,g ) .
printf ( " O resto da divisao por 2: % d " ,h ) ;
// Solicitando que o usurio aperte alguma tecla para
continuar :
system ( " pause " ) ;

35

// Limpando a tela :
system ( " cls " ) ;
return 0;
}
Primeiramente modicado o ttulo da janela para EXEMPLO DOS COMANDOS
DE SISTEMA. Depois so utilizadas as funes de entrada/sada para atribuir valor para
a varivel inteira

a.

Ento a tela limpada.

Em seguida so mostrados o resultado dos

clculos realizados em cima do valor da varivel digitada pelo usurio. Feito isso, aparece uma
mensagem na tela para que o usurio pressione uma tecla para continuar e, em seguida, a tela
limpada novamente.

36

Captulo 3
ESTRUTURAS DE CONTROLE DE
FLUXO
Estruturas de controle de uxo so comandos utilizados para determinar qual a ordem
e quais comandos devem ser executados pelo programa com uma dada condio.

3.1 ESTRUTURA SELETIVA: IF E ELSE


Em resumo, utilizamos if e else quando queremos vericar se algo verdadeiro ou
falso (bit

ou

0).

Traduzindo: if signica se.

Else signica se no.

Ento, estamos

dizendo para o computador: Se (If ) for tal coisa, faa isso! e Se no (Else), faa isso!.
fcil notar que esta estrutura seletiva possui a mesma lgica do smbolo

=(se,

ento) que

muito utilizado para demonstrao de teoremas matemticos.

Sintaxe:

if ( condio ) {
comandos_a_serem_executados_caso_a_condio_seja_verdadeira
;
}
else {
comandos_a_serem_executados_caso_a_condio_seja_falsa ;
}
Exemplo 12. Criar um programa que pea para o usurio que digite um nmero. Vericar
se o nmero digitado par ou mpar.

Soluo: Neste cdigo precisamos, primeiramente, perguntar ao usurio qual o nmero que
ele deseja vericar se par ou mpar e l-lo.

Utilizando os conhecimentos adquiridos no

captulo anterior j sabemos fazer esta parte. Em seguida precisamos vericar se o nmero
digitado pelo usurio par ou mpar. Para fazer isto utilizaremos o operador %, que retorna o
resto da diviso (ver Tabela 2.4). Alm disso, criaremos um vericador: SE o resto da diviso

37

do nmero digitado por

0,

ento o nmero par. SE NO, o nmero digitado mpar.

Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
/* possvel declarar as variveis de um mesmo tipo
em uma s linha do nosso cdigo .
Para isso , basta por vrgulas ( ,) entre as variveis .
No nosso caso estamos declarando duas variveis inteiras :
a e b */
int a , b ;
printf ( " Digite um numero inteiro : \ n " ) ;
scanf ( " % d " ,& a ) ;
system ( " cls " ) ;
b = a %2;
if ( b == 0) {
printf ( " O numero digitado eh par !\ n " ) ;
system ( " pause " ) ;
}
else {
printf ( " O numero digitado eh impar !\ n " ) ;
system ( " pause " ) ;
}
return 0;
}
Ao executar o programa, ir aparecer a mensagem Digite um numero inteiro.. Digitando

2, b = a%2 = 2%2 = 0,

Digitando

ento aparecer a mensagem O numero digitado eh par!.

11, b = a%2 = 11%2 que diferente de 0, ento aparecer a mensagem O numero

digitado eh impar!.

3.1.1

Operadores Lgicos
Para trabalhar melhor com a estrutura if/else precisamos conhecer os operadores

lgicos. Com eles fazemos o processo de anlise da condio, isto , vericar se falsa ou
verdadeira. Como no exemplo

13,

onde usamos o operador lgico == (igual a).

Alm dos operadores de condio existem dois especiais: && (e) e || (ou).

Que

fazem com que nossa gama de possibilidade contemple tudo o que precisamos para construir
os cdigos deste trabalho.
Na Tabela 3.1 temos uma tabela com os operadores lgicos.

38

Tabela 3.1: Operadores Lgicos

Operador Lgico

Descrio

Exemplo

==

igual a

2 == 2 (VERDADEIRO)

>=

maior ou igual a

2 >= 1 (VERDADEIRO)

<=

menor ou igual a

2 <= 1 (FALSO)

>

maior que

2 > 1 (VERDADEIRO)

<

menor que

2 < 1 (FALSO)

!=

diferente de

2 != 1 (VERDADEIRO)

2 > 1 && 3 < 4 (VERDADEIRO)

||

Ou

2 > 1 || 2 < 1 (VERDADEIRO)

No

2 ! 1 (VERDADEIRO)

&&

Agora que conhecemos os Operadores Lgicos podemos construir alguns cdigos um


pouco mais complexos.

Exemplo 13. Criar um programa que pea para o usurio digite um nmero natural. Se
ele for positivo, vericar se ele par ou mpar, se ele for par, retornar o seu valor elevado
ao quadrado. Se for mpar, retornar o resto de sua diviso por

2.

Se o nmero digitado for

negativo, mostrar uma mensagem dizendo que o nmero digitado no natural.

Soluo: Para construir este programa utilizaremos a estrutura if/else. Primeiramente usaremos as funes de entrada e sada para que o usurio digite um nmero inteiro.

Ento

usaremos a estrutura if/else para vericar se o nmero digitado positivo. Se for verdadeiro,
vamos construir outro vericador se o nmero par ou mpar (idntico ao exemplo

13).

Se

for par, vamos retornar o valor do nmero digitado elevado ao quadrado e se for mpar o resto
de sua diviso por dois. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int a ;
printf ( " Ola ! Digite um numero natural por gentileza .\ n \ n "
);
scanf ( " % d " ,& a ) ;
system ( " cls " ) ;
if ( a > 0) {
if ( a %2 == 0) {
printf ( " % d \ n " , a * a ) ;
system ( " pause " ) ;
}
else {
printf ( " % d \ n " , a %2) ;
system ( " pause " ) ;
39

}
}
else {
printf ( " O numero digitado nao eh natural ! \ n " ) ;
system ( " pause " ) ;
}
return 0;
}
Ao executar o programa, ir aparecer a mensagem Ola! Digite um numero natural
por gentileza..

Digitando

6, 15

aparecer na tela os seguintes resultados:

36, 1

e a

mensagem O numero digitado nao eh natural! respectivamente.

Exemplo 14. Criar um programa que pea para o usurio digitar1 para calcular a rea de uma
circunferncia de raio

R, 2

para calcular a rea de um quadrado de lado

a rea de um tringulo de base

e altura

H.

ou

para calcular

Em cada caso, pedir para que o usurio digite

os valores do raio, lado, base e altura para realizar os clculos. Mostrar os resultados na tela.

Soluo: O interessante deste exemplo que utilizaremos a estrutura if/else como se fosse
um menu de seleo para o usurio. Mais a frente estudaremos um modo mais simples de
fazer isto, mas if/else uma boa opo de qualquer maneira.
Para montar este programa precisaremos, primeiramente, de criar uma varivel do
tipo int para que o usurio possa digitar sua opo. Feito isso, utilizaremos a estrutura if/else
para impor o condicional e montar o menu. Em cada uma das opes basta montar os clculos
e mostrar o resultado na tela para o usurio. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int a ;
printf ( " Digite 1 para realizarmos o calculo da area de
uma " ) ;
printf ( " circunferencia de raio R . Digite 2 para
realizarmos o calculo " ) ;
printf ( " da area de um quadrado de lado L . Digite 3 para
realizarmos " ) ;
printf ( " o calculo da area de um triangulo de base B e
altura H : \ n " ) ;
scanf ( " % d " , & a ) ;
system ( " cls " ) ;
if ( a == 1 || a == 2 || a == 3) {
if ( a == 1 || a == 2) {
if ( a == 1) {
40

float R ;
printf ( " Digite o valor do raio R
da circunferencia \ n " ) ;
scanf ( " % f " , & R ) ;
system ( " cls " ) ;
printf ( " A area da circunferencia
de raio % f eh :\ n " ,R ) ;
printf ( " % f \ n \ n " ,3.14* R * R ) ;
system ( " pause " ) ;
}
else {
float L ;
printf ( " Digite o valor do lado do
quadrado \ n " ) ;
scanf ( " % f " , & L ) ;
system ( " cls " ) ;
printf ( " A area do quadrado de
lado % f eh : % f \ n \ n " , L , L * L ) ;
system ( " pause " ) ;
}
}
else {
float B , H ;
printf ( " Digite o valor da base do
triangulo : \ n " ) ;
scanf ( " % f " , & B ) ;
system ( " cls " ) ;
printf ( " Digite o valor da altura do
triangulo : \ n " ) ;
scanf ( " % f " , & H ) ;
system ( " cls " ) ;
printf ( " A area do triangulo de base % f e
altura % f eh : " , B , H ) ;
printf ( " % f \ n \ n " ,( B * H ) /2) ;
system ( " pause " ) ;
}
}
else {
printf ( " Entrada invalida ! \ n \ n " ) ;
system ( " pause " ) ;
}
return 0;
}
Ao executar o programa, ir aparecer a mensagem Digite 1 para realizarmos o calculo
da area de uma circunferencia de raio R. 2 para realizarmos o calculo da area de um quadrado
de lado L. Digite 3 para realizarmos o calculo da area de um triangulo de base B e altura

41

H:.. Digitando

L = 50

a = 1

o resultado ser:

R = 7

o resultado ser:

L2 = 2500.

Digitando

3.14 72 = 153.86.

a = 3, B = 3

Digitando

H = 16

a = 2

o resultado ser:

(3 16)/2 = 24.
Perceba que, para resolver este problema, precisamos impor vrias condies para
chegar ao desejado. Foi escolhido este modo de construo para que o programador iniciante
perceba que possvel construir vrios cdigos usando apenas o bsico. No quer dizer que o
melhor aprender apenas o bsico e car criando os cdigos utilizando apenas estes recursos.
Mas no precisamos saber tudo sobre a linguagem C para criar programas.
O exemplo acima pode ser feito de outras maneiras mais simples, uma delas vamos
aprender a seguir.

3.1.2

Else If
Else If (Se no, se) um vericador que utilizamos em alguns casos (como o

exemplo anterior) onde queremos criar outro vericador que no seja exatamente o contrrio
do que foi vericado no if/else.
Resumidamente, estamos dizendo ao computador: Se (if ) for tal coisa, faa isso!
Se no, se (else if ) for tal coisa, faa isso! e Se no (else), faa isso!.

Sintaxe:

if ( condio ) {
comandos_a_serem_executados_caso_a_condio_seja_verdadeira
;
}
else if ( condio ) {
comandos_a_serem_executados_caso_a_condio_seja_verdadeira
;
}
else {
comandos_a_serem_executados_caso_todas_as_condies_sejam_falsas
;
}
\ en \ art5d { lstlisting }
\ begin { example }
Criar um cdigo que reescreve o cdigo do exemplo $15$ utilizando
else if :
\ end { example }
\ begin { lstlisting }
# include < stdio .h >
# include < stdlib .h >
int main () {
int a ;

42

printf ( " Digite 1 para realizarmos o calculo da area de


uma " ) ;
printf ( " circunferencia de raio R . 2 para realizarmos o
calculo " ) ;
printf ( " da area de um quadrado de lado L . Digite 3 para
realizarmos " ) ;
printf ( " o calculo da area de um triangulo de base B e
altura H : \ n ) " ;
scanf ( " % d " ,& a ) ;
system ( " cls " ) ;
if ( a == 1) {
float R ;
printf ( " Digite o valor do raio R da
circunferencia :\ n " ) ;
scanf ( " % f " , & R ) ;
system ( " cls " ) ;
printf ( " A area da circunferencia de raio % f eh : " ,
R);
printf ( " % f \ n \ n " , 3.14* R * R ) ;
system ( " pause " ) ;
}
else if ( a == 2) {
float L ;
printf ( " Digite o valor do lado do quadrado \ n " ) ;
scanf ( " % f " , & L ) ;
system ( " cls " ) ;
printf ( " A area do quadrado de lado % f eh : % f \ n \ n
", L, L*L);
system ( " pause " ) ;
}
else if ( a == 3) {
float B , H ;
printf ( " Digite o valor da base do triangulo : \ n " )
;
scanf ( " % f " , & B ) ;
system ( " cls " ) ;
printf ( " Digite o valor da altura do triangulo : \ n
");
scanf ( " % f " , & H ) ;
system ( " cls " ) ;
printf ( " A area do triangulo de base % f e altura %
f eh : " , B , H ) ;
printf ( " % f \ n \ n " ,( B * H ) /2) ;
system ( " pause " ) ;
}
else {
43

printf ( " Entrada invalida ! \ n " ) ;


system ( " pause " ) ;
}
return 0;
}

3.2 ESTRUTURA SWITCH


A estrutura switch usada, assim como if/else, para fazer selees.

como um

if/else com vrias possibilidades, mas com algumas diferenas que fazem com que o switch
seja melhor em algumas situaes, outras no.
Antes de entendermos as diferenas vamos ver como funciona a sintaxe desta estrutura.

Sintaxe:

switch ( Variavel ) {
case valor_1 :
bloco_de_comandos1 ;
break ;
case valor_2 :
bloco_de_comandos2 ;
break ;
case valor_3 :
bloco_de_comandos3 ;
break ;
default :
bloco_de_comandos4 ;
}
A principal diferena que podemos detectar que, diferente da estrutura if/else,

switch no aceita operadores lgicos para realizar as comparaes. Ao invs disso, ele
verica se uma determinada varivel vale qualquer quantidade de valores que o programador
desejar vericar. Esta vericao feita atravs dos cases (que signica caso) e, caso nenhum
case seja verdadeiro, o compilador executa o bloco de comandos determinado pelo default,
do ingls padro, que o case ativado caso no tenha achado nenhum que fora denido. Ou
seja, o que aconteceria em ltimo caso. Vamos imaginar o seguinte cenrio: Seu programa
pede para que o usurio digite apenas duas opes (S ou N) para reiniciar o programa. Mas,
propositalmente ou por engano, o usurio digita uma opo totalmente diferente. E agora?
O que seu programa deve fazer? aqui que o default entra. Geralmente o default usado
quando previsto um erro, uma entrada de dado incorreta ou no de acordo com o contexto.

44

Basicamente estamos dizendo ao computador: Caso a varivel seja este valor, faa isso e,
caso no seja nenhum dos valores, faa isso.
Outro detalhe o break (que signica parar). No nal de cada case inclumos um
break para que o switch pare e o compilador saia do lao. Caso no seja adicionada esta linha
ao cdigo, o compilador vai percorrer todos os cases mesmo que j tenha encontrado um case
verdadeiro. A no utilizao do break diminui a performace do programa, o que no estamos
interessados. Break tambm pode ser utilizado nas seguintes estruturas: for, while e do while.

Exemplo 15. Criar um programa que simule as operaes bsicas de uma calculadora: Com
a estrutura switch criaremos um menu onde teremos as opes soma, subtrao, multiplicao
e diviso. Para o usurio, vamos pedir que ele digite dois nmeros (tipo oat) e escolher a
operao, digitando

1, 2, 3

ou

4.

# include < stdio .h >


# include < stdlib .h >
int main () {
int x ;
float a , b ;
printf ( " Ola , digite 1 para soma , 2 para subtracao , " ) ;
printf ( " 3 para multiplicacao e 4 para divisao :\ n " ) ;
scanf ( " % d " , & x ) ;
printf ( " Digite o primeiro numero real :\ n " ) ;
scanf ( " % f " , & a ) ;
printf ( " Digite o segundo numero real :\ n " ) ;
scanf ( " % f " , & b ) ;
// Usando a funo switch para a varivel x :
switch ( x ) {
// Caso o usurio digite 1:
case 1:
printf ( " o resultado da soma eh : % f \ n " , a
+ b);
break ;
// Caso o usurio digite 2:
case 2:
printf ( " o resultado da subtraao eh : % f \
n", a - b);
break ;
// Caso o usurio digite 3:
case 3:
printf ( o resultado da multiplicaao eh : %
f \n , a * b ) ;
break ;
45

// Caso o usurio digite 4:


case 4:
printf ( " o resultado da divisao eh : % f \ n "
, a / b);
break ;
// Caso o usurio no digite qualquer opo
anterior :
default :
printf ( " Entrada invalida ! \ n " ) ;
}
return 0;
}
Ao executar o programa, ir aparecer a mensagem Ola, digite 1 para soma, 2 para
subtracao, 3 para multiplicacao e 4 para divisao: e ento Digite o primeiro numero inteiro:
e Digite o segundo numero inteiro:.
Digitando

2, 124

5 6 = 30.

78

Digitando

o resultado ser:

4, 3

17

Digitando

1, 8

124 78 = 76.

o resultao ser:

19

o resultado ser:

Digitando

3, 5

8 + 19 = 27.

o resultado ser:

3/17 = 0.176471.

3.3 ESTRUTURA DE REPETIO: FOR


Muitas vezes precisamos que algum procedimento seja executado mais de uma vez em
um programa. Por exemplo, em mtodos numricos, onde realizamos clculos matemticos
vrias vezes at que consigamos chegar a um objetivo.
Traduzindo: for signica  para. Ento, estamos dizendo para o computador: Para
(for) tal coisa, faa isso!.
O comando for precisa de uma varivel para controlar os loops (voltas).

Essa

varivel dever ser inicializada, alm disso o programador dever indicar o seu critrio de

execuo (ou critrio de parada) e a sua forma de incremento ou decremento. Isto


quer dizer que a estrutura for precisa de trs condies, separadas por ponto-e-vrgula (;)
entre si.

Sintaxe:

for ( inicializao ; at_quando_ser_executado ;


incremento_ou_decremento ) {
procedimentos_a_serem_executados_em_cada_loop ;
}
Exemplo 16. Criar um programa que conte de
contagem para o usurio.

46

25,

mostrando na tela cada nmero da

Soluo: Para criar este cdigo, utilizaremos uma estrutura for onde iniciar em
cutado at

25,

1,

ser exe-

incrementando1 a cada repetio. Alm disso, em cada repetio utilizaremos

a funo printf para mostrar a contagem na tela. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
for ( int i = 1; i <= 25; i ++) {
printf ( " % d \ n " ,i ) ;
}
return 0;
}
Apesar de curto, este cdigo tem algo interessante a acrescentar aos nossos estudos.
Note que foi criada uma varivel dentro da estrutura for.

Isso foi feito porque quando os

loops acabarem o programa matar a varivel que foi criada.


existir para a execuo do for.

Isto quer dizer que ela s

Quando fazemos isso estamos economizando utilizao de

memria do computador, alm disso, voc poder criar novamente uma varivel chamada
(como no exemplo

18)

e trabalhar com ela sem comprometer o resto do programa. Este tipo

de declarao s funciona na verso C99 da linguagem C, que quando a declarao dentro


das funes (isso inclui na inicializao do for) passou a ser permitida. Para no complicar,
no utilizaremos mais esta sintaxe.

Exemplo 17. Criar um programa que conte de

1 a 25, mostrando na tela os nmeros mpares.

Soluo: Apesar de ser simples, este exemplo utiliza boa parte do que aprendemos at ento.
A diferena entre este cdigo e o anterior que, a cada loop, precisamos vericar se o nmero
par ou mpar (exemplo

13).

Se ele for mpar, utilizamos a funo printf para mostrar o seu

valor na tela para o usurio. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int i ;
for ( i = 1; i <= 25; i ++) {
if ( i %2 != 0) {
printf ( " % d \ n " ,i ) ;
}
// Sequncia dos restos da diviso de cada i por
2:
printf ( " % d \ n " , i %2) ;
}
return 0;
}
47

Os restos das divises de cada nmero da sequncia por

0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1.
para o usurio a seguinte sequncia:

1, 0, 1, 0, 1, 0, 1, 0, 1,

Ento, ao compilar o programa aparecer na tela

1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21,23, 25.

Exemplo 18. Criar um programa que pea para o usurio digitar um nmero. Retornar uma
mensagem dizendo se ele primo ou no.

Soluo: Lembrando: um nmero primo se ele divisvel por dois nmeros apenas,

e ele

prprio. Ento, vamos criar um If/else dever vericar a seguinte condio: Se o nmero de
divisores for exatamente dois, ento ele primo. Para isto, precisamos de criar uma varivel,
que inicialmente tenha valor nulo, e que incremente uma unidade cada vez que o nmero tenha
uma diviso com resto

0.

Agora que denimos como ser nossa estrutura if/else, vamos organizar o for, para
isso precisamos saber qual ser nossa inicializao. Como estamos querendo contar os divisves
de um determinado nmero, ento os valores acima dele no nos importa. Logo, conveniente
criar um for que v do prprio nmero at o nmero

1,

decrementando uma unidade a cada

loop. Com isso conseguimos construir o nosso cdigo. Ento vamos a ele:

# include < stdio .h >


# include < stdlib .h >
int main () {
system ( " title VERIFICAR SE UM NUMERO EH PRIMO " ) ;
int i , n , x = 0;
printf ( " Digite um numero inteiro que gostaria " ) ;
printf ( " de saber e eh primo :\ n " ) ;
scanf ( " % d " , & n ) ;
for ( i = n ; i >= 1; i - -) {
/* Este lao for tambm poderia ser feito da
seguinte maneira : for ( i = 1; i <= n ; i ++) : */
if ( n % i == 0) {
x ++;
}
// Sequncia dos restos da diviso de cada n por i
:
printf ( " % d \ n " , n % i ) ;
}
system ( " cls " ) ;
if ( x == 2) {
printf ( " O numero % d eh primo . \ n " , n ) ;
system ( " pause " ) ;
}
48

else {
printf ( " O numero % d nao eh primo . \ n " , n ) ;
system ( " pause " ) ;
}
return 0;
}
Ao executar o programa, ir aparecer a mensagem Digite um numero inteiro que
gostaria de saber e eh primo:.
Digitando

0.

Neste caso

7,

x = 2,

Digitando

a sequncia dos restos da diviso de


logo

22,

i (n%i)

por

0, 1, 2, 3, 1, 1,

primo.

a sequncia dos restos da diviso de

7, 8, 9, 10, 0, 2, 4, 6, 1, 4, 2, 2, 1, 0, 0.
3.3.1

Neste caso

x = 4,

por

logo

i (n)

22

0, 1, 2, 3, 4, 5, 6,

no primo.

Vetores e Matrizes
Alm de serem usados como vetores e matrizes, tambm costumeiro utiliz-los para

guardar vrios valores em uma s varivel, como por exemplo uma sequncia de nmeros (CPF,
CNPJ, RG, Telefone, etc.), guardar uma sequncia de nmeros, dentre outros.
Para declarar um vetor precisamos dizer qual o tipo de varivel que vamos trabalhar,
mas a varivel vai ser seguida de colchetes ([]), onde deniremos o tamanho do vetor.

Declarao de um Vetor:

tipo_de_varivel nomedovetor [ tamanho_do_vetor ];

Exemplicando:

// Vetor chamado meuvetorint com 100 posies :


int meuvetorint [100];
Um detalhe importante que o ndice inicial de acesso aos elementos de um

vetor sempre 0. Isto quer dizer que um vetor com

100 posies vai da posio 0 at a 99.

importante lembrar deste detalhe quando vamos fazer o preenchimento de um vetor ou de


uma matriz.
Para declarar uma matriz igual ao modo que declaramos um vetor, a diferena
que devemos especicar dois tamanhos: linhas e colunas.

Declarao de uma matriz:

tipo_de_varivel nomedamatriz [ tamanho_linhas ][ tamanho_colunas ];

Exemplicando:

49

// Matriz chamada matriz 5 X5 :


int matriz [5][5];
No exemplo a seguir aprenderemos a preencher vetores e matrizes.

Exemplo 19. Criar um programa que crie e preencha um vetor com

10

10.

50 posies e uma matriz

Onde cada entrada ser digitada pelo usurio.

Soluo: Para preencher tanto um vetor quanto uma matriz utilizaremos a estrutura for. A
questo conseguir acessar cada posio para o preenchimento, para isso basta dizer entre
colchetes qual posio estamos acessando. Por exemplo:

e coluna

da matriz chamada

z.

z[1][2],

estamos acessando a linha

Sabendo isto, para preencher um vetor ou matriz basta

percorrer todas as suas posies e utilizar as funes de entrada e sada.

Ento vamos ao

cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int i , a , b , v [50];
int m [10][10];
// Preenchendo o vetor :
for ( i = 0; i < 50; i ++) {
printf ( " Digite o valor da posiao % d do vetor :\ n "
, i);
scanf ( " % d " ,& v [ i ]) ;
}
/* Preenchendo a matriz utilizando dois laos for :
um que percorre as linhas e outro as colunas : */
for ( a = 0; a < 10; a ++) {
for ( int b = 0; b < 10; b ++) {
printf ( " Digite o valor da linha % d e
coluna % d da matriz :\ n " , a , b ) ;
scanf ( " % d " ,& m [ a ][ b ]) ;
}
}
return 0;
}
Agora que sabemos o procedimento para preencher matrizes e vetores, podemos criar
alguns cdigos interessantes que trabalha melhor o contedo.

Exemplo 20. Criar um programa que preenche uma sequncia numrica de tamanho escolhido
pelo usurio (mximo1000), de valores inteiros, onde o usurio digita as entradas. Feito isso,
calcular o somatrio e o produtrio da sequncia.

50

Soluo: Para criar este cdigo precisamos, primeiramente, criar um vetor do tipo int de
tamanho escolhido pelo usurio e ento utilizar as funes printf e scanf para povo-lo. Aps
isso, precisamos de um lao for para calcular o somatrio e o produtrio, onde criaremos uma
varivel para cada um dos resultados onde iremos, a cada volta do loop, somar e multiplicar o
termo atual com o resultado do que j temos, isto :
e

produt
orio = produt
orio sequencia[i].

somat
orio = somat
orio + sequencia[i]

Para que isto seja possvel, precisamos comear

igualando estas variveis a 0 e 1 respectivamente, que so as identidades das operaes de soma


e multiplicao, fazendo com que o primeiro valor, tanto do somatrio quanto do produtrio,
seja o primeiro termo da sequncia. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int i , sequencia [1000] , n , somatorio = 0 , produtorio =
1;
printf ( " Escolha o tamanho da sequencia numerica ( no
maximo 1000) :\ n \ n " ) ;
scanf ( " % d " , & n ) ;
system ( " cls " ) ;
// Preenchendo a sequncia numrica :
for ( i = 0; i < n ; i ++) {
printf ( " Digite o valor da posicao % d da sequncia
: \ n " , i +1) ;
scanf ( " % d " , & sequencia [ i ]) ;
system ( " cls " ) ;
}
// Calculando o somatrio e o produtrio da sequncia
digitada :
for ( i = 0; i < n ; i ++) {
somatorio = somatorio + sequencia [ i ];
produtorio = produtorio * sequencia [ i ];
}
printf ( " O somatorio da sequencia digitada eh : % d .\ n " ) ;
printf ( " E o produtorio eh : % d . " , somatorio , produtorio ) ;
return 0;
}
Ao executar o programa, ir aparecer a mensagem Escolha o tamanho da sequencia
numerica (no maximo 1000):. Digitando

33, 54, 87, 141.

Temos que o somatrio

12

e a seguinte sequncia:

369

e o produtrio

51

1, 1, 2, 3, 5, 8, 13, 21,

2029593312.

Exemplo 21. Criar um cdigo que verica se dois vetores, de tamanho e elementos digitados
pelo usurio, so Linearmente Independentes (LI) ou Linearmente Dependentes (LD).

Soluo: Dois vetores so LD se um deles for igual a uma constante vezes o outro, isto ,
no caso de dois vetores

B:
A=B

Ento, para montarmos este cdigo, precisamos primeiramente utilizar o operador for
para que o usurio preencha os vetores. Feito isto criaremos um terceiro vetor, chamado

do

tipo oat, que ir receber o resultado da diviso de cada membro de um vetor pelo outro, isto
,

c[i] = b[i]/a[i].

Para que os dois vetores sejam LD o vetor

precisa ter todos os elementos

tendo o mesmo valor, sendo assim, vamos criar um lao for para vericar com o operador
if se cada par de elementos do vetor

contador que somar uma unidade.

Ento, se o contador possuir valor maior do que

possui o mesmo valor, se for verdadeiro teremos um

os

vetores digitados so LD, caso contrrio so LI. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int i , a [1000] , b [1000] , n , contador = 0;
float c [1000];
printf ( " Digite o tamanho dos vetores :\ n " ) ;
scanf ( " % d " , & n ) ;
// Preenchendo os vetores utilizando o operador for :
for ( i = 1; i <= n ; i ++) {
printf ( " Digite o valor da posicao % d do primeiro
vetor :\ n " , i ) ;
scanf ( " % d " ,& a [ i ]) ;
system ( " cls " ) ;
}
for ( i = 1; i <= n ; i ++) {
printf ( " Digite o valor da posicao % d do segundo
vetor :\ n " , i ) ;
scanf ( " % d " ,& b [ i ]) ;
system ( " cls " ) ;
}
/* Preenchendo um vetor c que ser composto pelo resultado
da
diviso dos elementos do primeiro vetor pelo segundo : */
for ( i = 1; i <= n ; i ++) {
c [ i ] = b [ i ]/ a [ i ];
printf ( " % f " ,c [ i ]) ;
52

}
/* Para que os vetores sejam LD , o vetor c criado
anteriormente precisa
ter todos os membros iguais , isto , c [ i ]= c [ i +1].
O contador adicionar uma unidade caso isso no acontea :
*/
for ( i =1; i < n ; i ++) {
if ( c [ i ] == c [ i +1]) {
contador ++;
}
}
if ( contador == n -1) {
printf ( " \ nOs vetores digitados sao LD .\ n " ) ;
}
else {
printf ( " \ nOs vetores digitados sao LI .\ n " ) ;
}
return 0;
}
Ao executar o programa, ir aparecer a mensagem Digite o tamanho dos vetores:.
Digitando

b = (9, 33, 24).


a

c = b/a

ser

c = (3, 3, 3),

a = (3, 11, 8),

como todos os elementos de

so iguais,

so LD, ento aparecer a mensagem Os vetores digitados sao LD. para o usurio.

b = (3, 8, 7).
e

e digitando valores para formar os seguintes vetores:

O vetor

Digitando

O vetor

e digitando valores para formar os seguintes vetores:

a = (1, 4, 9),

c = b/a ser c = (3, 2, 0), como os elementos de c no so todos iguais,

so LI, ento aparecer a mensagem Os vetores digitados sao LI. para o usurio.

Exemplo 22. Criar um programa que retorne o mximo e o mnimo de um vetor, de tamanho

n,

digitado pelo usurio:

Soluo: Para resolver este problema precisamos criar um lao for para que o usurio digite
os elementos do vetor. Feito isto, criaremos um segundo lao for que ir vericar, utilizando
o operador if/else, se cada elemento do vetor digitado maior do que uma varivel auxiliar,
que chamaremos de auxmax, ou menor do que uma outra varivel auxiliar, que chamaremos
de auxmin. Caso seja verdadeiro algum dos vericadores, a varivel em questo assumir o
valor que o vetor possui naquela posio. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int i , n , a [1000] , auxmax , auxmin ;
printf ( " Digite o tamanho do vetor :\ n " ) ;
53

scanf ( " % d " , & n ) ;


// Preenchendo o vetor :
for ( i = 0; i < n ; i ++) {
printf ( " Digite o valor da posicao % d do vetor :\ n
" , i +1) ;
scanf ( " % d " ,& a [ i ]) ;
system ( " cls " ) ;
}
/* Criando lao for para verificar se cada posio do
vetor
maior do que a varivel auxmax e outro para verificar
se
menor do que auxmin , caso seja o valor ser substitudo
: */
auxmax = a [0];
auxmin = a [0];
for ( i = 1; i < n ; i ++) {
if ( a [ i ] > auxmax ) {
auxmax = a [ i ];
}
}
for ( i = 1; i < n ; i ++) {
if ( a [ i ] < auxmin ) {
auxmin = a [ i ];
}
}
printf ( " O maximo do vetor digitado eh : % d . \ n " , auxmax ) ;
printf ( " O minimo do vetor digitado eh : % d .\ n " , auxmin ) ;
return 0;
}
Ao executar o programa, ir aparecer a mensagem Digite o tamanho do vetor:.
Digitando

10

o mnimo

7.

e o vetor

a = (9, 12, 55, 68, 125, 1, 0, 93, 7, 2),

o mximo do vetor ser

Exemplo 23. Criar um programa que faa com que o usurio preencha uma matriz

10

125

10.

Ento mostrar na tela a mesma matriz:

Zerada;

Com todos os valores da diagonal sendo

1;

Soluo: Para criar este cdigo precisaremos, primeiramente, preencher uma matriz

10

10

(como vimos anteriormente). Ento criaremos um loop que atribua para cada posio da

54

matriz o valor

0.

Feito isto, criaremos outro loop que atribui o valor

diagonal principal (se

for igual a

j ).

para as posies da

Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int i , j , matriz [10][10];
for ( i = 0; i < 10; i ++) {
for ( j = 0; j < 10; j ++) {
printf ( " Digite um numero inteiro para a
posicao %d ,% d \ n " ,i +1 , j +1) ;
scanf ( " % d " ,& matriz [ i ][ j ]) ;
}
}
for ( i = 0; i < 10; i ++) {
for ( j = 0; j < 10; j ++) {
matriz [ i ][ j ] = 0;
}
}
for ( i = 0; i < 10; i ++) {
for ( j = 0; j < 10; j ++) {
if ( i == j ) {
matriz [ i ][ j ] = 1;
}
}
}
system ( " cls " ) ;
// Perceba que o retorno uma matriz identidade :
for ( i = 0; i < 10; i ++) {
for ( j = 0; j < 10; j ++) {
printf ( " Valor da posicao %d , % d : % d \ n " , i
+1 , j +1 , matriz [ i ][ j ]) ;
}
}
return 0;
}
Exemplo 24. Criar um programa que calcule o determinante de uma matriz

3X3.

Soluo: Vamos aproveitar o cdigo acima para preencher uma matriz

Para calcular o

determinante vamos utilizar a Regra de Sarrus:

55

3X3.

a b c

det d e f = (aei + bf g + cdh) (ceg + af h + bdi)


g h i
Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int a [3][3] , i , j , det ;
printf ( " Programa para calcular determinante de uma matriz
3 x3 :\ n \ n " ) ;
// Preenchendo a matriz :
for ( i = 0; i < 3; i ++) {
for ( j = 0; j < 3; j ++) {
printf ( " Digite um numero inteiro para a
posicao %d ,% d :\ n " ,i +1 , j +1) ;
scanf ( " % d " ,& a [ i ][ j ]) ;
}
}
// Regra de Sarrus :
det =(( a [0][0]* a [1][1]* a [2][2]) +( a [0][1]* a [1][2]* a [2][0]) +
( a [0][2]* a [1][0]* a [2][1]) ) -(( a [0][2]* a [1][1]* a [2][0]) +
( a [0][0]* a [1][2]* a [2][1]) +( a [0][1]* a [1][0]* a [2][2]) ) ;
system ( " cls " ) ;
printf ( " \ n O determinante da matriz digitada eh : % d " , det )
;
eturn 0;
}
Ao ser executado, o programa ir solicitar ao usurio que ele preencha uma matriz
X

3.

1 0 11 ,
8 10 7
det = (3 0 7 + 6 8 11 + 9 1 10) (9 0 8 + 3 11

Digitando valores para construir a seguinte matriz a =

o determinante ser

10 + 6 1 7) = 150.
Exemplo 25. Criar um programa que calcule a soma de duas matrizes

56

4:

Soluo: Para fazer este clculo criaremos uma terceira matriz, de modo que cada um de
seus elementos receber a soma dos elementos da mesma posio das duas matrizes digitadas
pelo usurio. Isto quer dizer que:

ci,j = ai,j + bi,j .

Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int a [4][4] , b [4][4] , c [4][4] , i , j ;
system ( " title PROGRAMA PARA CALCULAR A SOMA DE DUAS
MATRIZES 4 X4 " ) ;
// Preenchendo a primeira matriz :
printf ( " Preenchendo a primeira matriz :\ n " ) ;
for ( i = 0; i < 4; i ++) {
for ( j = 0; j < 4; j ++) {
printf ( " Digite um numero inteiro para a
posicao %d ,% d :\ n " ,i +1 , j +1) ;
scanf ( " % d " ,& a [ i ][ j ]) ;
system ( " cls " ) ;
}
}
// Preenchendo a segunda matriz :
printf ( Preenchendo a segunda matriz :\ n ) ;
for ( i = 0; i < 4; i ++) {
for ( j = 0; j < 4; j ++) {
printf ( " Digite um numero inteiro para a
posicao %d , % d \ n " , i +1 , j +1) ;
scanf ( " % d " ,& b [ i ][ j ]) ;
system ( " cls " ) ;
}
}
/* Preenchendo a terceira matriz , que receber a soma
das duas matrizes digitadas pelo usurio : */
for ( i = 0; i < 4; i ++) {
for ( j = 0; j < 4; j ++) {
c [ i ][ j ] = a [ i ][ j ] + b [ i ][ j ];
}
}
printf ( " A soma das duas matrizes digitadas eh : \ n " ) ;
printf ( " % d % d % d % d \ n " ,c [0][0] , c [0][1] , c [0][2] , c
[0][3]) ;
printf ( " % d % d % d % d \ n " ,c [1][0] , c [1][1] , c [1][2] , c
[1][3]) ;
57

printf ( " % d % d % d % d \ n " ,c [2][0] , c [2][1] , c [1][2] , c


[2][3]) ;
printf ( " % d % d % d % d \ n " ,c [3][0] , c [3][1] , c [3][2] , c
[3][3]) ;
return 0;
}
Ao ser executado, o programa ir solicitar ao usurio que ele preencha duas matrizes

1 1 1 1

2 2 2
4x4. Digitando valores para construir as matrizes a =
3 3 3

4 4 4

1+4 1+3 1+2

2+1 2+2 2+3


programa retornar a matriz c = a+b =
3+4 3+3 3+2

4+1 4+2 4+3

4 3 2 1

2
e b = 1

4
3

4
1

1+1
5

2+4
= 3

3+1
7
4+4
5

2 3 4
o
3 2 1

2 3 4

4 3 2

4 5 6
.
6 5 4

6 7 8

3.4 ESTRUTURA DE REPETIO: WHILE


While (do ingls: enquanto) uma forma de repetio da linguagem C que executa
uma comparao e, enquanto for verdadeira, executa o bloco de instrues ( {} ).
Fato interessante que boa parte dos programas que fazemos utilizando o comando
for, podemos fazer o mesmo usando while (e vice-versa). Mas no quer dizer que o cdigo
car mais simples, apesar de algumas vezes acontecer.
extremamente til para um matemtico saber usar o comando while, principalmente
quando falamos de Matemtica Aplicada Computacional, onde nem sempre o comando for
consegue suprir as necessidades do programador. Isto , existem situaes em que o comando
for no consegue fazer o desejado, por exemplo iteraes que tem um critrio de parada, onde
precisamos de fazer uma comparao para decidir se vai ou no ser feita a prxima iterao.

Sintaxe:

While ( comparaao ) {
bloco_de_instruoes ;
}
importante salienar que while no incrementa (ou decrementa) automaticamente
uma varivel. Ento devemos tomar cuidado, pois s vezes ao utilizar while ns entramos em
loops innitos (ver exemplo

28).

Exemplo 26. Criar um programa que faa um loop innito usando a estrutura while.

58

# include < stdio .h >


# include < stdlib .h >
int main () {
int n = 0 , x = 0 , y ;
/* Enquanto n for menor do que 100 ,
adicionar uma unidade varivel x e y = x +1: */
while ( n <100) {
x ++;
y = x + 1;
printf ( " % d \ n " , y ) ;
}
return 0;
}
Este programa nunca parar de rodar (a no ser que o usurio o mate). Note que a
comparao que criamos foi: Enquanto
S que

vai ser sempre igual a

fazendo com que

0!

for menor do que

100,

faa

x = x+1

y = x + 1.

Isso quer dizer que o while car rodando sem parar,

tendam ao innito.

Exemplo 27. Criar um programa que pea para o usurio adivinhar um nmero de

20.

Enquanto ele no digitar o nmero correto, mostrar uma mensagem o desaando a acertar.

Soluo: Para criar este programa precisamos, primeiramente escolher um nmero


para ser o correto, vamos cham-lo den. Ento criamos um while que verica o seguinte:
Enquanto o nmero digitado for diferente de

n, mostre uma mensagem desaando o usurio a

acertar o nmero. Caso ele acerte, mostrar uma mensagem parabenizando. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
int n = 0;
printf ( " Estou pensando em um numero de 1 a 20. Consegue
adivinhar ?\ n " ) ;
system ( " pause " ) ;
system ( " cls " ) ;
// Enquanto n for diferente de 14 , aparecer a mensagem "
Escolha um numero ":
while ( n != 14) {
printf ( " Escolha um numero :\ n " ) ;
scanf ( " % d " , & n ) ;
}
printf ( " Parabens ! Voce acertou ! " ) ;
59

return 0;
system ( " pause " ) ;
}
Exemplo 28. Criar um programa que calcule o epsilon da mquina (ou zero da mquina),
isto , a distncia entre

e o segundo maior nmero de ponto utuante em no computador.

Soluo: Para criar este programa criaremos uma varivel do tipo double chamada

epsilon

atribuir o valor

o valor atual de

epsilon

na inicializao.

Ento criaremos um lao while que substituir

por sua metade enquanto

mostraremos para o usurio o valor de

epsilon

1 + epsilon

for maior do que

1.

Ento

com a funo printr. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
// Declarando varivel local :
double epsilon =1;
// Calculando o valor de epsilon :
while ( 1+ epsilon > 1) {
epsilon = epsilon / 2;
}
// Mostrando o valor de epsilon para o usurio :
printf ( " O zero da maquina eh : % lf \ n " , epsilon ) ;
return 0;
}
Ao executar o cdigo aparecer a mensagem O zero da maquina eh:

3.4.1

0.00000.

Do While
Utilizamos a estrutura de repetio do while quando queremos que um determinado

loop seja executado pelo menos uma vez. Traduzindo, do signica faa e while enquanto.
A diferena entre do while e while que, no comando do while, executamos o bloco
de instrues e depois comparamos, enquanto que no while comparamos antes de executar o
bloco de instrues.

Sintaxe:

Do {
bloco_de_instruoes ;
} while ( comparaao ) ;

60

Exemplo 29. Criar um programa que verica qualquer quantidade de nmeros (um a um)
que o usurio digitar se par ou mpar, que naliza quando for digitado o nmero

0.

Soluo: J sabemos como vericar se um nmero digitado par ou mpar. A diferena


que agora criaremos uma varivel para comparao que nalizar um loop que ir receber uma
varivel e vericar se par ou mpar.

# include < stdio .h >


# include < stdlib .h >
int main () {
int n ;
do {
printf ( " Digite um numero para verificar se eh par
");
printf ( " ou impar ou 0 para finalizar o programa
:\ n " ) ;
scanf ( " % d " , & n ) ;
/* Se o resto da diviso de n por 2 for 0 e n for
diferente de 0 nmero par , caso contrrio
mpar . */
if ( n %2 == 0) {
printf ( " % d \ n " , n %2) ;
if ( n != 0) {
printf ( " O numero % d eh par .\ n " ,n )
;
}
system ( " pause " ) ;
system ( " cls " ) ;
}
else {
printf ( " O numero % d eh impar .\ n " ,n ) ;
system ( " pause " ) ;
system ( " cls " ) ;
}
} while ( n != 0) ;
return 0;
}
Ao executar o programa, ir aparecer a mensagem Digite um numero para vericar
se eh par ou impar ou
Digitando
numero

36

para nalizar o programa: \n.

o resto da diviso de

por

2 (n)

0,

ento aparecer a mensagem O

eh par..

Digitando
O numero

36,

197

197, o resto da diviso de n por 2 (n%2) 0, ento aparecer a mensagem

eh impar.

61

Digitando

o programa nalizar.

62

Captulo 4
FUNES
Em todos os nossos programas existe uma linha contendo  int main (). Trata-se
de uma funo. Mais do que isso, a funo principal de qualquer programa criado em
linguagem C.
Mas, o que uma funo?
Funes so blocos de cdigos que retornam valores. Assim como o int main, que
retorna um valor inteiro. Este o motivo da linha contendo return
estamos retornando o valor

0

de nossos programas:

0.

Neste captulo aprenderemos a criar funes em nossos programas, com o objetivo de


deixar os cdigos mais prticos.

4.1 Porque e Como Usar Funes


Suponha que voc tem um cdigo no qual precisa calcular quanto vale uma determinada funo em mais de um ponto, que seriam calculados dentro do prprio programa, um
dependendo do outro. Com o que sabemos at agora, iramos montar o cdigo da seguinte
maneira:
1. processos para clculo da funo no ponto
2. processos para manipulao do ponto

x1 ,

3. processos de clculo da funo no ponto

x1 ;

resultando em um ponto

x2 ;

x2 ;

4. este procedimento seria repedito diversas vezes at chegar ao resultado esperado.


Um cdigo assim caria muito extenso e de difcil compreenso.
Uma funo em linguagem C funciona como uma funo matemtica: valores de

entrada

clculos valores

de sada. Para exemplicar lembremos de uma funo que

temos usado muito em nossos programas: printf. Nela ns digitamos, por exemplo, um texto
que aparece na tela para o usurio.

No geral, a funo printf, segue o seguinte roteiro:

63

valores de entrada (texto)

clculos (ou processos)

valores de sada (texto na tela

para o usurio).
Usamos funes, principalmente, quando precisamos realizar algum clculo mais de
uma vez em um programa.

Elas devem ser escritas antes da funo principal para serem

compiladas primeiramente e, ento, serem chamadas dentro do programa principal.

Sintaxe:

tipo_de_retorno nome_da_funao ( argumentos ) {


bloco_de_comandos ;
}
Como exemplo podemos tomar a funo principal (int main () ).

4.1.1

Funes Sem Argumentos


Como o nome sugere, so funes que executam algo sem a necessidade de entrarmos

com argumentos. Utilizamos o tipo void no lugar dos argumentos quando construmos uma
funo deste tipo.

Sintaxe:

tipo_de_retorno nome_da_funao ( void ) {


bloco_de_comandos ;
}
Para chamar uma funo sem argumentos na funo principal basta digitar o nome
da funo e colocar nada entre os parnteses (assim como fazemos com a int main).

Exemplo 30. Criar um programa que faz com que o usurio preencha matriz uma

5.

Soluo: J sabemos preencher uma matriz (exemplo21). A diferena que agora vamos
criar uma funo que, toda vez que for chamada, mostre na tela uma mensagem para o usurio
digitar um valor. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
// O tipo da funo tambem void , pois no sero retornados
valores dela :
void mensagem ( void ) {
printf ( " Digite um valor para a matriz : \ n " ) ;
}
int main () {
int i , j ;
// Criando uma matriz 5 x5 :
64

int matriz [5][5];


// Loop para preenchimento da matriz :
for ( i = 0; i < 5; i ++) {
for ( j = 0; j < 5; j ++) {
mensagem () ;
scanf ( " % d " ,& matriz [ i ][ j ]) ;
}
}
system ( " cls " ) ;
for ( i = 0; i < 5; i ++) {
for ( j = 0; j < 5; j ++) {
printf ( " % d \ n " , matriz [ i ][ j ]) ;
}
}
return 0;
}

4.1.1.1

Retornar Valores
Funes podem retornar valores ou no. Quando denimos um tipo de retorno para

uma funo, espera-se que este retorno seja feito de algum modo.

Para isto utilizamos o

comando return. O tipo de retorno o tipo de varivel que a funo vai retornar (o resultado).
Quando no queremos que uma funo retorne valor, basta colocar o seu tipo como sendo
void (como foi visto no exemplo

31).

Em alguns livros funes que no retornam valores so

conhecidas como procedimentos.

Sintaxe:

tipo_de_retorno nome_da_funao ( argumentos ) {


bloco_de_comandos ;
return ( resultado_da_funao ) ;
}
Uma observao importante que a funo precisa ter para onde retornar o seu valor,
assim como na matemtica, onde o

recebe o valor da funo de

x.

Ento, precisamos ter

uma varivel esperando um valor no lugar onde a funo ser usada, que ser o resultado da
funo. Veremos melhor nos exemplos.

Exemplo 31. Criar um programa que contm uma funo que soma dois nmeros inteiros e
retorna o resultado da soma.

Soluo: Vamos criar uma funo que precisa de dois argumentos de forma implcita (tipo
void), chamada somar e que retornar o valor da soma de tipo int. Nesta funo iremos pedir

65

ao usurio digitar dois valores inteiros, em seguida somaremos e retornaremos o resultado. Na


funo principal precisamos nomear uma varivel do tipo int (x) para receber o valor retornado
pela funo. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
// Declarando a funo como tipo int , pois retornar um valor
inteiro :
int somar ( void ) {
int a , b , resultado ;
printf ( " Digite um valor inteiro : \ n " ) ;
scanf ( " % d " ,& a ) ;
printf ( " Digite outro valor inteiro : \ n " ) ;
scanf ( " % d " ,& b ) ;
resultado = a + b ;
return ( resultado ) ;
}
int main () {
// Criando uma varivel x , que receber o resultado da
funo somar :
int x ;
x = somar () ;
system ( " cls " ) ;
printf ( " O resultado da soma dos dois valores digitados eh
: % d " ,x ) ;
return 0;
}
Ao executar, o programa ir solicitar ao usurio que digite dois nmeros inteiros.
Digitando

179

235

o valor de

ser

x = 179 + 235 = 414.

resultado da soma dos dois valores digitados eh:

Aparecer a mensagem O

414.

Agora, sempre que quisermos somar dois nmeros em um programa, podemos simplesmente copiar a funo somar e colar no cdigo.

Exemplo 32. Criar um programa que contenha uma funo que calcula a derivada de uma
funo am digitada pelo usurio.

Soluo: Vamos criar uma funo chamada derivar_am que retorne um valor do tipo oat.
Na funo principal chamaremos a funo derivar_am, atribuindo o seu resultado a uma

66

varivel real que ser criada no programa principal. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
float derivar_afim ( void ) {
float a , b ;
/* Lembrando : uma funo afim do tipo f ( x ) = ax + b e sua
derivada o valor que acompanha o x , no caso , a . */
printf ( " Digite o valor que acompanha x da funcao afim :\ n "
);
scanf ( " % f " , & a ) ;
printf ( Digite o termo independente da funcao afim :\ n ) ;
scanf ( " % f " , & b ) ;
return ( a ) ;
}
int main () {
// Criando varivel x do tipo int que receber o resultado
da funo derivar_afim :
float x ;
x = derivar_afim () ;
system ( " cls " ) ;
printf ( " A derivada da funcao digitada eh : % d \ n " , x ) ;
return 0;
}
Ao executar, o programa ir solicitar ao usurio que ele digite os valores de
funo am
funo

4.1.2

f (x) = ax + b.

f (x) = 7.

Digitando

a=7

b = 12 (f (x) = 7 x + 12),

Aparecer a mensagem A derivada da funcao digitada eh:

da

a derivada da

7.

Funes Com Argumentos


At agora foram criadas todas as variveis utilizadas nas funes dentro delas prprias,

mas em muitos casos ns estaremos interessados em utilizar uma determinada funo utilizando
variveis que foram calculadas em outros procedimentos dentro da funo principal, podendo
ser at outras funes. Nestes casos criamos as funes com argumentos.

Argumentos so parmetros pr-especicados que so necessrios para o funcionamento de uma funo. Resumidamente, um argumento uma varivel, que necessrio
para algum processo especicado dentro da funo. Para criar uma funo com argumento

67

basta declarar uma varivel entre os parnteses depois do tipo de retorno e nome da funo. Quando fazemos isso, estamos dizendo que a funo est esperando uma varivel de um
determinado tipo. Para colocar mais de um argumento em uma funo basta separ-los por
vrgulas.
Os argumentos podem ser passados por valor ou por referncia. No primeiro caso
quando queremos enviar os dados para serem usados nos clculos dentro da funo, no
segundo caso quando queremos, alm de utilizar nos clculos dentro da funo, alterar o
valor da varivel. Quando passamos um valor por referncia, estamos enviando o endereo

de memria da varivel ao invs de seu valor. Para passar o valor por referncia basta utilizar
asterisco ( * ) na frente do nome do argumento e, quando vamos atribuir um valor novo para
a varivel que foi passada desta maneira, tambm utilizamos asterisco na frente de seu nome.
Tambm podemos passar funes como argumentos.

Sintaxe:

tipo_de_retorno nome_da_funao ( tipo_do_argumento argumento_1 ,


tipo_do_argumento * argumento_2 ,
tipo_do_argumento argumento_3 ,
...) {
bloco_de_comandos ;
return ( resultado_da_funao ) ;
}
Vamos ver um exemplo para axao.

Exemplo 33. Criar um programa que contm uma funo chamada divisao que divide dois
nmeros digitados pelo usurio.

Soluo: Para criar este programa precisamos utilizar as funes de entrada e sada para que
o usurio digite os dois nmeros para efetuarmos a diviso. Criaremos uma funo chamada
divisao que recebe como argumentos dois valores do tipo oat, os divide, e retorna o resultado
da diviso. Ento basta dar um printf no resultado na funo principal. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
float divisao ( float a , float b ) {
float resultado ;
resultado = a / b ;
return ( resultado ) ;
}
int main () {
/* Perceba que o nome da varivel no precisa ser o
mesmo do nome do argumento ! Mas o tipo precisa ser o
mesmo ! */
68

float x , y , res ;
printf ( " Digite qual eh o dividendo :\ n " ) ;
scanf ( " % f " , & x ) ;
y = 0;
while ( y == 0) {
printf ( " Digite qual eh o divisor : \ n " ) ;
scanf ( " % f " , & y ) ;
if ( y == 0) {
printf ( " o divisor nao pode ser 0! Digite
outro numero :\ n " ) ;
}
}
/* No necessrio especificar o tipo das variveis x e y
,
pois a funo est esperando valores do tipo float : */
res = divisao (x , y ) ;
printf ( " O retultado da divisao entre % f e % f eh : % f .\ n " ,
x , y , res ) ;
return (0) ;
}
Ao ser executado, o programa ir solicitar que o usurio digite o divisor e o dividendo,
respectivamente. Digitando
resultado da divisao entre

4.1.3

42

42

6,

eh:

temos que

x/y = 42/6 = 7.

Aparecer a mensagem O

7.

Prottipos de funes
Prototipagem trata-se de declarar uma funo para que o main (funo principal)

saiba que ela existe, mas o cdigo est em outro lugar. Esta tcnica permite que as funes
possam ser escritas em qualquer lugar do programa, e no mais antes da funo int main ().
til para saber quantas funes existem no programa, alm de melhorar a organizao. Criar
um prottipo de funo quase da mesma maneira que se cria uma funo, a diferena que
os blocos de comandos so substitudos por ponto e vrgula (;).

Sintaxe:

tipo_de_retorno nome_da_funo ( tipo_do_argumento argumento_1 ,


tipo_do_argumento * argumento_2 ,
tipo_do_argumento argumento_3 ,
...) ;

69

Qualquer cdigo deste captulo pode ser reescrito adicionando os prottipos das funes contidas neles.

Exemplo 34. Vamos reescrever o exemplo 33 utilizando prototipagem de funes:

# include < stdio .h >


# include < stdlib .h >
// Prottipo da funo somar :
int somar ( void ) ;
// Declarando a funo como tipo int , pois retornar um valor
inteiro :
int somar ( void ) {
int a , b , resultado ;
printf ( " Digite um valor inteiro : \ n " ) ;
scanf ( " % d " ,& a ) ;
printf ( " Digite outro valor inteiro : \ n " ) ;
scanf ( " % d " ,& b ) ;
resultado = a + b ;
return ( resultado ) ;
}
int main () {
// Criando uma varivel x , que receber o resultado da
funo somar :
int x ;
x = somar () ;
system ( " cls " ) ;
printf ( " O resultado da soma dos dois valores digitados eh
: % d " ,x ) ;
return 0;
}

4.1.4

Recursividade
Recursividade no um comando, mas um modo de chamar uma funo dentro dela

prpria. um artifcil muito til em alguns casos. Para chamar uma funo desta maneira,
basta utiliz-la como se j tivesse sido criada, escrevendo seu nome e os argumentos entre
parnteses (quando existem).

70

Para entender melhor, vamos ver um exemplo:

Exemplo 35. Criar um programa que construa a sequncia de Fibonacci.


Soluo: Como sabemos, a sequncia de Fibonacci consiste em: o

os termos seguintes so a soma dos dois termos anteriores. Ou seja, o

1+1 = 2

; o

termo a soma de

5, 8, 13, 21, 34, 55, 89,

1 + 2 = 3.

e o

termo a soma de

termos so

Resultando na seguinte sequncia :

1,

1, 1, 2, 3,

... Para criarmos a sequncia vamos utilizar recursividade de funes.

Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int fibonacci ( int t ) {
if ( t == 0 || t == 1) {
return 1;
}
else {
// Utilizando recursividade para calcular os
termos da sequncia :
return ( fibonacci (t -1) + fibonacci (t -2) ) ;
}
}
int main () {
int termo , fibo ;
printf ( " Digite o termo de fibonacci que deseja saber : " ) ;
scanf ( " % d " , & termo ) ;
if ( termo == 0) {
printf ( " Nao existe termo 0!\ n " ) ;
// Utilizando recursividade para chamar a funo
main :
main () ;
}
printf ( " \ nAguarde ! Processando ...\ n " ) ;
fibo = fibonacci ( termo -1) ;
printf ( " O termo % d da sequencia de Fibonacci eh % f .\ n " ,
termo , fibo ) ;
return 0;
}
Ao executar o programa, ir aparecer a mensagem Digite o termo de bonacci que

71

deseja saber:. Digitando

21, 34.

9,

temos que a sequncia at o nono termo :

Ento, aparecer a mensagem O termo

1, 1, 2, 3, 5, 8, 13,

da sequencia de Fibonacci eh

Exemplo 36. Criar um programa que calcule o fatorial de

34..

usando recursividade.

Soluo: Para fazer este cdigo, criaremos uma funo chamada fatorial que vai receber
um nmero do tipo int.

Como sabemos, o fatorial de

e de

igual a

1.

Sendo assim,

precisaremos criar um condicional if para validar o valor digitado pelo usurio no programa,
de modo que se for digitado

ou

a funo retornar1. Caso contrrio faremos o clculo

do fatorial do nmero digitado utilizando recursividade: a funo vai receber o valor digitado
pelo usurio e far com que uma varivel
Ento, enquanto

for maior do que

f at receba o valor resultante de n f atorial(n 1).

a funo vai car se chamando e fazendo o clculo,

sempre subtraindo uma unidade do valor digitado. Vamos ao cdigo:

# include < stdio .h >


# include < conio .h >
// O fatorial tambm pode ser feito utilizando while !
// Funo recursiva que calcula o fatorial de um nmero inteiro n :
int fatorial ( int n ) {
int fat ;
if ( n <= 1 )
// Caso base : fatorial de n <= 1 retorna 1:
return (1) ;
else {
// Chamada recursiva :
fat = n * fatorial ( n - 1) ;
return ( fat ) ;
}
}
int main () {
int n , f ;
printf ( " Digite o numero que deseja calcular o fatorial : " )
;
scanf ( " % d " ,& n ) ;
// Chamando a funo fatorial :
f = fatorial ( n ) ;
printf ( " O fatorial de % d eh %.0 lf " ,n , f ) ;
return 0;
}

72

Ao executar o programa, ir aparecer a mensagem Digite o numero que deseja calcular


o fatorial:. Digitando
O fatorial de

eh

n = 6, temos que 6! = 6 5 4 3 2 1 = 720.

Aparecer a mensagem

720.

4.2 VARIVEIS LOCAIS E VARIVEIS GLOBAIS


Agora que sabemos criar funes, aprenderemos a diferena entre variveis locais
e variveis globais e, com isso, melhorar o desempenho de nossos programas.

Variveis Locais: so aquelas que, uma vez declaradas, s podem ser utilizadas na funo onde esto. Elas s existem quando a funo chamada. At ento ns trabalhamos
apenas com variveis deste tipo.

Variveis Globais: so declaradas como as variveis locais: tipo da varivel seguido


do nome da varivel. A diferena que as declaramos fora de qualquer funo existente
no cdigo.
muito til quando queremos utilizar a mesma varivel em mais de uma funo

dentro do programa, alm de podermos modic-la em qualquer funo. importante tomar


cuidado ao utilizar este tipo de variveis, pois fcil confundir os seus valores nas etapas de
clculo em diferentes funes quando o cdigo muito grande, contendo muitas funes e
variveis.

Exemplo 37. Criar um programa que contenha uma funo que, depois que o usurio digita
o raio de uma circunferncia, incremente o raio para que o comprimento da circunferncia
nova

vezes maior do que a antiga..

Soluo: Vamos usar o raio como uma varivel global no nosso programa. Ento modic-lo
na nossa funo de acordo com a medida do comprimento da circunferncia. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
float r ;
/* Note que a varivel foi criada fora de qualquer funo ,
logo uma varivel global . */
float incrementa () {
float c1 , c2 ;
// Calculando o comprimento da circunferncia de raio r :
c1 = 2 * 3.1415 * r ;
// Encontrando quanto vale 5 vezes o comprimento :
c2 = c1 * 5;

73

// Modificando o valor de r :
r = c2 / (2* 3.1415) ;
return r ;
}
int main () {
float x ;
printf ( " Digite o valor do raio da circunferencia :\ n " ) ;
scanf ( " % f " , & r ) ;
x = incrementa ( r ) ;
printf ( " O raio incrementado vale : % f \ n " , x ) ;
return 0;
}
Ao executar o programa, ir aparecer a mensagem Digite o valor do raio da circunferencia:. Digitando
novo valor de
vale:

3,

ser:

temos que

c1 = 2 3.1415 3 = 18.849

94.245/(2 3.1415) = 15.

c2 = 18.849 5 = 94.245.

Aparecer a mensagem O raio incrementado

15.

4.3 BIBLIOTECA PADRO MATH.H


impportante para um matemtico conhecer a biblioteca padro math.h. Nela existem constantes e funes matemticas que auxiliam muito nos programas.

A seguir

listaremos o que encontramos na biblioteca:

Constantes matemticas: Todas as funes contidas na biblioteca so do tipo double,


o que, como sabemos, aumenta a preciso dos clculos realizados no programa.
tabela 4.1 temos uma descrio das funes e constantes da bilioteca math.h:

74

Na

Tabela 4.1: Biblioteca math.h

Simbologia

O que

Constante em C

Valor da constante

e
log2 e
log10 e
Ln2 (x)
Ln10
(x)
Q

Nmero de Euler

M_E

2,7182818284590452354

Logaritmo de e na base 2

M_LOG2E

1,4426950408889634074

Logaritmo de e na base 10

M_LOG10E

0,43429448190325182765

Logaritmo neperiano binrio

M_LN2

0,69314718055994530942

Logaritmo neperiano ou natural

M_LN10

2,30258509299404568402

Pi

M_PI

3,14159265358979323846

Q
Q /2
/4
q2

Meio Pi

M_PI_2

1,57079632679489661923

Quarto de Pi

M_PI_4

0,78539816339744830962

Raiz quadrada de 2

M_SQRT2

1,41421356237309504880

Raiz quadrada de meio

M_SQRT1_2

0,70710678118654752440

1
2

Funes: Vamos dividi-las em quatro tipos: Trigonomtricas, Logartmicas, Potncias e de Arredondamento.


 Trigonomtricas: Recebem como argumento o valor dos radianos em double.

sin (): Retorna o valor do seno.

cos (): Retorna o valor do co-seno.

tan (): Retorna o valor da tangente.

 Logaritmicas: Exigem como argumento uma varivel do tipo double.

log (): Retorna o valor do logaritmo na base

log10 (): Retorna o valor do logaritmo na base

2.
10.

 Potncias:

pow (): Retorna o valor da base elevada ao expoente. Recebe dois argumentos do tipo double, o primeiro a base e o segundo o expoente.

Exemplo:

pow(2, 10) = 210 = 1024

sqrt (): Retorna o valor da raiz quadrada.

Recebe como argumento um

double do qual ele deve extrair a raiz.


 Arredondamento: Recebem uma varivel do tipo oat como argumento.

ceil (): Retorna o primeiro oat sem casas decimais acima.

Exemplo:

ceil(45.98561) = 46.

oor (): Retorna o primeiro oat sem casas decimais abaixo.

Exemplo:

f loor(45.98561) = 45.

Exerccio 38. Criar um programa que mostra todas estas funes e constantes para melhor
entendimento:

75

# include < stdio .h >


# include < stdlib .h >
# include < math .h >
int main () {
float radianos , raio , expoente , x ;
printf ( " Digite um numero para realizarmos os calculos : \ n
");
scanf ( " % f " , & x ) ;
printf ( " Trigonometria \ nDigite o numero dos radianos :\ n " ) ;
scanf ( " % f " , & graus ) ;
printf ( " Geometria \ nDigite o raio do circulo :\ n " ) ;
scanf ( " % f " , & raio ) ;
printf ( " Potenciacao \ nDigite o expoente : \ n " ) ;
scanf ( " % f " , & expoente ) ;
system ( " cls " ) ;
// Funes trigonomtricas :
printf ( " O seno de % f eh : % f \ n " , radianos , sin ( radianos ) ) ;
printf ( " O co - seno de % f eh : % f \ n " , radianos , cos ( radianos
));
printf ( " A tangente de % f eh : % f \ n " , radianos , tan (
radianos ) ) ;
// Potncias :
printf ( " % f elevado a % f eh : % f \ n " , x , expoente , pow (x ,
expoente ) ) ;
printf ( " A raiz quadrada de % f eh : % f \ n " , x , sqrt ( x ) ) ;
// Funes Logartmicas :
printf ( " O log2 de % f eh : % f \ n " , x , log ( x ) ) ;
printf ( " O log10 de % f eh : % f \ n " , x , log10 ( x ) ) ;
// Funes de arredondamento :
printf ( " O teto de % f eh : % f \ n " , x , ceil ( x ) ) ;
printf ( " A parte inteira de % f eh : % f \ n " , x , floor ( x ) ) ;
// Funes geomtricas :
printf ( " Um circulo com % f cm de raio tem : % f cm de
comprimento " , raio , raio *2* M_PI ) ;
printf ( " e % f de area .\ n " , pow ( raio ,2) * M_PI ) ;
return 0;
}
76

Ao ser executado, o programa ir solicitar um nmero, radianos, raio e um expoente.

2, 0, 9 e 3, respectivamente, temos que sen(90) = 0, cos(90) = 1, tan(90) = 0,

x = 2 = 8, 2 = 1.414214, log2 2 = 0.693147, log10 2 = 0.301030, arredondando x

Digitando

pra cima ca

92

2,

parte inteira de

= 56.548668

e rea igual a

e um crculo com raio

tem comprimento igual a

9 = 254.469005.

Exemplo 39. Criar um programa que calcule a norma de um vetor digitado pelo usurio.
Soluo: J aprendemos a preencher um vetor no exemplo

21.

Para calcular a norma, vamos

utilizar as funes pow e sqrt da biblioteca math.h. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
# include < math .h >
int main () {
int v [3] , i ;
float norma ;
// Preenchendo o vetor utilizando o operador for :
for ( i = 0; i < 3; i ++) {
printf ( " Digite o valor da posicao % d do vetor :\ n
" , i +1) ;
scanf ( " % d " ,& v [ i ]) ;
}
// Calculando a norma do vetor :
norma = sqrt ( pow ( v [0] ,2) + pow ( v [1] ,2) + pow ( v [2] ,2) ) ;
printf ( " \ nA norma do vetor digitado eh : %.3 f " , norma ) ;
return 0;
}
Ao ser executado, o programa ir solicitar que o usurio preencha impute um vetor

v = (1, 2, 3), temos


p
p

(1)2 + (2)2 + (3)2 = (1) + (4) + (9) = 14 = 3.742. Aparecer

para fazer o clculo da norma. Digitando valores para construir o vetor


que a sua norma vale

a mensagem A norma do vetor digitado eh:

3.742.

Exemplo 40. Criar um programa que encontra as razes de uma equao do segundo grau.
Soluo: Para encontrar as razes vamos utilizar a Frmula de Bhaskara:

x=

b-4ac
2a

Para isto criaremos uma funo chamada bhaskara que ter um if/else que ir vericar
o resultado de

4 = b-4ac:

caso seja

<0

aparecer uma mensagem dizendo que a equao

77

no possui razes reais, caso seja

= 0 ou > 0, ir calcular utilizando a frmula acima e mostrar

a(s) razes para o usurio. Vamos declarar todas as variveis deste programa como variveis
globais. Na funo principal vamos pedir para que o usurio digite os coecientes da equao
do

grau e chamar a funo bhaskara. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
# include < math .h >
float a , b , c , x [2];
void bhaskara () {
float t ;
// Fazendo t = b ^2 -4 ac :
t = ( pow (b ,2) ) -(4* a * c ) ;
// Caso t =0: x = - b /2 a :
if ( t == 0.00000) {
x [0] = ( - b ) /(2* a ) ;
printf ( " A equaao possui apenas uma raiz , que eh :
% f \ n " ,x [0]) ;
}
// Caso t <0: a equao no possui razes reais :
else if ( t < 0.00000) {
printf ( " A equaao nao possui raizes reais !\ n " ) ;
}
// Caso x >0: x0 =( - b + sqrt ( t ) ) /2 a e x0 =( -b - sqrt ( t ) ) /2 a :
else {
x [0] = ( - b + sqrt ( t ) ) /(2* a ) ;
x [1] = ( - b - sqrt ( t ) ) /(2* a ) ;
printf ( " As raizes da equacao digitada sao : % f e %
f \ n " , x [0] , x [1]) ;
}
}
int main () {
printf ( " Digite o coeficiente que acompanha o x ^2 ( a ) :\ n \ n
");
scanf ( " % f " , & a ) ;
printf ( " Digite o coeficiente que acompanha o x ( b ) :\ n \ n " )
;
scanf ( " % f " , & b ) ;
printf ( " Digite o coeficiente independente ( c ) :\ n \ n " ) ;
scanf ( " % f " , & c ) ;

78

system ( " cls " ) ;


bhaskara () ;
return 0;
}
Ao ser executado, o programa ir solicitar os valores
grau

a, b

da equao do segundo

a x + b x + c = 0.
Digitando

como

= 0,

1, 2 e 1 (1 x2 + 2 x + 1 = 0), temos que = 22 4 1 1 = 4 4 = 0,

a equao possui apenas uma raiz, que vale

mensagem A equaao possui apenas uma raiz, que eh:


Digitando
como

x =

2
2

= 1.

Aparecer a

1.

1, 1 e 1 (1 x + 1 x + 1 = 0), temos que = 12 4 1 1 = 1 4 = 3,

< 0, a equao no possui razes reais.

Aparecer a mensagem A equaao nao possui

raizes reais!.
Digitando
como

2, 1 e 0 (2 x2 + 1 x + 0 = 0), temos que = 12 4 2 0 = 1 0 = 1,

> 0, a equao possui duas razes, que valem x1 =

Aparecer a mensagem As raizes da equacao digitada sao:

1+ 1
2

= 0 e x1 =

0.5

1 1
2

= 0.5.

.

Exemplo 41. Criar um programa que aplique o Mtodo de Newton [10] para a funo

f (x) = x2 2 x + 1,

sendo

a raiz de

f (x) = 0

(conrmar no exerccio

40).

Lembrando: o

Mtodo de Newton estima os zeros de uma funo, aproximando=os com a seguinte iterao:

xn+1 = xn
Com

f (xn )
f 0 (xn )

x0 dado.

Soluo: Vamos criar uma varivel de comparao (tol) que servir para nalizar o while.
Deixaremos ele xo neste cdigo em

0.00001, mas podemos utilizar printf e scanf para solicitar

ao usurio escolher o valor de validao. Criaremos tambm uma funo que deriva
e outra que calcula o valor no ponto digitado pelo usurio. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
# include < math .h >
// Funo que calcula fx :
double fx1 ( double x ) {
double f1 ;
f1 = pow (x ,2) -(2* x ) +1;
return ( f1 ) ;
}
// Funo que calcula dfx :
double dfx ( double x ) {
double dfx ;
79

x2 2x+1

dfx =(2* x ) -2;


return ( dfx ) ;
}
void newton () {
double fx , fdx , xo , tol , x , a , b ;
tol = 0.00001;
/* Pedindo para que o usurio digite o valor de a e b ,
de onde calcularemos o ponto mdio x0 para iniciar as
iteraes : */
printf ( " \ n Digite o valor de a :\ n " ) ;
scanf ( " % lf " ,& a ) ;
printf ( " \ n Digite o valor de b :\ n " ) ;
scanf ( " % lf " ,& b ) ;
xo =( a + b ) /2;
// Chamando as funes fx e dfx :
fx = fx1 ( xo ) ;
fdx = dfx ( xo ) ;
// While para fazer os clculos at que fabs ( fx ) seja
menor do que tol :
while ( fabs ( fx ) > tol ) {
x = xo -( fx / fdx ) ;
if ( fabs ( fx ) < tol ) {
printf ( " \ n xo eh raiz % lf \ n " ,x ) ;
}
else {
xo = x ;
fx = fx1 ( xo ) ;
fdx = dfx ( xo ) ;
}
printf ( " % f \ n " , x ) ;
}
printf ( " \ n A raiz eh aproximadamente : % lf .\ n " ,x ) ;
}
// Funo principal :
int main () {
newton () ;
return 0;
}

80

Ao ser executado, o programa ir solicitar os valores


programa far com que a varivel x assuma os valores:

1.015625, 1.007813, 1.003906, 1.001953,


0.00001

da raiz de

x 2 x + 1 = 0.

b.

Digitando

4,

2, 1.5, 1.25, 1.125, 1.0625, 1.03125,

sendo este ltimo a aproximao com tolerncia de

Aparecer a mensagem A raiz eh aproximadamente:

1.001953..
Exemplo 42. O ltimo Teorema de Fermat: Todo aluno do curso de matemtica deve
ter pelo menos ouvido sobre tal teorema que Pierre Fermat [7] enunciou e deixou, em uma
pgina de livro a seguinte observao: Eu descobri uma demonstrao maravilhosa, mas a
margem deste papel muito pequena para cont-la . A demonstrao s foi feita em 1995,
por Andrew Wiles, utilizando conhecimentos matemticos que na poca em que Fermat era
vivo ainda no tinham sido descobertos, o que leva muitos matemticos a duvidarem de que
Fermat realmente tinha demonstrado seu teorema, que diz que o Teorema de Pitgoras
(quadrado da hipotenusa igual soma do quadrado dos catetos) no vale para
,

x +y = z

no possui soluo para

n > 2.

n > 2.

Isto

Vamos construir um programa que verica

se o teorema vlido para combinaes destas variveis at

com a potncia digitada pelo

usurio.

Soluo: Para este cdigo vamos criar uma funo chamada fermat que receber um valor

n,

digitado pelo usurio, e ir variar os coecientes

utilizar o operador for onde ir de

at

5.

x, y

z.

Para fazer tal variao vamos

Para vericar se o teorema vale para o caso

apresentado criaremos uma varivel local do tipo int chamada


igualdade

x +y = z

valer, ser diferente de

0,

dentro da funo e, se a

caso contrrio ser

0.

Ento, caso

seja

o teorema ser vlido, e caso contrrio no ser vlido. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
# include < math .h >
int fermat ( int n ) {
int x , y , z , r = 0;
long int a , b , c , d ;
system ( " cls " ) ;
// Variando os valores de x , y e z de 1 at 5:
for ( x = 1; x <= 5; x ++) {
for ( y = 1; y <= 5; y ++) {
for ( z = 1; z <= 5; z ++) {
a = pow (x , n ) ;
b = pow (y , n ) ;
c = pow (z , n ) ;
d = a + b;
printf ( " x ^2+ y ^2:
z ^2 " ) ;
printf ( " % d
% d \ n " ,d , c ) ;
81

// Somando uma unidade a varivel r caso d


=c:
if ( d == c ) {
r ++;
}
}
}
}
return r ;
}
int main () {
int n , resposta ;
printf ( " Vamos confirmar o ultimo Teorema de Fermat " ) ;
printf ( " x ^ n + y ^ n = z ^ n nao vale para n >2 " ) ;
printf ( " variando os coeficientes ate 5\ n \ n " ) ;
printf ( " Digite o valor da potencia n maior do que 2:\ n " ) ;
scanf ( " % d " , & n ) ;
resposta = fermat ( n ) ;
if ( resposta > 0) {
printf ( " O Ultimo Teorema de Fermat nao eh " ) ;
printf ( " valido para a situacao proposta " ) ;
}
else {
printf ( " O ultimo Teorema de Fermat eh valido para
a situacao proposta " ) ;
}
return 0;
}
Ao executar o programa, ir aparecer a mensagem Digite o valor da potencia
do que

2:.

O programa far os clculos e mostrar na tela os valores de

x +y

n maior
e de

z2.

Alm disso aparecer ao nal a mensagem: O Ultimo Teorema de Fermat nao eh valido para
a situacao proposta.
Observao. Perceba que este programa no demonstra o teorema, mas verica se ele vlido
para casos particulares. Ele tambm no funciona se o usurio digitar valores muito grandes
para

n, isto se deve ao fato de os resultados dos clculos se tornaro muito altos e uma varivel

do tipo long int no possui memria o suciente para tal.

82

4.4 STRUCTS
As estruturas de dados (Structs) consistem em criar apenas um dado que contm
vrios membros, que nada mais so do que outras variveis. Em outras palavras, uma varivel
que contm um grupo de outras variveis. A vantagem em se usar estruturas de dados que
podemos agrupar de forma organizada vrios tipos de dados diferentes, por exemplo, dentro
de uma estrutura de dados podemos ter juntos tanto um tipo oat, um inteiro, um char ou um
double. Matematicamente falando, podemos guardar dentro de uma s varivel coordenadas
de pontos, retas, planos, polgonos, dentre outros.
As variveis que cam dentro da estrutura de dados so chamadas de membros.

Sintaxe:

struct nome_da_estrutura {
tipo_de_dado nome_do_membro ;
tipo_de_dado nome_do_membro ;
};

Alguns pontos a ressaltar:


 Os membros de uma struct so declarados um por linha, mesmo que sejam do
mesmo tipo;

 Aps nalizar a denio dos membros no bloco de dados, terminamo a linha com
um ponto-e-vrgula ( ; ).

 Para declarar uma varivel de tipo estrutura basta digitar o nome da estrutura
como tipo de varivel.

struct nome_da_struct nome_da_variavel;

Exemplo 43. Criar uma estrutura chamada pontos, onde sero guardados dois membros do
tipo inteiro: coordenada x e coordenada y.

struct pontos {
int x ;
int y ;
};

4.4.1

Acessando os membros de uma estrutura


Quando criamos uma estrutura de dados com struct, podemos utiliz-la como um

tipo de dado (ex.:

oat, int).

Para acessar seus membros utilizamos a varivel declarada

seguida de um ponto (.) e o nome do membro. Vamos utilizar o struct criado no exemplo
anterior para exemplicar.

83

Exemplo 44. Criar um programa que, dados dois pontos, calcule a distncia entre eles.
Soluo: Para resolver este programa vamos, primeiramente, utilizar a estrutura do exemplo

42

chamada pontos.

Vamos declarar duas variveis do tipo struct, acessar seus membros,

povo-los e ento calcular a distncia entre estes dois pontos utilizando as funes da biblioteca
math.h para realizar os clculos.

# include < stdio .h >


# include < stdlib .h >
# include < math .h >
struct pontos {
int x ;
int y ;
};
int main () {
// Declarando varivel do tipo float :
float a ;
// Declarando varivel do tipo pontos chamada
2:
struct pontos pontos [2];

de tamanho

/* Note que o scanf identico para structs , a diferena


que temos que acessar cada membro separadamente . */
printf ( " Digite a coordenada x do primeiro ponto : \ n " ) ;
scanf ( " % d " , & pontos [1]. x ) ;
printf ( " Digite a coordenada y do primeiro ponto : \ n " ) ;
scanf ( " % d " , & pontos [1]. y ) ;
printf ( " Digite a coordenada x do segundo ponto : \ n " ) ;
scanf ( " % d " , & pontos [2]. x ) ;
printf ( " Digite a coordenada y do segundo ponto : \ n " ) ;
scanf ( " % d " , & pontos [2]. y ) ;
// Limpando a tela :
system ( " cls " ) ;
a = sqrt ( pow (( pontos [1]. x - pontos [2]. x ) ,2) + pow (( pontos [1]. y pontos [2]. y ) ,2) ) ;
/* Calculando a distncia entre os dois pontos
de coordenadas digitadas pelo usurio : */
printf ( " A distancia entre os dois pontos das " ) ;
printf ( " coordenadas escolhidas eh :\ n % f " , a ) ;
return 0;
}

84

Ao ser executado, o programa ir solicitar que o usurio informe as coordenadas de


dois pontos (x1 ,y1 ) e (x2 ,y2 ).
pontos dada por:

2.236068.
eh:

Digitando 1, 1, 3 e 0, temos que a distncia entre os dois


p
p

(x1 x2 ) + (y1 y2 ) = (1 3) + (1 0) = 4 + 1 = 5 =

Aparecer a mensagem A distancia entre os dois pontos de coordenadas escolhidas

2.236068..

Para passar struct como referncia para uma funo usa-se a seguinte sintaxe:

nome_da_struct * nome_da_variavel
Exemplo 45. Vamos usar a struct pontos criada no exemplo anterior sendo passada como
referncia em uma funo chamada calcula:

# include < stdio .h >


# include < stdlib .h >
# include < math .h >
// Struct pontos contendo duas variveis do tipo int :
struct pontos {
int x ;
int y ;
} pontos ;
// Prototipando a funo calcula :
void calcula ( struct pontos * pontos ) ;
// Funo calcula , que calcula a distncia entre dois pontos :
void calcula ( struct pontos * pontos ) {
float a ;
a = sqrt ( pow (( pontos [1]. x - pontos [2]. x ) ,2) + pow (( pontos [1].
y - pontos [2]. y ) ,2) ) ;
printf ( " A distancia entre os dois pontos das " ) ;
printf ( " coordenadas escolhidas eh :\ n % f " , a ) ;
}
int main () {
struct pontos pontos [2];
// Preenchendo os pontos :
printf ( " Digite a coordenada
scanf ( " % d " , & pontos [1]. x ) ;
printf ( " Digite a coordenada
scanf ( " % d " , & pontos [1]. y ) ;
printf ( " Digite a coordenada
scanf ( " % d " , & pontos [2]. x ) ;
printf ( " Digite a coordenada
scanf ( " % d " , & pontos [2]. y ) ;

85

x do primeiro ponto : \ n " ) ;


y do primeiro ponto : \ n " ) ;
x do segundo ponto : \ n " ) ;
y do segundo ponto : \ n " ) ;

// Chamando a funo calcula , onde passamos a struct


pontos como referncia :
calcula (& pontos ) ;
return 0;
}

4.4.2

Typedef
Em C podemos redenir um tipo de dado, dando-lhe um novo nome. Isto muito

til quando queremos referenciar uma estrutura dentro de outra.


Para fazer esta redenio utilizamos o typedef, que faz com que o compilador assuma que um novo nome um determinado dado e passe a usar tal nome substituindo o antigo.
Por exemplo, poderamos utilizar o typedef para denir que, ao invs de int, chamaremos este
tipo de varivel de inteiro.

Sintaxe:

typedef nome_antigo nome_novo ;


Typedef deve vir sempre antes de qualquer programao que envolva procedimentos,
isto , logo aps o pr-processamento.

Exemplo 46. Criar um programa que usa typedef para denir int como inteiro e oat como
utuante:

# include < stdio .h >


# include < stdlib .h >
// Definindo int como inteiro e float como flutuante usando
typedef :
typedef int inteiro ;
typedef float flutuante ;
int main () {
inteiro x = 2;
flutuante y = 4.2;
printf ( " x = % d e y = % f " , x , y ) ;
return 0;
}
Para usar typedef em structs tem duas maneiras:

1 - Denir o nome da estrutura no nal:

86

Sintaxe:

typedef struct nome_da_estrutura novo_nome_da_estrutura ;


2 - Denir a estrutura junto com o nome:

Sintaxe:

typedef struct nome_da_estrutura {


} novo_nome_da_estrutura ;

4.5 PONTEIROS
Ponteiros um assunto extremamente complexo e que pode levar o programador a
cometer vrios erros em seus programas, que podem at danicar o computador [3]. Sendo
assim, vamos trabalhar apenas alguns tpicos do contedo que sero o suciente para fazermos
nossos programas.
Quando declaramos uma varivel de qualquer tipo, ela recebe um endereo de memria, que o local onde ela est armazenada na memria do computador. Um ponteiro , em
poucas palavras, uma varivel que aponta para um endereo de memria do seu computador.
Com isto os programas tornam-se mais ecientes, pois estamos trabalhando diretamente com
a memria do computador.

4.5.1

Declarao e Manipulao de Ponteiros


Um ponteiro tem um tipo assim como uma varivel normal, mas sua declarao

precedida de um asterisco (*). importante ter ateno ao declarar vrios ponteiros em uma
nica linha, pois cada uma precisa ter um asterisco para ser declarada corretamente.

Sintaxe:

tipo_do_ponteiro * nome_do_ponteiro ;
Exemplo 47. Alguns exemplos de ponteiros:

# include < stdio .h >


# include < stdlib .h >
// ponteiro apontando para int :
int * a ;
// ponteiro vazio :
int * b = NULL ;
// ponteiro para char :
char * c ;
// ponteiro para float :
float * d ;
87

Como j sabemos, a funo do ponteiro apontar.

O que o torna til que ele

pode apontar para endereos de memria de variveis j existentes no programa e, assim,


modic-las.
Existem dois operadores especiais para ponteiros: * e &.

& um operador que devolve o endereo de memria do seu operando;

* um operador que devolve o valor da varivel localizada no endereo que o segue;

Observao. A mscara de dados %p usada para trabalhar com ponteiros.

Exemplo 48. Criar um programa que utiliza os dois operadores acima:

# include < stdio .h >


# include < stdlib .h >
int main () {
int c = 0 , * a ;
// Fazendo o ponteiro a apontar para a varivel c :
a = &c;
printf ( " O valor de a eh : % p " , a ) ;
printf ( " O endereco de memoria de a eh : % p " , & a ) ;
printf ( " O valor de c eh : % p " , * a ) ;
return 0;
}
Perceba que no atribumos qualquer valor para a varivel

a,

isto faz com que o

resultado do primeiro printf seja o endereo de memria dela.

Exemplo 49. Criar um programa que exemplica manipulao de ponteiros.

# include < stdio .h >


# include < stdlib .h >
// Criando duas variveis : a do tipo int e b um ponteiro int :
int a ;
int * b ;
int main () {
/* Neste momento , o ponteiro est apontando para um
endereo de memria do tamanho de uma varivel do tipo
int . */
// Mostrando o endereo de memria que o ponteiro b est
apontando :
88

printf ( " Endereco de memoria do ponteiro b : % d \ n " ,& b ) ;


/* Fazendo o ponteiro apontar para a varivel a ,
a qual vamos atribuir um valor : */
a = 10;
b = &a;
printf ( " Valor do ponteiro b apos apontar para a : % d \ n " ,* b
);
// Modificando o valor da varivel a :
* b = 20;
printf ( " Valor de a depois de ser modificado : % d \ n " , a ) ;
return 0;
}
Observao. Cuidado para no atribuir valores para ponteiros sem antes ter certeza de que o
endereo de memria conhecido.

int x ;
int * y ;
x = 10;
* y = 15
O valor
o ponteiro

15

est em qual endereo? Ele est no endereo de memria que

est apontando, mas no sabemos qual este endereo. Ento importante ter

muito cuidado ao manipular ponteiros nos programas, pois podemos mudar valores de variveis
que podem danicar o computador.
Observao. O operador * igual ao de multiplicao. Ento bom tomar cuidado ao utilizlo.

4.5.2

Aritmtica de ponteiros
Existem duas expresses que podem ser usadas quando se trabalha com ponteiros:

subtrao (decremento) e adio (incremento). Quando incrementamos um ponteiro, ele


passa a apontar para a prxima varivel do tipo que ele aponta, o que anlogo para o
decremento.

Isto pode ser feito de duas maneiras:

utilizando os operadores ++ e  ou

somando/subtraindo inteiros de ponteiros.

Exemplo 50. Criar um programa que utiliza aritmtica de ponteiros:

# include < stdio .h >


# include < stdlib .h >
int main () {
int * a ;
89

printf ( " O endereo de a eh : % p \ n " , a ) ;


// Incrementando o endereo de a :
a = a ++;
printf ( " O novo endereo de a eh : % p \ n " , a ) ;
// Subtraindo 20 unidades de a :
a = a -20;
printf ( " O novo endereo de a eh : % p \ n " , a ) ;
return 0;
}
Perceba que, a cada printf, mostrado um endereo de memria diferente. Isto quer
dizer que o ponteiro

a est apontando para lugares dirferentes a cada incremento/decremento.

Observao. No podemos somar ou subtrair valores do tipo oat ou double a ponteiros;


No possvel multiplicar ou dividir ponteiros;

4.5.3

Alocao dinmica de memria


Muitas vezes no sabemos a quantidade de memria que uma determinada varivel

resposta de um programa vai precisar.

Para resolver este problema utilizamos de alocao

dinmica de memria, que consiste em reservar espaos de memria de tamanhos arbitrrios


e acess-los atravs de ponteiros. Para isto utilizaremos duas funes que se encontram na

biblioteca stdlib.h: malloc e free.

4.5.3.1

Funo malloc
Funo que reserva um bloco consecutivo de bytes na memria e retorna o seu en-

dereo. Para isto precisamos denir o tamanho que desejamos. Como o nosso parmetro de
medida em programao o tamanho de cada tipo de varivel em byte, utilizamos o operador

sizeof com a seguinte sintaxe:

Sintaxe:

sizeof ( tipo_de_variavel ) ;
No quer dizer que o tipo de varivel que colocamos o operador sizeof ser utilizada
no programa. O espao alocado pela funo malloc pode armazenar qualquer tipo de varivel.

Sintaxe:

malloc ( tamanho ) ;
Um ponto importante que esta sintaxe do tipo void, mas a funo malloc pode
alocar qualquer tipo de dado. Para isto, precisamos fazer com que um ponteiro, com tipo j
denido, receba o endereo. Deste modo, a sintaxe ca da seguinte maneira:

90

Sintaxe:

( tipo_de_variavel *) malloc ( tamanho ) ;


Exemplo:

( int *) malloc (2) ;


( float *) malloc ( n * sizeof ( float ) ) ;
Exemplo 51. Vamos exercitar um pouco alocao dinmica de memria utilizando a funo
malloc.

# include < stdlib .h >


int * a ;
a = malloc (1) ;
int * b ;
b = malloc (50* sizeof ( float ) ) ;
Primeiramente ns alocamos1 byte e, em seguida, alocamos

50

vezes o tamanho de

uma varivel do tipo oat.

4.5.3.2

Funo free
Funo que libera o espao reservado pela funo malloc.

Sintaxe:

free ( nome_da_variavel ) ;
O nome da variavel deve ser o mesmo endereo retornado pela funo malloc.

Exemplo 52. Criar um programa que aloca memria para um vetor de tamanho
vamos alocar int

n.

Isto ,

vezes o

a[n].

Soluo: Para fazer este programa utilizaremos a funo malloc alocando


tamanho de uma varivel do tipo int. Sendo que o

ser digitado pelo usurio como sendo

o tamanho do vetor. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
// Declarando um ponteiro
int * a ;
int n , i ;

do tipo int :

int main () {
printf ( " digite o tamanho do vetor :\ n " ) ;
scanf ( " % d " , & n ) ;
91

// Alocando um tamanho para o vetor a de modo dinmico :


a = malloc ( n * sizeof ( int ) ) ;
if ( a == NULL ) {
printf ( " Memoria insuficiente .\ n " ) ;
return 1;
}
// Preenchendo o vetor utilizando for :
for ( i = 0; i < n ; i ++) {
printf ( " Digite o valor da posiao % d :\ n " , i ) ;
scanf ( " % d " , & a [ i ]) ;
}
// Liberando o espao a memria que foi alocada :
free ( a ) ;
return 0;
}
Neste programa tem um vericador if muito til:

if ( a == NULL ) {
printf ( " Memoria insuficiente .\ n " ) ;
return 1;
}
Este vericador serve para vericar se deu certo a alocao de memria do nosso
vetor. Quando no d certo, a funo malloc retorna NULL. E, caso acontea isto, aparecer
uma mensagem na tela para o usurio ter conhecimento. bom manter a prtica de adicionar
este vericador nos programas que utilizam a funo malloc para previnir problemas futuros.

Exemplo 53. Criar um programa que calcule a norma innita de um vetor de tamanho n.
Lembrando:

kxk = m
ax{|xi | , i = 1, 2, ..., n}
Soluo: Para fazer este programa criaremos, na funo principal, um ponteiro
do tipo int, de tamanho

x,

digitado pelo usurio, que ter sua memria alocada utilizando a

funo malloc. Este ponteiro receber os valores do vetor que sero digitados pelo usurio.
Feito isto chamaremos a funo normainf, que ir igualar a varivel
valor de
ento

x[0],

norma,

ento ser feito um vericador para cada posio do vetor: se

|x[i]| = norma.

do tipo int, ao

|x[i]| > norma,

Ento ser mostrado para o usurio a norma innita do vetor. Vamos

ao cdigo:

# include < stdio .h >


# include < stdlib .h >

92

// Declarando variveis globais :


int *x , n ;
// Funo normainf do tipo void :
void normainf () {
// Declarando variveis locais :
int i , norma , a ;
// Calculando a norma infinita do vetor digitado :
norma = abs ( x [0]) ;
for ( i = 1; i < n ; i ++) {
a = abs ( x [ i ]) ;
if ( a > norma ) {
norma = a ;
}
}
// Mostrando a norma infinita do vetor para o usurio :
printf ( " A norma infinita do vetor digitado eh : % d " , norma
);
}
// Funo principal :
int main () {
// Declarando varivel local :
int i ;
// Pedindo para que o usurio digite o tamanho do vetor :
printf ( " Digite o tamanho do vetor : \ n " ) ;
scanf ( " % d " ,& n ) ;
// Alocando memria dinamicamente para o ponteiro x :
x = ( int *) malloc ( n * sizeof ( int ) ) ;
if ( x == NULL ) {
printf ( " Memoria insuficiente .\ n " ) ;
return 1;
}
// Preenchendo o vetor utilizando for :
for ( i = 0; i < n ; i ++) {
printf ( " Digite um valor inteiro para a posicao % d
:\ n " , i +1) ;
scanf ( " % d " , & x [ i ]) ;
}
// Limpando a tela :
system ( " cls " ) ;

93

// Chamando a funo normainf :


normainf () ;
// Liberando a memria alocada para o ponteiro x :
free ( x ) ;
return 0;
}
Ao ser executado, o programa ir solicitar que o usurio informe o tamanho do vetor,
digitando

4,

o programa pedir para que sejam digitados valores para as posies

do vetor. Digitando

2, 4, 8

6,

norma innita do vetor digitado eh:

temos que

kxk = 8.

1, 2, 3

Ento aparecer a mensagem A

8.

Exemplo 54. Criar um programa que calcule a norma

de um vetor de tamanho

n.

Lembrando:

kxk1 =

qX

|xi |, i = 1, ..., n

Soluo: Para fazer este programa criaremos, na funo principal, um ponteiro


tipo int, de tamanho
malloc.

x, do

n digitado pelo usurio, que ter sua memria alocada utilizando a funo

Este ponteiro receber os valores do vetor que sero digitados pelo usurio.

Feito

isto chamaremos a funo norma1, que ir fazer o somatrio do mdulo de cada elemento do
vetor (ver exemplo

22),

ento ser calculada a raiz quadrada do somatrio. Feito isto ser

mostrado para o usurio a norma 1 do vetor.

# include < stdio .h >


# include < stdlib .h >
# include < math .h >
// Declarando variveis globais :
int *x , n ;
// Funo norma1 do tipo void :
void norma1 () {
// Declarando variveis locais :
int i , norma = 0;
// Calculando a norma1 do vetor digitado :
for ( i = 0; i <n ; i ++) {
norma = norma + abs ( x [ i ]) ;
}
printf ( " A norma 1 do vetor digitado eh : % lf " , sqrt ( norma )
);
}
// Funo principal :
int main () {
94

// Declarando varivel local :


int i ;
// Pedindo para o usurio digitar o tamanho do vetor :
printf ( " Digite o tamanho do vetor : \ n " ) ;
scanf ( " % d " ,& n ) ;
// Alocando memria para o ponteiro x :
x = ( int *) malloc ( n * sizeof ( int ) ) ;
if ( x == NULL ) {
printf ( " Memoria insuficiente .\ n " ) ;
return 1;
}
// Preenchendo o vetor utilizando for :
for ( i = 0; i < n ; i ++) {
printf ( " Digite um valor inteiro para a posicao % d
:\ n " , i +1) ;
scanf ( " % d " , & x [ i ]) ;
}
// Limpando a tela :
system ( " cls " ) ;
// Chamando a funo norma1 :
norma1 () ;
// Liberando a memria alocada para o vetor x :
free ( x ) ;
return 0;
}
Ao ser executado, o programa ir solicitar que o usurio informe o tamanho do vetor,
digitando

3,

o programa pedir para que sejam digitados valores para as posies

vetor. Digitando

4, 2

a mensagem A norma

3,

temos que

kxk1 = |4| + |2| + |3|= 9 = 3.

do vetor digitado eh:

1, 2

do

Ento aparecer

3.00000.

Exemplo 55. Criar um programa que calcule a norma

de um vetor de tamanho

n.

Lembrando:

kxk2 =

qX

x2i , i = 1, ..., n

Soluo: Para fazer este programa criaremos, na funo principal, um ponteiro


do tipo int, de tamanho

x,

digitado pelo usurio, que ter sua memria alocada utilizando a

funo malloc. Este ponteiro receber os valores do vetor que sero digitados pelo usurio.
Feito isto chamaremos a funo norma2, que ir fazer o somatrio de cada elemento do vetor

95

elevado ao quadrado (ver exemplo

22),

ento ser calculada a raiz quadrada do somatrio.

Feito isto ser mostrado para o usurio a norma 2 do vetor.

# include < stdio .h >


# include < stdlib .h >
# include < math .h >
// Declarando variveis globais :
int *x , n ;
// Funo norma2 do tipo void :
void norma2 () {
// Declarando variveis locais :
int i , norma = 0;
// Calculando a norma 2 do vetor digitado :
for ( i = 0; i <n ; i ++) {
norma = norma + pow ( x [ i ] ,2) ;
}
printf ( " A norma 2 do vetor digitado eh : % lf " , sqrt ( norma )
);
}
// Funo principal :
int main () {
// Declarando varivel local :
int i ;
// Pedindo para o usurio digitar o tamanho do vetor :
printf ( " Digite o tamanho do vetor : \ n " ) ;
scanf ( " % d " ,& n ) ;
// Alocando memria para o ponteiro x :
x = ( int *) malloc ( n * sizeof ( int ) ) ;
if ( x == NULL ) {
printf ( " Memoria insuficiente .\ n " ) ;
return 1;
}
// Preenchendo o vetor utilizando for :
for ( i = 0; i < n ; i ++) {
printf ( " Digite um valor inteiro para a posicao % d
:\ n " , i +1) ;
scanf ( " % d " , & x [ i ]) ;
}
// Limpando a tela :
system ( " cls " ) ;
96

// Chamando a funo norma2 :


norma2 () ;
// Liberando a memria alocada para o ponteiro x :
free ( x ) ;
return 0;
}
Ao ser executado, o programa ir solicitar que o usurio informe o tamanho do vetor,
digitando

3,

vetor. Digitando

3.74165.

1, 2 e 3 do
p

2
2
kxk2 = 3 + 1 + (2)= 9 + 1 + 4 = 14 =

o programa pedir para que sejam digitados valores para as posies

3, 1

2,

temos que

Ento aparecer a mensagem A norma

do vetor digitado eh:

3.74165.

Exemplo 56. Criar um programa que calcule o valor numrico de um polinmio


grau

n,

p(x),

de

preenchido pelo usurio.

Soluo: Para fazer este programa criaremos dois vetores,


de tamanho

n,

pol

aux,

que tero suas memrias alocadas com a funo malloc.

do tipo oat,

O vetor

pol

ser

preenchido com os coecientes do polinmio digitados pelo usurio. Criaremos uma funo
chamada polinomio que preencher o vetor

com a seguinte regra:

aux(i) = pol(i) xi ,

isto , o valor de

somatrio do vetor

aux (ver exemplo 22), resultando no valor numrico do polinmio para um

valor

elevado a

aux

vezes o coeciente, para

i = 0, ..., n.

Ento faremos um

digitado pelo usurio. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
# include < math .h >
// Declarando variveis globais :
int n ;
float * pol , * aux ;
// Funo polinomio do tipo void :
void polinomio () {
// Declarando variveis locais :
int i ;
float resultado , x ;
// Pedindo para o usurio digitar o valor de x :
printf ( " Digite o valor de x :\ n " ) ;
scanf ( " % f " , & x ) ;
// Preenchendo o vetor aux :
for ( i = n ; i >=0; i - -) {
aux [ i ] = pol [ i ] * pow (x , i ) ;
}
97

// Fazendo o somatrio do vetor aux :


resultado = aux [0];
for ( i = 1; i <= n ; i ++) {
resultado = resultado + aux [ i ];
}
// Mostrando o resultado para o usurio :
printf ( " O valor numerico do polinomio " ) ;
printf ( " para x = % f eh : % f .\ n " , x , resultado ) ;
}
// Funo principal :
int main () {
// Declarando varivel local :
int i ;
// Pedindo para o usurio digitar o grau do polinmio :
printf ( " Digite o grau do polinomio : \ n \ n " ) ;
scanf ( " % d " ,& n ) ;
// Alocando memria para os ponteiros pol e aux :
pol = ( float *) malloc ( n * sizeof ( float ) ) ;
aux = ( float *) malloc ( n * sizeof ( float ) ) ;
// Verificador de erro da alocao dinmica :
if ( pol == NULL || aux == NULL ) {
printf ( " Memoria insuficiente .\ n " ) ;
return 1;
}
// Preenchendo o vetor utilizando for :
for ( i = n ; i >= 0; i - -) {
printf ( " Digite o coeficiente de grau % d :\ n " , i ) ;
scanf ( " % f " , & pol [ i ]) ;
}
// Limpando a tela :
system ( " cls " ) ;
// Chamando a funo polinomio :
polinomio () ;
// Liberando a memria alocada para os ponteiros pol e aux
:
free ( pol ) ;
free ( aux ) ;
return 0;
98

}
Ao ser executado, o programa ir solicitar que o usurio informe o grau do polinmio,
digitando

3,

o programa pedir para que sejam digitados os coecientes de grau

(independente). Digitando

3, 2, 1

4, 2, 1 e 9 o programa pedir para que o usurio informe o valor de

x, digitando 2 o programa far o seguinte clculo: p(2) = 4(2)3 +2(2)2 +1(2)1 +9(2)0 =
32 + 8 + 2 + 9 = 51.
x = 2.00000

eh:

Ento aparecer a mensagem O valor numrico do polinomio para

51.00000.

4.6 ARQUIVOS
Muitas vezes o usurio de um programa precisa registrar os resultados obtidos. Para
atender esta necessidade possvel manipular arquivos utilizando cdigos de programao.
Trabalhar com arquivos em linguagem C consiste em trs itens que vamos abordar a
seguir:

Abrir um arquivo;

Ler ou gravar informaes em um arquivo;

Fechar o arquivo;
Para declarar uma varivel do tipo arquivo, utilizamos o identicador de uxo FILE

*. A declarao do mesmo modo que fazemos com uma varivel do tipo ponteiro.

Sintaxe:

FILE * nome_da_variavel_do_tipo_arquivo ;

4.6.1

Abrir e fechar um arquivo


Para abrir um arquivo utilizamos a funo fopen. importante salienar que existem

vrios modos de acesso a um arquivo (ver alguns na Tabela 4.2), estes indicam ao programa
o que ser feito com o arquivo que foi aberto.

Sintaxe:

fopen ( nome_do_arquivo , modo_de_acesso ) ;

99

Tabela 4.2: Modos de Acesso a um Arquivo

Modo

Signicado

Abre o arquivo para leitura apenas. O arquivo tem que existir.

r+

Abre o arquivo para leitura e escrita. O arquivo tem que existir.

Abre o arquivo apenas para escrita no incio do arquivo.


Apagar o contedo que j tinha no arquivo e criar um novo, caso no exista.

w+

Abre o arquivo para leitura e escrita no incio do arquivo.


Apagar o contedo que j tinha no arquivo e criar um novo, caso no exista.

Abre o arquivo para escrita no nal. No apaga o contedo que j tem no arquivo.

a+

Abre o arquivo para leitura e escrita no nal do mesmo.

Se houver algum erro ao abrir um arquivo a funo retornar o valor NULL. Para
vericar se isto aconteceu comum inserir as seguintes linhas de cdigo aos programas:

// Linhas de cdigo para avisar se houve erro ao abrir algum


arquivo :
if ( nome_da_variavel_associada_ao_arquivo == NULL ) {
printf ( " Houve um erro ao abrir o arquivo .\ n " ) ;
return 0;
}
Para fechar um arquivo utilizamos a funo fclose. E para fechar todos os arquivos
abertos pelo programa utilizamos a funo exit.

Sintaxe:

fclose ( nome_da_variavel_associada_ao_arquivo ) ;
Exemplo 57. Criar um programa que utiliza abertura e fechamento de arquivos.

# include < stdio .h >


# include < stdlib .h >
int main () {
// Declarando uma varivel do tipo arquivo :
FILE * arq ;
// Usando a funo fopen para abrir o arquivo com o modo
de acesso w :
arq = fopen ( " ARQ1 . txt " , w ) ;
// Verificador de erro ao tentar abrir um arquivo :
if ( arq == NULL ) {
printf ( " Houve um erro ao abrir o arquivo .\ n " ) ;
return 0;
}
printf ( " Arquivo ARQ1 . txt foi criado .\ n " ) ;
100

// Usando a funo fclose para fechar o arquivo :


fclose ( arq ) ;
return 0;
}

4.6.2

Ler e Escrever em arquivos


Existem vrias funes para ler e escrever em arquivos, mas vamos utilizar apenas as

principais: fprintf e fscanf. Ambas funcionam de modo idntico s funes printf e scanf.

Sintaxe:

fprintf ( nome_da_variavel_associada_ao_arquivo , texto ) ;


fscanf ( nome_da_variavel_associada_ao_arquivo , formataao ) ;
Nota: A sigla EOF signica nal do arquivo. utilizada para vericar se estamos
no nal do arquivo.
Qualquer programa feito neste trabalho pode ser reescrito adicionando linhas de cdigo para manipular arquivos neles. interessante fazer este exerccio para axao.

Exemplo 58. Criar um programa para axar o que foi aprendido at ento sobre manipulao
de arquivos. Para isto, criaremos um arquivo chamado notas.txt onde colocaremos os seguintes
registros:
Thomaz 7.5 9 8
Rubens 7 10 5.8
Joozinho 8.6 9 10
Maria 10 9.3 8
Camila 9 10 8.4
Ricardo 4 3.5 7
Francielle 8 7.2 2.9
Johnny 5 8.1 9.7
Laura 7.7 9.3 10
Nosso programa vai ler estes registros, que so as notas de trs provas dos alunos de
uma turma, e exibir na tela para o usurio o nome de cada aluno seguido de sua mdia de
notas. importante salienar que o arquivo precisa estar no mesmo local onde est o executvel
do programa criado. Vamos ao cdigo:

# include < stdio .h >


# include < stdlib .h >
int main () {
/* Criando dois vetores do tipo char ,
101

de tamanho 50 chamado nome_do_aluno


e outro vetor de tamanho 9 que atribudo
na inicializao o seu preenchimento , isto ,
url [0]= n , url [1]= o ,... , url [8]= t . Esta sintaxe
no abordada no trabalho , mas pode ser encontrada
em [3]. */
char url []= notas . txt , nome_do_aluno [50];
float nota1 , nota2 , nota3 , media ;
// Declarando uma varivel do tipo arquivo :
FILE * arq ;
// Abrindo o arquivo para leitura apenas :
arq = fopen ( url , r ) ;
// Verificando se no deu erro na abertura do arquivo :
if ( arq == NULL ) {
printf ( " Houve um erro ao abrir o arquivo .\ n " ) ;
return 0;
}
else {
// Lendo e exibindo na tela as medias dos alunos :
while ( ( fscanf ( " arq ,% s % f % f % f \ n " , nome_do_aluno
, & nota1 ,
& nota2 , & nota3 ) ) != EOF ) {
media = ( nota1 + nota2 + nota3 ) /3;
printf ( " % s teve media %.2 f \ n " ,
nome_do_aluno , media ) ;
}
}
// Fechando o arquivo :
fclose ( arq ) ;
return 0;
}

102

Captulo 5
RESOLVENDO UM PROBLEMA
DE VALOR DE CONTORNO (PVC)
UTILIZANDO O MTODO DAS
DIFERENAS FINITAS (MDF) E A
LINGUAGEM C
Faremos agora uma aplicao, onde criaremos um programa que aplicar parte do que
foi aprendido sobre a Linguagem C. Para isto, vamos primeiro abordar um pouco sobre o que
um PVC e tambm o MDF. Vale lembrar que o foco deste trabalho no se aprofundar
neste tema.

5.1 Problema de Valor de Contorno e o Mtodo das


Diferenas Finitas
Um problema de valor de contorno um sistema de equaes diferenciais (EDO)
provido de um conjunto de restries adicionais, que so chamadas de condies de contorno
[2].

Uma soluo para um problema de valor sobre o contorno a soluo do sistema de

equaes diferenciais que satisfaz as condies de contorno, que podem ser lineares ou no
lineares.

Neste trabalho veremos a condio de contorno do tipo Robin, que dado por:

1 f (a) + 2 f 0 (a) = va ,
1

onde

va

o valor da combinao de

f (x)

f 0 (x)

no ponto

a,

com

dados.
O mtodo das diferenas nitas tem como princpio aproximar atravs de expres-

ses algbricas cada termo do modelo matemtico em cada n de uma malha que obtida ao
dividir o intervalo de domnio da funo incgnita em uma quantidade nita de

103

n subintervalos

[1].

Para fazermos o nosso cdigo, precisamos primeiramente entender como funciona o


MDF.

O primeiro passo chamado de discretizao do domnio, que consiste em dividir o


intervalo que representa o domnio da funo em

subintervalos de espaamento que

no precisa ser necessariamente do mesmo tamanho [1], porm aqui consideraremos


intervalos do mesmo tamanho

h.

O segundo passo chamado de discretizao da equao, que consiste em substituir as


derivadas da equao por aproximaes obtidas atravs da manipulao dos termos da
expanso da srie de Taylor. Tais manipulaes resultam em diferentes aproximaes,
como diferenas nitas progressivas, diferenas centrais, diferenas regressi-

vas, dentre outras [1].

Vamos ento ver como aplicar o MDF em um PVC Linear seguindo os dois passos
listados acima:

+ g(x)u = f (x), a < x < b


t(x) ddxu + q(x) du
dx

u(a) + du (a) = v
1
2 dx
a
u(b) + du (b) = v
1

2 dx

Discretizao do domnio: Dividir o intervalo [a,b] em n partes com espaamento


de tamanho h, dado por:

h=

ba
n

Assim obtendo cada um dos ns pela equao:

xi = a + ih,

com

i = 0, ..., n.

Discretizao da equao: Vamos discretizar a primeira equao utilizando diferenas centrais para aproximar a primeira e segunda derivada de

u.

E as condies de

contorno utilizando diferenas progressivas e regressivas, respectivamente. Obtendo:


Para a primeira equao:

t(xi )

ui+1 2ui +ui1 


h2

Colocando em evidncia

+ q(xi )

ui1 , ui

ui+1 ui1 
2h

+ g(xi )ui = f (xi )

ui+1 obtemos:

[2t(xi ) hq(xi )] ui1 + [2hg(xi ) 4t(xi )] ui + [2t(xi ) + hq(xi )] ui+1 = 2hf (xi )
Para as condies de contorno:

104

1 u0 + 2

3u0 +4ui u2
2h

Colocando em evidncia

u0 =

un

= va

u0

1 u n + 2

un ,

= vb

obtemos:

2hva 42 u1 +2 u2
e
2h1 32

2hvb +42 un1 2 un2


2h1 +32

un =

Desenvolvendo a equao em cada ponto

u0

3un +4un1 +un2


2h

obtm-se um sistema linear da forma

xi

do domnio discretizado e utilizando

Ax = r.

Onde as variveis so

ui ,

para

i = 1, ..., n 1.

b1 c 1

u1

r1

a2 b2 c2 0

u2 r2
0 a b

c3
0

u3 r3
3
3

0 0 a4 b 4

c4

. u4 = r4
.. .. .. . .
..
. .
..
..
. .
. . .

.
.
.
.
.


.
0 0 0 a

n2 bn2 cn2 un2

rn2
0

an1 bn1

un1

rn1

Onde,:

b1 = 2hr1 p1 (4 + 82 ) + 42 hq1 ;
bn1 = 2h2 rn1 pn1 (4 82 ) + 42 hqn1 ;
r1 = 2hf1 2hva (2p1 hq1 );
rn1 = 2hf1 2hvb (2pn1 hqn1 )
c1 = 2p1 ( + 2 ) + hq1 ( 2 );
an1 = 2pn1 ( 2 ) hqn1 ( + 2 );
Para

i = 2, ..., n 2:

bi = 2hri 4pi ;
ri = 2hfi ;
ci = 2pi + hqi ;
ai = 2pi hqi
sendo que:

= 2h1 32

= 2h1 + 32 .

Para resolver este sistema tridiagonal utilizaremos o Algortmo de Thomas [1], que
consiste em fatorar a matriz

da seguinte forma:

105

A = LU ,

onde:

L=

A2 B2

A3 B3

..

..

B1
0
0

.
.
.

.
.
.

A4 B4
.
.
.

..

An1 Bn1

An

.
.
.

Bn

e U =

1 C1

C2

C3

C4

.
.
.

.
.
.

.
.
.

..

..

.
.
.

Cn1

so matrizes triangulares inferior e superior, respectivamente. Os coecientes

i , i

..

so

obtidos por:

c1
1
ci
i =
,
Bi

B1 = b1 . C1 =
A i = ai ,

Bi = bi Ai Ci1 ,
A n = rn ,

Ento o sistema

Ax = r

2in1

Bn = bn An Cn1

substitudo pelo sistema

LU x = r.

De onde temos os dois

novos sistemas lineares a resolver:

Ly = r
Ux = y
que aps a soluo, temos a soluo do PVC.

5.2 Codicao
Vamos ento criar um cdigo em linguagem C, utilizando o procedimento que vimos
acima, para resolver o seguinte problema de valor de contorno:

du + u = 2cos(x), 0 < x <


dx
u0  + 3u  = 3, u0 () + 4u() = 4
2
2
cuja soluo xata dada por:

u(x) = cos(x).

// ====================================================
// Cdigo para resolver o problema de valor de contorno :
// t ( x ) d2u / dx2 + q ( x ) du / dx + g ( x ) u = f ( x )
// Neste caso : t ( x ) = -1 , q ( x ) =0 , g ( x ) =1 , f ( x ) = 2 cos ( x )
// ====================================================
# include < stdio .h >
106

# include < stdlib .h >


# include < math .h >
// DECLARAO DE VARIVEIS GLOBAIS :
// Declarando variveis do tipo int e double :
int n ;
double ax , bx , h , x , va , vb , alfa1 , alfa2 , beta1 , beta2 ;
// Declarando ponteiros para os vetores :
double * r , * b , *a , *c , * A , * B , * C , * s , *p , * uex , *t , *q , *g
, *f;
// Prototipando as funes do programa :
void funcao () ;
void Axr () ;
void LU () ;
void Lsr () ;
void Ups () ;
void salvar () ;
// Declarando varivel do tipo arquivo :
FILE * arquivo ;
// Funo que calcula os valores de t ( x ) , q ( x ) , g ( x ) e f ( x ) para
cada i :
void funcao () {
int i ;
for ( i = 1; i <= n ; i ++) {
x = ax + ( i * h ) ;
t [ i ] = -1.0;
q [ i ] = 0.0;
g [ i ] = 1.0;
f [ i ] = 2 * cos ( x ) ; // Termo fonte do PVC
}
}
// Funo que preenche a matriz A =[ a b c ]:
void Axr () {
int i ;
double aux1 , aux2 ;
for ( i = 1; i <= n -1; i ++) {
if ( i == 1) {
aux1 = (2* h * alfa1 -3* alfa2 ) ;
b [ i ] = 2*( pow (h ,2) ) * g [ i ]* aux1 - t [ i ]*(4*
aux1 +8* alfa2 ) +4* alfa2 * h * q [ i ];
c [ i ] = 2* t [ i ]*( aux1 + alfa2 ) + h * q [ i ]*( aux1 alfa2 ) ;
r [ i ] = 2*( pow (h ,2) ) * aux1 * f [ i ] -2* h * va *(2* t
[ i ] - h * q [ i ]) ;
107

}
else if ( i == n -1) {
aux2 = 2* h * beta1 +3* beta2 ;
a [ i ] = 2* t [ i ]*( aux2 - beta2 ) -h * q [ i ]*( aux2 +
beta2 ) ;
b [ i ] = 2*( pow (h ,2) ) * g [ i ]*( aux2 ) -t [ i ]*(4*
aux2 -8* beta2 ) +4* beta2 * h * q [ i ];
r [ i ] = 2*( pow (h ,2) ) * f [ i ]* aux2 -2* h * vb *(2* t
[ i ] - h * q [ i ]) ;
}
else {
a [ i ] = 2* t [ i ] - h * q [ i ];
b [ i ] = 2*( pow (h ,2) ) * g [ i ] -4* t [ i ];
c [ i ] = 2* t [ i ] + h * q [ i ];
r [ i ] = 2*( pow (h ,2) ) * f [ i ];
}
}
}
// Funo que calcula as matrizes L e U :
void LU () {
int i ;
B [ 1 ] = b [ 1 ] ;
C [ 1 ] = c [ 1 ] / B [ 1 ] ;
for ( i = 2; i <= n - 2; i ++ ) {
A [ i ] = a [ i ] ;
B [ i ] = b [ i ] - ( A [ i ] * C [ i - 1 ] ) ;
C [ i ] = c [ i ] / B [ i ] ;
}
A [ n - 1 ] = a [ n - 1 ] ;
B [ n - 1 ] = b [ n - 1 ] - ( A [ n - 1 ] * C [ n - 2 ] )
;
}
// Funo que resolve o sistema linear triangular inferior Ls = r :
void Lsr () {
int i ;
s [ 1 ] = r [ 1 ] / B [ 1 ];
for ( i = 2; i <= n - 1; i ++ ) {
s [ i ] = ( r [ i ] - ( A [ i ] * s [ i - 1 ] ) )
/ B [ i ] ;
}
}
// Funo que resolve o sistema linear triangular superior Up = s :
void Ups () {
int i ;
p [ n - 1 ] = s [ n - 1 ];
108

for ( i = n - 2; i >= 1; i - -) {
p [ i ] = s [ i ] - ( C [ i ] * p [ i + 1 ] ) ;
}
}
// Funo que salva os resultados em um arquivo txt :
void salvar () {
int i ;
arquivo = fopen ( " resultado . txt " , " w " ) ;
fprintf ( arquivo , " Resultados :\ n \ n \ n " ) ;
fprintf ( arquivo , " x p [] uex [] \ n \ n " ) ;
for ( i = 1; i <= n -1; i ++) {
x = ax + i * h ;
uex [ i ] = cos ( x ) ;
fprintf ( arquivo , " % f % f % f \ n " , x , p [ i ] , uex [ i ]) ;
}
}
// Funo principal :
int main () {
int i ;
printf ( " Entre com o numero de divisoes no intervalo [a , b
]: \ n " ) ;
scanf ( " % d " ,& n ) ;
/* Vamos atribuir valores para algumas de nossas
variveis que sero constantes no nosso programa : */
va = 3.0;
vb = -4.0;
alfa1 = 3.0;
alfa2 = 1.0;
beta1 = 4.0;
beta2 = 1.0;
ax = 0;
bx = M_PI ;
// Calculando o tamanho do espaamento h :
h = ( bx - ax ) / n ;
// Colocando um ttulo para a janela :
system ( " title RESOLVENDO UM PVC UTILIZANDO MDF : " ) ;
// Alocando memria para os vetores utilizando a funo
malloc :
r = ( double *) malloc ( n * sizeof ( double ) ) ;
b = ( double *) malloc ( n * sizeof ( double ) ) ;
a = ( double *) malloc ( n * sizeof ( double ) ) ;
c = ( double *) malloc ( n * sizeof ( double ) ) ;
109

A =
B =
C =
s =
p =
uex
t =
q =
g =
f =

( double *) malloc ( n *
( double *) malloc ( n *
( double *) malloc ( n *
( double *) malloc ( n *
( double *) malloc ( n *
= ( double *) malloc ( n
( double *) malloc ( n *
( double *) malloc ( n *
( double *) malloc ( n *
( double *) malloc ( n *

sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
* sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;

// Verificando se a alocao dinnica teve algum problema :


if ( r == NULL || b == NULL || a == NULL || c == NULL || A == NULL
|| B == NULL || C == NULL ||
s == NULL || p == NULL || uex == NULL || t == NULL || q == NULL ||
g == NULL || f == NULL ) {
printf ( " Memoria insuficiente .\ n " ) ;
return 1;
}
// Chamando as funes :
funcao () ;
Axr () ;
LU () ;
Lsr () ;
Ups () ;
salvar () ;
r = ( double *) malloc ( n *
b = ( double *) malloc ( n *
a = ( double *) malloc ( n *
c = ( double *) malloc ( n *
A = ( double *) malloc ( n *
B = ( double *) malloc ( n *
C = ( double *) malloc ( n *
s = ( double *) malloc ( n *
p = ( double *) malloc ( n *
uex = ( double *) malloc ( n
t = ( double *) malloc ( n *
q = ( double *) malloc ( n *
g = ( double *) malloc ( n *
f = ( double *) malloc ( n *

sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
* sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;
sizeof ( double ) ) ;

// Liberando a memria alocada pelos ponteiros :


free ( r ) ;
free ( b ) ;
free ( a ) ;
free ( c ) ;
free ( A ) ;
110

free ( B ) ;
free ( C ) ;
free ( s ) ;
free ( p ) ;
free ( uex ) ;
free ( t ) ;
free ( q ) ;
free ( g ) ;
free ( f ) ;
return 0;
}
Ao executar o programa aparecer a mensagem Entre com o numero de divisoes no
intervalo

[a, b]:.

Digitando

20

o programa salvar um arquivo .txt chamado resultado.txt

com as solues aproximada e exata do problema. Com este arquivo possvel construir o
seguinte grco para comparao dos resultados:

Figura 5.2.1: Resultados para n = 20

Sol. Aprox. (n= 20)


Sol. Exat.

0.8
0.6
0.4
0.2
0
-0.2
-0.4
-0.6
-0.8
-1
0

0.5

1.5

2.5

Ao observar o grco 5.2.1 possvel vericar que o programa construdo resolve


o problema proposto, uma vez que a soluo resultante do MDF (pontos com formato de
quadrados) se aproxima da soluo exata (linha contnua).

111

Captulo 6
CONCLUSO
Ao nal deste trabalho conseguimos apresentar alguns conceitos da linguagem C que
servir para que um aluno de matemtica comece a criar seus programas. Construmos diversos
programas para axao, nos quais pudemos ver abordagens diferentes para resolver o mesmo
problema. Alm disso, vimos um pouco sobre problemas de valor de contorno, assim como o
mtodo das diferenas nitas para resoluo dos mesmos. Tambm criamos um cdigo para
resoluo de um PVC com condies de contorno do tipo Robin, onde pudemos axar boa
parte do contedo aprendido.
importante salienar que, embora no tenhamos passado por todo o contedo da
linguagem C, aps o estudo destes tpicos abordados possvel construir uma gama enorme
de programas, sendo que as dvidas que forem surgindo no processo podem ser facilmente
sanadas agora que o programador possui um bom conhecimento prvio.

112

Referncias Bibliogrcas
[1] vila, D. M. Aplicao do Mtodo das Diferenas Finitas na Soluo de Problemas de
Valor de Contorno. Universidade Federal de Uberlndia, 2013.
[2] Boyce, W. E., Diprima, R. C., Equaes Diferenciais Elementares e Problemas de Valores
de Contorno. LTC Editora.
[3] Damas, L., Linguagem C. 10 Edio, 2007.
[4] Kernighan, B. W., Ritchie D. M., The C Programming Language. 2 Edio. Prentice
Hall, 1988.
[5] Lawisch, A., Linguagem de Programao C . UERGS - Universidade Estadual do Rio
Grande do Sul. Novo Hamburgo, 2012.
[6] Maiali, A. C., Costa, O. L. V., Mtodo de Diferenas Finitas e de Monte Carlo em
Derivativos. Universidade de So Paulo.
[7] Singh, S. O ltimo teorema de Fermat. 10. ed. Rio de Janeiro: Record, 2004.
[8] Tabela

ASCII

Completa.

Disponvel

http://187.7.106.14/marcelo/org_comp/tabelaASCII.pdf>.

em:
Acesso

em:

<
19

nov.

2014.
[9] UFMG, Curso de Linguagem C, Universidade Federal de Minas Gerais.
[10] Viana, P. E., Mtodo de Newton. Universidade Federal de Minas Gerais. Belo Horizonte,
2006.

113

Vous aimerez peut-être aussi