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

APOSTILA

de

A vida não termina

1
Onde a morte aparece.

Não transforme saudade


Em fel nos que se foram.

Eles seguem contigo,


Conquanto de outra forma.

Dá-lhes amor e paz,


Por muito que padeças.

Eles também te esperam


Procurando amparar-te.

Todos estamos juntos.


Na presença de Deus.

EMMANUEL

Mensagem recebida pelo médium


FRANCISCO CÂNDIDO XAVIER,
em 11/10/78.

I- INTRODUÇÃO
2
I.1 Conceitos de Programação
Os computadores surgiram na década de 40 com o objetivo de processar dados, fazer cálculos pesados,
fornecendo resultados exatos para problemas antes considerados complicados. Atualmente, eles continuam tendo
estas funções e muitas outras. A tecnologia de informática avança a cada dia, tornando os sistemas de computação
mais populares e amigáveis.

As modernas redes de computadores, os sistemas distribuídos, as arquiteturas do tipo cliente/servidor, os micro


computadores, os mainframes etc etc, se resumem em dois tipos de componentes:
 Hardware
 Software

Hardware se refere aos componentes físicos da máquina: memória, processador (chips),


teclado, mouse, cabo, monitor de vídeo, impressora, scanner, plotter etc.

Software se refere aos programas da máquina: sistema operacional, compilador, editor de textos, planilha
eletrônica, interface gráfica, aplicativos etc.

Portanto, windows, word, lotus, CAD, turbo pascal, clipper, fox, unix etc são programas ou softwares. Estes
programas geralmente são chamados de softwares básicos.
Aplicativos são os programas desenvolvidos para automatizar processos específicos de instituições comerciais,
industriais, de ensino, bancárias etc. Por exemplo, folha de pagamento, controle de estoque, emissão de passagens
aéreas, controle de produção, saques de terminais on-line com atualização de saldo bancário etc.

Para se desenvolver um programa básico ou um aplicativo, uma linguagem de programação deve ser escolhida e
instalada adequadamente.

Linguagens de 1a. geração são as linguagens de máquina.


Linguagens de 2a. geração são os Assemblers.
Linguagens de 3a. geração (Pascal, Cobol, C etc) são utilizadas para desenvolvimento de aplicativos “pesados” ou
“complicados”, de funções não existentes em ling. de 4a. geração e de softwares básicos.
Linguagens de 4a. geração (clipper, fox etc) são amigáveis e exigem menos esforços de programação. São
excelentes para o desenvolvimento de alicativos convencionais, pois estão associadas a bancos de dados na maioria
das vezes e a ferramentas case em alguns casos. Não possibilitam definição de estruturas de dados devido à
inexistência de recursos presentes em linguagens de 3a. geração.

Os compiladores traduzem programas escritos em linguagens de alto nível (2a., 3a., 4a. gerações) para linguagens
de baixo nível (binária - ling. de máquina).

Para fazer um programa precisamos de:

1. Digitar o código fonte em algum editor de textos (a maioria da lings. possui editor próprio).
2. Compilar o fonte, gerando o código objeto (linguagem de máquina).
3. Linkeditar módulos objeto gerando um código executável (várias linguagens dispensam este passo).

3
Funcionamento de um programa:

Um programa executável destina-se ao processamento de dados de entrada, fornecidos via teclado, disquetes,
winchesters, fitas, scanners, micro-fones... pelo usuário. As saídas processadas são direcionadas para o monitor,
impressoras, plotters etc.

Assim, um programa de controle de passagens aéreas, por exemplo, processa dados de entrada do passageiro, do
vôo, da companhia, do aeroporto etc e fornece como saídas
bilhetes de passagens, listas de passageiros, horários etc.

Entradas ------------ Processamento------------Saídas

I.2 LINGUAGEM C

* Concebida e implementada pôr Dennis Ritchie e Kem Thompson, nos laboratórios da AT&T (Bell) - 1972
* Unix é quase inteiramente programado em C
* Linguagem compacta, poderosa, portátil, flexível e perigosa.
* Padronização de compiladores existentes.
* Estruturas, módulos, funções Bons hábitos de programação.(Programas legíveis e documentados)
* Bibliotecas de funções podem ser criados ou usadas, sem se conhecer o código de cada uma delas.

Interpretador: lê uma instrução, faz consistência da sintaxe, converte-a para linguagem de máquina e executa-a.
Repete para a próxima instrução todos os passos.

Compilador: lê instruções, faz consistência de sintaxe, se não houver erro. Converte-a para linguagem de máquina.
Segue para a próxima e repete até a última instrução. Gera um .OBJ.

Linkeditor: junta rotinas necessárias ao .OBJ criando um produto final .EXE.

Programa fonte: com o sufixo .C (c padrão) ou .CPP (c++).

ESTRUTURA BÁSICA DE UM PROGRAMA C

void main( )  função principal a ser executada.


{  inicia o corpo da função (begin).
}  termina a função(end).

4
parênteses indicam que é uma função.
nome da função: qualquer um, exceto main, reservado para a função de início do programa.
void: tipo de dado nulo, indicando que a função não retorna nenhum valor.

ELEMENTOS OBRIGATÓRIOS DE UMA FUNÇÃO

Nome da função, parênteses, chaves.

* A função MAIN( ) deve existir em algum lugar do programa marcando o ponto de início da execução.

Um programa C pode ter 1 única função main( ) ou várias.

INSTRUÇÕES

* Devem estar dentro das chaves.


* Sempre encerradas por “;”.
* Exemplo: main( ) { printf (“Primeiro Programa”);}
main( )
{
printf (“Primeiro Programa”);
}

*A função PRINTF( )

- uma das funções C de E/S.


- “Primeiro Programa” é argumento da função.
- Sintaxe : printf (“expressão de controle”, lista de argumentos);
- formatação : printf (“Este é o dois %d”,2);
printf (“\n%s esta a %d milhões de milhas \n do Sol\n”,”Vênus”,67);
printf (“A letra %c”,’j’,”pronuncia-se %s”,”jota”);
Saídas: Este é o 2
Vênus está a 67 milhões de milhas
do Sol
A letra j pronuncia-se jota

Lembrete: Cadeia de caracteres = “ “


Caractere = ‘ ‘
Expressão de controle = “ “

Códigos Especiais Significado


\n nova linha
\t TAB
\b retrocesso

5
\” aspas
\\ barra
\f salta página
\o nulo

Formatador Descrição
%c caractere simples
%d decimal
%e notação científica
%f ponto flutuante
%g %e ou %f (mais curto)
%o octal
%s cadeia de caracteres
%u decimal sem sinal
%x hexadecimal

CONSTANTES E VARIÁVEIS

Exemplos de Constantes

- ‘C’ (constante caractere)


- “Primeiro Programa” (constante cadeia de caracteres)
- 8 (constante numérica)

main( )
{
printf (“Este é o dois:%d”,2);
}

O programa imprime a constante 2, no formato %d.

Uma VARIÁVEL em C é um espaço de memória reservado para armazenar dados. Os valores de uma variável ficam
armazenados na memória para utilização em vários pontos diferentes do programa.

main( )
{
int num;
num = 2;

6
printf ( “Este é o número dois %d”,num);
}

UMA DECLARAÇÃO DE VARIÁVEL CONSISTE NO NOME DE UM TIPO, SEGUIDO DO NOME DA


VARIÁVEL.

TIPOS DE VARIÁVEIS

Tipo Bit’s Byte’s Escala


char 8 1 -128 a 127
int 16 2 -32768 a 32767
float 32 4 3.4 E -38 a 3.4 E 38
double 64 8 1.7 E -308 a 1.7 E 308
void 0 0 sem valor

Modificadores:

* long ou long int ( 4 Bytes)


* unsigned char (de 0 a 255)
* unsigned int (de 0 a 65535)
* unsigned long
* short (2 bytes)

\nsalta linha

float = real (do Pascal)


3.16 E 7 = 3,16 x 10 x 10 x 10 x 10 x 10 x 10 x 10

notação científica

Exemplos de Programa C
#include <stdio.h> /* Biblioteca com funções de E/S padrão */
#include <conio.h> /* Biblioteca com funções de cotrole de tela */
void main( )
{
int evento;
char corrida;
float tempo;
evento = 5;
corrida = ‘C’;
tempo = 27,25
printf (“O tempo vitorioso na eliminatória %c”, corrida);
printf (“\n da competição %d foi %.2f”,evento,tempo);
}

7
A saída será:
O tempo vitorioso na eliminatória C
da competição 5 foi 27,25.

Obs.: A inicialização de variáveis pode ser feita na declaração.


Exemplos:

int evento = 5;
char corrida = ‘C’;
float tempo = 27.25;

Inteiros com e sem sinal:

void main( )
{
unsigned int j =65000;
int i = j;
printf (“%d %u \n”, i, j); /* imprime i e j que teoriamente deveriam ser iguais */
}

O resultado será: -536 65000

Nomes de Variáveis:

-Tamanho indeterminado.
-Primeira letra pode ‘-’ ou letra.
Outros caracteres ou números podem ser usados no meio da palavra.

Mais exemplos:

void main( )
{
int reajunste = 10;
printf (“O reajuste foi de %d %%,\n”,reajuste);
}

Saída: O reajuste foi de 10%.

void main( )
{
printf (“Os alunos são %2d. \n”, 350);
printf (“Os alunos são %4d. \n”, 350);
printf (“Os alunos são %6d. \n”, 350);
}

8
A saída será: Os alunos são 350.
Os alunos são 350.
Os alunos são 350.

II - OPERADORES
A Função Scanf( )
Função de E/S, complementar à printf( ), para ler dados do teclado.

Sintaxe : Scanf (“Expressão de controle”, argumentos)

A expressão de controle pode conter códigos de formatação, precedidos por %.


%* indica que será lido um valor do tipo especificado, mas não será atribuído a nenhuma variável (sem parâmetro
na lista de argumentos).
A lista de argumentos consiste no endereço das variáveis.
C oferece um operador para tipos básicos chamado operador de endereço &, que retorna o endereço do
operando.
O Operador de endereço (&):
main( )
{
int num;
num = 2;
printf (“Valor %d, endereço = %u”, num, &num);
}

O programa acima imprime o valor e o endereço de memória de num.


%u é usado pois endereço é visto como inteiro sem sinal.
Ex. de saída: Valor=2, endereço = 1370

Códigos de Formatação para Scanf ( )

%c leia um único caractere


%d leia um inteiro decimal
%e leia um número em notação cientí-
fica
%f leia um número em ponto flutuante
%o leia um inteiro octal
%s leia um série de caracteres
%x leia um número hexadecimal
%u leia um decimal sem sinal
%l leia um inteiro longo

9
Exemplo de Scanf( ):

1 - void main ( )
{
float anos, dias;
printf (“Digite sua idade em anos :”);
scanf (“%f”, &anos);
dias = anos * 365;
printf (“Sua idade em dias é %.0f .\n”,dias);
}
Saída:
Digite sua idade em anos : 4
Sua idade em dias é : 1460.0.

2 - void main ( )
{
char a;
printf (“Digite um caractere e vejo-o em decima,”);
printf (“octal e hexadecimal.\n”);
scanf (“%c”,&a);
printf (“\n%c=%d dec., %o oct e %x hex.\n”,a,a,a,a);
}
Saída:
Digite um caractere e veja-o em decimal, octal e hexadecimal.
m
m=109 dec., 155 oct. e 6D hex.

As Funções Getche( ) e Getch( )


Não precisam de [enter] para ler um caractere.
Não aceitam argumentos.
Getche( ) : permite que caractere lido seja mostrado na tela.
Getch ( ) : não permite que caractere lido seja mostrado na tela.
Exemplo:
main ( )
{
char ch;
printf (“Digite algum caractere :”);
ch = getche( );
printf (“\n A tecla que você pressionou foi %c.”,ch);
printf (“E a sua sucessora ASCII é %c, ch + 1);
}
Execução: Digite algum caractere : a
A tecla que você pressionou foi a e a sua sucessora ASCII é b.

Substituindo a linha 5 por ch = getch( );, temos:

Execução: Digite algum caractere:

10
A tecla que você pressionou foi a e a sua sucessora ASCII é b.

A função Getchar( )
Lê um caractere de entrada.
Não aceita argumentos.
Precisa de [enter].

A função Putchar( )
Complemento de getchar( ).
Aceita um argumento cujo valor será impresso.
c=getchar( );

putchar(c); = putchar(getchar(c));

Operadores Aritméticos

Seis Binários (operam sobre dois operandos) e um unário (1 operando).

Binários:

= Atribuição (num=cont=50 é válido)


+ Soma
- Subtração
* Multiplicação
/ Divisão
% Módulo (resto da divisão inteira)

Unários:

- Menos unitário (troca de sinal algébrico)

Operadores de Incremento e Decremento


++ incrementa de 1 seu operando
-- decrementa de 1 seu operando

x = n++  x = n p/n=5 x = 5
n=n+1 n=6

x=++n n=n+1 p/n=5 x = 6


x=n x=6

11
Errado: (a * b)++; 5++;

Não confundir precedência com ordem de avaliação:

a = 2;
b = 5;
n = (a + b++) * 3

Substituindo valores:

n = (2 + 5) * 3 = 7 * 3 = 21

Somente depois da expressão ser avaliada, b é incrementado para 6.

Operadores Aritméticos de Atribuição


+=, -=, *=, /=, %=

i += 2; equivale a i = i + 2;
x *= y + 1; equivale a x = x * (y + 1);
t /= 2,5; equivale a t = t / 2,5;
p %= 5; equivale a p = p % 5;
d -= 3; equivele a d = d - 3;

Operadores Relacionais (Precedência menos que os Aritméticos)

> maior
>= maior igual
< menor
<= menor igual
== igual
!= diferente

Em C não existe variável Booleana.


Valor zero(0) = falso
Quaquer outro valor = verdadeiro, representado por 1 (um)

void main( )
{
/* Programa que mostra expressões booleanas com o argumento de printf ()*/.
int verdad, falso;
verdad = (15 < 20);
falso = (15 = = 20);

12
printf (“Verdadeiro = %d, falso = %d”,verdad,falso);
}

A saída será: Verdadeiro = 1, falso = 0.

III - LAÇOS
For  * engloba três expressões(inicialização, teste e incremento) em uma única;
* quando queremos repetir algo um número fixo de vezes.

/* Lacofor.c */
/* Imprime números de 0 a 9 */
void main( )
{
int conta;
for (conta = 0; conta < 10; conta ++) /* não coloque ; */
printf (“Conta = %d\n”,conta);
} 
corpo do laço

O teste é feito antes logo após a iniialização e toda vez que o laço é reiniciado.
O incremento conta ++ é feito após a execução do corpo do laço.
A ordem é: inicialização, teste, execução do corpo do loop, incremento, teste, execução...

FLEXIBILIDADE DO FOR
1)Qualquer das 3 expressões pode ter mais de 1 instrução.

void main( ) /* imprime de 0 a 98 c/ incremento de 2*/


{
int x,y;
for (x=0, y=0; x+y<100; x++, y++)
printf (x+y);
}

2)Podemos usar caracteres:

void main( )
{
char ch;
for (ch=‘a’; ch<=‘z’; ch++)
printf (“O valor ASCII de %c é %d”, ch, ch);
}

3)Podemos usar chamadas de funções:

13
void main( )
{
char ch;
for (ch=getch( ); ch != ‘X’; getch( ) )
printf (“%c”, ch + 1);
}

4)Qualquer expressão pode desaparecer, permanecendo o ;

void main( )
{
char ch;
for (; (ch = getch( ) ) != ‘X”;)
printf (“%c”, ch + 1);
}

5)O corpo do laço for pode ser vazio. Permanece o ;

void main( )
{
char c;
for (; (c=getch( ) ) != ‘X’; printf (“%c”, c + 1))
;
}

INTRUÇÕES MÚLTIPLAS NO CORPO DO LAÇO FOR:

/*Imprime números de 0 a9 e totais */


void main( )
{
int conta, total;
for (conta=0, total=0; conta<10; conta++)
{ /* begin */
total+=conta;
printf (“Conta=%d, total=%d\n”, conta, total);
} /* end */
}

O LAÇO WHILE

Inicialização;
While [ expressão de teste ]  verdadeira se != 0
{

14
intrução;  repetida ate que expressão de teste = 0
 a ordem depende de lógica
incremento;
}

O laçoWhile é mais apropriado quando a condição de término puder ocorrer inesperadamente.

Exemplo: void main( ) /* conta caracteres de uma frase*/


{
int cont=0;
printf (“Digite uma frase:\n”);
while (getche( ) != 13) /*13 = Return*/
cont++;
printf (“\nO número de caracateres é %d”, cont);
}

O LAÇO DO WHILE
Do
{
intrução 1;
instrução 2;
...
instrução n;
} while (expressão de teste); ponto e vírgula aqui !

* executa pelo menos uma vez antes do primeiro teste.


*expressão de teste é avaliada somente após a execução do corpo do laço.
*mesmo com uma única intrução,{ } aumentam a legibilidade.
*usado somente em 5% dos casos.

Comandos Break e Continue

Break: causa saída imediata de um laço. (loop)

Continue: força próxima interação do laço, ignorando intruções ainda não executadas.Deve ser evitado, pois causa
confusão e dificuldade de manutenção.

Comando Goto

*só para compatibilidade com Basic, Cobol e Fortran.


*kerninghan e Rich (criadores do C) desaprovam seu uso.
*Exemplo: goto parte1;
parte1;
printf (“Análise 1”);

15
gotoxy(coluna,linha); - comando que pode ser usado para posicionar o curso em uma deterinada posição da tela,
cujas coordenadas são dadas pelos números de coluna e linha passados como argumentos.

IV - COMANDOS DE DECISÕES
if, if-else, else-if, switch-case, ?:
1) IF
/*Programa que conta caracteres e palavras*/
void main ( )
{
int caracteres = 0;
int palavras = 0;
char ch;
printf (“Digite uma frase \n”);
while ((ch = getche( ) ) != 13) {
caracteres++;
if (ch= = ‘ ‘) { /*espaço ?*/
palavra++; /* não existe then */
printf (“Foi computada mais uma palavra.”);
}
}
printf (“\nForam contados %d caracteres”, caracteres);
printf (“\ne %d palavras nesta frase.”,palavras + 1);
}

void main( ) /*Eleva um n ao quadrado*/


{ /*O quadrado de n = soma dos primeiros n números ímpares*/
int n, i, soma;
printf (“Digite um número:”);
scanf (“%d”,&n);
if (n < 0) n = -n;
for (i = 1, soma = 0;n > 0;soma += i, n--, i += 2)
;
printf (“O quadrado de %d é %d”,n, soma);
}

2)IF - ELSE
void main( )
{
char ch;

16
ch = getche( );
if (ch == ‘p’)
printf (“\nVocê pressionou a tecla p.”);
else
printf (“\nVocê não pressionou a tecla p.”);
}

Ifs ANINHADOS

if (n > 0) if (n > 0){


if (a > b) if (a > b)
z = a;  z = a;
else }else
z = b; z = b;

OPERADORES LÓGICOS

&& E lógico
 ou lógico
! lógico de negação

exp1 && exp2  expressão 1 e expressão 2 verdadeiras


exp1  exp2  expressão 1 ou expressão 2 verdadeiras
! exp1  expressão 1 falsa

PRECEDÊNCIA

Operadores Tipos
! - ++ -- unários, não lógicos; (in)decremento
* / % aritméticos
+ - aritméticos
< > <= >= relacionais
= = != relacionais
&&  lógico
= += -= *= /* %= aritméticos de atribuição

Exemplo de operados lógicos:


/*Conta caracteres e dígitos de uma frase*/
void main( )
{

17
int numchar = 0;
int numdigit = 0;
char c;
printf (“Digite uma frase =\n”);
while ((c = getche( )) != 13) {
numchar++;
if (c >= ‘0’ && c <= ‘9’)
numdigit++;
}
printf (“\nO número de caracteres é : %d”,numchar);
printf (“\n, dos quais %d são digitos”,numdigit);
}

3)ELSE - IF
A construção de else-if é uma naneira reformatada de nunhos if-else.

/*Calculadora com 4 operações*/


main( )
{
float num1, num2;
char op;
while (1) { */Sempre verdadeira*/
printf (“Digite um número, operador, número \n”);
scanf (“%f %c %f”,&num1,&op,&num2);
if (op = = ‘+’)
printf (“= %f “,num1 + num2);
else if (op = = ‘-’)
printf (“= %f”,num1 - num2);
else if (op = = ‘*’)
printf (“= %f”,num1 * num2);
else if (op = = ‘/’)
printf (“=%f”,num1/num2);
printf (“\n\n”);
}
}
4)OPERADOR TERNÁRIO ?:
condição
if (num1 > num2) 
max = num1;  max = (num > num2)?num1:num2
else
max = num2;

5)SWITCH
Escolha entre várias alternativas.
void main( ); /*exemplo da calculdora de 4 operações */
{

18
float num1, num2;
char op;
while (1) { /*Verdadeiro*/
printf (“Digite um número,operador, número\n”);
scanf (“%f %c %f”,&num1, &op, &num2);
switch (op) {
case ‘+’:
printf (“=%f”, num1 + num2);
break;
case ‘-’:
printf (“=%f”, num1 - num2);
break;
case ‘*’:
case ‘x’:
printf (“=%f”,num1 * num2);
break;
case ‘/’:
printf (“=%f”,num/num2);
break;
default:
printf (“Operador desconhecido.”);
}
}
}

19
V - FUNÇÕES
*Uma função é um miniprograma
*Um programa pode ser composto por várias funções
*Uma função pode invocar outras funções
*Uma função pode invocar a si mesma => recursividade
* A utilização de funções proporciona modularidade do programa.
* Funções evitam repetição do mesmo código em pontos diferentes do programa.
*main() é a função principal de um programa C
*Exemplo:
void main( )
{
void linha(); /* declara existência da função linha() p/ main() */
linha( ); /* main() chama linha() */
printf (“\xDBUm programa em C\xDB\n”); /* \xDB imprime caractere escuro na tela */
linha( );
}
void linha( ) /* aqui começa a função (subprograma) linha() */
/* função linha() é do tipo void e desenha linha escura de 20 caracteres*/
{
int j;
for (j = 1;j <= 20;j++)
printf (“\xDB”);
printf (“\n”);
}

Saída :
Um programa em C

\xDB : cor escura


\xBO : cor clara
\x7 : sinal sonoro
\CD : traço duplo
void linha(); - declaração para main() (com ;)
void linha( ) - início do código da função (sem ;)
linha( ); - chamada ( com ;)
A ordem main( )  linha( ) pode ser trocada! Se o código de linha() estiver antes do código de main(), linha() não
precisa ser declarada para main().

20
Variáveis locais (classe auto) são conhecidas só na própria função.
As variáveis de main( ) também são locais.

Comando Return ( só volta um valor ! )

*O tipo de uma função corresponde ao tipo do dado retornado pelo comando return e não aos tipos dos
argumentos.
*exemplo:
char minusculo( ) /* função minusculo é do tipo char */
{
char ch;
ch = getche( );
if (ch >= ‘A’ && ch <= ‘Z’)
return (ch + ‘a’ - ‘A’); ? /*return retorna valor do tipo char */
else
return (ch); /*função minusculo retorna, qdo. for chamada, o valor minúsculo de ch*/
}

Argumento Formal

void main( )
{
int abs(int x); /* declaração de abs() */
printf (“%d%d%d\n”,abs(0),abs(-3),abs(10)); /*chamda de abs() 3 vezes */
}
int abs(int x) /*definição de abs() - x é argumento recebido por abs(), do tipo inteiro */
{
return ((x<0)?-x:x);
/*abs() retorna -x ou x, dependendo do fato de x ser negativo ou positivo*/
}

*Podemos passar tantos argumentos quantos forem necessários.

Mais de Uma Função


* Todas as funções são visíveis pelas outras.
* Não se pode definir uma função dentro de outra.

void main( )
{
float area( ); /* declaração da função area() para main() */
float raio; /* declaração da variável raio, local à fução main() */
printf (“Digite o raio da esfera : “);
scanf (“%f”,&raio);
printf (“A area é %f.”,area(raio)); /* chamada da função area() dentro do printf()*/
}
int sqr(int y) /* definição da função sqr()*/
{
return(y*y);

21
}
/*area ( ) */
float area(r) /*definição da função area()*/
float r;
{
return (4 * 3,14159 * sqr(r)); /* chamada da função sqr() */
}

* Declaração de função é reconhecida por ( ).

Funções do Tipo Void

* Não retornam valor => não têm return.

void main( )
{
void linha ( ); /* declaração */
linha( ); /* chamada */
...
}
void linha( ) /*definição*/
{
int j;
...
}
*A chamada de uma função do tipo void é feita diretamente. ex: linha();
*O resultado de chamada de uma função de tipo diferente do void deve ser atribuído a alguma variável do mesmo
tipo ou impresso por printf().

Argumentos - Chamada por Valor

* Uma função não consegue alterar o valor de um argumento, só sua copia temporária.
* Passagem de argumentos em C é por valor.

Funções Recursivas

long fac(int n)
{
long resposta;
if (n = = 0) return (1);
resposta = fac (n - 1) * n;
return (resposta);
}
ex. de execução:

22
n=3 fac(3)
 3*2
3 * fac(2) 
2*1
n=2 2 * fac(1) 
1*1
n=1 1 * fac(0) 

n=0 1

Classes de Variáveis

Auto - automáticas ou locais às funções onde são declaradas (default).


Extern- são conhecidas por todas as funções declaradas depois delas (globais).
int teclanum /*variável externa*/
main( )
{
extern teclanum;
:
:
}
teste( )
{
extern teclanum;
:
:
}

Obs.: Não é necessário declarar em função variáveis extern se a declaração global foi feita no mesmo fonte.
É preferível passar argumentos, pois extern’s retêm valores durante a execução, mantendo posições de
memória alocadas, ao contrário das automáticas, “destruídas”após utilização.

Static - locais às funções onde são declaradas, mantêm seus valores mesmo após o término da função.
void main( )
{
soma ( );
soma ( );
soma ( );
}
void soma ( )
{
static int i = 0; /*i não é inicializado*/

23
printf (“\n i = %d”, i++); /*a cada chamada de soma*/
}

Saídas:
i = 0;
i = 1;
i = 2;

Obs.: Uma variável externa estática só pode ser usada por funções do mesmo fonte  privacidade.
Uma função também pode ser estática - conhecida só em um fonte.

Register: tornam o programa mais rápido, alocando a variável diretamente em um registro. Um IBM-PC só
possui 2 registradores  limite.

Flexibilidade nas Declarações de Variáveis

int i = 3;
void main( )
{
int i = 5; /*1ª variável*/
printf (“Em main( ) - endereço de i = %u\n”,&i);
printf (“Em main( ) - valor de i = %u\n”,i);
func1( );
if (i = = 5) {
int i; /*2ª variável*/
i = 2;
printf (“No bloco - endereço de i = %u\n”,&i);
printf (“No bloco - valor de i = %d\n”,i);
}
}
void func1( )
{
printf (“\nEm func1( ) - i = %d”,i);
}

Pré-Processador

* Traduz diretivas para o compilador.


* O pré-processador substitui as diretivas por seus significados, antes do programa ser compilado.

Diretiva #define:
*Possibilita a criação de macros (“apelidos”) para determinados comandos ou valores constantes

24
maiúsculo, de preferência
  não tem ;
 
1)#define PI 3,14159 /*constante*/
2)#define ERRO printf (“\nERRO.\n”)

void main( )
{
int i;
scanf (“%d”,&i);
if (i < 0 || i > 100)
ERRO;
}

3) não tem espaço



#define PRN(n) printf (“%.2f\n”,n)

void main( )
{
float num1 = 27.25;
float num2;
num2 = 1.0/3.0;
PRN(num1);
PRN(num2);
}

Obs.:diretivas usualmente são declaradas ANTES de main( ).


* Se quiser continuar #define em outra linha, colocar uma \ ao final da linha.
* Cuidado com parênteses em macros:

#define SOMA(x,y) x + y  ERRADO !


#define SOMA(x,y) (x + y)  CERTO !

*Macros muito utlizadas podem ser agrupadas e guardadas em arquivos(bibliotecas) com extensão .h
* Biblioteca C de macros : ctype.h
* Código de macro é substituído dentro do programa, onde é usada, em cada ponto.

Características de Macros:

* Maior rapidez.
* Código aumentado depois da compilação.
* Código da Função não é copiado.
* Macros não necessitam de especificações de tipo de argumento.

MACRO

25
#define SRQ(x) printf(“%d”,x * x)

FUNÇÃO

double sqr(double x)
{
return (x * x);
}

Diretiva #include
Copia um código de biblioteca para uma área do seu programa.
Exemplo :
Arquivo Áreas.h
#define PI 3,14159
#define AREA_CIRCULO(raio) (Pi * raio * raio)
#define AREA_RETANG(base,altura) (base * altura)
#define AREA_TRIANG(base,altura) ((base * altura)/2)

* Para usar macros em um programa, basta dar #include em “arq.h”, onde elas estão definidas. No exemplo :
#include “área.h”

* getchar( ) e putchar( ); por exemplo, são macros definas em stdio.h.

#include “pascal.h”
program
begin
write (“Isto é uma linguagem C ??”);
end

Arquivo pascal.h

#define program main( )


#define begin {
#define write (x) printf(x)
#define end }

Outras Diretivas

#undef  suspende a última definição.

#define x5  define x = 5
#define x10  redefine x = 10
#undef x  volta x = 5
#undef x  cancela definição de x

#if, #ifdef, #ifndef, #else, #endif

26
 compilações condicionais

#ifdef CORES
#include “cores.h”
#define TAB 10
#else
#include “cores1.h”
#define TAB 20
#endif

 portabilidade

#if sys = = “IBM”


#include “IBM.h”
#endif

VI - MATRIZES, STRINGS
* Matriz é uma variável de n posições que substitui n variáveis de uma mesmo tipo (homogêneas).

/*programa que calcula média de notas de uma turma*/

#define lim 40
void main( )
{
float notas[lim], soma;
int i;
for (i = 0, soma = o.o;i<lim;soma += notas[i++]) {
printf (“Digite a nota do aluno %d”,i);
scanf (“%f”,&notas[i]);
}
printf (“Médias das notas : %.2f”,soma/lim);

Inicializações: feitas em tempo de compilação (na declaração) só valem para variáveis das classes extern e static.
Não valem para classe auto.

Ex. :
#define lim = 5
int tab[lim] = {50,25,10,5,1}; /*tab é da classe extern */
void main( )
{ ...
}

27
Obs.: Podemos omitir a dimensão de uma matriz da classe auto. Se isto acontecer nas classes stac ou extern, a
matriz deve ser inicializada.

void main( )
{
static int tab[ ] = {50,25,10,5,1}
...
}

Matriz de mais de uma Dimensão


#define A 5 /*Batalha Naval*/
#define L 10
char inimigo[A] [L] =
{ {0,0,0,0,0,0,0,0,0,0}
{0,1,1,1,1,0,0,1,0,1} /* inimigo é da classe extern */
{0,0,0,0,0,0,0,1,0,1}
{1,0,0,0,0,0.0,1,0,0}
{1,0,1,1,1,0,0,0,0,0} };
void main( )
{
char amigo [A] [L]; /* amigo é da classe auto */
int x,y;
for (y = 0; y < A; y++) /* matriz bidimensional requer 2 for’s*/
for (x = 0;x < L; x++)
amigo[y][x] = ‘.’;
printf (“Digite coordenadas na forma x,y.\n”);
printf (“Use número negativo para sair.\n”);
while ( x >= 0) {
for (y = 0; y < A; y++){
for (x = 0; x < l; x ++)
printf (“%c”,amigo[y][x];
printf (“\n”);
}
printf (“\nCoordenadas : “);
scanf (“%d, %d”,&x,&y);
if (inimigo[y][x] = = 1 ) amigo [y][x] = ‘\xDB’;
else
amigo[y][x] = ‘\xBO’;
}
}

Strings : matrizes do tipo char, terminadas pelo caractere null(‘\0’).



ocupa 1 byte;

28
se string tem 15 posições
digite 14.

void main( )
{
char nome[15];
printf (“Digite seu nome : “);
scanf (“%s”,nome); /*leitura*/
 
 não tem &, pois cada letra está em 1 endereço diferente

quando scanf encontra 1 branco, insere \0, automaticamente.

Leitura

gets( ) : lê caracteres até encontrar \n(enter). Aí é incluído o \0. Caracteres brancos são aceitos como parte da string,
ao contrário de scanf( ).

Impressão

puts( ) : Imprime todos os caracteres até encontrar um \0; para imprimir mais de uma string por linha, use printf.

void main( )
{
static char salute[] = “Saudações”;
char nome [18];
puts (“Digite seu nome : “);
gets (nome);
puts (nome);
puts (&nome[4]);
puts (salute);
}

Saída :

Digite seu nome :


Hamilton Gomes
Hamilton Gomes
ilton Gomes
Saudações

Funções úteis encontradas em string.h:

não precisa de &



* strlen( )  aceita endereço da string como argumento e retorna o tamanho.

29

não conta caractere null.
exemplo: tam = strlen(nome);

* strcat(salute,nome)  concatena 2 strings : puts(salute) fica Saudações Hamilton Gomes.


* flag=strcmp(r1,resp)  compara string r1 com string resp, por exemplo: retorna 0 se iguais.
* strcpy  copia uma string em outra : ex: strcpy(b,msg); copia msg sobre b

V-Ponteiros
*Ponteiros são variáveis que armazenam endereços de memória de outras variáveis.
*Devem ser declarados.
*Utilizações:
 Passagem de parâmetros por referência
 Alocação dinâmica de memória
 Criação das estruturas de dados listas, pilhas, filas, árvores
 Tornam os programas mais rápidos
 Matrizes e strings odem ser declaradas de maneira simplificada

*Exemplo:

void main( )
{
int x =5, y = 6;
int *px, *py; /* px e py são variáveis que guardam endereços de outras vars. do tipo int*/
px = &x; /* valor da variável px é endereço de x*/
py = &y; /* valor da variável py é endereço de y*/
/* *px é o conteúdo apontado por px */
/* *py é o conteúdo apontado por py */
printf (“px = %u, *px = %d, &px = %u\n”,px,*px,&px);
printf (“py = %u, *py = %d, &py = %u\n”,py,*py,&py);
px++;
printf (“px = %u, *px = %d, &px = %u\n”,px,*px,&px);
py = px + 3;
printf (“py = %u, *py = %d, &py = %u\n”,py,*py,&py);
printf (“py - px = %u\n”,py - px);
}
Saídas:
px = 65488 ; *px = 5 ; &px = 65492
py = 65490 ; *py = 6 ; &py = 65494
px = 65490 ; *px = 6 ; &px = 65492
py = 65496 ; *py = -28 ; &py = 65494
py - px = 3

30
/*Exemplo de passagem de parâmetros por referência: as variáveis são entregues à função, logo, todos as
alterações feitas nas variáveis pela função chamada são vistas pela chamadora */
void main()
{
int x = 1, y = 1;
void altera (int *px, int *py); /* argtos. de altera são ponteiros */
altera (&x, &y); /* altera recebe endereços de x e y */
printf(“x = %d, y = %d”,x, y);
}
void altera( int *px, int *py)
{
*px = 3;
*py = 5;
}
Saída: x = 3, y = 5

/* Exemplo de string declarada como ponteiro: */


void main()
{
char *salute = “saudacoes”;
char *nome;
puts(“Digite seu nome:”);
gets(nome); puts(salute); puts(nome);
}

/* Exemplo de matriz declarada como ponteiro: */


#define TAM 25
void main()
{
float *mat; /* mat é o endereço de memória do 1o. elemento da matriz */
mat = (float *) malloc (TAM*sizeof(mat)); /*alocação dinâmica de 25 elementos da matriz*/
for (i=0;i<TAM;i++) {
printf(“Digite um inteiro:”);
scanf(“%d”,&mat[i]); /* leitura igual na alocação estática*/
}
for (i=0;i<TAM;i++)
printf(“matriz[%d] = %d”, i, mat[i]); /* impressão igual na alocação estática*/
getch();
free(mat);
}

/*Exemplo de passagem de argumentos na linha de comandos: passa.cpp */


/* argc = no. de argumentos digitados no prompt do dos c> */
/* argv[] é um vetr de strings - cada posição recebe um argto. digitado no prompt*/
/* argv[0] recebe sempre o nome do programa executavel, por ex. passa */

void main(int argc, char *argv[])


{

31
/* Programa que imprime número de argumentos e valor de cada argumento */
int j;
printf (“número de argumentos = %d”, argc);
for (j=0;j<argc;j++)
printf(“\n argumento %d = %s”, j, argv[j);
}
/* Exemplo de programa que recebe tamanho de uma matriz e um no. inteiro como argumentos da linha de
comando: */
void main()
{
int i, tam;
float *mat;
float valor;
if (argc != 3) {
printf(“Erro! Este programa requer 2 inteiros como parâmentros”);
exit(0);
}
tam = atoi (argv[1]); /* atoi converte alfanumérico (string) em inteiro */
valor = atof (argv[2]); /* atof converte alfanumérico (string) em float */
mat = (float *) malloc (tam * sizeof(float));
for (i=0;i<tam;i++)
mat[i] = valor;
for (i = 0; i<tam; i++)
printf(“mat[%d] = %f”, i, mat[i]);
free(mat);
}

Estruturas - Registros
Cada informação de um banco de dados é normalmente chamada de registro.
Um grupo de registros do mesmo tipo armazenados em memória secundária (discos,
fitas etc) é denominado arquivo.
Nosso programas processam informações que estão na memória principal (RAM). A
passagem de registros entre os arquivos residentes em disco e a RAM é denominada operação de I/O(input/output).
Quando um programa precisa de um registro que não está na memória principal, uma operação de I/O é iniciada e
“páginas”da memória secundária são levadas, pelo sistema operacional, para a memória principal. Este processo é
denominado paginação. Uma página é um bloco de bytes (2K, 4K, 8K etc, dependendo do sistema) que facilita
operações de I/O, uma vez que não é necessário transferir byte a byte e sim página a página as informações
processadas.

Cada registro é constituído por uma gama de informações pertinentes à natureza do dado representado. Por
exemplo: Em um arquivo de alunos de uma escola, os registros contêm as seguintes informações (campos):

32
nome, endereço, filiação, idade, turma

Na linguagem C, os registros são chamados de estruturas.


Definimos um tipo de estrutura através do comando typedef.
O tipo definido passa a ser referenciado em declarações de variáveis como fazemos com int, float, char etc.

/* Primeiro Exemplo*/
void main( )
{
typedef struct { /*define tipo de dados*/
int num; /*facil*/
char ch;
} facil;
facil xx1; /* declara variáveis xx1 e xx2 do tipo facil */
facil xx2;
xx1.num = 2;
xx1.ch = ‘z’;
xx2.num = 3;
xx2,ch = ‘y’;
printf (“%d, %c”,xx1.num, xx1.ch);
printf (“%d, %c”,xx2.num, xx2.ch);
}

/*Segundo exemplo */

typedef struct {
char titulo[30];
int regnum;
}livro;
livro livro1= /*inicialização*/
{“Helena”,102};
livro livro2 =
{“Iracema”,000};

void main( )
{
char numstr[81];
printf (“Digite um número de registro : “);
gets (numstr);
livro2.regnum = atoi(numstr); /*converte string em inteiro*/
printf (“Título : %s\n”,livro1.titulo);
printf (“Registro : %03d\n”,livro1.regnum);
printf (“Título : %s\n”,livro2.titulo);
printf (“Registro : %03d\n”,livro2.regnum);
}
Para agrupar várias estruturas em uma única variável, utilizamos matrizes:

33
/* Terceiro exemplo: */

livro bibilioteca[100];
for (i=0;i<100;i++) {
printf (“Digite titulo:”);
gets(biblioteca[i].titulo);
printf(“Digite codigo”);
scanf(“%d”,&biblioteca[i].regnum);
}

Arquivos

Um arquivo armazena informações em memória secundária (discos, fitas etc).


As informações de um arquivo podem ser do tipo caracter, string, inteiro, ponto flutuante ou estrutura.Existem dois
modos de gravação em arquivos:
 Texto: Tem uma marca EOF (fim de arquivo)
 Binário: Não tem uma marca EOF

Declaração de arquivo:

FILE *nome_do_arquivo_no_programa;

Abertura de arquivo:
nome_do_arquivo_no_programa=fopen(“Nome_Externo_do_Arquivo”, “tipo_abertura”);
Tipos de abertura de arquivos:

“r” - abrir arquivo texto para leitura. O arquivo deve estar presente no disco.
“w” - abrir arquivo texto para gravação - se existir, será destruído e reinicializado. Se não existir, será criado.
“a” - abrir arquivo texto para gravação - se existir, os dados serão adicionados no fim
“r+”- abrir arquivo texto para gravação e leitura - se existir, os dados serão atualizados
“w+”- abrir arquivo texto para gravação e leitura - se existir, será reinicializado
“a+”- abrir arquivo texto para atualizações e inserções no fim do arquivo

“rb” - abrir arquivo binário para leitura. O arquivo deve estar presente no disco.
“wb” - abrir arquivo binário para gravação - se existir, será destruído e reinicializado. Se não existir, será criado.
“ab” - abrir arquivo binário para gravação - se existir, os dados serão adicionados no fim
“rb+”- abrir arquivo binário para gravação e leitura - se existir, os dados serão atualizados
“wb+”- abrir arquivo binário para gravação e leitura - se existir, será reinicializado
“ab+”- abrir arquivo binário para atualizações e inserções no fim do arquivo

/* Exemplo de abertura e fechamento de arquivo: */


void main( )
{
FILE *fptr; /*fprt é um ponteiro para o arquivo*/
if ((fptr = fopen (“arqtext.txt”,”w”))== NULL) {

34
printf(“Erro de abertura de arquivo!”);
exit(0);
}
fclose (fprt);
}

Função de leitura de caractere de arquivo:


char caract;
caract = getc(nomearq);

/* Exemplo de Leitura de caractere de arquivo: */

void main( )
{
FILE *fptr; /*fprt é um ponteiro para o arquivo*/
char ch;
if ((fptr = fopen (“arqtext.txt”,”r”))==NULL) {
printf(“Erro de abertura de arquivo!”);
exit(0);
}
while ((ch = getc (fptr )) != ‘EOF’) /* Busca todos os caracteres de fptr e */
printf(“%c”,ch); /* imprime na tela */
fclose (fprt);  exit; é um sinônimo só que fecha o arquivo e encerra o programa.
}

Função de gravação de caractere em arquivo:

char caract;
putc(caract, nomearq);

/* Exemplo de Gravação de caractere de arquivo: */

void main( )
{
FILE *fptr; /*fprt é um ponteiro para o arquivo*/
char ch;
if ((fptr = fopen (“arqtext.txt”,”w”))==NULL) {
printf(“Erro de abertura de arquivo!”);
exit(0);
}

while ((ch = getche( )) != ‘\r’)


putc(ch,fptr); 
 /* return */
/* grava ch no arquivo fprt */
fclose (fprt);
}

35
Função de leitura de string de arquivo:

fgets(nome_string, tamanho_string, nomearq);

/* Exemplo de Leitura de String de arquivo */

void main( )
{
FILE *fptr; /*fprt é um ponteiro para o arquivo*/
char string[81];
if ((fptr = fopen (“arqtext.txt”,”r”))==NULL) {
printf(“Erro de abertura de arquivo!”);
exit(0);
}
while (fgets(string,80,fptr) != NULL)
puts(string); /* imprime na tela string lida de fptr*/
fclose (fprt);
}

Função de gravação de string em arquivo:

fputs(nome_string, nomearq);

/* Exemplo de Gravação de String em arquivo */

void main( )
{
FILE *fptr; /*fprt é um ponteiro para o arquivo*/
char string[81];
if ((fptr = fopen (“arqtext.txt”,”w”))==NULL) {
printf(“Erro de abertura de arquivo!”);
exit(0);
}
while (strlen(gets(string)>0) {
fputs(string,fptr); /* grava em fptr string lida da tela */
fputs(“\n”,fptr);
}
fclose (fprt);
}

Função de leitura formatada de arquivo:

fscanf(nomearq, “lista de formatos” , lista de variáveis);

/* Exemplo de Leitura Formatada de arquivo */

void main( )
{

36
FILE *fptr; /*fprt é um ponteiro para o arquivo*/
char titulo[30];
int regnum;
double preco;
if ((fptr = fopen (“arqtext.txt”,”r”))==NULL) {
printf(“Erro de abertura de arquivo!”);
exit(0);
}
while (fscanf(fptr,”%s %d %lf”, titulo, &regnum, &preco) != EOF)
printf (“%s %d %lf”, titulo, regnum, preco); /* imprime na tela dados lidos de fptr*/
fclose (fprt);
}

Função de gravação formatada em arquivo:

fprintf(nomearq, “lista de formatos” , lista de variáveis);

/* Exemplo de Gravação Formatada de arquivo */

void main( )
{
FILE *fptr; /*fprt é um ponteiro para o arquivo*/
char titulo[30];
int regnum;
double preco;
if ((fptr = fopen (“arqtext.txt”,”w”))==NULL) {
printf(“Erro de abertura de arquivo!”);
exit(0);
}
do {
printf (“Digite tiutlo, codigo e preco de um livro:”);
scanf(”%s %d %lf”, titulo, &regnum, &preco);
fprintf (fptr,“%s %d %lf”, titulo, regnum, preco); /* grava dados lidos em fptr*/
} while (strlen(tiulo > 1);
fclose (fprt);
}

Função de leitura de estrutura de arquivo:

fread(endereco_da_estrutura,tamanho_da_estrutura,
numero_de_estruturas_a_serem_gravadas, nomearq);

/* Exemplo de Leitura de estrutura de arquivo */

void main( )
{
FILE *fptr; /*fprt é um ponteiro para o arquivo*/
typedef struct {

37
char *titulo; /*string titulo definida como ponteiro */
int regnum;
float preco;
} tipo_livro; /* tipo_livro e um tipo de dado */
tipo_livro livro; /* livro é uma variável */
if ((fptr = fopen (“arqtext.txt”,”r”))==NULL) {
printf(“Erro de abertura de arquivo!”);
exit(0);
}
while (fread(&livro,sizeof(livro),1,out)==1) {
printf (“\n Titulo = %s”, titulo); /* imprime na tela dados lidos de fptr*/
printf (“\n Código=%d”, regnum); /* imprime na tela dados lidos de fptr*/
printf (“\n Preço =%f”, preco); /* imprime na tela dados lidos de fptr*/
}
fclose (fprt);
}

Função de gravação de estruturas em arquivo:

fwrite(endereco_da_estrutura,tamanho_da_estrutura,
numero_de_estruturas_a_serem_gravadas, nomearq);

/* Exemplo de gravação de estrutura de arquivo */

void main( )
{
FILE *fptr; /*fprt é um ponteiro para o arquivo*/
typedef struct {
char *titulo;
int regnum;
float preco;
} tipo_livro; /* tipo_livro e um tipo de dado */
livro; /* livro é uma variável */
char *aux; /* aux é string auxiliar */
if ((fptr = fopen (“arqtext.txt”,”w”))==NULL) {
printf(“Erro de abertura de arquivo!”);
exit(0);
}
do {
printf (“\n Titulo:”);
gets(livro.titulo);
printf (“\n Código:);”
scanf(“%d”,&livro.regnum);
printf (“\n Preço:);
gets(aux);
livro.preco=atof(aux);
fwrite(&livro,sizeof(livro),1,out); /* grava estrutura livro em fptr */
printf(“Adiciona outro livro? s/n”);

38
} while (getche() ==‘s’);
fclose (fptr);

Podemos usar fread/fwrite para leitura/gravação de matrizes inteiras. Exemplo:


int tabela[10] = {0,1,2,3,4,5,6,7,8,9};
void main() {
FILE *out;
if ((out = fopen(“TABELA.DAT”,”w”))==NULL) {
printf (“ Erro no arquivo!”);
exit(0);
}
fwrite(tabela,sizeof(tabela),1,out); /*grava tabela no arquivo out */
fclose(out);
}

Existe um comando para deslocamento de bytes dentro de um arquivo:

fseek(nomearq,número_de_bytes_a_serem_deslocados,opção_de_deslocamento);

Opções de deslocamento:

0 - a partir do início do arquivo


1 - a partir da posição corrente
2 - a partir do fim
“Caminha, e nos teus caminhos,
no rastro dos passos que
deixares, não te esqueças
de deixar o rastro de
teu sorriso”
Enderson, 1994

39