Você está na página 1de 289

Linguagem C Li

Prof. Rafael Fernandes Lopes


rafaelf@cefetrafaelf@cefet-ma.br 2008.2

Slides gentilmente cedidos pelo prof. Gentil


1

Introduo

Introduo I t d
C - Dennis Ritchie (Laboratrios Bell) ( ) Inicialmente para mquinas do tipo PDP-1 (com UNIX). Depois para os IBM PC e compatveis D i t i ( (ambientes MS DOS, e MS Windows) , )

O Standard ANSI-C St d d ANSI C


Verso C que segue a norma da American National Standard Institute (ANSI), e da g ( ) International Standards Organization (ISO). Os Compiladores da Borland foram os p primeiros a oferecer compatibilidade com esta norma (os compiladores de Turbo C a partir da verso 2.0).
4

Caractersticas C t ti
A linguagem C muito famosa e muito utilizada:

pela conciso de suas instrues; pela facilidade de desenvolvimento de Compiladores C; pela rapidez de execuo de programas; e principalmente pelo f t que o poderoso i i l t l fato d sistema operacional Unix foi escrito em C.

Um Programa Simples
#include <stdio.h>
/* um programa bem simples q que imprima: Ate logo. p g */

void { }
6

main ()

printf("Ate logo. ");

Exemplo 1 E l
#include <stdio.h> #define B 20 int a,s; int { } void main () { scanf("%d",&a); " " s=somar(a,B); printf("%d",s); }
7

/* 1 */ /* 2 */ /* 3 */ / /* 4 */ /

somar (int x int y) x, return (x+y);

/* 5 */ /* 6 */ /* 7 */ /* 8 */

Comentrios E 1 C t i Ex1
/* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ / /* 6 */ / /* 7 */ /* 8 */
8

incluso de um arquivo da biblioteca de C que implementa as funes printf, scanf... b deve ser substitudo por 20 declarao de duas variveis inteiras: a e s definio de uma funo somar definio da funo principal: main leitura do valor de a entrado pelo usurio chamada da funo somar com argumentos a e b impresso do resultado s da soma de a e b

Estrutura de um Programa C
Um conjunto de funes j A funo principal main obrigatria. A funo main o ponto de entrada principal do p g p p programa.
9

main i
void main () { declaraes instrues 1 instrues 2 ... instrues n }
10

As outras funes
Tipo nome (declarao-de-parmetros)

{ declaraes; instrues 1; instrues 2 i t 2; ... instrues n; i t }


11

Consideraes sobre as funes


O tipo da funo = tipo do valor que a funo retorna

Ele d El pode ser predefinido, ou d fi id d fi id definido pelo usurio.

Por default o tipo de uma funo int.


12

Compilao C il
Pre-Processadores:
Transformao lexical d t t d programa. T f l i l do texto do

Compiladores:
Traduo do texto gerado pelo pre-processador e sua transformao em instrues da mquina. q

Observao
Geralmente, o pre-processador considerado como fazendo parte integrante do compilador.
13

Tipos Bsicos

14

Principais ti P i i i tipos de Dados d D d


int i t float fl double char famlia dos f li d nmeros i t i inteiros famlia dos f li d nmeros pontot flutuantes (pseudo-reais) famlia dos caracteres

Observao: No tem o tipo Boolean!


15

Inteiros I t i
Podem receber dois atributos:
de preciso (para o tamanho) de representao (para o sinal)

Atributos de preciso:

short int int long int

: : :

representao sobre 1 byte p y representao sobre 1 ou p ( ) 2 palavra(s) representao sobre 2 palavras

16

Inteiros I t i
Atributos de representao

unsigned signed g

: :

somente os positivos positivos e negativos g

17

Combinao de Atributos - Inteiros


unsigned short int : rep. sobre 8 bits [0, 255] [ , ] signed short int : rep. sobre 7 bits
[-128, 127]

: rep. sobre 16 bits [0, 65535] signed int : rep sobre 15 bits rep. [-32768, 32767] unsigned long int : rep. sobre 32 bits g g p [0, 4294967295] signed long int : rep. sobre 31 bits [-2147483648, [ 2147483648 2147483647] unsigned int
18

Os Inteiros
Em Resumo, temos seis tipos de inteiros:

int; short int; long int;

todos signed

e

19

unsigned int; unsigned short int; g ; unsigned long int;

Pseudo-Reais P d R i
(representao da forma: M * 10EXP) Os flutuantes podem ser:
float : representao sobre 7 algarismos
[-3.4*10-38, 3.4*1038 ] double :representao sobre 15 algarismos [ [-1.7*10-308, 1.7*10308 ] long double : representao sobre 19 algarismos [-3.4*10-4932, 3.4*104932 ]
20

Caracteres C t
Um caracter representado por seu cdigo ASCII (cdigo numrico). Ele pode ser manipulado como um inteiro. Um caracter codificado sobre um b te m byte podemos representar at 256 caracteres.
21

Caracteres C t
O tipo : Char
char c,b; c = \65; b = c;

22

E o ti tipo String? St i ?
No existe em C o tipo string p g propriamente dito. Um substituo: os vetores de caracteres:
char nome[20]
23

E o ti tipo Boolean? B l ?
Ateno: O Boolean no existe em C! Isto geralmente substitudo pelo tipo int:
0 1
24

: :

false true

Em i t E sistemas 32 bit bits


char signed char unsigned char short unsigned short int unsigned int long unsigned long nsigned float double long double 1 1 1 2 2 4 4 4 4 4 8 10 -128 a 127 -128 a 127 128 0 a 255 -32,768 a 32,767 0 a 65,535
-2,147,483,648 a 2,147,483,647

25

0 a 4,294,967,295 -2,147,483,648 a 2,147,483,647 0 a 4 294 967 295 4,294,967,295 3.4E+/-38 (7 dgitos) 1.7E+/ 308 1.7E+/-308 (15 dgitos) 1.2E+/-4932 (19 dgitos)

DECLARAO DE VARIVEIS

26

Identificadores Id tifi d
Um identificador um meio para manipulao da informao Um U nome que i di uma varivel, indica i l funo, tipo de dados, etc. , p ,

27

Identificadores Id tifi d
Formado por uma combinao de caracteres alfanumricos Comea por uma l t d alfabeto ou C letra do lf b t um sublinhado, e o resto pode ser , p qualquer letra do alfabeto, ou qualquer d it numrico ( l i l dgito i (algarismo), ) ou um sublinhado.
28

Exemplos de identificadores E l d id tifi d


Exemplo:

nome_1; _a; Nota; nota; imposto_de_renda; imposto de renda; !x;


Ateno:

4_nota;

Os identificadores Nota e nota por exemplo representam duas variveis diferentes.


29

Regras para a nomeao


Como os compiladores ANSI usam variveis que comeam por um sublinhado, melhor ento no us-las. De D acordo com o standard ANSI C d t d d ANSI-C:

somente 32 caracteres podem ser considerados pelos compiladores, os outros so ignorados.

No usar as palavras chaves da linguagem.


30

Palavras Chaves P l Ch
(so 32 palavras)
auto break case char const continue default do
31

double else enum extern float for goto if

int long register return short signed g sizeof static

struct switch typedef union unsigned void volatile while

Declaraes D l
tipo lista-de-nomes-de-variveis

Exemplo: p

int i,a; double d1, d2; char c; h

32

Inicializao de Variveis I i i li d V i i
C no inicializa automaticamente suas variveis. Isto pode ser feito no momento da declarao: int i=1,j=2, k=somar(4,5); short int l=1; char c=\0;
33

Operaes

34

Atribuio At ib i
Exemplo:

i=4; a=5*2; d=-b/a; raiz=sqrt(d);

35

Exemplos de Atribuio E l d At ib i
i = (j = k) - 2; 5 3 (caso k=5) j=5 i=3

Atribuio mltipla: a=b=c=8;


36

Converso d Ti C de Tipos (1)


O compilador faz uma converso automtica float r1,r2=3.5; int i1,i2=5; char c1,c2=A; h 1 2 A
r1=i2; i1=r2; i1=c2; c1=i2; r1=c2; c1=r2;
37

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

r1 5.0 */ i1 3 */ / i1 65 */ c1 5 */ r1 65.0 */ c1 3 */

Converso d Ti C de Tipos (2)


int a = 2; float x = 17.1, y = 8.95, z; char c; c c c c = = = = (char)a + (char)x; (char)(a + (int)x); (char)(a ( h )( + x); ) a + x;

z = (float)((int)x * (int)y); z = (float)((int)(x * y)); z = x * y;


38

Adio/subtrao/multiplicao Adi / bt / lti li


Expresso1 + expresso2 Expresso1 - expresso2 Expresso1 * expresso2

As duas expresses so avaliadas, depois a adio/subtrao/multiplicao realizada, e o valor obtido o valor da li d l btid l d expresso.
Pode ter uma converso de tipos, depois da avaliao das expresses: float x,y; int z; x=y+z;
39

Diviso Di i (1)
Expresso1 / expresso2

Em C, o / designa no mesmo tempo a diviso dos inteiros e dos reais. Isto depende ento dos valores retornados pelas expresses:

Se os dois so inteiros ento a diviso inteira, mas se um deles real ento a diviso real.

40

Diviso Di i

(2)

Caso os dois operandos inteiros so positivos, o sistema arredonda o iti i t d d resultado da diviso a zero:
7 / 2 retorna 3

Caso os dois operandos inteiros so de sinais diferentes, o arredondamento depende da implementao mas p p geralmente feito a zero:
41

-7 / 2 ou 7 / -2 retornam -3 ou -4 (mas geralmente -4)

O Mdulo % Md l
Expresso1 % Expresso2 Retorna o resto da diviso inteira. R t t d di i i t i
7 % 2 retorna 1

Caso um dois operadores negativo, o sinal do mdulo depende da implementao, mas geralmente o sinal do primeiro
7 % 2 -7 % 2 7 % -2
42

retornam 1 retornam -1 retornam 1

Operadores Relacionais O d R l i i
Expresso1 op-rel Expresso2 Onde op-rel um dos seguintes smbolos: op rel Operador Semntica == igual g != diferentes > superior >= superior ou igual < inferior <= inferior ou igual O resultado da comparao um valor lgico: 1 (se a comparao verificada) e 0 (seno)

43

Operadores Lgicos
Para combinar expresses lgicas
Operador Semntica

&& || !

e ou negao

Exemplos:
a >= b > (a = = 0) || (b != 0) ! ((a = = 0) && (b<3))
44

Operador & O d
o operador de endereamento p (ponteiro): &a o endereo da varivel a acesso ao contedo da varivel a.

45

Incremento/decremento I t /d t
x = x + 1; ; x++; ++x; s+=i; z = y++; y ; z = ++y;
46

/* isto incrementa x */ /* isto incrementa x */ /* isto incrementa x */ / s=s+i / /* s=s+i*/ /* z = y e depois y++ */ p y /* y++ e depois z = y (novo) */

O decremento de igual modo

Regra
v = v operador expresso v operador= expresso operador

47

Condicional
a = (b >= 3.0 ? 2.0 : 10.5 );
if (b >= 3.0) a = 2 0; 2.0; else a = 10 5; 10.5;

c = (a > b ? a : b); c = (a > b ? b : a);


48

/ c maior(a,b) / /* c=maior(a,b) */ /* c=menor(a,b) */

Entradas e Sadas

49

Sadas S d
printf("Bom dia"); puts("Bom dia"); putch(a) printf
idade)

/* para imprimir um string */ / /* para imprimir um char */ /

("Meu nome : %s\ne tenho %d anos.", nome,

50

Entradas E t d
gets(s); char c; c = getch(); g (); c = getchar();
/* com echo */ /* leitura de um string */

scanf ("%d",&nome);
/* para a l it leitura d var. nome */ da

51

Constantes utilizados no printf C t t tili d i tf


\n \t \v \b \r \a \ \\ \% \{} \?
52

nova linha tabulao (horizontal) tabulao vertical um espao para trs um return um bip backslash o caracter % um apostrofo um ponto de interrogao

Converso de Tipos
d o x e u c s f
53

notao de decimal notao octal notao hexadecimal notao matemtica notao sem sinal notao de caracter notao de string notao de flutuante

Formatao
Cada um desses caracteres de converso utilizado depois do % para indicar o formato da sada (da converso) Mas, entre os dois podemos entrar outros argumentos:
54

Formatao
+ n 0n n.m justificar a esquerda o sinal sempre aparente o comprimento mnimo da sada (seno brancos) o comprimento mnimo da sada (seno 0s esquerda) para separar as partes antes e depois da virgula total de n dgitos cujo m so depois dgitos, da virgula. para indicar um long

l
55

Exemplo
#include <stdio.h> int main() { int a; long int b; short int c; unsigned int d; char e; float f; double g; a = 1023 1023; b = 2222 2222; c = 123 123; d = 1234; e = X; f = 3 14159 3.14159; g = 3.1415926535898; ... }

56

Exemplo
{
printf("a = %d\n", a); a = 1023 printf( a printf("a = %o\n", a); a = 1777 %o\n , printf("a = %x\n", a); a = 3ff printf("b = %ld\n",b); b = 2222 \ printf("c = %d\n", c); c = 123 printf("d = %u\n", d); d = 1234 printf( e printf("e = %c\n", e); e = X %c\n printf("f = %f\n", f); f = 3.141590 printf("g = %f\n", g); g = 3.141593 \
57

Exemplo
{ printf("\n"); i tf("\ ") printf("a = %d\n", a); printf("a = %7d\n", a); p printf("a = %-7d\n", a); ( \ , ); c = 5; d = 8; printf("a = %*d\n", c, a); printf("a = %*d\n", d, a); }
58

Exemplo
{
printf( \n ); printf("\n"); printf("f = %f\n", f); printf("f = %12f\n" f); %12f\n", printf("f = %12.3f\n", f); printf("f = %12.5f\n", f); p printf("f = %-12.5f\n", f); ( \ , );

}
59

Exemplo
As sadas so:

f f f f f

= 3.141590 = 3.141590 = 3.142 = 3.14159 = 3.14159

60

Diretivas de Compilao

61

Diretivas de compilao
So instrues para o pre-processador. Elas no so instrues C, portanto elas no terminam por uma virgula. Para diferenci-las das instrues C, elas p p p so precedidas pelo smbolo especial # Temos principalmente as seguintes diretivas:
#include #define #if, #else, # dif #if # l #endif
62

Incluso de Fontes: #i l d Fontes #include


#include <nome de arquivo>
Para a incluso de um arquivo arquivo. A busca do arquivo feita em primeiro no diretrio atual e depois no local das bibliotecas: p Em Unix: Em DOS: /usr/lib/include

APPEND (~ PATH, mas para os arquivos de dados e no para os executveis) Em Windows: isto especificado no ambiente
63

Incluso de Fontes: #i l d Fontes #include

#include #incl de

nome-de-arquivo nome de arq i o

Para a incluso de um arquivo usurio. Neste caso, a busca do arquivo feita apenas no diretrio atual. Seno, pode se especificar o caminho completo do arquivo
64

Exemplo de incluso E l d i l
... #include "f2.c" ...

f2.c
for (i=0;i<5;i++) p printf("Oi");

f1.c f1.c
... for (i=0;i<5;i++) printf("Oi"); ...
65

Arquivos h d A i headers ( h) (.h)


Arquivos headers standards: stdlib, stdio.h, conio.h, etc. t

Um arquivo header contm um conjunto de declaraes de variveis e funes. Observao: Os headers includos podem p tambm incluir outros arquivos (mas no pode existir uma referencia mtua)
66

Substituies: #d fi #define
#define MAX 60 #define TRUE 1 #define FALSE 0 #define BOOLEAN int
{

BOOLEAN a=FALSE; if (a = = TRUE) ...; else ...;


}

( (uma conveno: usar os masculos) )


67

Macro Substituies: #d fi #define


#define maior(A,B) ((A)>(B)?(A):(B)) f() () { ... maior(i+1,j-1); ... } A instruo maior(i+1,j-1) ser j compilada como se nos escrevemos: ((i+1)>(j-1)?(i+1):(j-1))
68

Outros Macros O t M
#define quadrado(a) (a)*(a) #define quadrado(a) a*a #define adicionar(a,b) ((a)+(b)) #define adicionar(a,b) (a)+(b) quadrado(3-2); (3-2)*(3-2) = 1 5 adicionar(2+1,4); 5 ((2+1)+(4)) 5*adicionar(2+1 4); 5*((2+1)+(4)) = 35
regra geral: colocar todas as variveis entre parnteses e o resultado tambm l d b
69

Substituies S b tit i parciais i i


#define MAX 60 ... #undef MAX #define MAX 45 ...
/*aqui MAX=60*/

/*aqui MAX=45*/

70

Compilao condicional (1) C il di i l


Objetivo: a otimizao #if (condio) corpo 1 [#else corpo 2] #endif

71

Compilao condicional (2)


#ifdef identificador corpo 1 #endif #ifndef identificador corpo 1 #endif
72

O const t
Para declarar variveis constantes podemos usar a palavra chave const const int N 20
Isto proibe que N seja modificado no programa (toda tentativa de modificao vai dar erro)

Diferena para o #d fi Dif #define: - Usando o const teremos uma reserva de um espao
na memria. Ele se aplica sobre qualquer tipo de var memria var. - O #define serve somente para o pre-processador que faz as substituies necessrias antes da compilao.
73

Estruturas de Controle

74

Blocos d instrues Bl de i t
{ declaraes instruo_1 ..... instruo_2 } Em um bloco pode-se declarar variveis, que ficam visveis somente no bloco bloco.
75

/*um bl /* bloco de instrues d i t delimitado por duas chaves*/

Instruo if I t if...else (1) l


if (condio) instruo_1; instruo 1; [else instruo_2;] Exemplos: E l if (a>=b) max=a; else max=b;
76

if (a!=0) x=-b/a; b/

Instruo if I t if...else (2) l


Qualquer instruo simples C pode ser substituda por uma instruo composta: if (d>0) (d 0) { x1=(-b-sqrt(d))/2*a; 1 ( b t(d))/2* x2=(-b+sqrt(d))/2*a; }
77

Instruo if if...else (3) else


Observao: o else refere-se ao ltimo if if (condio_1) instruo_1; instruo 1; else if (condio_2) instruo_2; instruo 2; else if (condio_3) instruo_3; instruo 3; else instruo_4;

78

Instruo if if...else (4) else


int a=3, b=2, c=1, d=0; if ( b) if ( d) b 2* (a>b) (c<d) b=2*a; else a=2*b; l 2*b seno, seno tem que escrever: if (a>b) { if (c<d) b=2*a; } else a=2*b;
79

Instruo if if...else (5) else


Observao: o else refere ao ltimo if seno tem que usar chaves ( (bloco) ) if (condio 1) (condio_1) { instruo_1; if ( (condio_2) di 2) instruo_2; } else if (condio_3) instruo_3; _
80

Observao
A condio no obrigatoriamente uma comparao. P d ser qualquer Pode l expresso retornando um valor que pode ser comparado a zero. d int b=0; if (b) { }

/* equiv. a: if(b!=0)*/ ...

81

Instruo switch (1) I t it h


escolha mltipla
switch (expresso) { case constante_1: instrues break; ; case constante_2: instrues break; b k ... default: instrues }

82

Instruo switch (2)


Quando as mesmas instrues devem ser executadas no caso de um conjunto de valores:
switch (expresso) { case val_1: ... case val_n:

}
83

instrues break; case val 3: val_3: instrues break; default: instrues

Instrues de Repetio

84

while hil
while (condio) instruo instruo Exemplo: c=s; while (c!=f) { c=getch(); }
85

pode ser simples ou composta.

fim d wh do hile

condio!=0 ? sim instrues

no

do...while (1) d hil


do instruo(es) i ( ) while (condio) o equivalente de repeat do Pascal. Ai t instrues d l do lao d repetio so de ti executadas pelo menos uma vez.

86

do...while d hil
do c=getch(); while (c==s)

(2)

instruo i t
fim f do do sim condio! 0 condio!=0 ?

no

87

for

(1)

for (expresso1, condio, expresso2) instruo(es) ( )


expresso1 avaliada s uma vez depois a condio

se condio OK, as instrues so executadas

depois a expresso2 antes de voltar a avaliar expresso2, novamente a condio


Exemplo: for (i=1; i<=10; i++) { printf( Vasco printf(Vasco da Gama ); Gama); }

88

for

(2)
expresso1 inicializao fim do for

condio!=0 ? sim

no

instrues i t
expresso2
89

for f

(3)

A novidade que as expresses podem ser instrues instr es mltiplas (separadas por virgula) irg la)
Exemplo: for (i=1,j=10; i<=j; i++,j--) { instrues; }

90

break b k
O break permite parar a instruo de d repetio (for, do ou while) ti ( )
Se temos vrios nveis, o controle volta , penltima estrutura de repetio. for (i 0 i 20 i ) f (i=0;i<20;i++) if (vet[i]==10) break;

91

continue
Utilizada dentro de uma instruo for, while ou do O continue permite parar a iterao atual e passar iterao seguinte seguinte. Exemplo: p for (i=1;i<20;i++) { if (vet[i]<0) continue; ... }
92

Funes

93

Definio d D fi i de uma f funo


Alm das funes predefinidas nos arquivos header da biblioteca (no diretrio LIB, usando o #include) O usurio pode definir novas funes. Exemplos de funes predefinidas da biblioteca: stdio.h, math.h, conio.h, , , , stdlib.h e dos.h

94

Ex. de funes: (stdio.h) E d f ( )


Principalmente:
puts gets printf i tf scanf

95

Ex. de funes: (math.h) E d f ( )


abs fabs exp ceil il floor pow pow10 hypot sqrt
96

mdulo de int. mdulo de real exponencial arredondar ao max d d arredondar ao min xy 10x hipotenusa raiz quadrada
double

int

abs(int)

double fabs(double) double exp(double) double d bl double double double ceil(double) il(d bl ) floor(double)

pow(double x,double y)

pow10(double)

double hypot(double, double)

sqrt(double)

Ex. de funes: (conio.h) E d f ( )


clrscr clreol delline insline gotoxy kbhit apaga a tela apaga o resto da linha apaga a linha atual insere uma linha
posiciona o cursor

void clrscr () void clreol () void delline () void insline ()


void gotoxy (int x, int y)

testa se tecla

int
int

kbhit ()
putch (int c)

putch imprima um char c getch leia char sem echo int t h herex posio x do cursor herey h
97

putch () t h int int i t wherex () wherey () h

posio y do cursor i d

Ex. de funes: (stdlib.h) E d f ( )


min max rand d exit
retorna o min retorna o max ret. num. alea. t l type min(type, type) type max(type, type) int i t rand() d()

ret. nvel de erro void exit(int) int random(int n) int randomize()

random ret. num. alea de 0 a n-1

randomize inicializa o gen. al.

precisa tambm de <time.h>


98

Ex. de funes: dos.h E d f


delay sound nosound parar o som sleep suspende em seg void sleep(unsigned s) l (unsigned exemplo: { sound(300); /* emitir um som de 300 Hz*/ delay(2000); /* esperar 2 segundos */ nosound(); / /* antes de parar */ /

99

Exemplos de f E l d funes
graphics.h
rectangle desenha um retngulo void rectangle (int e, int c, int d, int b)

string.h g

100

Definio d D fi i de uma funo f


tipo identificador ([lista de id.]) [lista de declaraes 1] { [lista de declaraes 2] lista de instrues }
101

Semntica S ti
tipo:
o tipo do valor devolvido pela funo

identificador: nome da funo lista dos identificadores: os parmetros p


formais

lista de declaraes 1: a lista de declarao


dos parmetros formais

lista de dec a aes 2: declarao das sta declaraes : dec a ao


variveis locais a funo

lista de instrues: so as instrues a executar


102

quando a funo chamada.

Exemplo E l
float media (a,b) float fl t a,b; b /* / declarao dos
parmetros formais */

{ float resultado; /* var. locais */ resultado=(a+b)/2; /2 return (resultado); }


103

/* retornar o res. ao remetente */

Os parmetros formais - opcionais


double pi () /* no temos param. p p
formais */

/* / no temos var. locais */ / return (3 14159) t (3.14159);

104

Observao Ob
A prototipagem da funo pode ser feita de uma vez: int min (int a, int b) { if (a<b) return (a); else return (b); }
105

Chamada de uma f Ch d d funo


identificador (lista de expresses) As expresses so avaliadas, depois passadas como parmetros efetivos funo de nome identificador.
{ int m_1, m_2; float p, d=4.5; (4,3); m_2 = max(6*2-3,10); ( , ); m_1 = max ( , ); p = d * pi(); }
106

Procedimentos P di t
Funes que no retornam valores: usando o tipo especial void void linha ()
{ printf("-------------------------\n"); }

Observao: no temos aqui a instruo return (o tipo especial void no existia nas primeiras verses da linguagem)
107

Omisso do tipo da funo!


C considera por defaut o tipo int. somar (int a, int b) { return (a+b); } Melhor no usar esta possibilidade.
108

Passagem dos Parmetros P d P t


int somar (int x, int y) { return (x+y); } void main () { int a=8, b=5, s; s = somar(a b); /*os parmetros efetivos*/ somar(a,b); }
109

Passagem por V l P Valor


Na chamada temos passagem de parmetros. p g p Mas, as modificaes dos parmetros formais no afetam os parmetros efetivos.

110

Passagem por Referncia


(ou por endereo)
Usar o operador de endereamento

&

void somar (int x, int y, int * som) { *som = x+y; } void main () oid { int a=5, b=6, s; somar(a,b, &s); printf("%d + %d = %d",a,b,s); }
111

Outro O t uso do void d id


void f (void) { ... } para indicar que a funo no tem parmetros

112

Declarao de Funes
Uma funo F conhecida implicitamente por uma outra funo G se elas so definidas no mesmo arquivo, e que F definida antes de G. Fora desse caso, e para um controle de tipo e um bom link preciso declarar as link, funes antes de usar.
113

Exemplo E l
void { } ... int maior (int x, int y) { return (x>y?x:y); }
/*a main pode ser definida antes*/
114

main

(void)

int maior (int, int); maior (2 8); (2,8);

Dois f D i formatos para a declarao t d l


int maior (); 1a

int maior (int x int y); 2a x, Mas, melhor usar o segundo formato que mais completo

115

Funes Iterativas
exemplo do fatorial long int fat (long int n) { long int i,res=1; for (i=1;i<=n;i++) res=res*i; return (res); }
116

Funes Recursivas F R i
exemplo do fatorial long int fat (long int n) { if (n == 1) return 1 t 1; else return (n*fat(n-1)); }
117

Exerccios
Escreva as funes real_dlar e dlar_real dlar real de converses Real Dlar e vice Real-Dlar versa. Escreva as verses recursiva e it ti E i iterativa da funo soma que retorna a soma dos n primeiros termos:
S(n) = 1 + 1/2 + 1/3 + ... + 1/(n-1) + 1/n

Escreve a funo S(n) tal que:


S(n) = 1/n - 2/(n-1) +3/(n-2) + ... - (n-1)/2 + n/1
118

Declaraes

119

Escopo d d l E das declaraes


so 4 escopos:

Um identificador declarado fora das funes, tem um escopo em todo o programa. Um parmetro formal de uma funo, tem um escopo local funo. Um identificador declarado em um bloco tem um escopo local ao bloco. bloco Uma etiqueta de instruo, tem escopo em toda a funo onde ela declarada declarada.

120

Visibilidade d identificadores Vi ibilid d dos id tifi d


int i=1; j ; int j=1; void p() { int i 2; i=2; int k;

/ /* este i cobre o precedente */ /

if (a==b) { int i=3;


int j=2; int k;

/*cobre o i precedente*/ / /* cobre o j precedente / precedente*/ /*cobre o k precedente*/

}
121

Durao vida d uma varivel D id de i l


Variveis Estticas:
Alocao no incio do programa e liberao no final da execuo do programa.

Variveis Automticas V i i A t ti
Alocao na entrada de uma instruo composta (um bloco) e liberao na sada sada.

Variveis Dinmicas
A declarao e liberao so explicitamente realizadas pelo programador (usando malloc e free). Mas, essas funes so da biblioteca e no fazem parte integrante da linguagem.
122

Durao vida d uma varivel D id de i l


A durao de vida de uma varivel depende p normalmente de seu escopo de declarao: varivel global varivel l i l local l var. esttica var. automtica t ti

123

Durao vida d uma varivel D id de i l


As variveis globais so variveis estticas. g As variveis locais podem ser estticas ou automticas (dependendo do programador) programador), usando os qualificadores de classes de armazenagem: static e auto. , Por default, uma varivel local automtica.

124

Indicadores de classes de memria


Em C, temos quatro indicadores de classes , q de memria:

auto static t ti register extern


125

auto t
{auto int i; ... }
Este tipo de indicador autorizado somente para as variveis locais a uma instruo composta (um bloco). ( bl ) Ele indica que a varivel tem uma durao q de vida local ao bloco. O uso deste indicador quase inexistente, pois inexistente por default toda varivel local automtica
126

static
{static int i; ... }

O static indica que a varivel tem uma durao de vida ao longo da execuo do programa. Mas que ela fica local ao bloco (ela fica desconhecida fora de seu bloco). Portanto, a varivel guardar seu valor para cada chamada ao bloco.

Este indicador pode ser usado para as


declaraes de variveis e funes. d l d i i f
127

exemplo de uso de static


void f () { static int num_chamadas = 0; num_chamadas++; num chamadas++; / /* para contar
quantas vezes f foi chamada */

}
A varivel num_chamada inicializada somente uma vez Tem durao de vida ao vez. longo da execuo do programa. Mas ela tem escopo local.
128

register
{register int a,b; ... }
Este tipo de indicador autorizado somente para as variveis locais a uma instruo composta (um bloco) e para as declaraes de parmetros de funes. Ele tem o significado do auto alm de provocar o auto, armazenamento da varivel em um registro e no na memria. acesso mais rpido. i id Claro que isto depende das capacidades da mquina (nmero e tamanho dos registros)
129

extern t
int a; void f() { {... extern int a; ...} }

Os outros indicadores so relacionados s variveis locais ari eis locais. Uma varivel global definida fora de qualquer corpo de funo. l d f O extern permite usar (acessar) uma varivel que definida fora.

Este indicador auto ado para as ste d cado autorizado pa a


declaraes de variveis e funes.
130

Classes d memria (1) Cl de i


Na execuo de um programa, existe trs zonas de memria: onas memria

Zona das variveis estticas ; Zona das variveis automticas (organizada em forma de pilhas pois as funes podem ser pilhas, recursivas)

Zona das variveis di i Z d i i dinmicas ( (organizada em forma de i d f d monto ou tas / stack) monto

131

Classes de memria (2)


Esta diviso existe nas outras linguagens, mas a alocao feita pelo compilador. Ao contrrio, em C a declarao da classe contrrio da varivel feita pelo prprio programador. d auto, auto static e register so indicadores de classe de memria (mas
132

o extern no realmente)

Tabelas

133

Tabelas T b l
O objetivo da estrutura de tabela agrupar um conjunto de informaes de p mesmo tipo em um mesmo nome. Uma tabela pode ser multidimensional ou unidimensional (vetor). dimensional

134

Declarao
float vet[10]; [ ]; long int v1[8], v2[15];
/* v1 um vetor de 8 long int e v2 um vetor de 15 long int */

Os elementos so indexados de 0 a N-1


135

Dimenso Di
Na prtica, recomendado definir sempre uma constante que indica o nmero de elementos: l t #define N 60 short int v[N];
/* declara um vetor de 60 inteiros indexado de 0 a 59 */
136

Acesso aos elementos A l t


Sintaxe: nome-varivel [expresso]
expresso deve retornar um inteiro (o indexador) p ( )

Exemplos: vet[0]=6; vet[4+1] 2; vet[4+1]=-2; x=3*vet[2*a-b];


137

Inicializao I i i li
#define N 4 int v[N]={1,2,3,4};
Incializao de somente uma parte do vetor:

#define N 10 int v[N]={1,2}; //o resto ser zerado


Inicializao p pelo mesmo valor:

for (i=0;i<=9;i++) v[i]=2;


Inicializao pelo usurio:

for (i=0;i<=9;i++) scanf("%d",&v[i]);


138

Operadores abrangentes O d b t
lembramos que:
x++ i ++ incrementa x mas retorna o valor inicial t t l i i i l ++x incrementa x e retorna o valor incrementado i=0; v[i++]=0; /* v[0]=0 e i=i+1 */ v[i++]=0; [ ] ; / v[1]=0 e i=i+1 */ /* [ ] / i=1; v[++i]=0; v[++i]=0; /* i=i+1 e v[2]=0 */ /* i=i+1 e v[3]=0 */

idem para o operador -139

Uso da instruo nula U d i t l


Inicializao de um vetor:
for (i=0;i<10;v[i++]=1); Isto equivalente a: q for (i=0;i<10;i++) v[i]=1;

Pesquisar em um vetor:
for (i=0; i<N && t[i]!=10; i++);
/* usando a instruo nula */ d i t l

Isto equivalente a: for (i=0; i<N; i++) if t[i]==10 break;


140

Tabelas MultiDimensionais T b l M ltiDi i i


Matrizes
Declarao:
int mat [3][4];
/* matriz bidimensional de li h d 3 linhas 4 colunas */ l

Inicialiazao:
int mat [3][4] = { {5,6,8,1}, {4,3,0,9}, {12,7,4,8}, }

141

Exemplo E l
/* Declarao: */
#define L 4; #define C 3; int mat[L][C]; [ ][ ];

/* leitura: */
for (i=0;i<=L;i++) for (j=0;j<=C;j++) { printf("digite o elemento [%d,%d]: ",i,j); scanf("%d",&mat[i][j]); }

142

Observao 1 Ob
for (i=0,j=0;i<L && j<C;i++,j++) {
printf("digite o elemento [%d,%d]: ",i,j); scanf("%d",&mat[i][j]);

} no a mesma coisa que:


for (i=0;i<=L;i++) for (j=0;i<=C;j++) { printf("digite o elemento [%d,%d]: ",i,j); scanf("%d",&mat[i][j]); &mat[i][j]); }
143

Observao 2 Ob
int sum (int n) { int res=0; for (;n>0;n--) /*n inicializada na chamada / (;n>0;n ) / n chamada*/ res=res+n; return (res); ( ) }
chamada: sum(5)

O que faz este cdigo?


144

Exerccios
A.1 Escreva o procedimento ini_num_dias que inicializa um vetor num_dias[12] q indica para cada [ ] que p ms do ano seu nmero de dias: (num_dias[i] indica o nmero de dias do ms i do ano), sabendo que:
Se i=2 ento num dias=28; num_dias=28; Se (i par e i<=7) ou (se i impar e i>7) ento num_dias=30 Seno num_dias=31.

A.2 Escreva o procedimento imp_num_dias que imprima os nmeros de dias de todos os meses do ano. B. Escreva a funo ordenar que ordena um vetor.
145

C. Escreva a f C E funo palindromo que d determina se um i vetor um palindromo.

Tipos Enumerados

146

enum
A enumerao permite de agrupar um conjunto de constantes (compartilhando a mesma semntica)

exemplos:
enum dias {Domingo, Segunda, Tera, Quarta, Quinta, Sexta, Sbado};

declarao:
dias d1,d2=Quinta; , Q

enum defini um novo tipo cujo os elementos so numerados automaticamente de pelo compilador: 0 1 2 ...
147

Exemplo E l
#include <stdio.h> enum dias {Segunda Tera Quarta Quinta {Segunda,Tera,Quarta,Quinta, Sexta,Sbado,Domingo} d; // d uma varivel declarada de tipo dias void main (void) { // di dias d uma outra maneira de declarar d; t i d d l for(d = Segunda ; d < Domingo ; d++) printf(O cdigo do dia : %d\n , d); %d\n" }
Vai imprimir os valores dos dias:
148

0 1 at 6 0, 6.

enum
Essa numerao permite comparar os elementos do tipo: if (d1<=d2) ... Portanto podemos mudar essa numerao:
enum boolean {true=1,false=0};

Quando um item no numerado ele pega o valor de se precedente alor seu precedente:
enum temperatura { {baixa=2,media=4,alta}; , , };
149

Ponteiros

150

Variveis Di i V i i Dinmicas
Todas as variveis vistas at agora so estticas (reserva imediata na memria), contudo precisamos de variveis dinmicas Um ponteiro uma referncia sobre um objeto na memria ( um endereo).

151

Variveis Dinmicas
Exemplo de Declarao de Ponteiros: p float * pf
/* declara que pf um ponteiro sobre um real */

pf 4.6
152

Os O O Operadores & e * (1) d


O operador de endereamento & se aplica sobre uma varivel e permite retornar seu endereo memria O operador de indireo * se aplica sobre um ponteiro e permite p p p retornar (manipular) o objeto apontado.
153

Os Operadores & e * (2)


*P

P
(Ponteiro)

V
(Varivel)

&v
154

Exemplo E l
int i,j; int *pi;
/* pi um ponteiro sobre um inteiro */

i=5; pi=&i; *pi=6; j=*pi-2; pi=&j; i &j


155

pi &i &j 56 i 4 j

Exerccio
1. Declare um inteiro i e um ponteiro p sobre um inteiro 2. 2 Inicialize o inteiro com um valor qualquer 3. Aponte o ponteiro sobre a varivel i 4. Imprima o valor de i 5. 5 Modifique o valor de i usando o ponteiro 6. Imprima o novo valor de i
156

int i; int * p; i=8; p=&i; printf("i= %d\n",i); *p=5; p=5; printf("novo i= %d\n",i);
157

/* 1 */ /* 1 */ /* 2 */ /* 3 */ /* 4 */ / /* 5 */ / /* 6 */

Passagem de Parmetros P d P t
Passagem de parmetros (dois tipos):

por valor l por referncia (passar o endereo da varivel)

Estratgias adotadas pelas linguagens:


Todo feito por referncia

(FORTRAN, PL/1)

Temos a escolha entre a passagem por valor p g p ou por referncia (caso de PASCAL) Toda passagem feita por valor (caso de C)

158

Estratgia d E t t i de C
Em C, toda passagem de parmetros portanto feita por valor. Como ento fazer as passagens por referncia? A soluo de declarar os parmetros formais de tipo ponteiro ponteiro. Isto feito pelo uso do operador & (usado na chamada a funo).

159

Exemplo E l
void
{ }

adicionar (int a, int b, int * res)


observe a declarao de res p como um ponteiro sobre um inteiro: um endereo

*res=a+b;

void main (void) { int i,j,k; j adicionar (i,j,&k); }


160

observe que na chamada tem que passar o endereo da varivel onde deseja-se recuperar o resultado

Um outro exemplo
A funo troca
void troca (int * x, int * y) { int temp; temp=*x; *x=*y; *y=temp; }

chamada da funo troca(&a,&b);


161

/* passagem por referncia */

Funes Genricas
O problema que esta funo troca que ns definimos se aplica somente sobre os inteiros p void troca (void * x, void * y) { int temp; temp=*x; *x=*y; * * *y=temp; } Infelizmente isto no pode ser feito em C Mas o problema resolvido em C++
162

Tabelas e Ponteiros

163

Relao t T b l R l entre Tabela e P t i Ponteiros


O nome de uma tabela no um identificador de
dados mas um ponteiro: d d t i :
#define N 45 int t[N];

o endereo do primeiro elemento: t[0] t=&t[0] t[i] = *(t + i)

t + i: Incrementa de i vezes o tamanho dos bj t d d objetos do vetor (e no de i unidades) t ( d id d )


164

Conseqncia 1 C i
Trs conseqncias principais da considerao que uma tabela um id t b l ponteiro: O operador de indexao [ ] no til: p Mas ele foi adotado pela linguagem parar no quebrar os costumes dos g programadores
165

Conseqncia 2
Manipulao de sub-tabelas:
int t[10]; int * p; p=&t[2];
0 1 2 3 9

p t

podemos escrever ento p[0], p[1]...


(p[0]=t[2],...)
166

Conseqncia 3 C i
O operador de indexao comutativo: t[i] = i[t] isto i t porque a adio comutativa: di t ti
t[i] i[t] *(t+i) *(i+t)

Mas, por razes de legibilidade do programa esta possibilidade muito pouco utilizada.
167

Aritmtica dos Ponteiros


Podem ser efetuadas operaes de adio p e de subtrao sobre os ponteiros ou entre ponteiros e inteiros. Esta possibilidade usada para manipulao de tabelas

168

Ilustrao do Clculo de Ponteiros Il t d Cl l d P t i


#define N 10 int t[N]; i t t[N] int *p, *q, *r, *s; p=&t[0]; q=p+(N-1); r=&t[N-1]; &t[N 1] s=r-(N-1);
169

/*aponta sobre o 1o elem do vetor*/ /*aponta sobre o ltimo elem do vetor*/ /*aponta sobre o lti /* t b ltimo elem do vetor*/ l d t */ /*aponta sobre o 1o elem do vetor*/

Passagem d P t P de Parmetros
Em C uma tabela pode ser passada como parmetro a uma funo Quando isto feito, em realidade, o endereo do primeiro elemento que passado como parmetro. A passagem ento feita por referncia. O parmetro formal da funo chamada deve ento ser declarado de tipo ponteiro p p
170

1a Abordagem
void imp_tabela (int * t, int num_elem)

{ int i; for (i=0;i<num_elem;i++) printf("%d",*(t+i)); i tf("%d" *(t+i)) }


chamada: imp_tabela(tab,N);
/* que equiv. a: */

imp_tabela(&tab[0],N); i t b l (&t b[0] N)


171

Crtica C ti
Este mtodo apresenta inconvenientes: p A declarao e a chamada no parecem muitos naturais para os programadores
Na declarao int * t no mostra se t aponta sobre um inteiro ou sobre uma zona de p inteiros (a tabela)

172

2a Ab d Abordagem
Por esta razo, C permite uma declarao mais natural dos parmetros formais: p
void imp_tabela (int t[],int n) { int i; for (i=0;i<n;i++) printf("%d",t[i]); }

Ateno: No preciso conhecer o tamanho exato da tabela. o tamanho geralmente passado como g p parmetro separado.
chamada:
173

imp_tabela(tab,L); i t b l (t b L)

Tabelas M lti Di T b l Multi Dimensionais i i


No caso de uma tabela multidimensional somente a primeira di t i i dimenso pode no d estar especificada:
int min (int m[][C], int l) { int i,j,min=m[0][0]; for(i=0,j=0;i<l&&j<C;i++,j++) if (m[i][j]<min) min=m[i][j]; return(min); }

chamada: min(mat,L);
174

Algumas consideraes Al id
A funo min aplicada a uma tabela que tem qualquer nmero de linhas, mas deve ter um exato C de linhas colunas. As outras dimenses ( 1a) devem ser especificadas por ), que o compilador precisa para gerar o cdigo que permite o acesso aos elementos: No caso de uma matriz binria t por exemplo, o endereo de t[i][j] : t+(i*C+j)*T (T o tamanho de um elemento de t, C o nmero de colunas) Representao da tabela na memria:
175

11 12 13 14 21 22 23 24 31 32 33 34 41...

Modificao dos elementos M difi d l t


void f (int t[],int nb_elem) { int i; for (i=0;i<nb_elem;i++) t[i]++; }
a chamada: f(tab,L); /* j que a passagem d parmetros f it por referncia de t feita f i ento qualquer modificaes sobre o vetor fsica */ O que faz esta funo?
176

Tabelas d T b l de ponteiros t i
possvel declarar uma tabela de ponteiros: exemplo: #define N 15 char * tab[N]; /* declara um vetor de ponteiros
sobre elementos de tipo caracter */ /

acesso: *tab[i]
tab

177

*tab[i]

Objeto apontado

Ponteiro de Ponteiro

178

Ortogonalidade do operador * Ot lid d d d


J que um ponteiro uma varivel como as outras, muito normal que um ponteiro aponte sobre um ponteiro Um exemplo um ponteiro sobre um ponteiro sobre mais um inteiro

declarao: int **ppint


pp ppint
179

int

Argumentos do main A t d i
Um programa C pode ser chamado externamente com alguns parmetros: t t l t A funo main recebe sempre dois parmetros:

argc (argument count) que determine o nmero de argumentos da linha de comando; e argv (argument vector), que um ponteiro sobre uma tabela de ponteiros sobre strings:

180

argv
um ponteiro sobre um vetor de ponteiros sobre strings: char * argv[]; g []; argv[0] aponta sobre o nome do arquivo (nome do programa)
argv[i] vai apontar sobre os argumentos passados ao programa na linha de comandos.
181

exemplo
Suponha: programa achar_max pega como parmetros um conjunto qualquer de strings e que deve determinar e imprimir a maior string:

argv achar_max\0 \0 \0 \0
argv[0] o nome do programa: achar_max,e os outros argv[i] so os argumentos passados ao programa na linha de comandos.

182

#include <stdio.h> #include <string.h> void main (int argc, char * argv[]) { int com_max=0, arg_max=0; argc--; while (argc>=1) { if (strlen(argv[argc])>com_max) { com_max=strlen(argv[argc]); arg_max=argc; } argc--; } if ( (arg_max) printf("O string maior % " argv[arg_max]); ) i tf("O t i i : %s", [ ]) } 183

Strings

184

String ~ Vetor St i V t
Um string um conjunto de caracteres. Em C, um string uma estrutura equivalente estrutura de vetor, A nica diferena que o string termina sempre pelo caractere \0 Isto para facilitar o tratamento dos strings p g (para poder detectar o fim do string)
185

Declarao D l
O tipo string no existe em C, Portanto existe duas maneiras para simular este tipo de variveis:

Como um vetor de char, ou Como um ponteiro sobre uma zona de chars

186

Como V t d C C Vetor de Caracteres t


Declarao: #define N 20 #d fi char ch [N];

Os strings declarados como vetor de chars tm um tamanho limite fixo (o tamanho do vetor). Se o tamanho do string menor do que o tamanho do vetor, o compilador C completa pelo caractere especial \0 para indicar o fim do string.

187

Inicializao de Vetor de Caracteres I i i li d V t d C t


A inicializao de um vetor de char pode ser feita, no momento da declarao, de duas maneiras:
1. Atribuindo um conjunto de caracteres:
char ch [20]={e,x,e,m,p,l,o}; (como normalmente feito para inicializar qualquer tipo de vetor). vetor)

2. Atribuindo um string ( mais prtica):

char ch[20]= "exemplo"; O tamanho pode ou no estar especificado: char nome[]="este tem 23 caracteres";
188

Acesso aos El A Elementos t


feito de uma maneira normal, como para qualquer q alq er tipo de vetor: etor
#define N 3 char ch [N]={O,i}; ch[0]= H /* refere ao 1o caractere */ ch[1] /* refere ao 2o caractere */ ... ch[N-1]
189

O i

\0

H i

\0

/* refere ao Nsimo caractere */

Como P t i sobre Caracteres C Ponteiro b C t


A manipulao dos strings como vetores de caracteres pode aparecer como pouco prtica. Portanto, podemos criar strings de tamanho dinmico usando um ponteiro sobre um char: char * ch = "exemplo"; exemplo ;

Contrariamente outra maneira, a reserva do espao memria no feita no momento da declarao, mas dinamicamente no momento da atribuio. atrib io
190

Inicializao e Atribuio I i i li At ib i
A Inicializao feita diretamente por uma string:

char * ch = "exemplo"; exemplo ; C completa o string pelo caracter \0 indicando


o fim do string.

A Atribuio tambm direta (contrariamente ao vetor de char):

ch ch = "uma mudana"; ch = " "outra mudana"; d " uma mudana\0 outra mudana\0
Isto I t no uma copia mas uma atribuio de ponteiros. i t ib i d t i
191

Manipulao d Strings M i l de St i
As funes de manipulao de strings so definidas no arquivo da biblioteca string.h

Temos principalmente as seguintes funes: strcpy, strlen strcat, t t strcmp, strchr, strchr
192

strncpy strncat t t strncmp strrchr

Strcpy/strncpy
A funo especial strcpy permite atribuir um valor texto a uma varivel de tipo texto: O strcpy apresenta dois formatos de uso:
strcpy(string1,string2); strncpy(string1,string2,N);

exemplo:
char *ch1="boa", *ch2="noite"; strcpy(ch1,"isto um exemplo"); strncpy(ch2,ch1,4); /* ch2 vai pegar "isto" */
193

strlen
strlen permite retornar o tamanho de um string: nmero de chars que compem o g string (o \0 no faz parte) exemplo:
int a; char * nome; strcpy(nome,brasil ); strcp (nome brasil") a=strlen(nome); /* a=6 */
194

strcat/strncat
strcat se aplica sobre dois strings e retorna um ponteiro sobre a concatenao dos dois. exemplo:
char *ch1="boa", *ch2="noite", ch1= ch2= *ch3, *ch4;

ch3=strcat(ch1,ch2); ch4=strncat(ch1,ch2,3); printf("%s %s",ch3,ch4);

/* vai imprimir boanoite boanoi*/

195

strcmp/strncmp
Lembramos que as letras so ordenadas dando seu cdigo: a< ... z< A...<Z a < z < A < Z

strcmp compara dois strings s1 e s2 e retorna um valor: negativo se s1 < s2


0 positivo se s1 == s2 se s1 > s2

exemplo: l
*ch1="boa tarde", *ch2="boa noite"; ch2 ; int a,b; a=strcmp(ch1,ch2); b=strncmp(ch1,ch2,4); b=strncmp(ch1 ch2 4); char
196

/* a vai receber um valor >0 e b 0*/

strchr/strrchr t h / t h
strchr procura por um caractere em um string e retorna um ponteiro sobre sua ltima ocorrncia, seno retorna null. t exemplo:
char ch[]="informtica"; [] char *pc, c='f';

pc=strchr(ch,c);
if (pc) /* i.e. if pc!=null */ printf("%d",*pc); else printf("Caractere inexistente"); O strrchr faz a busca no senso inverso.
197

touppar/tolower
toupper converte um caractere minsculo em maisculo. tolower faz o contrrio. # include <ctype.h>
char c='a';

c=toupper(c); pp ( ) c=toupper(c); c=tolower(c); ( );


198

/* c= 'A'

*/

/* c j esta ='A' */ /* c volta a ser 'a' */

Exerccios 1
A. Defina a funo ocorrncia que retorna o
nmero de ocorrncias de um caractere em um string.

B.1 Defina a funo tamanho1 que pega como


parmetro um vetor de caracteres e retorna seu comprimento.

B.2 Defina tamanho2 que implementa a mesma funo


mas que pega como parmetro um ponteiro sobre uma zona de caracteres caracteres.

B.3 Defina o main que chama essas duas funes.


199

int tamanho1 (char s[]) /* com um vetor */ { int i=0; while (s[i]) /* equiv. while (s[i]!= '\0' ) */ i++; return (i); } int tamanho2 (char * s) /*com os ponteiros*/ { int i=0; while (*s) /* equiv. while (*s!= '\0 ') */ {i++;s++;} return (i); ( ) }
200

void

main (void)

{
char ch[]="So Luis"; int a,b; a=tamanho1(ch); b=tamanho2(ch); /* a= 8*/ /* b= 8*/

printf("O tamanho de %s : %d\n",ch,a); printf( O printf("O tamanho de %s : %d\n",ch,b); %d\n ,ch,b);

201

Exerccios 2: C i t E i 2 Criptografia Simples fi Si l


1. Defina as funes Criptar e Decriptar que codificam e decodificam um caractere aplicando o p seguinte algoritmo de criptografia: - Um caractere substitudo por um outro aplicando um shift de 3 (por exemplo a seria substitudo por D). - Apenas os caracteres do alfabeto so codificados. - Os masculos passam a ser minsculos e vice-versa. 2. Defina a funo main que leia e codifica ou decodifica uma mensagem usando as funes definidas acima.

202

Tipos usurios

203

typedef t d f
Podemos definir novos tipos usando o typedef: typedef <tipo> <sinnimo> exemplo: l
typedef float largura; typedef float comprimento; largura l l l; comprimento c=2.5; l=c; l //* warning *// i
204

typedef e struct t d f t t

O typedef se usa mais com o tipo struct (as estruturas)

205

Estruturas

206

Declarao: mtodo 1
struct cliente { int cpf; char nome [20]; char endereco[60]; };

struct cliente c1,c2,c3;


207

Declarao: mtodo 2 D l t d
Podemos criar estruturas sem nome: struct { t t int cpf; char nome [20] h [20]; char endereco[60]; } c1,c2; 1 2 Problema: para criar uma outra varivel de mesmo i t i l d tipo em outro lugar do programa preciso rescrever tudo tudo.
208

Declarao: mtodo 3 D l t d
Podemos, no mesmo tempo, dar um nome estrutura e declarar as variveis: struct cliente { int cpf; char nome [20] h [20]; char endereco[60]; } c1,c2; 1 2

struct cliente c3; li 3


209

Declarao: mtodo 4 D l t d
Definindo um tipo estrutura typedef struct { int cpf; char nome [20]; char endereco[60]; } Cliente; Cliente
210

c1,c2={28400,"Maria","Rua Liberdade, N. 140"};

Acesso aos Campos


Usando o operador de seleo: . (o ponto) nome-estrutura.nome-do-campo exemplo: retorna o campo nome da estrutura c1: Maria c2.nome=" Jeane" Muda o contedo de nome c2.nome
211

Exemplo
void { imprimir_cliente (Cliente c)

printf("cpf: %d\n%s\n%s", c.cpf,c.nome,c.endereco); }

chamada da funo: imprimir_cliente (c2);


212

Combinao de Estruturas
Podemos definir estruturas de estruturas, estruturas d vetores, t t t t de t vetores de estruturas.... exemplo
typedef t d f struct {int num; char * rua; t t {i t h char * bairro; int cep} End; struct {int cpf; char * nome; End endereco} Pessoa;

typedef
213

Vetores d Estruturas V t de E t t
Podemos criar um vetor de estruturas (dois mtodos): exemplo: struct cliente vet[100]; /* seguindo o mt. 1*/ Cliente vet[100]; /*seguindo o mt. 4*/ declara um vetor de 100 clientes. Referencia aos elementos: Para referenciar o nome do isimo cliente do vetor: vet[i].nome
214

Exerccio E i
Escreve um programa C que:

Declara um vetor de alunos: turma (um aluno definido pelo cpd, nome, trs notas, mdia, e conceito) Preenche esse vetor (campos: cpd, nome, e notas). Preenche os campos mdia e conceito (bom se mdia8, regular se 7 e ruim seno); Define a funo que imprime todos o elementos do vetor. Define a funo que pesquisa um elemento do vetor (pesquisa pelo nome, pelo cpd, ou pelo conceito). ( i l l d l it )

215

Estruturas e Ponteiros

216

Estruturas di i E t t dinmicas
Usando as estruturas e os ponteiros p podemos entrar no mundo das estruturas auto referenciais: Listas, Arvores, Grafos, etc. Listas Arvores Grafos etc

217

Ponteiros sobre uma Estrutura P t i b E t t


typedef struct { char * nome; int idade; } Pessoa ; Pessoa pess; /* pess uma varivel de tipo pessoa */ Pessoa *pp; /* p um ponteiro sobre uma pessoa */ pp=&pess; /* p agora aponta sobre a pessoa pess */
218

Ponteiros sobre uma Estrutura P t i b E t t


pess.idade=18; pess.nome joao ; pess.nome="joao";

Para acessar aos campos da estrutura apontada por pp usamos o operador -> pp->nome; /* equiv. a pess.nome */ pp->idade=25; /* pess.idade=18 */

p printf("%s",pp->nome); ( ,pp ) // escreveria Joo printf( %d ,pp >idade); printf("%d",pp->idade); // escreveria 25


219

Observao sobre o acesso


Para acessar o campo nome de pessoa apontada por um ponteiro pp: *pp.nome Mas o operador de seleo . mais prioritrio do que o operador de indireo * isto equiv. a: *(pp.nome) (pp.nome) o que est errado (pois pp no uma ) estrutura). Deveremos escrever: (*pp).nome Mas esta notao um pouco complicada. Por isso temos um novo operador -> (pp->nome)

220

Estrutura apontando sobre uma outra Estrutura (1)


exemplo:
struct pessoa { ... struct pessoa * next; } ;
/* next um ponteiro sobre p uma outra pessoa */
221

Estrutura apontando sobre uma outra Estrutura (1)


exemplo:
typedef struct pessoa * Pt P t d f t t PtrPessoa; // PtrPessoa um ponteiro sobre a estrutura pessoa typedef struct pessoa { char nome[30]; int i t id d idade; PtrPessoa next; } Pessoa;
/* next um ponteiro sobre uma outra pessoa */

PtrPessoa
222

pp;

Ilustrao
CPF nome endereco next CPF nome endereco next
223

Acessos aos elementos de uma Estrutura Apontada


PtrPessoa p;

... printf("Entra com o nome: "); scanf("%s",&p->nome); printf("Entra com a idade: "); scanf("%d",&p->idade); p->next=NULL;
224

Tamanho alocado uma Estrutura T h l d E t t


O tamanho alocado a um tipo pode ser conhecido usando o operador sizeof (a medida feita em nmero de bytes). sizeof pode ser usada de duas maneiras d d d d i (aplicao a um tipo ou uma varivel) exemplos: , ; int tamanho,i; tamanho=sizeof i; tamanho=sizeof (short i); ( ); tamanho=sizeof (Pessoa);
225

Listas Li t
O fato de que uma estrutura pode apontar para uma o tra permite criar listas encadeadas. ma outra encadeadas Uma lista encadeada til principalmente p p quando ns no sabemos a priori (no momento da compilao) o nmero de seus elementos, o que uma necessidade no caso do uso do tipo vetor. Contrariamente aos vetores uma lista vetores, encadeada uma estrutura dinmica: os elementos so criados dinamicamente:
226

Alocao e Liberao de Memria Al Lib d M i


Para poder criar listas preciso poder alocar memria di l i dinamicamente: i t A alocao e liberao de memria feita usando as funes malloc e calloc:

malloc para a alocao do espao memria para um elemento; e calloc para a alocao do espao memria para um conjunto de elementos.

227

malloc ll
um nico parmetro que o tamanho (em bytes) do espao memria do elemento que ns desejamos criar, e retorna um ponteiro sobre o elemento criado.

malloc

pega

Obs. O tamanho do elemento obtido usando o operador sizeof. i f exemplo: Pessoa * p p; p=malloc(sizeof(Pessoa));
228

p=malloc(sizeof(char));

calloc ll
calloc pega dois parmetros: - o nmero de elementos que d l t desejamos criar; - e o tamanho de um elemento (em bytes). O objetivo de alocar espaos para vrios elementos de s uma vez.
229

calloc ll
exemplo: Pessoa * p; int num_elementos=4; ... p=calloc(num_elemenetos, ll ( l t sizeof(Pessoa)); Podemos, depois, usar p[0], p[1], p[1] ... P[num_elementos - 1]
230

Observao Ob
As funes malloc e calloc so definidas no arquivo <alloc.h> d biblioteca. i ll h da bibli t Geralmente antes do malloc tem que especificar o tipo da estrutura cujo o ponteiro que ser criado vai apontar:
pat (PtrPessoa)malloc(sizeof(Pessoa)); pat=(PtrPessoa)malloc(sizeof(Pessoa));

p=(char *)malloc(sizeof(char));
231

null ll
Quando no tem mais espao livre, as funes malloc e calloc retornam o valor null Este valor pode servir tambm para inicializar uma ponteiro exprimindo que ele aponta sobre nada.
232

Liberao de Memria Lib d M i


Podemos liberar o espao memria alocado para uma varivel dinmica: free(nome-do-ponteiro); int * p; ... p=(int *)malloc(sizeof(int)); ... free(p); /* liberao de p */

// 2 bytes

233

As Estruturas como Parmetros


C no permite p p passar uma estrutura como
parmetro uma funo. Mas nada proibe p p passar um p ponteiro sobre uma estrutura:

234

Exemplo
typedef struct {int dia,mes,ano;} data;

/* funo de comparao entre duas datas */ int comp_datas(data * d1, data * d2) { if (d1->ano==d2->ano) && ... return 1; else return 0; } data d1,d2; ... comp_datas (&d1,&d2);
235

Funes retornando Estruturas F t d E t t


Uma funo no pode retornar uma estrutura mas pode retornar um ponteiro sobre uma d t t i b estrutura:
/ * funo retornando um ponteiro sobre uma data 01/01/2000 */

data * d2001 () { data * p; p=malloc(sizeof(data)); p p->dia=1; p->mes=1; p->ano=2000; p p return (p); } data * d; d=d2001();
236

Observao
Pessoa * p; p=malloc(...) ll ( ) Normalmente o malloc no retorna um ponteiro sobre uma estrutura. Isto pode g causar um warning. Uma maneira correta de escrever :
p=(Pessoa*)malloc(sizeof(Pessoa))

Uma outra soluo : Pessoa * malloc();


237

Exerccio E i
Defina a funo proximo_aniv que pega em entrada a data de nascimento de uma pessoa e retorna uma estrutura designando a data de seu prximo aniversrio.

238

data * proximo_anniv (data * p) { data * anniv; anniv=(data*)malloc(sizeof(data)); anniv->ano=p->ano + 1; anniv->mes=p->mes; anni >mes p >mes anniv->dia=p->dia; return ( (anniv); i ) } data d_nasci,d_anniv; ... d nasci d anniv; d_anniv=proximo_anniv(&d_nasci);
239

Criao de Li t C i d Listas
typedef struct { char nome[20]; int peso; Pessoa * seguinte; } Pessoa;
nome, peso nome, peso

Cabea

nome,peso

next
240

next

...

NULL

Pessoa * cabeca,pant,patu; char resp; patu=(Pessoa *)malloc(sizeof(Pessoa)); patu->peso=30; ... cabeca=patu; puts("mais uma pessoa ( / ) ") resp=getch(); t (" i (s/n): "); t h() while (toupper(resp)!=N) { pant=patu; patu=(Pessoa *)malloc(sizeof(Pessoa)); )malloc(sizeof(Pessoa)); ... /* leitura dos dados da nova pessoa */ pant->seguinte=patu; patu->seguinte=NULL: puts("mais uma pessoa (s/n): ");resp=getch(); }

241

Modos FIF Vs. M d FIFo V LIFO


Existe dois modos para a criao das listas: FIFO: First In First Out LIFO: Last In First Out Exerccio: 1. Qual o modo de criao de listas aplicado no cdigo da pgina anterior? 2. Cria uma lista usando o outro modo.
242

Listas Li t
Conjunto de elementos individualizados em que cada um referencia um outro elemento distinto como sucessor

243

Listas Li t
Lista de Tarefas
Comeo em 3 C Item 1. 1 Pagar as contas no banco 2. Comprar os livros na livraria 3. Deixar o carro no estacionamento 4. Pegar algumas fitas na videolocadora p 5. Enviar carta pelo correio 6. Buscar as fotos reveladas 7. Autenticar documentos no cartrio 8. Passa na banca de jornais
244

Prximo 6 4 8 Final 1 2 5 7

Insero no meio da Lista


Antes Farmcia (9) Foto (6) Livraria (2)

245

Insero no meio da Lista


1 passo Farmcia (9) Foto (6) Livraria (2)

246

Insero no meio da Lista


2 passo Farmcia (9) Foto (6) Livraria (2)

247

Insero no meio da Lista


Inserir o item farmcia entre Foto e Livraria 1 Passo

lista[9].prox = lista[6].prox;

2 Passo

248

Lista[6].prox = 9;

Insero no fim da Lista


Antes Farmcia (9) Locadora (4) 0

249

Insero no fim da Lista


1 passo Farmcia (9) Foto (6) 0

250

Insero no fim da Lista


2 passo Farmcia (9) Foto (6) 0

251

Insero no fim da Lista


Inserir o item farmcia depois de locadora 1 Passo

lista[9].prox = lista[4].prox;

2 Passo

252

Lista[4].prox = 9;

Insero no incio da Lista


Antes Farmcia (9) comeo Estacionam (3)

253

Insero no incio da Lista


1 passo Farmcia (9) comeo Estacionam (3)

254

Insero no incio da Lista


2 passo Farmcia (9) comeo Estacionam (3)

255

Insero no fim da Lista


Inserir o item farmcia no inicio da lista (antes do primeiro item) 1 Passo

lista[9].prox = comeco;

2 Passo

256

comeco = 9;

Insero em uma lista


void insere(int novo, int antecessor) { lista[novo].prox = antecessor; antecessor = novo; }

257

Remoo em uma Lista


Antes Farmcia (9) comeo Estacionam (3)

258

Remoo em uma Lista


1 passo Farmcia (9) comeo Estacionam (3)

259

Remoo em uma lista


void remove(int velho, int antecess) { antecess = lista[velho].prox; }

260

Filas Fil (FIFO)


tambm uma Lista Regra: todo o elemento que entra na , lista, entra no final e todo o elemento que sai da lista, sai do incio dela. FIFO (First In, First Out) In

261

Filas Fil (FIFO)


#define MAX 100 char *p[MAX]; int rpos=0 spos=0; rpos=0, void armazena(char *c) { if (spos==MAX) { printf(Lista Cheia\n); else p[spos] = c; spos++; } }
262

Filas Fil (FIFO)


char *retira() { if (rpos==spos) printf(Sem eventos\n); return NULL; else rpos++; ++ return(p[rpos-1]); }
263

PILHA (LIFO)
o inverso de uma fila Regra: todo o elemento que entra na lista, entra no final e todo o elemento que sai da lista, sai do final dela. ltimo a entrar, primeiro a sair lti t i i i LIFO (Last In, First Out) push/pop (empilha/desempilha)
264

PILHA (LIFO) - vetor t


int p[100], top=0; void push(int i) { if (top>=100) printf( pilha cheia\n ); printf("pilha cheia\n"); else { p[top] = i; top++; } }

265

PILHA (LIFO) - vetor t


int pop(); { top--; if (top<0) { p printf("pilha vazia"); ( p ); return 0; } else return(p[top]); }
266

PILHA (LIFO) - ponteiro t i


int *p, *top, *b; p = (int*)malloc(MAX*sizeof(int)); ( ) ( ( )) top = p; b = p+MAX-1; +MAX 1

267

PILHA (LIFO) - ponteiro t i


void push(int i) { if (p>b) printf("pilha cheia\n"); else { *p = i; p++; } }
268

PILHA (LIFO) - ponteiro t i


int pop(); { p--; if (p<top) { p printf("pilha vazia"); ( p ); return 0; } else return(*p); }
269

rvores Bi i Binrias
Rapidez na pesquisa, incluso e excluso ( d ordenadas) l (qdo d d )
info

info
270

info
0 0 0

rvores - conceitos it
Raiz Ns N terminal Sub-rvore Altura

271

Transversalizao T li
d b a c e f g

Ordenada Preordenada Ps-ordenada P d d


272

abcdefg dbacfeg acbegfd

Unies de Tipos

273

Objetivo Obj ti
Todas variveis que nos vimos at agora possuam um i tipo. nico ti As vezes interessante atribuir vrios tipos a uma varivel (uma mesma zona memria). Isto pode ser feito atravs do mecanismo de unies de tipos usando a palavra chave union. Portanto, uma varivel teria, a um dado instante, um nico tipo, porm pode mudar.
274

Declarao D l
Exemplo:
/* declarao de um tipo que una os inteiros e os reais */
typedef union { int i; float f; } nmero;

numero n; Podemos ento escrever: P d t


n.i=20; /* para atribuir um inteiro */ n.f=3.14159; /* para atribuir um real
275

*/

Observao Ob
A declarao parecida s estruturas, mas nas unies somente um campo atribudo i t t ib d um valor. O problema que nos no podemos saber a um dado instante do programa qual o tipo do programa, atual valor da varivel. Por isso que na prtica a unio associada a um indicador de tipo (o tipo atual) e os dois so combinados em uma estrutura: bi d t t
276

Utilizao P ti d U i Utili Prtica das Unies


#define #define #d fi INTEIRO REAL 1 0

typedef struct { int tipo_var; union { int i; float f; } nmero; aritmtica; it ti

}
277

Utilizao P ti d U i Utili Prtica das Unies


/* declarao */ aritmtica a1,a2;

a1.tipo_var=INTEIRO; a1.tipo_var=REAL a1.nmero.i=10; a1.nmero.i=10;


278

Facilitar F ilit o acesso aos campos


O acesso aos campos da unio dentro da estrutura no muito prtico: a1.nmero.i=10; Isto pode ser resolvido usando as substituies e o define: #define #define I nmero.i; R nmero.f;

Agora podemos escrever: a1.I=10;ou a2.R=8.5;


279

Arquivos i

280

Streams St
Stream de texto

Sequncia de caracteres

Stream binria

Sequncia de bytes com uma correspondncia de 1 para 1 com aqueles encontrados no dispositivo externo

281

Funes mais comuns


Nome
Funo

fopen() fclose() putc(), fputc() f t () g (), getc(), fgetc()


282

Abre um arquivo Fecha um arquivo q Escreve um caractere em um arquivo L um caractere em um arquivo

#include <stdio.h>

Funes mais comuns


Nome fseek() fprintf() fscanf() feof() ferror() () rewind() remove() Funo Posiciona o arquivo em um bytes especfico = printf console = scanf console Final de arquivo? Ocorreu um erro? Indicador de posio no incio do arquivo Apaga um arquivo

283

Ponteiro de arquivo
Ponteiro para informaes que definem vrias coisas sobre o arquivo:

Nome, St t N Status, P i atual, ... Posio t l

Ponteiro do tipo FILE


FILE *fp; p;
284

Abrindo um arquivo
FILE *fopen(nomearq, modo); fopen devolve um ponteiro de arquivo (em caso de erro o ponteiro retornado nulo)

285

Abrindo um arquivo
r w a rb wb ab
286

r+ w+ a+ r+b w+b a+b

Abrindo um arquivo
file *fp; if ((fp=fopen(test,w))==null) { printf(no pode ser aberto); exit(1); }
287

Fechando um arquivo
Funo fclose() Exite uma quantidade mxima de arquivos que podem ser abertos FOPEN_MAX (exemplo: 20)

288

Lendo / Escrevendo
void carrega_arquivo(char s[10000], char nome arquivo[1000]) { nome_arquivo[1000]) FILE *fp; int i=0; if ((fp = fopen(nome_arquivo,"r"))==NULL) { printf("erro\n"); exit(1); } for (i 0 i 9999 && s[i]!=EOF;i++) f (i=0; i<9999 [i]! EOF i ) s[i] = getc(fp); fclose(fp); }
289