Академический Документы
Профессиональный Документы
Культура Документы
h>
#include<stdio.h>
#include<stdlib.h>
LinguagemdeProgramaoC
float max(float x,
float y){
if (x > y)
return
x;
return y;
}
SUMRIO
PREFCIO...........................................................................................................................................4
arquivo para
escrita
printf("Nao
conseguiu criar arquivo de saida.\n");
exit(0);
// Aborta execucao
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
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
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
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;
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
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
/* 128 em decimal */
/* 10 em decimal */
1.3.1 CONSTANTESPRDEFINIDAS
2.1
OPERADORESBITABIT
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
=
=
=
=
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
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
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
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 */
operando
operando
res
res
res
res
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*
O primeiro operador de ponteiro &. Ele um operador unrio que devolve o endereo na
memriadeseuoperando.Porexemplo,
2.5
EXERCCIOS
1.
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
FUNES
Aformageraldeumafuno:
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
/* x elevado na n potncia */
NoExemplo3.2,osargumentosforampassadosporvaloreafunoretornaumvalordotipo
inteiro.Achamadaseria:
// funo
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);
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.
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
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()
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.
int main() {
auto int x;
...
}
equivalentea
int main() {
int x;
...
}
3.5.2 STATIC
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() {
...
}
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)
}
21
LinguagemdeProgramaoC
22
LinguagemdeProgramaoC
3.8
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
Afunodeveretornaromultiplicatriodeian.Porexemplo,achamada
multiplicatorio(3,10)
retorna1814400(345678910).
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:
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;
}
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
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);
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;
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].
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]);
}
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.
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
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
indicaumafunoqueaceitaumargumentointeiroeretornaumponteiroparauminteiro.Poroutro
lado,adeclarao
int
int
int
int
int
int
int
int
int
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
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
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.
5.2
CAMPOSDEBITS
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.
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;
};
/* 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;
}
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
};
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;
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.
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.
MAPADEMEMRIA
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
Este tipo de converso deve ser realizado em todas as funes de alocao como calloc(),
realloc()emalloc().
43
LinguagemdeProgramaoC
44
LinguagemdeProgramaoC
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.
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.:
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
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:
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
49
LinguagemdeProgramaoC
50
LinguagemdeProgramaoC
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.
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
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
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
Todososarquivossofechadosautomaticamentequandooprogramatermina,normalmente
commain()retornandoaosistemaoperacionalouumachamadaexit().Osarquivosnosofechados
quandoumprogramaquebra(crash).
7.4
SISTEMADEARQUIVOS
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);
ondefpoponteirodearquivodevolvidopelachamadafopen().Ovalorderetorno0significauma
operaodefechamentobemsucedida.
7.8
VERIFICANDOFIMDEARQUIVO
ondefpumponteirodearquivodevolvidoporfopen()echocaractereaserescrito.
Se a operao putc() foi bemsucedida, ela devolve o caractere escrito. Caso contrrio, ela
devolveEOF.
Paraleituradecaracteresemumarquivoutilizamseasfunesgetc()efgetc(),asquaisso
equivalentes(getc()umamacro).Oprottipoparaessafuno
Sintaxe:
Sintaxe:
int getc(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);
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.
7.13 FUNESDETRATAMENTODEARQUIVOS
Nasprximasseesserovistasalgumasfunesutilizadasemoperaescomarquivoscom
buffer.
7.13.1 REWIND()
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);
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.
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;
}
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:
Afunomemcmp()comparaosprimeiroscountcaracteresdasmatrizesapontadasporbuf1e
buf2.Ovalordevolvidosegueosvaloresdafunostrcmp().Oprottipodafuno
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;
}
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
Sintaxe:
12 10 2007 32.7
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);
}
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.