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

#include<math.

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

LinguagemdeProgramaoC

float max(float x,
float y){
if (x > y)
return
x;

return y;
}

SUMRIO
PREFCIO...........................................................................................................................................4

float mediaHarmPond(float amostra1,


float peso1,
float amostra2,
float peso2,
float amostra3,
float peso3) {
return
(peso1
+
peso2
+peso3)/(peso1/max(amostra1,0.0001)+peso2/max(amostra2,0.0001)+peso3/
max(amostra3,0.0001));
}
void main(){
unsigned long int cod;
int i, n=0;
float p1, p2, p3, mh[60], mh_media=0, somatorio=0, s;
FILE *saida;

if ((saida = fopen("l:medias.DAT", "w"))== NULL){

arquivo para
escrita

printf("Nao
conseguiu criar arquivo de saida.\n");
exit(0);
// Aborta execucao

printf("O desvio padrao eh %.4f\n",s);

Cria

OPERADORES.............................................................................................................................10
2.1 OPERADORESBITABIT.....................................................................................................................10
2.1.1
OperadoresbitabitdeAtribuio.....................................................................................12
2.2 OPERADOR?:................................................................................................................................12
2.3 OPERADORESDEPONTEIROS&E*.....................................................................................................13
2.4 PRECEDNCIADOSOPERADORES.........................................................................................................13
2.5 EXERCCIOS.....................................................................................................................................14

//

TIPOSDEDADOS.........................................................................................................................5
1.1 ENUMERAO..................................................................................................................................7
1.2 MODIFICADORESDETIPODEACESSO....................................................................................................7
1.2.1
Const.....................................................................................................................................7
1.2.2
Volatile..................................................................................................................................8
1.3 CONSTANTES....................................................................................................................................8
1.3.1
Constantesprdefinidas......................................................................................................9

FUNES...................................................................................................................................15
3.1 LOCALIZAODASFUNES...............................................................................................................15
3.1.1
Corpodafunoantesdoprogramaprincipal(nomesmoarquivo)..................................16
3.1.2
Corpodafunodepoisdoprogramaprincipal(nomesmoarquivo)................................16
3.1.3
Corpodafunoescritoemarquivoseparado...................................................................16
3.2 ARGUMENTOSPARAFUNOMAIN()..................................................................................................17
3.3 PROTTIPODEFUNES...................................................................................................................17
3.4 RETORNODEPONTEIROS..................................................................................................................18
3.5 CLASSESDEARMAZENAMENTO..........................................................................................................18
3.5.1
auto.....................................................................................................................................18
3.5.2
static...................................................................................................................................18
3.5.3
extern..................................................................................................................................19
3.5.4
register................................................................................................................................20
3.6 DIRETIVA#DEFINE...........................................................................................................................20
3.7 FUNESRECURSIVAS......................................................................................................................20
3.8 EXERCCIOS.....................................................................................................................................21

um

while(1){
printf("Forneca o codigo do aluno\n");
scanf("%ld",&cod);
if (cod==0) break; // Sai do laco
printf("Forneca as notas das provas do aluno\n");
scanf("%f %f %f",&p1, &p2, &p3);
if (p1>=0 && p1<=10 && p2>=0 && p2<=10 && p3>=0 && p3<=10){
mh[n] = mediaHarmPond(p1,1,p2,2,p3,3);
mh_media += mh[n];
fprintf(saida,"Codigo: %8ld Prova 1: %2.2f Prova 2: %2.2f
Prova 3: %2.2f Media harmonica ponderada: %2.2f\n", cod, p1, p2, p3,
mh[n]);
n++;
} else
printf("Intervalo de notas invalido\n");
}
mh_media = mh_media/n;
for(i=0;i<n;i++)
somatorio+=(mh[i]-mh_media)*(mh[i]-mh_media);
s = sqrt(somatorio/(n-1));

PONTEIROS................................................................................................................................24
4.1 EXPRESSESCOMPONTEIROS............................................................................................................24
4.1.1
AtribuiodePonteiros......................................................................................................24
4.1.2
AritmticadePonteiros......................................................................................................24
4.2 INICIALIZAODEPONTEIROS............................................................................................................25
4.2.1
ComparaodePonteiros..................................................................................................26
4.3 PONTEIROSEMATRIZES....................................................................................................................26
4.3.1
MatrizesdePonteiros.........................................................................................................27
4.3.2
AcessandopartesdeMatrizescomovetores.....................................................................27
4.4 INDIREOMLTIPLA.......................................................................................................................28
4.5 PONTEIROSPARAFUNES...............................................................................................................28
4.6 MAISSOBREDECLARAESDEPONTEIROS...........................................................................................29
4.7 EXERCCIOS.....................................................................................................................................31

ESTRUTURASEUNIES..............................................................................................................32
5.1

ESTRUTURAS...................................................................................................................................32

LinguagemdeProgramaoC

ALOCAODINMICA...............................................................................................................41
6.1 MAPADEMEMRIA.........................................................................................................................41
6.2 FUNESDEALOCAODINMICAEMC.............................................................................................41
6.2.1
malloc()...............................................................................................................................42
6.2.2
calloc()................................................................................................................................43
6.2.3
free()...................................................................................................................................43
6.2.4
realloc()...............................................................................................................................44
6.3 MATRIZESDINAMICAMENTEALOCADAS...............................................................................................44
6.4 LISTASENCADEADAS........................................................................................................................45
6.4.1
ListasSingularmenteEncadeadas......................................................................................45
6.4.2
ListasDuplamenteEncadeadas..........................................................................................46
6.5 RVORESBINRIAS..........................................................................................................................48
6.6 EXERCCIOS.....................................................................................................................................50

E/SCOMARQUIVO....................................................................................................................51
7.1 E/SANSIXE/SUNIX.....................................................................................................................51
7.2 STREAMS.......................................................................................................................................51
7.3 ARQUIVOS......................................................................................................................................51
7.4 SISTEMADEARQUIVOS.....................................................................................................................51
7.5 ESTRUTURAFILE.............................................................................................................................52
7.6 ABERTURADEARQUIVOS..................................................................................................................52
7.7 FECHAMENTODEARQUIVO...............................................................................................................53
7.8 VERIFICANDOFIMDEARQUIVO...........................................................................................................53
7.9 CONDIESDEERRO........................................................................................................................53
7.10 STREAMSPADRO...........................................................................................................................54
7.11 LEITURAEGRAVAODECARACTERES.................................................................................................54
7.12 TRABALHANDOCOMSTRINGS............................................................................................................55
7.13 FUNESDETRATAMENTODEARQUIVOS.............................................................................................56
7.13.1 rewind()..............................................................................................................................56
7.13.2 ferror()................................................................................................................................56
7.13.3 remove().............................................................................................................................57
7.13.4 fflush().................................................................................................................................57
7.13.5 Acessoaleatrio:fseek().....................................................................................................57
7.13.6 ftell()...................................................................................................................................58
7.14 COMANDODEGRAVAOEMMODOTEXTOFORMATADO........................................................................58
7.15 LENDOEGRAVANDOREGISTROS.........................................................................................................59
7.15.1 Escritadeumblocodedados.............................................................................................59
7.15.2 Leituradeumblocodedados.............................................................................................59
7.15.3 Utilizandooscomandosdeleituraegravaoderegistros...............................................60
7.16 FUNESPARAMANIPULAODEBUFFERS...........................................................................................60
7.17 EXERCCIOS.....................................................................................................................................62

A. TABELAASCII.............................................................................................................................63
8

LinguagemdeProgramaoC

5.1.1
InicializandoEstruturas......................................................................................................33
5.1.2
EstruturasAninhadas.........................................................................................................33
5.1.3
Estruturasefunes...........................................................................................................34
5.1.4
VetordeEstruturas.............................................................................................................34
5.1.5
PonteirosparaEstruturas...................................................................................................35
5.2 CAMPOSDEBITS.............................................................................................................................35
5.3 UNIES.........................................................................................................................................37
5.4 SIZEOF()........................................................................................................................................38
5.5 TYPEDEF........................................................................................................................................39
5.6 EXERCCIOS.....................................................................................................................................40
6

BIBLIOGRAFIA............................................................................................................................64

PREFCIO
Este texto tem o objetivo de fornecer os subsdios para o desenvolvimento de programas
avanados na linguagem C. Os tpicos estudados neste texto so estruturas, unies, campos de bits,
alocaodinmicaearquivos.

LinguagemdeProgramaoC

LinguagemdeProgramaoC

TIPOSDEDADOS

EmCexistem5tiposdevariveisbsicas.NoscomputadoresdalinhaIBMPC(plataforma32
bits), a Tabela 1.1 vlida. Estes tipos de dados definem a quantidade de memria que ocupa e o
intervalodevaloresqueconseguerepresentar.
Bits

FaixaMnima

char

128a127

int

32

2,147,483,648a2,147,483,647

float

32

3.4E38a3.4E+38

double

64

1.7E308a1.7E+308

void

semvalor

Comexceodevoid,ostiposdedadosbsicospodemestaracompanhadospormodificadoresna
declaraodevariveis.OsmodificadoresdetiposdalinguagemCso:
unsigned;
short.

Osmodificadoressigned,short,longeunsignedpodemseraplicadosaostiposbsicoschareint.
Contudo,longtambmpodeseraplicadodouble.

Tabela1.2Utilizaodostiposdedados(plataforma32bits)

Bits

Inteiros

Formatao
printf()

Inicio

3,4E38

4.294.967.295
3.4E+38

double

64

%lf

1,7E308

1,7E+308

longdouble

80

%Lf

3,4E4932

3,4E+4932

Exemplo1.1
#include <stdio.h>
int main() {
int qtde;
char tam;
float total;
qtde = 2; tam = G;
total = 20.70;
printf(Comprei %d camisas de tamanho %c., qtde, tam);
printf(\nNo total, paguei R$ %f., custo);
return 0;
}

As variveis podem ser inicializadas no momento em que se faz a declarao das mesmas.
Podeseveristousandooprogramaanterior,queaexecuoseramesmadaversoanterior.

A Tabela 1.2 mostra todas as combinaes de tipos de dados e as informaes sobre tamanho,
formataoeintervalo.

%f

Comprei 2 camisas de tamanho G.


No total, paguei R$ 20.70.

Oespecificadordeformatolongpodeseraindautilizadoparatipoponto
flutuante (indicando que segue um double): %le, %l E, %lf, %lg, e %lG.
OutroespecificadodeformatooL,oqualutilizadoparaassociarum
longdouble:%Le,%LE,%Lf,%Lg,e%LG.

Tipo

%lu

32

Execuo:

Afunoprintf()possuiespecificadoresdeformatoquepermitemmostrar
inteiros short e long. O %ld,%li,%lo,%lu,%lxespecificam queotipode
dadolong.O%hd,%hi,%ho,%hu,%hxespecificamqueotipodedado
short.

32

float

O tamanho, e conseqentemente o intervalo de valores, pode variar de


plataforma para plataforma. Por exemplo, o long double em algumas
plataformas possui 10 bytes de tamanho. O char j um tipo que no
variadeplataforma.

Os tipos char e int armazenam nmeros inteiros, enquanto que os tipos


floateDoublearmazenamnmerosdepontoflutuante(umformatode
representaodigitaldenmerosreais).

signed;
long;

unsignedlongint

Ousodesignedcominteirosredundante.Noentanto,elepermitidoporqueadeclarao
defaultdeinteirosassumeumnmerocomsinal.Ousomaisimportantedesignedmodificarcharem
implementaesemqueessetipo,porpadro,notemsinal.Algumasimplementaespodempermitir
queunsignedsejaaplicadoaostiposdepontoflutuante(comoemunsigneddouble).Porm,issoreduz
aportabilidadedeseucdigoegeralmentenorecomendado.Omodificadorunsignedalteraovalor
dafaixamnimadotipoatravsdousodobitmaissignificativo(indicadordesinal).

Tabela1.1Tiposdedadosbsicosparaplataformas32bits

Tipo

Ponto
Flutuant
e

Intervalo

Exemplo1.2
#include <stdio.h>
int main() {
int qtde=2;
char tam=G;
float total=20.70;
printf(Comprei %d camisas de tamanho %c., qtde, tam);
printf(\nNo total, paguei R$ %f., custo);
return 0;
}

Fim

char

%c

128

127

unsignedchar

%c

255

signedchar

%c

128

127

shortint

16

%hi

32.768

32.767

signedshortint

16

%hi

32.768

32.767

unsignedshortint

16

%hu

65.535

int

32

%i

2.147.483.648

2.147.483.647

signedint

32

%i

2.147.483.648

2.147.483.647

unsignedint

32

%u

4.294.967.295

longint

32

%li

2.147.483.648

2.147.483.647

signedlongint

32

%li

2.147.483.648

2.147.483.647

Devido s diferenas de tipos em diferentes mquinas e plataformas,


podese utilizar a funo sizeof() para descobrir o tamanho real da
variveloutipo.
Exemplo1.3
#include <stdio.h>
int main() {
printf("Tipo\t\tTamanho\n");
printf("char\t\t%d\n",sizeof(char));
printf("int\t\t%d\n",sizeof(int));
printf("float\t\t%d\n",sizeof(float));
printf("double\t\t%d\n",sizeof(double));
printf("long int\t%d\n",sizeof(long int));
return 0;

LinguagemdeProgramaoC

LinguagemdeProgramaoC

Exemplo1.6
const int a=10;

Execuo:
Tipo
char
int
float
double
long int

1.1

Tamanho
1
4
4
8
4

Sintaxe:
enumnome{lista_de_enumerao}lista_de_variveis;

Aqui, tanto o nome da enumerao quanto a lista de variveis so opcionais. O nome da


enumeraousadoparadeclararvariveisdaqueletipo.Comissopodesedeclararascores
Exemplo1.4
enum cores {amarelo, verde, vermelho};
enum cores semaforo;

Omodificadorvolatileusadoparainformaraocompiladorqueovalordeumavarivelpode
seralteradodemaneiranoexplicitamenteespecificadapeloprograma.Porexemplo,umendereode
uma varivel global pode ser passado para a rotina de relgio do sistema operacional e usado para
guardarotemporealdosistema.Nessasituao,ocontedodeumavarivelalteradosemnenhum
comando de atribuio explicito no programa. Isso ajuda o programa no sentido de avisar ao
compiladorqueocontedodeumavarivelmutvel,mesmoquesuareferncianoaparecernolado
esquerdodaexpresso.

possvelusarconstevolatilejuntos.Porexemplo,se0x30assumidocomosendoovalorde
uma porta que mudado por condies externas. Para evitar efeitos colaterais devese declarar da
seguinteforma:
const volatile unsigned char *port = 0x30;

Dadaessadefinioedeclarao,ostiposdecomandosseguintessoperfeitamentevlidos:

1.3

semaforo = verde;
if (semaforo==verde) printf(Passagem permitida \n);

Uma constante tem valor fixo e inaltervel durante a execuo do programa. Isto pode ser
exemplificadopelosExemplos3.1e3.2dafunoprintf().

Paramelhorcompreensodaenumeraoentendesequecadasmbolorepresentaumvalor
inteiro.Ovalordoprimeirosmbolodaenumerao0.Assim,
printf (%d %d, verde, vermelho);

mostra12natela.

Como extenso, podese inicializar os smbolos de forma alternada para algum problema
especfico.
Exemplo1.5
enum cores { amarelo, verde=10, vermelho };

Agoraosvaloresdestessmbolosso

amarelo
verde
vermelho

1.2

Umexemplodousodoconstparaverificarseumavarivelemparticularmodificadapelo
seuprograma.

1.2.2 VOLATILE

ENUMERAO

Enumerao um conjunto de constantes inteiras que especifica todos os valores legais de


umavariveldessetipopodeser.Aformageralparaenumerao:

OExemplo1.6criaumavarivelinteirachamadaa,comumvalorinicial10,queseuprograma
nopodemodificar.

0
10
11

MODIFICADORESDETIPODEACESSO

OpadroANSIintroduziudoisnovosmodificadoresdetipoquecontrolamamaneiracomoa
variveis podem ser acessadas ou modificadas. Esses modificadores so const e volatile. Devem
precederosmodificadoresdetipoeosnomesqueelesmodificam.

1.2.1 CONST

Variveisdotipoconstnopodemsermodificadasporseuprograma(porissoelarecebeum
valorinicial).

CONSTANTES

Em uma constante caractere escrita entre aspas simples (), uma constante cadeia de
caracteresentreaspasduplas()econstantesnumricascomoonmeropropriamentedito.
Exemplo1.7

C
programa
8
465.67

ConstantesemCpodemserdequalquerumdoscincotiposdedadosbsicos.Amaneiracomo
cada constante representada depende do seu tipo. Podese especificar precisamente o tipo da
constantenumrica atravsdautilizaodeumsufixo. Para tipos empontoflutuantecolocaseumF
apsonmero,elesertratadocomofloat.SeforcolocadoumL,eletornarseumlongdouble.Para
tipos inteiros, o sufixo U representa unsigned e o L representa long. A Tabela 1.3 mostra alguns
exemplosdeconstantes.
Tabela1.3Exemplodeconstantes

TipodeDado

ExemplodeConstantes

int

112321000234

longint

35000L34L

shortint

101290

unsignedint

10000U987U40000

float

123.23F2.34e3F

double

123.23123123330.9876324

longdouble

1001.2L

LinguagemdeProgramaoC

10

LinguagemdeProgramaoC

AlmdestetemseasconstantesHexadecimaiseOctais.Usamsetaissistemasnumricospara
facilitar a programao. Uma constante hexadecimal deve consistir em um 0x seguido por uma
constantenaformahexadecimal.Umaconstanteoctalcomeacom0.

Exemplo1.8
int hex = 0x80;
int oct = 012;

OPERADORES

A linguagem C muito rica em operadores internos. C define quatro classes de operadores:


aritmticos,relacionais,lgicosebitabit.Almdisso,Ctemalgunsoperadoresespeciaisparatarefas
particulares.

/* 128 em decimal */
/* 10 em decimal */

1.3.1 CONSTANTESPRDEFINIDAS

2.1

OPERADORESBITABIT

Em alguns compiladores C, algumas constantes simblicas j esto prdefinidas. Estas


constantesemgeraldefinamalgunsvaloresmatemticos(,/2,e,etc.),limitesdetiposetc.Aseguir
so apresentadas algumas (existem muitas outras) constantes simblicas prdefinidas no compilador
TurboC++daBorland.

Os operadores bit a bit so comumente utilizados para trabalhar com dispositivos (pois os
mesmosutilizambytesoupalavrascodificadasparacomunicao),mododearmazenamento(umbyte
pode representar 8 informaes binrias), e at compactao de dados (utilizao de bits ociosos). A
Tabela2.1mostraosoperadoresbitabitsuportadospelalinguagem.
Tabela2.1Operadoresbitabit

Biblioteca

Constante

Valor

Significado

math.h

M_PI

3.14159...

Operador

Ao

math.h

M_PI_2

1.57079...

/2

&

E(AND)

math.h

M_PI_4

0,78539...

/4

OU(OR)

OUexclusivo(XOR)

math.h

M_1_PI

0,31830...

1/

math.h

M_SQRT2

1,41421...

Complementodeum

>>

Deslocamento esquerda

<<

Deslocamentodireita

Osoperadores bit abitspodemserutilizadossobreum byte ouuma


palavra, isto , aos tipos de dados char e int e variantes do padro C.
Operaesbitnopodemserusadasemfloat,double,longdouble,void
ououtrostiposmaiscomplexos.
Ooperadorbitabit&executaumelgicoparacadapardebits,produzindoumnovobyteou
palavra.Paracadabitdosoperandos,ooperador&retornaobitem1seambososbitsdosoperandos
1.Casoalgumbitdosoperandosfor0,ooperadorretornaobit0.Esteoperadormaisutilizadopara
desligarbits(realizandoaoperaocomumoperandotambmchamadodemscaracujosbitsque
devam ser desligados estejam com valor 0, enquanto que os outros esto em 1) ou verificar se um
determinadobit estligadoou desligado(realizandoaoperaocomumoperandocujobitquedeva
serchecadoestejacomvalor1,enquantoqueosoutrosestoem1).
Exemplo2.1
unsigned
unsigned
unsigned
unsigned
res
res
res
res

=
=
=
=

x
y
y
y

&
&
&
&

char
char
char
char

x = 7;
y = 4;
mascara = 252;
res;

y;
mascara;
2
4

/*
/*
/*
/*

res
res
res
res

=
=
=
=

/* 0000 0111 */
/* 0000 1010 */
/* 1111 1100 */

0000
0000
0000
0000

0010
1000
0010
0000

*/
desligar os bits 0 e 1
*/
bit ligado qdo res > 0
*/
bit desligado qdo res == 0 */

Ooperadorbitabit|executaumoulgicoparacadapardebits,produzindoumnovobyteou
palavra.Paracadabitdosoperandos,ooperador|retornaobitem1sealgumdosbitsdosoperandos
1.Casoambososbitsdosoperandosfor0,ooperadorretornaobit0.Esteoperadormaisutilizado
paraligar(realizandoaoperaocomumoperandocujosbitsquedevamserligadosestejamcomvalor
1,enquantoqueosoutrosquenodevemseralteradosestoem0).
Exemplo2.2
unsigned
unsigned
unsigned
unsigned

char
char
char
char

x = 7;
y = 4;
mascara = 1;
res;

/* 0000 0111 */
/* 0000 1010 */
/* 0000 0001 */

11

LinguagemdeProgramaoC

12

LinguagemdeProgramaoC

res = x | y;
res = y | mascara;
res = x | 8;

5. 2
6. 32
7. 2
8. 40

/* res = 0000 1111


*/
/* res = 0000 1011 ligar o bit 0 */
/* res = 0000 1111 ligar o bit 3 */

Ooperadorbitabit^executaumouexclusivo(XOR)lgicoparacadapardebits,produzindo
umnovobyteoupalavra.Paracadabitdosoperandos,ooperador^retornaobitem1sesomenteum
dosbitsdosoperandos1.Casoosbitsdosoperandosforemiguais,ooperadorretornaobit0.Este
operador mais utilizado para inverter bits (realizando a operao com um operando cujos bits que
devamserinvertidosestejamcomvalor1,enquantoqueosoutrosestoem0).
Exemplo2.3
unsigned
unsigned
unsigned
unsigned

char
char
char
char

x = 7;
y = 4;
mascara = 3;
res;

res = x ^ y;
res = y ^ mascara;
res = y ^ 8;

OExemplo2.5mostraqueosoperadoresdedeslocamentopodemserutilizadoscomvariveis,
constanteseatmesmoexpresses.Entretanto,deveseverificaraprecednciadeoperadoresquando
trabalhandocomexpresses.
Exemplo2.6
unsigned char x = 7;
unsigned char res;

/* 0000 0111 */
/* 0000 1010 */
/* 0000 0011 */

/* res = 0000 1101


/* res = 0000 1001 inverter os bits 0 e 1
/* res = 0000 0010 inverter o bit 3

res
res
res
res
res

*/
*/
*/

res = ~x;
res = ~127;

x
x
x
x
x

<<
<<
<<
>>
>>

1;
3;
2;
1;
2;

/*
/*
/*
/*
/*

res
res
res
res
res

= 14 */
= 112 */
= 192 */
= 96 */
= 24 */

ATabela2.2mostraosoperadoresbitabitdeatribuiosuportadospelalinguagem.
Tabela2.2Operadoresaritmticosdeatribuio

Operador

Ao

x&=y

x=x&y

x|=y

x=x|y

x^=y

x=x^y

x ~=y

x=x~y

x>>=y

x=x>>y

x<<=y

x=x<<y

<< nmero de bits


>> nmero de bits

Conforme os bits so deslocados para um direo, zeros so utilizados para preencher a


extremidade contrria da direo (isto , deslocamento para a direita coloca zeros os bits mais
significativos).Estesoperadoressoutilizadospararecebimentoeenviodedadosbitabit(conversores
analgico/digitais, portas seriais), e multiplicao (deslocamento para a esquerda) e diviso inteira
(deslocamentoparaadireita)por2.
Exemplo2.5
#include <stdio.h>
int main() {
unsigned char x=7;
printf("1. %2i\n",x >> 1);
printf("2. %2i\n",x << 1);
printf("3. %2i\n",x >> 2);
printf("4. %2i\n",x << 2);
printf("5. %2i\n",8 >> 2);
printf("6. %2i\n",8 << 2);
printf("7. %2i\n",x+3 >> 2);
printf("8. %2i\n",x+3 << 2);
return 0;
}

1. 3
2. 14
3. 1
4. 28

00001110
01110000
11000000
01100000
00011000

2.1.1 OPERADORESBITABITDEATRIBUIO
/* res = 1111 1000 */
/* res = 1000 0000 */

Sintaxe:

Execuo:

=
=
=
=
=

/* 0000 0111 */

Os operadores de deslocamento, e , movem todos os bits de um operando para a


esquerdaoudireita,respectivamente.Aformageraldocomandodedeslocamento:

operando
operando

res
res
res
res
res

No confunda os operadores relacionais && e || com & e |,


respectivamente.Osoperadoresrelacionaistrabalhamcomosoperandos
como um nico valor lgico (verdadeiro ou falso), e eles produzem
somente dois valores 0 ou 1. Os operadores bit a bit podem produzir
valoresarbitrriospoisaoperaorealizadaemnveldebit.

O operador bit a bit ~ executa um no lgico (complemento de 1) no valor a sua direita


(operadorunrio),produzindoumnovobyteoupalavracomosbitsinvertidos.
Exemplo2.4
unsigned char x = 7;
unsigned char res;

=
=
=
=
=

/* 0000 0111 */

Asexpressescomesteoperadoressomaiscompactasenormalmenteproduzemumcdigo
demquinamaiseficiente.
Aexecuodaoperaobitabitocorreporltimoapsaavaliaoda
expressodireitadosinaligual.

2.2

OPERADOR?:

Ooperador?substituisentenasdaformaSeentoseno.

Sintaxe:
Exp1 ? Exp2 : Exp3;

OndeExp1,Exp2eExp3soexpresses.OndeExp1avaliadaeseamesmaforverdadeira,
entoExp2avaliadaesetornaovalordaexpresso.SeExp1falso,entoExp3avaliadaesetorna
ovalordaexpresso.
Exemplo2.7
x = 10;
y = x > 9 ? 100 : 200;

13

LinguagemdeProgramaoC

14

LinguagemdeProgramaoC

No Exemplo 2.7, y recebe o valor 100, porque x (valor 10) maior que 9. Uma expresso
equivalenteseria

5
6
7
8
9
10
11
12
13
14

x = 10;
if (x > 9) y = 100;
else y = 200;

2.3

OPERADORESDEPONTEIROS&E*

Um ponteiro um endereo na memria de uma varivel. Uma varivel de ponteiro uma


varivelespecialmentedeclaradaparaguardarumponteiroparaseutipoespecificado.

O primeiro operador de ponteiro &. Ele um operador unrio que devolve o endereo na
memriadeseuoperando.Porexemplo,

2.5

EXERCCIOS
1.

Faa um programa que leia umnmero binrio de 16bits,armazeneo,emostreovalorem


hexadecimal,decimaleoctal.

2.

Faaumafunoquerecebaumvalordotipointcomoparmetroeescrevanatelaosvalores
dobitsdovalor

3.

Faaumafunoquerecebaumvalordotipointcomoparmetroedevolvaumnovovalorint
comaordemdosbitsinvertidos.

4.

Faa uma funo que receba um valor do tipo char como parmetro e devolva quantos bits
estoligados.

5.

Faaumafunocrossover(n,m,pontoDeCorte)queretornauminteiroquerepresentaosbits
maissignificativosdeneosbitsmenossignificativosdem,deacordocomopontodecorte,
queaposioondeonmeroserpartido.Porexemplo:

m = &cont;
atribuioendereodememriadavarivelcontemm.

Estetipodeoperandonopodeserutilizadoemtrscasos:
1. &(cont+4)sempreseassociaaumavarivelenoexpresso;
2. &3constantesnosovlidas;
3. variveis declaradas com classe de armazenamento register (no existe endereo para
registrador).

Osegundooperador*.Eleumoperadorunrioquedevolveovalordavarivellocalizada
noendereoqueosegue.Porexemplo,semcontmoendereodavarivelcont,

int main(){
crossover(10,69,2); // retorna 13 = 0000 1101
// 10 = 0000 1010, teremos que pegar desse n, os bits +
significativos, ou seja: 0000 1???
// 69 = 0100 0101, teremos que pegar desse n, os bits menos
significativos, ou seja: ???? ?101
crossover(10,69,3); // retorna 5 = 0000 0101, ou seja, metade de um +
metade do outro
}

q = *m;
colocaovalordecontemq.

Osseguintesoperadores*e&colocamovalor10navarivelchamadatarget.Oresultado(o
valor10)desteprogramamostradonatela.
Exemplo2.8

6.

#include <stdio.h>
int main() {
int target, source;
int *m;
source = 10;
m = &source;
target = *m;
printf(%d,target);
return 0;
}

2.4

7.

Escreva uma funo criptografa(int n) que recebe um inteiro n com 8 bits (ndices:
7,6,5,4,3,2,1,0)equeretornaesseinteiroembaralhandoessesbitsparaaseguinteseqncia
(7,5,3,1,6,4,2,0)
int main(){
criptografa(73);

ATabela2.3mostraaprecednciadosoperadoresdalinguagemC.
Tabela2.3:Precednciadosoperadores

Operador
()[]>
(menosunrio)++!~&(endereo)*(ponteiro)
*/%
+
<<

Faa a funo rodaEsquerda(int n, int nBits) que retorna o n com nBits rotaes esquerda.
Perceba que uma rotao no deve perder bits, ao contrrio do operador de deslocamento.
Trabalhepensandoapenasnos8bitsparan.
int main(){
unsigned char x;
x = rodaEsquerda (4, 2); // se 4 = 0000 0100,
// ento rodaEsquerda (4,2)== 0000 1000
}

PRECEDNCIADOSOPERADORES

Precedncia
1
2
3
4
4

<<=>>=
==!=
&
^
!
&&
||
?:
=*=/=%=+==&=|=^=~=<<=>>=
,

// se 73 = 0100 1001,
// ento criptografa(73) == 0010 1001 == 41

8.

Faaafunodescriptografa(intn)quefazoprocessoinvertidodaquesto7.

9.

Faaumafunoquerecebaumvetorde32posiesdeinteiros(valores0e1)equeretorne
umvalorcomosbitsligadosoudesligadosconformeocontedodecadaposiodovetor.

15

LinguagemdeProgramaoC

16

3.1.1 CORPO DA FUNO ANTES DO PROGRAMA PRINCIPAL (NO MESMO


ARQUIVO)

FUNES

Aformageraldeumafuno:

Quando escrevemos a definio de uma funo antes do programa principal e no mesmo


arquivodeste,nenhumaoutrainstruonecessria.

Sintaxe:

LinguagemdeProgramaoC

tipo_funonome_funo(declarao_parmetros){
corpo_funo;
}

Exemplo3.1
int soma(int x, int y) {
...
}

Exemplo3.4
float media2(float a, float b) {
float med;
med = (a + b) / 2.0;
return(med);
}

int main() {
// programa principal
float num_1, num_2, med;
puts(Digite dois nmeros:);
scanf(%f %f, &num_1, &num_2);
med = media2(num_1, num_2);
// chamada da funo
printf(\nA media destes nmeros %f, med);
return 0;
}

As funes retornam um valor (do tipo indicado em tipo_funo). O valor retornado pela
funodadopelocomandoreturn(ovalorretornadopodeounoserutilizado).

Existem dois tipos de passagem de argumentos: por valor e por referncia. A segunda
realizadaatravsdeapontadores.
Exemplo3.2

int pot(int x, int n) {


int p;
for(p=1;n>0;n--)
p *= x;
return p;
}

/* x elevado na n potncia */

NoExemplo3.2,osargumentosforampassadosporvaloreafunoretornaumvalordotipo
inteiro.Achamadaseria:

// funo

3.1.2 CORPO DA FUNO DEPOIS DO PROGRAMA PRINCIPAL (NO MESMO


ARQUIVO)
Quando escrevemos a definio de uma funo depois do programa principal e no mesmo
arquivo deste, devemos incluir um prottipo da funo chamada. Um prottipo uma instruoque
define o nome da funo, seu tipo de retorno e a quantidade e o tipo dos argumentos da funo. O
prottipo de uma funo indica ao compilador quais so as funes usadas no programa principal os
tipo.Asintaxegeralparaistoaseguinte:
Sintaxe:

a = pot(10,2);

NoExemplo3.3,nenhumvalorretornado(porissousaseotipovoid)masrealizadouma
trocadosvaloresdasvariveis,necessitandodeumapassagemdeparmetrosporreferncia.
Exemplo3.3
/* troca os valores de duas variveis*/
void troca(int *a, *b) {
int aux;
aux = *a;
*a = *b;
*b = aux;
}

Achamadaparaestafunoseria:
int x=1,y=2;
troca(&x,&y);

Na passagem de parmetros por referncia passado explicitamente o endereo da varivel


com o uso do operador &. Quando o argumento for uma matriz automaticamente ser passado o
endereodamatrizparaafuno.

int main() {
tipo nomef(...);
...
var = nomef(...)
...
}

// programa principal
// prottipo da funo

tipo nomef(...){
[corpo de funo]
}

// definio da funo

// chamada a funo

Exemplo3.5
#include <stdio.h>
int main() {
// programa principal
float media2(float,float);
// prottipo de media2()
float num_1, num_2, med;
puts(Digite dois nmeros:);
scanf(%f %f, &num_1, &num_2);
med = media2(num_1, num_2);
// chamada a funo
printf(\nA media destes nmeros %f, med);
}
float media2(float a, float b){ // funo media2()
float med;
med = (a + b) / 2.0;
return(med);
}

AlinguagemCaceitachamadasrecursivasdefunes.

3.1

LOCALIZAODASFUNES

Existem basicamente duas posies possveis para escrevermos o corpo de uma funo: ou
antes ou depois do programa principal. Podemos ainda escrever uma funo no mesmo arquivo do
programaprincipalouemarquivoseparado.

Prottipodeumafunonadamaisqueadeclaraodafunosemo
seucorpo.Porisso,alistadeargumentosdoprottipopodemserescritas
apenascomostiposdosargumentos.

3.1.3 CORPODAFUNOESCRITOEMARQUIVOSEPARADO

17

LinguagemdeProgramaoC

18

LinguagemdeProgramaoC

EmC,comoemmuitasoutraslinguagens,permitidoqueousuriocrieumafunoemum
arquivo e um programaque a chame em outro arquivo distinto. Esta facilidade permite a criaode
bibliotecas de usurio: um conjunto de arquivos contendo funes escritas pelo usurio. Esta
possibilidadeumagrandevantagemutilizadaemlargaescalaporprogramadoresprofissionais.

ProttipospermitemqueCforneaumaverificaomaisfortedostipos.Prottiposdefunes
ajudamadetectarerrosantesqueelesocorram.verificadonmerodeparmetros,compatibilidade
detipos,entreoutras.

Quando escrevemos a definio de uma funo em arquivo separado do programa principal


devemos incluir este arquivo no conjunto de arquivos de compilao do programa principal. Esta
incluso feita com a diretiva #include. Esta diretiva, vista nas sees 2.4.2 e 3.7.1, instrui o
compiladorparaincluirnacompilaodoprogramaoutrosarquivosquecontemadefiniodasfunes
deusurioedebiblioteca.

Existemtrstiposdedeclaraodeprottipos:
Sintaxe

tipo_funonome_funo();

tipo_funonome_funo(lista_tipo_argumentos);
tipo_funonome_funo(lista_tipo_nome_argumentos);

Exemplo
intpot();
intpot(int,int);
intpot(intx,inty);

Sintaxe:
#include path
int main() {
...
var = nomef(...)
...
}

// incluso da funo
// programa principal

3.4

// chamada a funo

Ponteiros para variveis no so variveis e tampouco inteiros sem sinal. So endereos na


memria.Aformageral:

Nadiretiva#include,indicamosentreaspasduplasocaminhodelocalizaodoarquivoonde
estdefinidaafunochamada.
Exemplo3.6
#include c:\tc\userbib\stat.h
int main() {
float num_1, num_2, med;
puts(Digite dois nmeros:);
scanf(%f %f, &num_1, &num_2);
med = media2(num_1, num_2);
//
printf(\nA media destes nmeros
return 0;
}

3.2

// incluso da funo
// programa principal

Sintaxe:

tipo_funo*nome_funo(lista_de_argumentos);

3.5

chamada a funo
%f, med);

ARGUMENTOSPARAFUNOMAIN()

A funo main() aceita argumentos para a passagem de parmetros realizada atravs da


chamadadoprograma.Osdoisargumentosso:
argc:contadordeargumentos;

RETORNODEPONTEIROS

CLASSESDEARMAZENAMENTO
AlinguagemCpossuiquatroclassesdearmazenamentodevariveis:

auto
extern
static
register

(automticas)
(externas)
(estticas)
(emregistradores)

3.5.1 AUTO

Asvariveisdeclaradasnosexemplosanterioresspodemseracessadassomentesfunes
ondeestodeclaradas.Taisvariveissochamadaslocaisouautomticaseelassocriadasquandoa
funochamadaedestrudasquandoafunoouoblocodecdigoterminaasuaexecuo.

argv:vetordeargumentos(vetordeapontadoresparastrings).
Sintaxe:
main(int argc, char *argv[])

importantelembrarque

Exemplo3.7
#include <stdio.h>
int main(int argc, char *argv[]) {
int cont;
printf(Foram encontrados %d argumentos \n,argc -1);
for (cont=1;cont < argc;cont++)
printf(Argumento %d: %s \n, cont, argv[cont]);
return 0;
}

3.3

Oprimeiroargumento(argv[0])onomedoprograma.

PROTTIPODEFUNES

OpadroANSICexpandiuadeclaraotradicionaldefuno,permitindoqueaquantidadee
ostiposdosargumentosdasfunessejamdeclarados.Adefinioexpandidachamadaprottipode
funo.ProttiposdefunesnofaziampartedalinguagemCoriginal.

As variveis declaradas dentro de uma funo so automticas por padro. A classe de


variveisautomticaspodeserexplicitadausandoseapalavraauto.Ocdigo

int main() {
auto int x;
...
}

equivalentea

int main() {
int x;
...
}

3.5.2 STATIC

Dentro de sua prpria funo ou arquivo, variveis static so variveis permanentes. Ao


contrriodasvariveisglobais,elasnosoreconhecidasforadesuafunoouarquivo,masmantm
seus valores entre chamadas. O especificador static tem efeitos diferentes em variveis locais e em
variveisglobais.
Umavarivelestticainicializadaumanicavez,nomomentoemque
criada.
OExemplo3.7mostraousodeumavarivelesttica.Notequeavarivelifoideclaradacomo

19

LinguagemdeProgramaoC

staticenquantoquejfoideclaradonormalmente(ouauto).Acadachamada,avariveljinicializada
comzeroenquantoqueavarivelimantmoltimovalor.Almdisso,apesardeiserinicializada,isto
ocorresomentenaprimeiravez.
Exemplo3.7
#include <stdio.h>
void imprimeValor() {
static int i = 10;
int j =0;
for (; j<5; j++)
printf("%3d\t",i++);
printf("\n");
}

3.5.4 REGISTER

A classe de armazenamento register indica que a varivel associada deve ser guardada
fisicamentenumamemriadeacessomuitomaisrpido,chamadaregistrador.NocasodoIBMPCpode
sercolocadootipointecharassociadoaregisterpoisoregistradortemapenas16bits.

int main() {
imprimeValor();
imprimeValor();
imprimeValor();
return 0;
}

Basicamente,variveisregistersousadasparaaumentaravelocidadedeprocessamento.Por
exemplo,variveisdeusofreqentecomovariveisdelaoseargumentosdefunes.

3.6

11
16
21

12
17
22

13
18
23

14
19
24

#define PI 3.14159

Variveisestticaspodemmanteracontagemdequantasvezesumafunofoichamada.

3.5.2.1 VARIVEISLOCAISSTATIC

S pode ser escrito um comando destes por linha, e no h pontoevrgula aps qualquer
diretivadoprprocessador.

Quandoomodificadorstaticaplicadoaumavarivellocal,ocompiladorcriaarmazenamento
permanenteparaelaquasedamesmaformacomocriaarmazenamentoparaumavarivelglobal.Em
termossimples,umavarivellocalstaticumavarivellocalqueretmseuvalorentrechamadas.Mas
elasreconhecidaapenasnoblocoemqueestdeclarada.

3.5.2.2 VARIVEISGLOBAISSTATIC

3.5.3 EXTERN

Todavariveldeclaradaforadequalquerfunotmaclassedearmazenamentoextern.Como
podesesomenteumanicavezdeclararumavarivelglobal,aousardiversosarquivosparaummesmo
programa(porsergrande,porexemplo)deveseutilizaradeclaraoexternnosoutrosarquivosondea
varivelutilizada.Senoprocederassim,ocompiladoracusarumerrodeduplicidadedevarivel.
Exemplo3.8

Arquivo2

int x,y;
char ch;
int main() {
...
}

extern int x,y;


extern char ch;
void func22() {
x = y / 10;
}

void func1() {
x = 123;
}

void func23() {
y = 10;
}

Estadiretivausadaparadefinirmacroscomargumentos.
#define AREA(x) (4*PI*x*x)

A declarao acima define a funo AREA() aqual calcula a rea de umaesfera. A vantagem
destadeclaraoanotipagemdoargumentox.Nodevehaverespaosentreonomedamacroe
seusidentificadores.

3.7

Quandoomodificadorstaticaplicadoaumavarivelglobal,ocompiladorcriaumavarivel
quereconhecidaapenasnoarquivonaqualamesmafoideclarada.

Arquivo1

DIRETIVA#DEFINE

Adiretiva#definepodeserusadaparadefinirconstantessimblicascomnomesapropriados.
Porexemplo,aconstantePIpodeserdefinidacomovalor3.14159.

Execuo
10
15
20

Noarquivo2,alistadevariveisglobaisfoicopiadadoarquivo1eoespecificadorexternfoi
adicionadosdeclaraes.Oespecificadorexterndizaocompiladorqueostiposdevarivelenomes
que o seguem foram declarados em outro lugar. Isto , o compilador no reserva um espao de
memriaparaessasvariveisdeclaradascomoespecificadorexternnacertezadeestaremdeclaradas
emoutromdulo.

FUNESRECURSIVAS

Uma funo dita recursiva quando se definida dentro dela mesma. Isto , uma funo
recursivaquandodentrodelaestpresenteumainstruodechamadaaelaprpria.
Exemplo10.9
// imprime uma frase invertida utilizando recurso
#include <stdio.h>
#include <conio.h>
void inverte()
int main() {
clrscr( );
inverte( );
return 0;
}
void inverte() {
char ch ;
if ((ch=getche( )) != \r ) inverte();
scanf(%c,ch)
}

Toda funo recursiva deve possuir uma condio que termina a


recursividade,senoelapodecausarumaparadainesperadadosistema

21

LinguagemdeProgramaoC

22

LinguagemdeProgramaoC

3.8

long int x=14;


if (perf(x)==1) printf("%d perfeito",x);
else printf("%d no perfeito",x);

EXERCCIOS

1. Escreva um programa que receba como parmetro um ndice (float). Aps, ler uma seqncia de
nmeros (a qual termina por 0) e exibir o seu valor multiplicado pelo ndice. A funo que
transformaumastringemumfloatatof(char*x).
2. Escrevaumafunoquerecebaumcaracterecomoargumentoequeretornealetramaisculasea
mesmaforminscula.funes:islower(intch),toupper(intch).
3. Existeumalgoritmointeressanteparaseobteraraizquadradadeumnmeroquandoelaexata.
Paraisso,bastasubtrair nmerosmparesconsecutivosdonmerodoqualsedesejaretirararaiz
quadrada.Onmerodevezesseraraizdonmero.Porexemplo:

25 = 25 1 3 5 7 9 = 0
Noexemplo,subtraramsede25os5primeirosnmerosmparesconsecutivosatquesechegasse
0.Assim,araizquadradade255.Escrevaumafunoquerecebauminteironeretornearaiz
quadrada de n. Por exemplo, se a funo receber 49, ele retornar 7. O calculo da raiz quadrada
dever ser feito usando o algoritmo acima, sem usar qualquer funo prexistente de alguma
bibliotecaC.

6. Escreva uma funo em C que receba como argumentos a altura (alt) e o sexo de uma pessoa e
retorneoseupesoideal.Parahomens,calcularopesoidealusandoafrmula

PI m= 62.1 alt 44.7 .


7. EscrevaumafunoemCcomoseguinteprottipo
long int multiplicatorio(int i, int n)

Afunodeveretornaromultiplicatriodeian.Porexemplo,achamada
multiplicatorio(3,10)

retorna1814400(345678910).

long int somatrio(int i, int n)

Afunodeveretornarosomatriodeian.Porexemplo,achamada
somatrio(3,10)

retorna52(3+4+5+6+7+8+9+10).
break;
break;
break;
break;
break;
break;
resto);

void main(){
int N;
scanf("%d",&N);
x(N);
}

O que ser escrito na tela, supondo que o valor fornecido para N seja 10846? Mostre o teste de
mesacompletoutilizadoparadeterminarasada.

9. EscrevaumafunoemCquerecebadoisnmeroseretorneomaiordeles.
10. A acelerao a taxa de variao da velocidade em relao ao tempo, isto , a razo entre a
variaodavelocidadeeointervalodetempo.Matematicamente,

a=

#include<stdio.h>
int perf(long int N){
long int i, divs=0;
for(i=1; i<= N/2; i++)
if (N%i == 0) divs = divs + i;
if (divs == N) return 1;
else return 0;
}

onde

v = v f vi
avariaodavelocidadeouavelocidadefinalmenosavelocidadeinicial.EscrevaumafunoemC
que receba como parmetros a velocidade inicial, a velocidade final e o intervalo de tempo
correspondente e retorne a acelerao. Mostre, tambm, uma funo main() que chame essa
funo.
11. Ovalorde/2podesercalculadopelaseguintesriedeprodutos:

5. Simule a execuo do programa abaixo mostrando todas as mudanas de valores de variveis e o


resultadodaimpresso.

void main(){

PI h= 72.7 alt 58

e,paramulheres,

8. EscrevaumafunoemCcomoseguinteprottipo

4. Sejaoseguinteprograma:
#include<stdio.h>
void x(int n){
int i, resto;
i = n;
do{
resto = i%16;
i=i/16;
switch(resto){
case 10: printf("A");
case 11: printf("B");
case 12: printf("C");
case 13: printf("D");
case 14: printf("E");
case 15: printf("F");
default: printf("%d",
}
}while(i>0);
printf("\n");
}

22446688
L
13355778

EscrevaumafunoemCquerecebacomoargumentoumnmerointeironeretorneovalorde
calculadoatravsdasrieacimacomntermos.
12. Umaoclassificadodeacordocomoresultadodetrstestes,quedevemverificarseelesatisfazs
seguintesespecificaes:

Teste1:contedodecarbonoabaixode7%;

Teste2:durezaRokwellmaiorque50;

23

LinguagemdeProgramaoC

24

LinguagemdeProgramaoC

Teste3:resistnciatraomaiordoque80.000psi.

Oaorecebegrau10sepassarpelostrstestes;9,sepassarapenasnostestes1e2;8,sepassarno
teste1;e7,senopassounostrstestes.EscrevaumafunoemCqueocontedodecarbono
(em%),adurezaRokwellearesistnciatrao(empsi)deumaamostradeaoeretorneograu
obtido.
13. EscrevaumafunoemCquerecebaumnmeroneretorne1seasomadosdgitosformantesden
for10;0casocontrrio.Porexemplo,seovalordenrecebidofor145afunoretorna1.
14. Escreva uma funo em C que receba um numero e retorne seu fatorial. O fatorial de n
representadoporn!sendoque
0! = 1
1! = 1
2! = 12 = 2
3! = 123 = 6

PONTEIROS

Paraumaboautilizaodosponteirosdevesecompreendercorretamenteoseuuso.Existem
trs razespara isso: primeiro,ponteirosfornecemos meiospelosquaisasfunespodemmodificar
seus argumentos; segundo, eles so usados para suportar as rotinas de alocao dinmica de C, e
terceiro,ousodeponteirosparaaumentaraeficinciadecertasrotinas.

Por ser um dos aspectos mais poderosos da linguagem tambm so os mais perigosos. Por
errosnousodeponteiros(comoanoinicializaodeponteirosponteirosselvagens)podemprovocar
quebradosistema.

Por definio, um ponteiro uma varivel que contm um endereo de memria. Esse
endereonormalmenteumaposiodeoutravarivelnamemria.

4! = 1234 = 24

Umadeclaraodeponteirosconsistenotipobase,um"*"eonomedavarivel.Aformageral

tipo*nome;

5! = 12345 = 120
ondetipoqualquertipovlidoemCenomeonomedavarivelponteiro.

O tipo base do ponteiro define que tipo de variveis o ponteiro pode apontar. Basicamente,
qualquer tipo ponteiro pode apontar para qualquer lugar, na memria. Mas, para a aritmtica de
ponteirosfeitaatravsdotipobase.

4.1

Osoperadoresutilizadosso*e&,comojfoiexplicadonaseo6.6.

EXPRESSESCOMPONTEIROS
Nestaseoseroanalisadosalgunsaspectosespeciaisdeexpressescomponteiros.

4.1.1 ATRIBUIODEPONTEIROS

Como o caso com qualquer varivel, um ponteiro pode ser usado no lado direito de um
comandodeatribuioparapassarseuvalorparaoutroponteiro.
Exemplo4.1
#include <stdio.h>
void main() {
int x;
int *p1,*p2;
p1 = &x;
p2 = p1;
printf(%p,p2);
return 0;
}

/* declarao do ptr p1 e p2 com o tipo base int. */


/* escreve o endereo de x, no seu valor */

Agora,tantop1quantop2apontamparax.Oendereodexmostradousandoomodificador
de formato de printf() %p, que faz com que printf() apresente um endereo no formato usado pelo
computadorhospedeiro.

4.1.2 ARITMTICADEPONTEIROS

Existem apenas duas operaes aritmticas que podem ser usadas com ponteiros: adio e
subtrao.Osoperadorespermitidosnocasoseriam:+,,++,.

25

LinguagemdeProgramaoC

26

LinguagemdeProgramaoC

#include <stdio.h>
#include <string.h>
char *p=alo mundo;
int main() {
register int t;
printf(p);
for (t=strlen(p) - 1; t > -1; t--) printf(%c,p[t]);
return 0;
}

Oincrementosemprerealizadodotamanhobsicodearmazenamentodotipobase.Isto,
seotipobaseforuminteiroeincrementarmosemumaunidade,oapontadorapontarparaoprximo
inteiro (no casodo inteiroocupar2bytesoincrementoserdedoisbytes),nocasodeumcaractere
(char)serdeumbyte.
Exemplo4.2
int *ptri=3000;
char *ptrc=4000;
float *ptrf=4000;
ptri++;
ptrc++;
ptrf++;
ptri = ptri - 10;
ptrc = ptrc - 10;
ptrf = ptrf - 10;

/* ptri apontar
/* ptrc apontar
/* ptrf apontar
/* ptri apontar para o
/* ptrc apontar para o
/* ptrf apontar para o

para o endereo 3002 */


para o endereo 4001 */
para o endereo 5004 */
endereo 2982 */
endereo 3991 */
endereo 4964 */

Alm de adio e subtrao entre um ponteiro e um inteiro, nenhuma outra operao


aritmticapodeserefetuadacomponteiros.Isto,nopodemultiplicaroudividirponteiros;nopode
aplicar os operadores de deslocamento e de mascaramento bit a bit com ponteiros e no pode
adicionarousubtrairotipofloatouotipodoubleaponteiros.
Nosealteraovalordeumponteiroconstante(ponteiroparaumtipode
dado bsico int, float double, ), somente de um ponteiro varivel
(ponteirodeestruturascomplexasvetores,matrizes,strings,).

4.2

INICIALIZAODEPONTEIROS

Aps um ponteiro ser declarado, mas antes que lhe seja atribudo um valor, ele contm um
valordesconhecido.Aousaresteponteiroantesdeinicializar,provavelmenteprovocarumafalhado
programaouatdosistemaoperacional.

4.2.1 COMPARAODEPONTEIROS

possvelcomparardoisponteirosemumaexpressorelacional.

Exemplo4.6
if (p<q) printf(p aponta para uma memria mais baixa que q /n);

Geralmente,autilizaodecomparao entreponteiros quandoosmesmosapontampara


umobjetocomum. Exemplodistoapilha,onde verificadoseosponteirosdeincioefimdapilha
estoapontandoparaamesmaposiodememria,significandopilhavazia.

4.3

PONTEIROSEMATRIZES

Existe uma estreita relao entre matrizes e ponteiros. Pois C fornece dois mtodos para
acessar elementos de matrizes: aritmtica de ponteiros e indexao de matrizes. Aritmtica de
ponteiros pode ser mais rpida que indexao de matrizes. Normalmente utilizamse ponteiros para
acessarelementosdematrizesdevidoavelocidadedeacesso.
Exemplo4.7
char str[80], *p1;
p1 = str;

Como um ponteironulo assumido como sendono usado, podeseutilizar oponteironulo


parafazerrotinasfceisdecodificaremaiseficientes.Porexemplo,podeseutilizarumponteironulo
paramarcarofimdeumamatrizdeponteiros.Umarotinaqueacessaessamatrizsabequechegarao
final ao encontrar o valor nulo. A funo search(), mostrada no Exemplo 4.3, ilustra esse tipo de
abordagem.

Paraacessarastringstrpodeseutilizarestesdoismecanismos

Exemplo4.3
/* procura um nome */
search(char *p[], char *name)
{
register int t;
for (t=0;p[t];++t)
if(!strcmp(p[t],name)) return t;
return -1;
/* no encontrado */
}

*(p1 + 4)

O lao for dentro de search() executado at que seja encontrada uma coincidncia ou um
ponteironulo.Comoofinaldamatrizmarcadocomumponteironulo,acondiodecontroledolao
falhaquandoeleatingido.

Outra utilizaodeinicializaodeponteirosainicializaodestrings.Istopodeserlevado
comoumavariaonotemadeinicializaousadonavarivelargv.
Exemplo4.4
char *p= alo mundo \n;

O ponteiro p (Exemplo 4.4) no uma matriz, mas como o compilador C cria uma tabela de
strings,aconstante stringcolocadaemtaltabelasendoqueamesmapodeserutilizadaemtodoo
programacomosefosseumastringcomum.Porisso,inicializarumamatrizdestringsusandoponteiros
alocamenosmemriaqueainicializaoatravsdematriz.
Exemplo4.5

str[4]

/* indexao de matrizes */

ou
/* aritmtica de ponteiros */

Osdoiscomandosdevolvemoquintoelemento.
*(matriz+ndice)omesmoquematriz[ndice].

Para uma melhor compreenso ou facilidade de programao as funes de indexao


trabalhamcomponteiros(comomostraoExemplo4.8aimplementaodafunoputs()).
Exemplo4.8
/* Indexa s como uma matriz */
void put(char *s) {
register int t;
for (t=0;s[t]; ++t) putchar(s[t]);
}
/* Acessa s como um ponteiro */
void put(char *s) {
while (*s) putchar(*s++);
}

Nocasodapassagemdeparmetrospossveltratarumamatrizcomosefosseumponteiro.

Exemplo4.9
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void le_tab(int *p) {

27

LinguagemdeProgramaoC

28

LinguagemdeProgramaoC

register int i;
for(i=0; i<20; i++)
scanf(%d,(p+i));

char *p[10];
for (i = 0;i<10;i++)
p[i] = nome[i];
ordena(p);
return 0;

}
void mostra_tab(int *p) {
register int i;
for(i=0; i<20; i++)
printf(%d,*(p+i));
}
void main(void) {
int mat[20];
le_tab(mat);
mostra_tab(mat);
}

4.4

INDIREOMLTIPLA

Indireomltiplaumasituaoondeoponteiroapontaparaoutroponteiroequeomesmo
apontaparaumvalorfinal.AFigura4.1mostraoconceitodeindireomltipla.
Ponteiro

endereo

4.3.1 MATRIZESDEPONTEIROS

Ponteirospodemserorganizadosemmatrizescomoqualqueroutrotipodedado.Adeclarao
deumamatrizdeponteirosint,detamanho10,

Varivel
valor

IndireoSimples

Ponteiro

endereo

Ponteiro

Varivel

endereo

valor

int *x[10];

Paraatribuiroendereodeumavarivelinteira,chamadavar,aoterceiroelementodamatriz
deponteiros,deveseescrever

IndireoMltipla
Figura4.1Indireosimplesemltipla

x[2] = &var;

paraencontrarovalordevar,escrevese

A indireo mltipla pode ser levada a qualquer dimenso desejada, mas raramente
necessriomaisdeumponteiroparaumponteiro.

*x[2];

Sefornecessriopassarumamatrizdeponteirosparaumafuno,podeserusadoomesmo
mtodoqueutilizadoparapassaroutrasmatrizessimplesmentechamaseafunocomonomeda
matrizsemqualquerndice.
Exemplo4.10
void display_array(int *q[]) {
register int t;
for (t=0; t<10; t++)
printf(%d,*q[t]);
}

Lembrese de que q no um ponteiro para inteiros; q um ponteiro para uma matriz de


ponteirosparainteiros.Portanto,necessriodeclararoparmetroqcomoumamatrizdeponteiros
para inteiros, como mostrado no Exemplo 4.10. Isto , no uma passagem de parmetros por
refernciapordoismotivos:primeiro,matrizcomoargumentodefunoautomaticamentepassada
por refernciaporquestoda implementaodalinguagem,e segundo, umamatrizdeponteirose
conseqentementesuadeclaraocaracterizadapeloasterisconafrentedonomedavarivel.

Matrizesdeponteirossousadasnormalmentecomoponteirosdestringscomo,porexemplo,
oargumentodalinhadecomandosargv.

4.3.2 ACESSANDOPARTESDEMATRIZESCOMOVETORES

A linguagem C trata partes de matrizes como matrizes. Mais especificamente, cada linha de
umamatrizdeduasdimensespodeserconsideradacomoumamatrizdeumadimenso.Istopodeser
muitotilnotratamentodematrizes.OExemplo4.11mostraaatribuiodeumalinhadamatriznome
paraumponteiro.
Exemplo4.11
int main() {
static char nome[10][10];

Noconfundaindireomltiplacomlistasencadeadas.

Adeclaraodestetipodevarivelfeitacolocandoseum*adicionalemfrenteaonomeda
varivel,comomostraoExemplo4.12.Talexemplomostraadeclaraodavarivelptrptrintcomoum
ponteiroparaumponteirodotipoint.
Exemplo4.12
int **ptrptrint;

Paraacessarovalorfinalapontadoindiretamenteporumponteiroaumponteiro,vocdeve
utilizarooperadorasteriscoduasvezes,comonoExemplo4.13:
Exemplo4.13
#include <stdio.h>
int main() {
int x, *p, **q;
x = 10;
p = &x;
q = &p;
printf(%d, **q);
return 0;
}

4.5

/* imprime o valor de x */

PONTEIROSPARAFUNES

AlinguagemCpermiteapontadoresparafunes.Istopermitidopoistodafunotemuma
posiofsicanamemriaquepodeseratribudaaumponteiro.Portanto,umponteirodefunopode
serusadoparachamarumafuno.

Oendereodeumafunoobtidousandoonomedafunosemparntesesouargumentos.
Mas para declarar este tipo de apontador tem que se seguir uma sintaxe especial como mostra o
Exemplo4.14.
Exemplo4.14

29

LinguagemdeProgramaoC

30

LinguagemdeProgramaoC

#include <stdio.h>
#include <string.h>
void check(char *a, char *b, int (*cmp)());
int main() {
char s1[80], s2[80];
int (*p)();
p = strcmp;
gets(s1);
gets(s2);
check(s1,s2,p);
return 0;
}

Nessadeclarao,(*p)(..)indicaumponteiroparaumafuno.Porisso,int*(*p)(...)indicaum
ponteiro para uma funo que retorna um ponteiro para um inteiro. Dentro do ltimo par de
parnteses(aespecificaodosargumentosdafuno),(*a)[]indicaumponteiroparaumvetor.Assim
int (*a)[] representa um ponteiro para um vetor de inteiros. Juntando todas as peas, (*p)(int (*a)[])
representaumponteiroparaumafunocujoargumentoumponteiroparaumvetordeinteiros.E,
finalmente,adeclaraooriginalrepresentaumponteiroparaumafunoqueaceitaumponteiropara
umvetordeinteiroscomoargumentoedevolveumponteiroparauminteiro.
Se logo aps um identificador existir um abre parnteses indica que o
identificador representa uma funo e os colchetes representam uma
matriz.Osparntesesecolchetestmmaiorprecednciadoquequalquer
operador.

void check(char *a, char *b, int (*cmp)()) {


if (!(*cmp) (a, b)) printf(igual);
else printf(diferente);
}

Quando a funo check() chamada, dois ponteiros para caractere e um ponteiro para uma
funosopassadoscomoparmetros.Dentrodafunocheck(),notecomooponteiroparafuno
declarado,poisestaaformacorretadesedeclararestetipodeponteiro.Osparntesesaoredorde
*cmpsonecessriosparaqueocompiladorinterpreteocomandocorretamente.

Outra forma de fazer a chamada mostrada no Exemplo 4.14 o qual dispensa o uso de um
ponteiroadicional.

int
int
int
int

check(s1, s2, strcmp);

Umadasgrandesutilidadesousodedriversdedispositivos(placasdesom,placasdevdeo,
modems,entreoutros)quefornecemrotinasdetratamentoparaaquelehardwareespecfico.Ondeo
programador l o arquivo do driver para a memria e o executa de acordo com as especificaes do
fabricante.

Outrautilidadeoprogramadorpoderenviarafunoqueseapropriaparaacomparaopor
exemplo.Isto,nocasodestringspodesepensaremumcomparadordestringsgenricoondecomo
terceiro parmetro enviado a funo que vai realizar a comparao. Antes da chamada da funo
genrica pode verificar se a string composta por caracteres alfanumricos (atravs da funo
isalpha()) e enviar a funo strcmp(), caso contrrio uma funo que realize uma comparao de
nmerosinteiros(nestafunoconteraconversodasstringsemuminteiro(funoatoi()).

4.6

MAISSOBREDECLARAESDEPONTEIROS

As declaraes de ponteiros podem ser complicadas e necessrio algum cuidado na sua


interpretao.principalmenteemdeclaraesqueenvolvemfunesematrizes.Assim,adeclarao
int *p(int a);

indicaumafunoqueaceitaumargumentointeiroeretornaumponteiroparauminteiro.Poroutro
lado,adeclarao

int

int
int
int
int

int

int

int

int

int (*p)(int a);

indica um ponteiro para uma funo que aceita um argumento inteiro e retorna um inteiro. Nessa
ltima declarao, o primeiro par de parnteses usado para o aninhamento e o segundo par, para
indicarumafuno.

int

int

Ainterpretaodedeclaraesmaiscomplexaspodeserextremamentemaistrabalhosa.Por
exemplo,considereadeclarao
int
int *(*p)(int (*a)[]);

Aseguirsermostradovriasdeclaraesenvolvendoponteiroseseusignificado.
pumponteiroparaumvalorinteiro
p uma matriz de ponteiros com 10 elementos para valores
inteiros
(*p)[10];
pumponteiroparaumamatrizdeinteiroscom10elementos
*p(void);
pumafunoqueretornaumponteiroparaumvalorinteiro
*p(char *a);
pumafunoqueaceitaumargumentoqueumponteiropara
umcaractereeretornaumponteiroparaumvalorinteiro
(*p)(char *a);
pmponteiroparaumafunoqueaceitaumargumentoque
umponteiroparaumcaractereeretornaumvalorinteiro
(*p(char *a))[10];
pumafunoqueaceitaumargumentoqueumponteiropara
umcaractereeretornaumponteiroparaumamatrizinteirade10
elementos
p(char (*a)[]);
pumafunoqueaceitaumargumentoqueumponteiropara
umamatrizdecaractereeretornaumvalorinteiro
p(char *a[]);
p uma funo que aceita um argumento que uma matriz de
ponteirosparacaractere eretornaumvalorinteiro
*p(char a[]);
p uma funo que aceita um argumento que uma matriz de
caractereeretornaumponteiroparaumvalorinteiro
*p(char (*a)[]);
pumafunoqueaceitaumargumentoqueumponteiropara
uma matriz de caractere e retorna um ponteiro para um valor
inteiro
*p(char *a[]);
p uma funo que aceita um argumento que uma matriz de
ponteiros para caracteres e retorna um ponteiro para um valor
inteiro
(*p)(char (*a)[]);
pumponteiroparaumafunoqueaceitaumargumentoque
um ponteiro para uma matriz de caractere e retorna um valor
inteiro
*(*p)(char (*a)[]);
pumponteiroparaumafunoqueaceitaumargumentoque
umponteiroparaumamatrizdecaractereeretornaumponteiro
paraumvalorinteiro
*(*p)(char *a[]);
pumponteiroparaumafunoqueaceitaumargumentoque
uma matriz de ponteiros para caracteres eretornaumponteiro
paraumvalorinteiro
(*p[10])(char a);
p uma matriz de ponteiros com 10 elementos para funes;
cada funo aceita um argumento que umcaracteree retorna
umvalorinteiro
*(*p[10])(char a);
p uma matriz de ponteiros com 10 elementos para funes;
cada funo aceita um argumento que umcaracteree retorna
umponteiroparaumvalorinteiro
*(*p[10])(char *a);
p uma matriz de ponteiros com 10 elementos para funes;
cada funo aceita um argumento que um ponteiro para um
caractereeretornaumponteiroparaumvalorinteiro

int *p;
int *p[10];

31

LinguagemdeProgramaoC

32

LinguagemdeProgramaoC

4.7

1. Comoreferenciarmat[x][y]emnotaodeponteiros.
2. Qualserasadadesteprograma?
int main() {
int i=5;
int *p;
p = &i;
printf(%u %d %d %d %d \n, p, *p+2,**&p,3**p,**&p+4);
return 0;
}

3. Escrevaumafunoqueinvertaaordemdoscaracteresdeumastring.
4. Crie uma funo que receba como parmetro uma matriz de ponteiros para strings e devolve a
matrizordenada.
5. Faaumafunoquerecebaumponteiroparaumamatrizequerealizeaordenaodamesma.

AlinguagemCpermitecriartiposdedadosdefinveispelousuriodecincoformasdiferentes.
A primeira estrutura, que um agrupamento de variveis sobre um nome e, algumas vezes,
chamadadetipodedadoconglomerado.Osegundotipodefinidopelousurioocampodebit,que
uma variao da estrutura que permite o fcil acesso aos bits dentro de uma palavra. O terceiro a
unio,aqualpermitequeamesmaporodamemriasejadefinidapordoisoumaistiposdiferentes
devariveis.Umquartotipodedadoaenumerao,queumalistadesmbolos,comofoivistona
seo 1.5. O ltimo tipo definido pelo usurio criado atravs do uso de typedef e define um novo
nomeparaumtipoexistente.

5.1

ESTRUTURAS

Otipoestruturadostructpossibilitaacriaodeestruturasdedadoscomplexas,isto,pode
se obter estruturas que contenham mais de um tipo de dado. Tal estrutura conhecida em outras
linguagenscomoregistros.

Cadaelementoquecompeaestrutura(chamadocampo)podeseracessadoindividualmente,
assimcomoaestruturapodeseracessadacomoumtodo.EmC,adeclaraodeumaestruturafeita
daseguinteforma:

6. Faaadeclaraodeumafuno(nome:teste)querecebaumponteiroparaumafunoquepossui
doisargumentos(intechar)eretorneumponteiroparaumfloat.

struct[nome_struct]{
tipovar1;
tipovar2;

tipovarN;}[nome_var];

7. Faaadeclaraoeinicializaodeumamatrizdeponteirosparaosdiasdasemana.
8. Faa uma funo que receba uma matriz de ponteiros para caracteres e realize a ordenao
alfabticadamesma.

ESTRUTURASEUNIES

EXERCCIOS

Devese encerrar com um pontoevrgula a declarao porque a definio de estrutura na


realidadeumainstruoC.

Adeclaraodeestruturaspodeseapresentardediversasformas.Taiscomo:
struct {
char nome[30];
int idade;
int codigo;
float saldo;
} conta1, conta2;

Na declarao acima, o nome_struct no utilizado, pois esta estrutura ser utilizada pelas
variveisdeestruturaconta1econta2.Parautilizarestaestruturanadefiniodeoutrasvariveistem
se que declarlas juntas com a definio da estrutura. No caso de um programa que utilize esta
estruturaparapassarparmetros,declararvariveislocais,entreoutros,alinguagempermiteacriao
dertulosdeestruturas(nome_struct).
Exemplo5.1
struct cad_conta {
char nome[30];
int idade;
int codigo;
float saldo;
} conta1, conta2;

Como mostra Exemplo 5.1, foram declaradas as variveis conta1 e conta2 como sendo uma
estrutura do tipo cad_conta. Quando rotulase a estrutura podese omitir a declarao das variveis,
comomostradonoExemplo5.2.
Exemplo5.2
struct cad_conta {
char nome[30];
int idade;

33

LinguagemdeProgramaoC

};

Parausarestaestruturaemoutrasdeclaraesdeveseespecificardestaforma:
struct cad_conta conta1, conta2;

Asestruturasseguemopadrodoescopodevariveis,isto,seadeclaraoestivercontida
numafuno,aestruturatemescopolocalparaaquelafuno;seadeclaraoestiverforadetodasas
funes,elaterumescopoglobal.

Paraacessarumcampoespecficodeumastructutilizaseooperador.(ponto).

Exemplo5.3
conta1.saldo = 0;
conta1.codigo = 0;
strcpy(conta1.nome,Joao);
conta1.idade = 21;

LinguagemdeProgramaoC

int codigo;
float saldo;

34

permitidaaatribuioentrestruct.Nestecasotodososcampossocopiados.

Exemplo5.4
conta2 = conta1;

5.1.1 INICIALIZANDOESTRUTURAS

Umaestruturaspodeserinicializadasepertencersclassesstaticouextern.Observequea
classedeumaestruturadadapelopontoemqueasvariveisforamdeclaradasenopelopontoonde
aestruturafoidefinida.

Damesmaformaqueosvetores,asestruturassoinicializadascomumalistadevalores(cada
umcorrespondenteaumcampodeestrutura)entrechaveseseparadosporvrgulas.
Exemplo5.5
struct cad_conta {
char nome[30];
int idade;
int codigo;
float saldo;
};
int main() {
static struct cad_conta
conta1 = {Andre, 23, 9507, 1567.89},
conta2 = {Carlos, 33, 9678, 1000.59};

5.1.2 ESTRUTURASANINHADAS

Como os campos da estrutura podem ser de qualquer tipo, tambm permitido o uso de
estruturasnadeclarao.
Exemplo5.6
struct data {
int dia;
char mes[10];
int ano;
};
struct func {
char nome[20];
int codigo;
float salario;
struct data nascimento;

};
int main() {
static struct func
funcionario = {Marcio, 1234, 3743.44, {10, Janeiro, 1967}},
gerente
= {Jose, 456, 5634.28, {18, Marco, 1950}};
return 0;
}

Observe a inicializao das variveis. A estrutura inicializada tambm com uma lista de
valoresentrechaveseseparadosporvrgulas.Oacessoaumcampodeumaestruturaaninhadafeito
naforma:
funcionrio.nascimento.dia = 10;
strcpy(gerente.nascimento.mes,Abril);

5.1.3 ESTRUTURASEFUNES

EmversesmaisantigasdecompiladoresC,asestruturasnopodiamserusadasempassagem
deparmetrosporvalorparafunes.Istosedeviaarazesdeeficincia,umavezqueumaestrutura
pode ser muito grande e a cpia de todos os seus campos para a pilha poderia consumir um tempo
exagerado. Desta forma, as estruturas eram obrigatoriamente passadas por referncia, usandose o
operadordeendereo(&).

NoTurboCeoutroscompiladoresmaisrecentes,aresponsabilidadedadecisoficaacargodo
programador.Assim,umafunopodepassarouretornarumaestrutura.
Exemplo5.7
struct cad_conta {
char nome[30];
int idade;
int codigo;
float saldo;
};
int main() {
static struct cad_conta conta1;
conta1 = ins_conta();
lista(conta1);

}
struct cad_conta ins_conta() {
struct cad_conta aux;
gets(aux.nome);
scanf(%d, &aux.idade);
scanf(%d, &aux.codigo);
scanf(%f, &aux.saldo);
return(aux);
}
void lista(struct cad_conta aux) {
printf(Nome
: %s\n,aux.nome);
printf(Idade
: %d\n, aux.idade);
printf(Codigo : %d\n, aux.codigo);
printf(Saldo
: %.2f\n, aux.saldo);
}

5.1.4 VETORDEESTRUTURAS

Acriaodetabeladeestruturasmantmasintaxenormaldedefiniodematrizes,como
mostradanoExemplo5.8:
Exemplo5.8
struct cad_conta {
char nome[30];

35

LinguagemdeProgramaoC

36

LinguagemdeProgramaoC

Certasrotinasdecriptografiaprecisamacessarosbitsdentrodeumbyte.

int idade;
int codigo;
float saldo;
};
int main() {
int i
static struct cad_conta conta[10]=
{ {Andre, 23, 9507, 1567.89},
{Carlos, 33, 9678, 1000.59},
...
};
for (i=0;i<10;i++) {
printf(Nome
: %s\n,conta[i].nome);
printf(Idade
: %d\n, conta[i].idade);
printf(Codigo : %d\n, conta[i].codigo);
printf(Saldo
: %.2f\n, conta[i].saldo);
}

5.1.5 PONTEIROSPARAESTRUTURAS

Cpermiteponteirosparaestruturasexatamentecomopermiteponteirosparaoutrostiposde
variveis.Noentanto,halgunsaspectosespeciaisdeponteirosdeestruturas.

Paraacessarosbits,Cusaummtodobaseadonaestrutura.Umcampodebits,naverdade,
apenasumtipodeelementodeestruturaquedefineocomprimento,embits,docampo.Aformageral
deumadefiniodecampodebit:
structnome{

tipovar1:comprimento;

tipovar2:comprimento;

tipovarN:comprimento;
}[lista_de_variaveis];
Um campo de bit deve ser declarado como int, unsigned ou signed. Campos de bit de
comprimento1devemserdeclaradoscomounsigned,porqueumnicobitnopodetersinal.(Alguns
compiladoresspermitemcamposdotipounsigned).
Um exemplo de campos de bits a comunicao via serial que devolve um byte de estado
organizadocomomostraaTabela5.1.
Tabela5.1:Estadodacomunicaoserial.

Bit
0
1
2
3
4
5
6
7

Como outros ponteiros, declarase colocando um * na frente do nome da estrutura. No


Exemplo5.9declaraseptr_ctacomoumapontadordaestruturapreviamentedefinidacad_conta.
Exemplo5.9
struct cad_conta *ptr_cta;

H dois usos primrios para ponteiros de estrutura: gerar uma chamada por referncia para
uma funo e criar estruturas de dados dinmicas (listas, pilhas, filas, entre outras) utilizandose do
sistemadealocaodeC.

Na forma de acessar os elementos ou campos de uma estrutura usando um ponteiro para a


estrutura, devese utilizar o operador > (seta). A seta usada sempre no caso de apontador de
estruturas.NoExemplo5.10mostradaadeclarao,atribuioeutilizaodeponteirosdeestruturas.
Exemplo5.10
struct cad_conta {
char nome[30];
int idade;
int codigo;
float saldo;
} conta;
int main() {
struct cad_conta *ptr;
ptr = &conta;
ptr->idade = 23;
ptr->codigo = 1000;
return 0;
}

5.2

/* o ptr recebe o end. da estrutura */

CAMPOSDEBITS

Ao contrrio das linguagens de computador, C tem um mtodo intrnseco para acessar um


nicobitdentrodeumbyte.Issopodesertilpordiversasrazes:
Se o armazenamento limitado, voc pode armazenar diversas variveis Booleanas
(verdadeiro/falso)emumbyte.
Certosdispositivostransmiteminformaescodificadasnosbitsdentrodeumbyte.

Significadoquandoligado
alteraonalinhacleartosend
alteraoemdatasetready
bordadesubidadaportadoradetectada
alteraonalinhaderecepo
cleartosend
datasetready
chamadadotelefone
sinalrecebido

Podeserepresentarainformaoemumbytedeestadoutilizandooseguintecampodebits:

Exemplo5.11
struct status_type {
unsigned delta_cts
unsigned delta_dsr
unsigned tr_edge
unsigned delta_rec
unsigned cts
unsigned dsr
unsigned ring
unsigned rec_line
} status;

: 1;
:
:
:
:
:
:
:

1;
1;
1;
1;
1;
1;
1;

Paraatribuirumvaloraumcampodebit,simplesmenteutilizaseaformaparaatribuiode
outrotipodeelementodeestrutura.
status.ring = 0;

Nonecessriodarumnomeatodocampodebit.Istotornafcilalcanarobitquesedeseja
acessar, contornando os no usados. Por exemplo, se apenas cts e dtr importam, podese declarar a
estruturastatus_typedestaforma:
struct status_type {
unsigned
: 4;
unsigned cts : 1;
unsigned dsr : 1;
} status;

37

LinguagemdeProgramaoC

38

Almdisso,notasequeosbitsapsdsrnoprecisamserespecificadossenosousados.

Variveisdecampodebittmcertasrestries:

Nopodeobteroendereodeumavariveldecampodebit.
Variveisdecampodebitnopodemserorganizadasemmatrizes.
Nopodeultrapassaroslimitesdeuminteiro.
No pode saber, de mquina para mquina, se os campos estaro dispostos da esquerda
paraadireitaoudadireitaparaaesquerda.
Em outras palavras, qualquer cdigo que use campos de bits pode ter algumas
dependnciasdamquina.

Finalmente, vlido misturar elementos normais de estrutura com elementos de campos de


bit. O Exemplo 5.12 define um registro de um empregado que usa apenas um byte para conter trs
informaes:oestadodoempregado,seoempregadoassalariadoeonmerodededues.Semo
campodebits,essavarivelocupariatrsbytes.
Exemplo5.12
struct emp {
struct addr endereco;
float salario;
unsigned ativo
: 1;
unsigned horas
: 1;
unsigned deducao : 3;
};

5.3

LinguagemdeProgramaoC

int i;
double d;
float f;
} data;

Como mostra o Exemplo 5.14, foi declarada a varivel data como sendo uma unio do tipo
tipos. Quando rotulase a unio podese omitir a declarao das variveis, como mostrado no
Exemplo5.15:
Exemplo5.15
union tipos {
char c;
int i;
double d;
float f;
};

union tipos data1, data2;

/* ocioso ou ativo */
/* pagamento por horas */
/* dedues de imposto */

UNIES

Umaunioumtipodedadoquepodeserusadodemuitasmaneirasdiferentes.Porexemplo,
uma unio pode ser interpretada como sendo um inteiro numa operao e um float ou double em
outra.Embora,asuniespossamtomaraaparnciadeumaestrutura,elassomuitodiferentes.

Asestruturasseguemopadrodoescopodevariveis,isto,seadeclaraoestivercontida
numafuno,aestruturatemescopolocalparaaquelafuno;seadeclaraoestiverforadetodasas
funes,elaterumescopoglobal.

Para acessar um campo especfico de uma union utilizase o operador . (ponto). Podese
declararestruturasdentrodeunies.
Exemplo5.16
struct so_int {
int i1,i2;
};
struct so_float {
float f1,f2;
};

Uma unio pode conter um grupo de muitos tipos de dados, todos eles compartilhando a
mesma localizao na memria. No entanto, uma unio s pode conter informaes de um tipo de
dadosdecadavez.Paracriarumaunioutilizaseaseguintesintaxe:

union {
struct so_int i;
struct so_float f;
} teste;

union[nome_union]{

tipovar1;

tipovar2;

tipovarN;
}[nome_var];

int main() {
teste.i.i1
teste.i.i2
printf(i1
teste.f.f1
teste.f.f2
printf(f1
return 0;
}

Devese encerrar com um pontoevrgula a declarao porque a definio de unio na


realidadeumainstruoC.Adeclaraodeuniespodeseapresentardediversasformas.Taiscomo:
Exemplo5.13
union {
char c;
int i;
double d;
float f;
} data;

Nadeclaraoacima,onome_unionnoutilizadopoisestaunioserutilizadapelavarivel
data. Para utilizar esta unio na definio de outras variveis temse que declarlas juntas com a
definio da unio. No caso de um programa que utilize esta unio em vrias partes do programa a
linguagemCpermiteacriaodertulosdeestruturas(nome_union).
Exemplo5.14
union tipos {
char c;

Parausarestaunioemoutrasdeclaraesdeveseespecificardestaforma:

5.4

=
=
=
=
=
=

2;
3;
%-3d i2 = %-3d\n,teste.i.i1,teste.i.i2);
2.5;
3.5;
%.1f
f2 = %.1f\n,teste.f.f1,teste.f.f2);

SIZEOF()

Comusodeestruturas,unieseenumeraespodeseutilizlasparaacriaodevariveisde
diferentestamanhosequeotamanhorealdessasvariveispodemudardemquinaparamquina.O
operador unrio sizeof() calcula o tamanho de qualquer varivel ou tipo e pode ajudar a eliminar
cdigosdependentesdamquinadeseusprogramas.
Exemplo5.17
union tipos {
char c;
int i;
double d;
float f;
} data;

39

LinguagemdeProgramaoC

40

LinguagemdeProgramaoC

};

O sizeof(data) 8. No tempo de execuo, no importa o que a unio data est realmente


guardando. Tudo o que importa o tamanho da maior varivel que pode ser armazenada porque a
uniotemdeserdotamanhodoseumaiorelemento.

5.5

int main() {
cad_conta *ptr;
ptr = &conta;
ptr->idade = 23;
ptr->codigo = 1000;
return 0;
}

TYPEDEF

A linguagem C permite que definase explicitamente novos nomes aos tipos de dados,
utilizando a palavrachave typedef. No h criao de uma nova varivel, mas sim, definindose um
novonomeparaumtipojexistente.Serveparaumaboadocumentaoouattornarosprogramas
dependentesdemquinaumpoucomaisportteis.Aformageraldeumcomandotypedef
typedeftiponome;

typedef struct conta cad_conta;

Porexemplo,poderiasercriadoumnovonomeparacharutilizando
typedef char boolean;

Essecomandodizaocompiladorparareconhecerbooleancomooutronomeparachar.Assim,
parasecriarumavarivelchar,usandoboolean
boolean ok;

Tambm vlida a redefinio, isto , utilizar um novo nome para um nome atribudo aum
dadopreviamenteestabelecido.
Exemplo5.18
#include <stdio.h>
typedef char boolean;
typedef boolean bool;
int main() {
boolean a;
bool b;
a = 1;
b = 2;
printf("%d %d",a,b);
return 0;
}

A declarao typedef usado tambm para definir tipos estruturados (struct e union) para
facilitaranomenclaturadostiposnadeclaraodevariveis.
Exemplo5.19
typedef struct conta {
char nome[30];
int idade;
int codigo;
float saldo;
} cad_conta;
int main() {
cad_conta *ptr;
ptr = &conta;
ptr->idade = 23;
ptr->codigo = 1000;
return 0;
}
ou
struct conta {
char nome[30];
int idade;
int codigo;
float saldo;

5.6

EXERCCIOS

1. Faa um programa que leia os dados de 10 clientes de um banco e aps leia 100 conjuntos de 3
valores:
cdigodeoperao0depsito,1retirada,
valordaoperao
cdigodocliente.

Realize as movimentaes nas contas correspondentes e ao final escreva o nome e saldo de


cadacliente.
2. Faa um programa de cadastro de clientes que contenham as seguintes opes: incluir, alterao,
excluireconsultarporcdigooupornome.Ocadastrodeveserdaseguinteforma:
nome(30caracteres);
cdigo(0a255);
idade(char);

41

LinguagemdeProgramaoC

42

LinguagemdeProgramaoC

antigosdevolvemponteirosparachar.Nessecaso,deveseusarumcastquandoatribuiraponteirosde
tiposdiferentes.

ALOCAODINMICA

Programasconsistememduascoisas:algoritmoseestruturasdedados.Umbomprograma
uma combinao de ambos. A escolha e a implementao de uma estrutura de dados so to
importantesquantoasrotinasquemanipulamosdados.

Paraamanipulaodedadosutilizadomecanismosqueauxiliamtantonaformadecomo
armazenado ou recuperado. Existem vrios mecanismos que realizam este tipo de processamento.
Abaixoestolistadosalgunsmecanismosbsicos:

6.2.1 MALLOC()

Estafunodevolveumponteiroparaoprimeirobytedeumaregiodememriadetamanho
size que foi alocada do heap. No caso em que no houver memria suficiente, a funo devolve um
ponteironulo.
Cuidado!Aousarumponteironulo,podecausarumafalhanoprograma.

Listas

Filas

Pilhas

rvores

Sintaxe.:
void *malloc(size_t size);

Cada um destes mecanismos pode ter variaes de acordo com a poltica de processamento
(armazenamento/recuperao). Neste captulo ser abordado com mais nfase as listas encadeadas,
porqueserocomobaseparaaconstruodosdemais.

6.1

Ondesize_tpodeserconsideradouminteirosemsinalesizeonmerodebytesdememria
que se quer alocar. Essa funo devolve um ponteiro void, como mostra a sintaxe, portanto podese
atribuiraqualquertipodeponteiro.

Para assegurar a portabilidade de um programa que utilize a alocao dinmica, fazse


necessrioautilizaodafunosizeof().

MAPADEMEMRIA

Quando um programa em C executado, quatro regies de memria so criadas: cdigo do


programa, variveis globais, heap e pilha, como ilustrado Figura 6.1. A regio da pilha a poro de
memriareservada paraarmazenaro endereoderetornodaschamadasdefunes,argumentosde
funesevariveislocais,oestadoatualdaCPU.Apilhacrescedecimaparabaixo,isto,doendereo
maisaltoparaomaisbaixo.Oheaparegioutilizadaparausodoprogramadoratravsdasfunesde
alocaodinmica.Comooheapcrescedebaixoparacima(endereomaisbaixoparomaisalto),pode
haver umacoliso entre as duas regies, o que causa umafalhano programa. Masistopodeocorrer
somentequandodeterminadosmodelosdememriasoutilizadosparaexecutaroprograma.

Exemplo6.1:
/* Esta funo aloca memria suficiente para conter uma
estrutura do tipo addr */
struct addr {
char nome[40];
char rua[40];
char cidade[40];
char estado[3];
char cep[10];
};
struct addr *get_struct(void) {
struct addr *p;
if ((p=(struct addr*)malloc(sizeof(addr)))==NULL)
{
printf( erro de alocao - abortando);
exit(1);
}
return p;
}

Ofragmentodocdigomostraaalocaode1000bytesdememria.

Figura6.1:MapadememriadeumprogramaemC

6.2

char *p;
p = (char*)malloc(1000);

Nofragmentoabaixoalocadomemriasuficientepara50inteiros.

FUNESDEALOCAODINMICAEMC
int *p;
p = (int*)malloc(50 * sizeof(int));

OpadroCANSIdefineapenasquatrofunesparaosistemadealocaodinmica:calloc(),
malloc(), free(), realloc(). No entanto, sero estudadas, alm das funes descritas, algumas funes
queestosendolargamenteutilizadas.

OpadroCANSIespecificaqueosprottiposparaasfunesdealocaodinmicadefinidas
pelo padro esto em STDLIB.H. Entretanto, tais funes esto especificadas na biblioteca ALLOC.H,
ondeencontramsemaisfunesdealocaodinmica.

O padro C ANSI especifica que o sistema de alocao dinmica devolve ponteiros void, que
so ponteiros genricos, podendo apontar para qualquer objeto. Porm, alguns compiladores mais

O compilador deve conhecer duas informaes sobre qualquer ponteiro: o endereo da


varivelapontadaeseutipo.Porisso,precisasefazerumaconversodetipo(cast)dovalorretornado
pormalloc(),jqueomesmoretornaumvoid.Portanto,noExemplo6.1deveseindicaraocompilador
queovalorretornadopormalloc()dotipoponteiroparastructaddr.
p=(structaddr*)malloc(sizeof(addr))

Este tipo de converso deve ser realizado em todas as funes de alocao como calloc(),
realloc()emalloc().

43

LinguagemdeProgramaoC

44

LinguagemdeProgramaoC

printf("String: %s\n", str);

6.2.2 CALLOC()

/* libera a memria */
free(str);

Estafunodevolveumponteiroparaoprimeirobytedeumaregiodememriadetamanho
size*numquefoialocadadoheap.Nocasoemquenohouvermemriasuficiente,afunodevolve
umponteironulo.
Sintaxe.:
void *calloc(size_t num, size_t size);

Ondesize_tpodeserconsideradouminteirosemsinalesizeonmerodebytesdememria
que se quer alocar. Essa funo devolve um ponteiro void, como mostra a sintaxe, portanto podese
atribuiraqualquertipodeponteiro.

Para assegurar a portabilidade de um programa que utilize a alocao dinmica, fazse


necessrioautilizaodafunosizeof().

return 0;
}

6.2.4 REALLOC()

Esta funo modifica o tamanho da memria previamente alocada apontada por ptr para
aqueleespecificadoporsize.Ovalordesizepodesermaioroumenorqueooriginal.Umponteiropara
o bloco de memria devolvido porque realloc() pode precisar mover o bloco para aumentar seu
tamanho.Seissoocorre,ocontedodoblocoantigocopiadononovobloco;nenhumainformao
perdida.
Sintaxe.:

void *realloc(void *ptr, size_t size);

Adiferenaentrecalloc()emalloc()queaprimeiraalocaamemriaeinicializaacomzeros.

Exemplo6.2
/* Esta funo aloca memria suficiente para conter um
vetor de 100 elementos */
#include <stdlib.h>
#include <stdio.h>
float *get_mem() {
float *p;
p=(float*)calloc(100, sizeof(float));
if (!p) {
printf( erro de alocao - abortando);
exit(1);
}
return p;
}

Septrumnulo,realloc()simplesmentealocasizebytesdememriaedevolveumponteiro
paraamemriaalocada.Sesizezero,amemriaapontadaporptrliberada.

Se no h memria livre suficiente no heap para alocar size bytes, devolvido um ponteiro
nuloeoblocooriginaldeixadoinalterado.
Exemplo6.4:
/* Esta programa primeiro aloca 23 caracteres, copia a string isso so
22 caracteres neles e, em seguida, usa realloc() para aumentar o
tamanho para 24 e, assim, pr um ponto no final. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

Nofragmentoabaixoalocadomemriasuficientepara50inteiros.

int main() {
char *p;
p=(char*)malloc(23);
if (!p) {
printf( erro de alocao - abortando);
exit(1);
}
strcpy(p,isso so 22 caracteres);
p = (char*)realloc(p,24);
if (!p) {
printf( erro de alocao - abortando);
exit(1);
}
strcat(p,.);
printf(p);
free(p);
return 0;
}

int *p;
p = (int*)calloc(50,sizeof(int));

6.2.3 FREE()

Estafunodevolveaoheapamemriaapontadaporptr,tornandoamemriadisponvelpara
alocaofutura.

Afunofree()deveserchamadasomentecomumponteiroquefoipreviamentealocadocom
uma das funes do sistema de alocao dinmica. A utilizao de um ponteiro invlido na chamada
provavelmente destruir o mecanismo de gerenciamento de memria e provocar uma quebra do
sistema.
Exemplo6.3
#include <string.h>
#include <stdio.h>
#include <alloc.h>
int main() {
char *str;
/* aloca memria para uma string */
str = (char*)malloc(10);
/* copia "Hello" para a string */
strcpy(str, "Hello");
/* mostra a string */

6.3

MATRIZESDINAMICAMENTEALOCADAS

Qualquerponteiropodeserindexadocomosefosseumamatrizunidimensional,portantono
havernenhumproblemaparautilizar.
Exemplo6.5:
/* Aloca memria para uma string dinamicamente, solicita
/* a entrada do usurio e, em seguida, imprime a string
/* de trs para frente.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

*/
*/
*/

45

LinguagemdeProgramaoC

LinguagemdeProgramaoC

int main() {
char *s;
register int t;
s=(char*)malloc(80);
if (!s) {
printf( erro de alocao - abortando);
exit(1);
}
gets(s);
for (t=strlen(s)-1; t>=0; t--) putchar(s[t]);
free(s);
return 0;
}

Para acessar uma matriz unidimensional simples, mas para mais de uma dimenso levam
algunsproblemascomaindexao.

Para conseguir uma matriz alocada dinamicamente, devese utilizar um truque: passar um
ponteiro como um parmetro a uma funo. Dessa forma, a funo pode definir as dimenses do
parmetroquerecebeoponteiro,permitindo,assim,aindexaonormaldamatriz.Istomostradono
Exemplo6.6.
Exemplo6.6:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void le_tab(int mat[20][5]) {
register int i,j;
for(i=0; i<20; i++)
for(j=0; j<5; j++)
scanf(%d,&mat[i][j]);
}
void mostra_tab(int mat[20][5]) {
register int i,j;
for(i=0; i<20; i++)
for(j=0; j<5; j++)
printf(%d,mat[i][j]);
}
int main() {
char *p;
register int t;
s=(int*)calloc(100, sizeof(int));
if (!p) {
printf( erro de alocao - abortando);
exit(1);
}
le_tab(p);
mostra_tab(p);
return 0;
}

6.4

46

LISTASENCADEADAS

Listas encadeadas so usadas para dois propsitos fundamentais. O primeiro criarmatrizes


detamanhodesconhecidonamemria.Listasencadeadastambmsousadasemarmazenamentode
bancodedadosemarquivosemdisco.

Listasencadeadaspodemsersingularmente(simplesmente)umeloparaoprximoitemou
duplamenteelosparaoanterioreprximoelementodalistaencadeadas.

Uma lista singularmente encadeada requer que cada item de informao contenha um elo
comooprximodalista.Cadaitemdedadogeralmenteconsisteemumaestruturaqueincluicampos
deinformaoeponteirodeenlace(oudeligao).

Antes,precisasedefiniraestruturadedadosquecontenhaainformaoeoselos.Considere
umexemplodearmazenamentodecoordenadascartesianas(x,y,z)pararepresentaodeumafigura
geomtrica.Aestruturadedadosparacadaelementodefinidoaqui:

struct ponto {
int x,y,z;
struct ponto *prox;
} figura1;
typedef struct ponto figura;

Na estrutura acima, declarado um apontador para a prxima estrutura, por isso declarase
umapontadorparaaprpriaestrutura (autoreferncia).Apsa declarao,foidefinidoquefigura
umtipo,querepresentaumastructponto,oqualpodeserutilizadoemtodooprograma.

A funo inclui() constri uma lista singularmente encadeada colocando cada novo item no
finaldalista.Deveserpassadoumponteiroparaumaestruturadotipoponto,ponteiroparaoprimeiro
elementoeponteiroparaoltimoelemento.
void inclui(figura *i, figura **inicio, figura **fim) {
if (!*fim) {/* Primeiro elemento da lista */
*fim = i;
*inicio = i;
} else {
(*fim)->prox = i;
*fim = i;
}
}

Osparmetrosincioefimdafunotmdoisasteriscosporque representamumaindireo
mltipla. Isto , so apontadores para apontadores da estrutura figura. Isto necessrio para poder
implementarapassagemdeparmetrosporreferncia.

Apagarumitemdeumalistasingularmenteencadeadapodeocorreremtrssituaes:apagar
oprimeiroitem,apagar umitemintermedirioeapagaroltimoitem.Afunoaseguirexcluirum
itemdeumalistadeestruturasdotipoponto:
void exclui(
figura *p,
figura *i,
figura **inicio,
figura **ultimo) {
if (p)
p->next = i->next;
else
*start = i->next;
if (i==*last && p)
*last = p;
}

/*
/*
/*
/*

item anterior */
item a apagar */
incio da lista */
final da lista */

Listas singularmente encadeadas tm uma desvantagem que a lista no pode ser lida em
ordeminversa.

6.4.2 LISTASDUPLAMENTEENCADEADAS
6.4.1 LISTASSINGULARMENTEENCADEADAS

Consistememdadoseelosparaoprximoitemeparaoitemprecedente.Umnovoelemento
pode ser inserido em uma lista duplamente encadeada de trs maneiras: inserir um novo primeiro
elemento,inserirumelementointermedirioouinserirumnovoltimoelemento.

47

LinguagemdeProgramaoC

48

LinguagemdeProgramaoC

Aconstruodeumalistaduplamenteencadeadasemelhantedeumalistasingularmente
encadeada,excetopelofatodequedoiselosdevemser mantidos.Utilizandoaestruturaponto,ser
mostradoadeclaraodeumnododelistaduplamenteencadeada.

Htrscasosaconsideraraoexcluirumelementodeumalistaduplamenteencadeada:excluir
oprimeiroitem,excluirumitemintermedirioouexcluiroltimoitem.
void delord(figura *i,
/* item a apagar */
figura **inicio,
/* primeiro elemento da lista */
figura **fim) {
/* ultimo elemento da lista */
figura *old, *p;
p = *inicio;
old = NULL;
while (p && (p->x != i->x) &&(p->y != i->y)) {
old = p;
p = p->prox;
}

struct ponto {
int x,y,;
struct ponto *prox;
struct ponto *ant;
};
typedef struct ponto figura;

Usandofiguracomooitemdedadobsico,afunoseguinteconstriumalistaduplamente
encadeada.Estafunoincluiumnovodadonofimdalista:

if ((p->x = i->x) &&(p->y = i->y)) {


if (!old)
/* excluso nico elemento da lista */
*inicio=*fim=NULL;
else {
if (!p->prox) {
/* excluso do ultimo elemento da lista */
old->prox = NULL;
*fim = old;
} else {
/* excluir item de uma posio */
old->prox = p->prox;
/* intermediria da lista */
p->prox->ant = old;
}
}
free(p);
}

void incfim(figura *i, figura **fim) {


if (!*fim)
*fim = i;
/* o primeiro item da lista */
else
(*fim)->prox = i;
i->prox = NULL;
i->ant = *fim;
*fim = i;
}

Paraarmazenagemdeumdadosemumaposioespecficaafunoabaixorealizaaincluso
emordemcrescentepeloeixoxdeumalistaduplamenteencadeada.
void incord(figura *i,
/* novo elemento */
figura **inicio,
/* primeiro elemento da lista */
figura **fim) {
/* ultimo elemento da lista */
if (!*fim) {
/* o primeiro item da lista */
i->prox = NULL;
i->ant = NULL;
*inicio = i;
*fim = i;
} else {
figura *old, *p;
p = *inicio;
old = NULL;
while (p && (p->x < i->x)) {
old = p;
p = p->prox;
}
if (!old) {
i->prox = p;
/* inserir no inicio da lista */
i->ant = NULL;
p->ant = i;
*inicio = i;
} else {
if (p->ant) {
/* inserir em uma posio */
p->ant->prox = i;
/* intermediria da lista */
i->prox = p;
i->ant = p->ant;
p->ant = i;
} else {
old->prox = i; /* inserir no fim da lista */
i->prox = NULL;
i->ant = old;
*fim = i;
}
}
}

Como o ponteiro de incio e fim de lista podem ser alterados, a funo incord() atualiza
automaticamenteestesponteirosatravsdasvariveisinicioefim.

6.5

RVORESBINRIAS

A estrutura utilizada para a construo dervores binrias semelhantealistas duplamente


encadeadas.Adiferenaestnapolticadeorganizaodasmesmas.OExemplo6.7mostraumafuno
queconstriumarvorebinriaordenadarecursivamente.
Exemplo6.7
struct tree {
char info;
struct tree *esq;
struct tree *dir;
};
typedef struct tree arvore;
arvore *stree (
arvore *raiz;
arvore *r;
char info) {
if (!r) {
r = (arvore *) malloc(sizeof(arvore));
if (!r) {
printf(Sem memria \n);
exit(0);
}
r->esq = NULL;
r->dir = NULL;
r->info = info;
if (!raiz)
return r;
/* primeira entrada */
if (info < raiz->info)
raiz->esq = r;
else
raiz->dir = r;
return r;
}
if (info < r->info)
stree(r,r->esq, info);
else
stree(r,r->dir, info);
}

49

LinguagemdeProgramaoC

50

LinguagemdeProgramaoC

arvore *p, *p2;


if (raiz->info==key) {
/* apagar a raiz */
if (raiz->esq== raiz->dir) { /*no tem filhos */
free(raiz);
return NULL;
} else
if (raiz->esq == NULL) {
p = raiz->dir;
free(raiz);
return p;
} else
if (raiz->dir == NULL) {
p = raiz->esq;
free(raiz);
return p;
} else {
p2 = raiz->dir;
p = raiz->dir;
while (p->esq)
p = p->esq;
p->esq = raiz->esq;
free(raiz);
return p2;
}
}
if (raiz->info < key)
raiz->dir = dtree(raiz->dir, key);
else
raiz->esq = dtree(raiz->esq, key);
return raiz;
}

Achamadadestafunorealizadadestaforma:
if (!rt)
rt = stree(rt, rt, info);
else
stree (rt, rt, info);

Dessa forma, tanto o primeiro quanto os elementos subseqentes podem ser inseridos
corretamente.Afunostree()umalgoritmorecursivo.

Existem trs formas de acessar os dados de uma rvore: ordenada, preordenada e ps


ordenada. Onde a ordenada, visitado a subrvore da esquerda, a raiz e em seguida a subrvore da
direita.Napreordenada,visitasearaiz,subrvoredaesquerdae,emseguida,asubrvoredadireita.
Napsordenada,visitaseasubrvoredaesquerda,subrvoredadireitae,depois,araiz.

d
b

Figura6.2Exemplodeumarvorebinria

Utilizandoafigura14.1,aordemdeacessorvoreusandocadamtodo
ordenada
preordenada
psordenada

a
d
a

b
b
c

c
a
b

d
c
e

e
f
g

f
e
f

g
g
d

rvores binrias oferecem grande poder, flexibilidade e eficincia quando usadas em


programasdegerenciamento de bancodedados.Principalmentepelasuapolticadeorganizaoea
nolimitaodotamanho(excetoaquelaimpostapelamemria).

6.6

Para o acesso de forma ordenada, pelas formas descritas anteriormente, podese utilizar as
funesdescritasabaixo:
void inorder(arvore *raiz) {
if(!raiz)
return;
inorder(raiz->esq);
printf(%c, raiz->info);
inorder(raiz->dir);
}
void preorder(arvore *raiz) {
if(!raiz)
return;
printf(%c, raiz->info);
preorder(raiz->esq);
preorder(raiz->dir);
}
void postorder(arvore *raiz) {
if(!raiz)
return;
postorder(raiz->esq);
postorder(raiz->dir);
printf(%c, raiz->info);
}

Para excluso de um n de uma rvore tem que ser verificado se o n a raiz, um nodo
esquerdooudireitoequeosmesmospodemtersubrvoresligadasaele.Nafunoaseguirrealizada
umaexclusorecursivaobservandoasrestriesdelineadasanteriormente.
arvore *dtree(arvore *raiz, char key) {

EXERCCIOS

1. Escrevaumprogramaqueleiavriosnomeseendereos,rearranjeosnomesemordemalfabtica
e,depois,imprimaalistaemordemalfabtica.Utilizevriasestruturas.
2. Escreva um programa que gerencie uma pilha. O mesmo deve conter a funo de empilhar e
desempilhar para o usurio os quatro tipos de dados bsicos da linguagem C (char, float, int,
double).
3. EscrevaumprogramaquegerencieumafilacirculardotipoFIFO(Primeiroqueentraoprimeiro
quesai).
9. Faa um programa que leia o nmero de alunos; construa uma matriz dinamicamente alocada de
tamanho N X 4, onde N o nmero de alunos e 4 as respectivas notas de cada aluno. Calcule a
mdiaemostrenatelaconformedescrioaseguir:
ALUNO
1
2

N1
8.5
7.5

N2
7.0
7.0

N3
9.5
6.5

N4
7.0
7.0

MEDIA
8.0
7.0

51

LinguagemdeProgramaoC

52

LinguagemdeProgramaoC

E/SCOMARQUIVO

Sogruposdedadosarmazenadosemmeionovoltil(disco,fita,entreoutros).Soutilizados
paraarmazenardadosdeformapermanente.

AlinguagemCnocontmnenhumcomandodeE/S.Aocontrrio,todasasoperaesdeE/S
ocorrem atravs de chamadas a funes da biblioteca C padro. Essa abordagem faz o sistema de
arquivosdeCextremamentepoderosoeflexvel.OsistemadeE/SdeCnico,porquedadospodem
sertransferidosnasuarepresentaobinriainternaouemumformatodetexto.

7.1

E/SANSIXE/SUNIX

OpadroANSIdefineumconjuntocompletodefunesdeE/Squepodeserutilizadoparaler
eescreverqualquertipodedado.Emcontraste,oantigopadroCUNIXcontmdoissistemasdistintos
derotinasquerealizamoperaesdeE/S.Oprimeiromtododenominadodesistemadearquivocom
buffer(algumasvezesostermosformatadooualtonvelsoutilizadosparareferencilo).Osegundo
o sistema de arquivo tipo UNIX (algumas vezes chamado de no formatado ou sem buffer) definido
apenassoboantigopadroUNIX.

7.2

STREAMS

A linguagem C oferece uma abstrao da interface para controle de E/S, independente do


dispositivo real (terminais, acionadores de disco, acionadores de fita, entre outros) que acessado.
Sendoqueodispositivorealchamadodearquivo.

Existem dois tipos de streams: texto e binria. A primeira uma seqncia de caracteres
organizados em linhas e terminadas por um caractere de nova linha (depende da implementao). A
segundaumaseqnciadebytescomumacorrespondnciadeumparaumcomaquelesencontrados
nodispositivoexternoisto,noocorrenenhumatraduodecaracteres.

7.3

ARQUIVOS

fputc()

Omesmoqueputc()

getc()

Lumcaracteredeumarquivo

fgetc()

Omesmoquegetc()

fseek()

Posicionaoarquivoemumbyteespecfico

fprintf()

paraumarquivooqueprintf() paraoconsole

fscanf()

paraumarquivooquescanf()paraoconsole

feof()

Devolveverdadeiro seofimdearquivoforatingido

ferror()

Devolveverdadeiroseocorreuumerro

rewind()

Repeoindicadordeposiodearquivonoinciodoarquivo

remove()

Apagaumarquivo

fflush()

Descarregaumarquivo

OarquivocabealhoSTDIO.HforneceosprottiposparaasfunesdeE/Sedefineestestrs
tipos:size_t,fpos_teFILE.Otiposize_tessencialmenteomesmoqueumunsigned,assim comoo
fpos_t.OtipoFILEdiscutidonaprximaseo.

STDIO.H define vrias macros como: EOF, SEEK_SET, SEEK_CUR e SEEK_END. A macro EOF
geralmente definida como 1 e o valor quando uma funo de entrada tenta ler alm do final do
arquivo.Asoutrasmacrossousadascomfseek(),queumafunoqueexecutaacessoaleatrioem
umarquivo.

7.5

ESTRUTURAFILE

Paraamanipulaodearquivosutilizadoadeclaraodeponteiro(ponteirodearquivo).Isto
,umponteiroparainformaesquedefinemvriosdadossobreoarquivo,comooseunome,status,e
a posio atual do arquivo. Um ponteiro de arquivo uma varivel ponteiro do tipo FILE . Todas as
funessorealizadasutilizandooponteiro.Paraadeclaraodeumponteirodearquivoutilizasea
seguintesintaxe:

Sintaxe:

Um arquivo pode ser qualquer coisa, desde um arquivo em disco at um terminal ou uma
impressora.Associase uma stream comumarquivo especfico realizando uma operao deabertura.
Todosasstreamssoiguais,masnotodososarquivos.Isto,umarquivodiscopodesuportaracesso
aleatrioenquantoumtecladonopode.

FILE *<var>
Exemplo7.1
FILE *fp;

7.6

Cada streamassociada aum arquivo temumaestrutura de controle de arquivodotipoFILE.


EssaestruturadefinidanocabealhoSTDIO.H.

Todososarquivossofechadosautomaticamentequandooprogramatermina,normalmente
commain()retornandoaosistemaoperacionalouumachamadaexit().Osarquivosnosofechados
quandoumprogramaquebra(crash).

7.4

SISTEMADEARQUIVOS

O sistema de arquivos ANSI composto de diversas funes interrelacionadas. As mais


comunssomostradasnaTabela7.1.EssasfunesexigemqueocabealhoSTDIO.Hsejaincludoem
qualquerprogramaemquesoutilizadas.
Tabela7.1Funesmaiscomunsdosistemadearquivocombuffer

Nome

Funo

fopen()

Abreumarquivo

fclose()

Fechaumarquivo

putc()

Escreveumcaractereemumarquivo

ABERTURADEARQUIVOS

Afunofopen()abreumastreamparausoeassociaumarquivoaela.Retornaoponteirode
arquivoassociadoaessearquivo.
Sintaxe:
FILE *fopen(const char * <nome_arquivo>, const

char * <modo_abertura>);

Omododeaberturadefineaformacomofeitooacessoaosdados(somenteleitura,leiturae
escrita,etc).AsformaprincipaissoapresentadasnaTabela7.2.
Tabela7.2Osmodosdeaberturavlidos

Modo

Significado

Abreumarquivotextoparaleitura

Criaumarquivotextoparaescrita

Anexaaumarquivotexto

rb

Abreumarquivobinrioparaleitura

wb

Criaumarquivobinrioparaescrita

53

LinguagemdeProgramaoC

54

LinguagemdeProgramaoC

ab

Anexaaumarquivobinrio

r+

Abreumarquivotextoparaleitura/escrita

w+

Criaumarquivotextoparaleitura/escrita

a+

Anexaoucriaumarquivotextoparaleitura/escrita

r+bourb+

Abreumarquivobinrioparaleitura/escrita

w+bouwb+

Criaumarquivobinrioparaleitura/escrita

a+bouab+

Anexaaumarquivobinrioparaleitura/escrita

A primeira parte da mensagem fornecida pelo programa, e a segunda parte, pelo sistema
operacional.

7.10 STREAMSPADRO

Exemplo7.2
FILE *arq;
/* ponteiro de arquivo */
arq = fopen(dados.dat,wb);

Seaoabrirumarquivoparaleituraomesmonoexistirafunofopenretornaumponteiro
nulo(NULL).

Semprequeumprogramainiciadotrsstreamspadressoabertasautomaticamente:

stdin
stdout
stderr
stdaux
stdprn

(entradapadroteclado);
(sadapadrotela);
(sadadeerropadrotela);
(sadaauxiliarpadroportaserial);
(impressorapadroimpressoraparalela).

EssasstreamspodemserutilizadasnormalmenteparaexecutaroperaesdeE/Sbufferizada.

7.11 LEITURAEGRAVAODECARACTERES
arq = fopen(dados.dat,rb);
if (arq == NULL)
arq=fopen(dados.dat,wb);

7.7

FECHAMENTODEARQUIVO

Para as operaes de leitura e gravao so utilizadas duas funes padres: getc() e putc()
(consideradastecnicamentemacros).Paracadaumadestasfunesexistemduasequivalentes:fgetc()
e fputc(). Nesta seo so apresentadas as funes declaradas padro ANSI (as duas primeiras). As
outrasfunestmamesmasintaxequesuasequivalentes.

A funo fclose() fecha uma stream que foi aberta atravs de uma chamada fopen(). Esta
funotemaseguintesintaxe:

Paraaescritadecaracteresemumarquivoutilizamseasfunesputc()efputc(),asquaisso
equivalentes(putc()umamacro).Oprottipoparaessafuno

Sintaxe:

Sintaxe:
int fclose(FILE *fp);

int putc(int ch, FILE *fp);

ondefpoponteirodearquivodevolvidopelachamadafopen().Ovalorderetorno0significauma
operaodefechamentobemsucedida.

7.8

VERIFICANDOFIMDEARQUIVO

ondefpumponteirodearquivodevolvidoporfopen()echocaractereaserescrito.

Se a operao putc() foi bemsucedida, ela devolve o caractere escrito. Caso contrrio, ela
devolveEOF.

A funo feof()devolve verdadeiroquando for encontrado o fim de arquivo. O prottipo desta


funoestdeclaradoabaixo:

Paraleituradecaracteresemumarquivoutilizamseasfunesgetc()efgetc(),asquaisso
equivalentes(getc()umamacro).Oprottipoparaessafuno

Sintaxe:

Sintaxe:
int getc(FILE *fp);

int feof(FILE *fp);

7.9

Estafunopodeseraplicadatantoparaarquivotextocomoparaarquivosbinrios.

CONDIESDEERRO

Paradeterminarseumerroocorreuutilizaseafunoferror(),masestainformaonobasta
para a soluo por parte do usurio. Para isso utilizase a funo perror() em conjunto com a funo
ferror(). O argumento de perror() uma string fornecida pelo programa que normalmente uma
mensagemdeerroqueindicaemquepartedoprogramaocorreuerro.
Sintaxe:
void perror (const char *str);

Sefordetectadoumerrodedisco,ferror()retornarumvalorverdadeiro(nozero)eperror()
imprimiraseguintemensagem
Erro de Busca: Bad data

ondefpumponteirodearquivodevolvidoporfopen().

Seaoperaogetc()foibemsucedida,eladevolveocaracterelido.Casocontrrio,eladevolve
EOF. O Exemplo 7.3 mostra umlao querealizaumaleituradeumarquivotexto atque amarcade
finaldearquivosejalida.
Exemplo7.3
do {
ch = getc(fp);
} while (ch!=EOF);

As funes fopen(), getc(), putc() e fclose() constituem o conjunto mnimo de rotinas de


arquivos.Oprogramaaseguirlcaracteresdotecladoeosescreveemumarquivoemdiscoatqueo
usuriodigiteumcifro($).Onomedoarquivopassadopelalinhadecomando.
Exemplo7.4
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
FILE *fp;
char ch;

55

LinguagemdeProgramaoC

56

LinguagemdeProgramaoC

if(argc !=2) {
printf(Voc esqueceu de entrar o nome do arquivo \n);
exit(1);
}

#include <stdlib.h>
#include <string.h>
int main() {
char str[80];
FILE *fp;
if ((fp=fopen(frase.dat,w))==NULL) {
printf(Arquivo no pode ser aberto\n);
exit(1);
}
do {
printf(entre uma string (CR para sair): \n);
gets(str);
strcat(str,\n);
fputs(str,fp);
} while (*str != \n);
fclose(fp);
return 0;
}

if((fp=fopen(argv[1],w))==NULL) {
printf(Arquivo no pode ser aberto\n);
exit(1);
}
do {
ch = getchar();
putc(ch,fp);
} while(ch!=$);
fclose(fp);
return 0;
}

tela.

OprogramacomplementardescritoaseguirlqualquerarquivoASCIIemostraocontedona

Exemplo7.5
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
FILE *fp;
char ch;
if (argc !=2) {
printf(Voc esqueceu de entrar o nome do arquivo \n);
exit(1);
}
if ((fp=fopen(argv[1],r))==NULL) {
printf(Arquivo no pode ser aberto\n);
exit(1);
}
ch = getc(fp);
while (ch!=EOF) {
putchar(ch);
ch = getc(fp);
}
fclose(fp);
return 0;
}

7.12 TRABALHANDOCOMSTRINGS

Paraagravaoeleituradestringsdecaractereparaedeumarquivoemdiscosoutilizadas
asfunesfgets()efputs(),respectivamente.Soosseguintesosseusprottipos:
Sintaxe:
int fputs(const char *str, FILE *fp);
char *fgets(char *str, int length, FILE *fp);

A funo fputs() opera como puts(), mas escreve a string na stream especificada. EOF
devolvidoseocorreumerro.

Afunofgets()lumastringdastreamespecificadaatqueumcaracteredenovalinhaseja
lido ou que length1 caracteres tenham sido lidos. Se uma nova linha lida, ela ser parte da string
(diferente de gets()). A string resultante ser terminada por um nulo. A funo devolve um ponteiro
parastrsebemsucedidaouumponteironuloseocorreumerro.

O programa a seguir l strings do teclado e escreveas no arquivo chamado frase.dat. A


condio de sada uma linha em branco. Como gets() no armazena o caractere de nova linha,
adicionado um antes que a string seja escrita no arquivo para que o arquivo possa ser lido mais
facilmente.
Exemplo7.6
#include <stdio.h>

7.13 FUNESDETRATAMENTODEARQUIVOS

Nasprximasseesserovistasalgumasfunesutilizadasemoperaescomarquivoscom
buffer.

7.13.1 REWIND()

Esta funo reposiciona o indicador de posio de arquivo no incio do arquivo especificado


comoseuargumento.Seuprottipo:
Sintaxe:
void rewind(FILE *fp);

OExemplo7.7reposicionaoindicadordeposiodoarquivodoprogramaanterioremostrao
contedodomesmo.
Exemplo7.7
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char str[80];
FILE *fp;
if((fp=fopen(frase.dat,w))==NULL) {
printf(Arquivo no pode ser aberto\n);
exit(1);
}
do {
printf(entre uma string (CR para sair): \n);
gets(str);
strcat(str,\n);
fputs(str,fp);
} while (*str != \n);
rewind(fp);
/* reinicializa o file pointer */
while(!feof(fp)) {
fgets(str, 79, fp);
printf(str);
}
fclose(fp);
return 0;
}

7.13.2 FERROR()

Afunoferror()determinaseumaoperaocomarquivoproduziuumerro.Afunoferror()
temesseprottipo:

57

LinguagemdeProgramaoC

58

LinguagemdeProgramaoC

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

Sintaxe:
int ferror(FILE *fp);

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


FILE *fp;
char ch;
if(argc !=3) {
printf(Uso: SEEK nomearq byte \n);
exit(1);
}
if((fp=fopen(argv[1],r))==NULL) {
printf(Arquivo no pode ser aberto\n);
exit(1);
}
if(fseek(fp, atol(argv[2]), SEEK_SET)) {
printf(erro na busca\n);
exit(1);
}
printf(O byte em %ld %c\n, atol(argv[2]), getc(fp));
fclose(fp);
return 0;
}

Ela retorna verdadeiro se ocorreu um erro durante a ltima operao no arquivo; caso
contrrio,retornafalso.

7.13.3 REMOVE()

Afunoremove()apagaoarquivoespecificado.Seuprottipo:

Sintaxe:
int remove(char *nome_arq)

Ela devolve zero caso seja bemsucedido e um valor diferente de zero caso contrrio. O
Exemplo7.8apresentaumtrechodeprogramaqueapagaoarquivodados.dat.
Exemplo7.8
if (remove(dados.dat)) {
printf(Arquivo no pode ser apagado\n);
exit(1);
}

No Exemplo 7.9 verificase a utilizao da funo atol(), que tem por funo converter uma
stringemuminteirolongo.Noprintf()utilizaseomododeformatao%ldqueparaapresentaode
umdecimallongoouuminteirolongo.

7.13.4 FFLUSH()

Para se esvaziar o contedo de uma stream de sada, devese utilizar a funo fflush(), cujo
prottipomostradoaseguir:
Sintaxe:
int fflush(FILE *fp);

Essafunoescreveocontedodequalquerdadoexistentenobufferarquivoassociadoafp.
Sefflush()devolve0paraindicarsucesso;casocontrrio,devolveEOF.

Estafunoretornaaposiodoponteirodeumarquivobinrioemrelaoaoseucomeo.
Esta funo aceita um nico argumento, que o ponteiro para a estrutura FILE do arquivo. Seu
prottipomostradoaqui:
Sintaxe:
long ftell (FILE *fp);

Retornaumvalordotipolong,querepresentaonmerodebytesdocomeodoarquivoata
posioatual.

7.13.5 ACESSOALEATRIO:FSEEK()

Operaes de leitura e escrita aleatrias podem ser executadas utilizando o sistema de E/S
bufferizado com a ajuda de fseek(), que modifica o indicador de posio de arquivo. Seu prottipo
mostradoaqui:
Sintaxe:
int fseek (FILE *fp, long numbytes, int origem);

Onde, numbytes, um inteiro longo, o nmero de bytes a partir de oriem, que se tornar a
novaposiocorrente,eorigemumadasseguintesmacrosdefinidasemSTDIO.H.
Tabela7.3MacrosdefinidasemSTDIO.Hparaasposiespermitidasnafunofseek().

Origem
Inciodoarquivo
Posioatual
Finaldoarquivo

7.13.6 FTELL()

NomedaMacro
SEEK_SET
SEEK_CUR
SEEK_END

A funo ftell() pode no retornar o nmero exato de bytes se for usada com arquivos em
modotexto,devidocombinaoCR/LFquerepresentadaporumnicocaractereemC.

7.14 COMANDODEGRAVAOEMMODOTEXTOFORMATADO

Como extenso das funes bsicas de E/S j discutidas, o sistema de E/S com buffer inclui
fprintf() e fscanf(). Essas funes se comportam exatamente como printf() e scanf() exceto por
operarememarquivos.Osprottiposdefprintf()efscanf()so
Sintaxe:
int fprintf(FILE *fp, const char *control_string, ...);
int fscanf(FILE *fp, const char *control_string, ...);

ondefpumponteirodearquivodevolvidoporumachamadafopen().fprintf()efscanf()direcionam
suasoperaesdeE/Sparaoarquivoapontadoporfp.

A funo fseek() devolve 0 se a operao for bemsucedida e um valor diferente de zero se


ocorreumerro.

Afscanf()devolveonmerodeelementoslidos,convertidosearmazenados.Nocasodefimde
arquivoofscanf()devolveovalorEOF.

OExemplo7.9mostraautilizaodafunofseek()numprogramaquerecebepelalinhade
comandoodeslocamentoaserrealizadoapartirdoinciodoarquivo(SEEK_SET).

OExemplo7.10mostraumprogramaquelumastringeuminteirodoteclado,escreveosem
umarquivoemdiscoeemseguidalemostraainformaonatela.

Exemplo7.9

Exemplo7.10

59

LinguagemdeProgramaoC

60

LinguagemdeProgramaoC

#include <stdio.h>
#include <stdlib.h>
#include <io.h>
int main() {
FILE *fp;
char s[80];
int t;
if((fp=fopen(teste,w))==NULL) {
printf(Arquivo no pode ser aberto\n);
exit(1);
}
printf(entre com uma string e um nmero: );
fscanf(stdin, %s%d, s, &t); /* le do teclado */
fprintf(fp, %s %d, s, t);
/* escreve no arquivo */
fclose(fp);
if((fp=fopen(teste,w))==NULL) {
printf(Arquivo no pode ser aberto\n);
exit(1);
}
fscanf(fp, %s%d, s, &t);
/* le do arquivo */
fprintf(stdout, %s %d, s, t); /* imprime na tela */
return 0;
}

A formatao realizada para leitura e escrita de dados pode comprometer a velocidade de


processamentodoprograma.

Para se ler um bloco de dados maiores que um byte o sistema de arquivo ANSI C fornece a
funofread().Seuprottipoestdefinidoaseguir:
Sintaxe:
size_t fread(void *buffer, size_t num_bytes, size_t count, FILE *fp);

ondebufferumponteiroparaumaregiodememriaquereceberosdadosdoarquivo.Onmero
de bytes para ler especificado por num_bytes. O argumento count determina quantos itens sero
lidos.E,finalmente,fpumponteirodearquivoparaumastreamabertaanteriormente.

Estafunodevolveonmerodeitenslidos.Onmeroretornadopodesermenorquecount
quandoofinaldearquivoforatingidoouocorrerumerrodeleitura.
Exemplo7.12
int var_int;
FILE *arq;
arq = fopen(dados.dat,rb);
fread(&var_int,sizeof(var_int),1,arq);

7.15.3 UTILIZANDOOSCOMANDOSDELEITURAEGRAVAODEREGISTROS

7.15 LENDOEGRAVANDOREGISTROS

Uma das mais teis aplicaes de fread() e fwrite() envolve ler e escrever tipos de dados
definidospelousurio,especialmenteestruturas.

Asfunesfread()efwrite()possibilitamumamaneiradetransferirblocosdedadosdodisco
paraamemriadocomputadoreviceversa.Agrandevantagemdestescomandospoderleregravar
dadosmaioresqueumbyteequeformemestruturascomplexas(vetor,matriz,ouumregistro,ouat
umvetorderegistros).

Exemplo7.13
#include <stdio.h>
struct pto {
int x,y;
};
typedef struct pto ponto;

7.15.1 ESCRITADEUMBLOCODEDADOS

ParasegravarumblocodedadosmaioresqueumbyteosistemadearquivoANSICfornecea
funofwrite().Seuprottipoestdefinidoaseguir:
Sintaxe:
size_t fwrite(void *buffer, size_t num_bytes, size_t count, FILE *fp);

ondebufferumponteiroparaumaregiodememriaquecontmasinformaesqueseroescritas
no arquivo. O nmero de bytes para gravar especificado por num_bytes. O argumento count
determinaquantositensserogravados.E,finalmente,fpumponteirodearquivoparaumastream
abertaanteriormente.

Esta funo devolve o nmero de itens escritos. O nmero retornado pode ser menor que
countquandoofinaldearquivoforatingidoouocorrerumerrodegravao.
Exemplo7.11
int var_int;
FILE *arq;
arq = fopen(dados.dat,wb);
var_int = 5;
fwrite(&var_int,sizeof(var_int),10,arq);

int main() {
FILE *fp;
int i;
ponto coord[10];
for (i=0; i < 10; i++) {
printf(Coordenada x:);
scanf(%d \n,&coord[i].x);
printf(Coordenada y:);
scanf(%d \n,&coord[i].y);
}
if ((fp=fopen(figura.dat,w))==NULL) {
printf(Arquivo no pode ser aberto\n);
exit(1);
}
for (i=0; i < 10; i++)
fwrite(&coord[i], sizeof(ponto),1, fp);
rewind(fp);
i = 0;
while(!feof(fp)) {
fread(&coord[i], sizeof(ponto), 1, fp);
printf(Coordenadas (x,y) = (%d,%d),coord[i].x,coord[i].y);
}
fclose(fp);
return 0;
}

7.16 FUNESPARAMANIPULAODEBUFFERS
7.15.2 LEITURADEUMBLOCODEDADOS

Paratrabalharcombuffersutilizamsealgumasfunesespecializadasquesoindependentes
detipo.

61

LinguagemdeProgramaoC

62

LinguagemdeProgramaoC

Afunomemchr()procura,novetorapontadoporbuffer,pelaprimeiraocorrnciadechnos
primeiros count caracteres. Devolve um ponteiro para a primeira ocorrncia de ch em buffer ou um
ponteironulosechnoforencontrado.Oprottipodafuno

Sintaxe:

Sintaxe:

void *memset(void*buf, int ch, size_t count);


Exemplo7.17
/* Inicializa com nulo os 100 primeiros bytes */
memset(buf, \0, 100);
/*do vetor apontado por buf */

void *memchr(const void*buffer, int ch, size_t count);


Exemplo7.14
#include <stdio.h>
#include <string.h>
int main() {
char *p;
p = memchr(isto e um teste. ,14);
printf(p);
return 0;
}

Afunomemcmp()comparaosprimeiroscountcaracteresdasmatrizesapontadasporbuf1e
buf2.Ovalordevolvidosegueosvaloresdafunostrcmp().Oprottipodafuno

/* Inicializa com X os 10 primeiros bytes */


memset(buf, X, 10);
printf(buf);

7.17 EXERCCIOS
1.

Faaumprogramaqueescrevaosnmerosde0a10emumarquivo.

2.

Faaumprogramaqueleia11nmerosdeumarquivo.

3.

EscreverumprogramaemCqueleiaumnmeroindeterminadodecdigos(inteiro)etaxasde
consumo (real), em Kw, dos consumidores de uma cidade e grave os dados em um arquivo
chamadomedidas.txt.Oprogramapradelerquandoocdigofornecidoforzero.

4.

EscreverumprogramaemCqueleiaoarquivogeradonoexerccio1emostrequantastaxas
existemeomaiorconsumo.

5.

Escrever um programa em C que leia um arquivo texto (temp.txt) e grave em outro arquivo
(tempMax.txt).Oarquivoorigempossuiuumnmeroindeterminadodelinhas,ondecadalinha
possui 5 colunas: dia, ms, ano, temperatura mnima (real), temperatura mxima (real). O
programa deve escrever no arquivo tempMax.txt o dia, ms, ano, e a temperatura mxima
somente quando ela for maior que a temperatura mxima do dia anterior. Por exemplo,
assumaqueoarquivotemp.txtpossuaoseguintecontedo:

Sintaxe:
int memcmp(const void*buf1, const void*buf2, size_t count);

Afunomemcpy()copiaosprimeiroscountcaracteresdovetororigemparaovetorapontado
pordestino.Eladevolveumponteiroparadestino.Oprottipodafuno
Sintaxe:
void *memcpy(void*destino, const void*origem, size_t count);
Exemplo7.15
#include <stdio.h>
#include <string.h>
#define SIZE 80
int main() {
char buf1[SIZE], buf2[SIZE];
strcpy(buf1, Quando, no curso do ...);
memcpy(buf2, buf1, SIZE);
printf(buf2);
return 0;
}

10 10 2007 16.5 32.2


11 10 2007 15.4 31.0
12 10 2007 17.5 32.7
13 10 2007 18.6 32.4
14 10 2007 17.5 30.3
15 10 2007 18.3 31.2

A funo memmove() copia count caracteres do vetor apontado por origem para o vetor
apontado por destino. Se as matrizes se sobrepem, a cpia ocorrer corretamente, colocando o
contedocorretoemdestino,pormorigemsermodificado.Eladevolveumponteiroparadestino.O
prottipodafuno

16 10 2007 16.8 30.2

Sintaxe:

12 10 2007 32.7

17 10 2007 17.6 31.3

OprogramadevegeraroarquivotempMax.txtcomoseguintecontedo:
15 10 2007 31.2

void*memmove(void*destino,constvoid*origem,size_tcount);
Exemplo7.16
#include <stdio.h>
#include <string.h>
#define SIZE 80
int main() {
char buf1[SIZE], buf2[SIZE];
strcpy(buf1, Quando, no curso do ...);
memmove(buf2, buf1, SIZE);
printf(buf2);
}

A funo memset()copiao bytemenossignificativodechnosprimeiroscountcaracteresdo


vetorapontadoporbuf.Eladevolvebuf.muitoutilizadonainicializaodeumaregiodememria
comalgumvalorconhecido.Oprottipodafuno

17 10 2007 31.3

63

LinguagemdeProgramaoC

64

LinguagemdeProgramaoC

BIBLIOGRAFIA

A. TABELAASCII
BERRY,J.ProgramandoemC++.SoPaulo:MakronBooks,1991.
Cd

Car

Cd

Car

32

Cd

Car

Cd

Car

Cd

Car

Cd

Car

Cd

Car

Cd

Car

64

96

128

160

192

224

33

65

97

129

161

193

225

34

66

98

130

162

194

226

35

67

99

131

163

195

227

36

68

100

132

164

196

228

37

69

101

133

165

197

229

38

&

70

102

134

166

198

230

39

71

103

135

167

199

231

40

72

104

136

168

200

232

41

73

105

137

169

201

233

10

42

74

106

138

170

202

234

11

43

75

107

139

171

203

235

12

44

76

108

140

172

204

236

13

45

77

109

141

173

205

237

46

78

110

142

174

206

238

15

47

79

111

143

175

207

239

16

48

80

112

144

176

208

240

17

49

81

113

145

177

209

241

18

50

82

114

146

178

210

242

19

!!

51

83

115

147

179

211

243

20

52

84

116

148

180

212

244

21

53

85

117

149

181

213

245

22

54

86

118

150

182

214

246

23

55

87

119

151

183

215

247

24

56

88

120

152

184

216

248

25

57

89

121

153

185

217

249

26

58

90

122

154

186

218

250

27

59

91

123

155

187

219

251

28

60

<

92

124

156

188

220

252

29

61

93

125

157

189

221

253

30

62

>

94

126

158

190

222

254

31

63

95

127

159

191

223

255

14

ECKEL,B.C++.SoPaulo:McGrawHill,1991.
ELLIS,M.A.etalliC++:Manualderefernciacompleto.RiodeJaneiro:Campus,1993.
IBPI.DominandoaLinguagemC.RiodeJaneiro:IBPI,1993.
MIZRAHI,V.V.TreinamentoemLinguagemC.SoPaulo:McGrawHill,1990.
PAPPAS,C.H.;MURRAY,W.TurboC++completoetotal.SoPaulo:McGrawHill,1991.
SCHILDT,H.CCompletoetotal.SoPaulo:McGrawHill,1991.

Вам также может понравиться