Escolar Documentos
Profissional Documentos
Cultura Documentos
Origem: Wikilivros, livros abertos por um mundo aberto. < Programar em C Ir para: navegao, pesquisa
Esta a verso para impresso de Programar em C
Se vo ! "or imprimir esta p#gina, es ol$a %&isuali'ar impresso% no seu navegador, ou lique em Verso para impresso, vo ! ir# ver esta p#gina sem esse aviso, sem os elementos de navegao a esquerda ou a ima, e sem as (OC)s de ada p#gina. *tuali'e esta p#gina para ter erte'a de que est# imprimindo a verso mais atual. Para maiores in"orma+es sobre a verso para impresso, in luindo omo "a'er arquivos P,- realmente adequados para a impresso, ve.a Wikilivros:&ers+es para impresso.
ndice
/ Por que aprender a linguagem C 0 1ist2ria da 3inguagem C 0./ 1ist2ria 0././ ,esenvolvimentos ini iais 0./.0 C de 456 0./.7 Os Padr+es C *8SI e C ISO 0./.9 C:: 0./.; 6esumo em ingl!s 7 Pr<=requisitos 7./ >ditor 7.0 Compilador 7.7 3igador ou linker 7.9 Obtendo um ompilador 7.9./ Para Windo?s ou ,OS 7.9.0 Para 3inu@ABni@=like 7.; 3inks e@ternos 9 Btili'ando um ompilador 9./ Compiladores: viso geral
9.0 g 9.7 &isual CCC ; 8o+es de ompilao ;./ Compilao ;.0 >tapas da ompilao D Bm programa em C D./ Bm programa em C D.0 Compilando o programa D.0./ 3inu@ E Con eitos b#si os E./ >strutura b#si a E././ >s opo E.0 Introduo Fs "un+es E.7 >@press+es E.9 Coment#rios G &ari#veis G./ &ari#veis G.0 ,e larando vari#veis G.7 *tribuindo valores G.9 >@emplo de erro G.; 8omes de vari#veis : >ntrada e saHda simples :./ >ntrada e saHda simples :.0 putsIJ e put $arIJ :.7 print"IJ :.7./ >spe i"i a+es de "ormato :.7././ Op+es :.7./.0 3argura do ampo :.7./.7 Pre iso :.7./.9 (aman$o da vari#vel :.7.0 Sequ!n ias de es ape :.7.0./ 6epresentao o tal e $e@ade imal :.9 s an"IJ :.9./ &alor de retorno :.; getsIJ e get $arIJ :.D sprint"IJ e ss an"IJ /K Opera+es matem#ti as IL#si oJ /K./ Opera+es matem#ti as /K././ *brevia+es // Opera+es matem#ti as I*vanadoJ //./ -un+es (rigonom<tri as //././ *s "un+es a os e asin //./.0 *s "un+es atan e atan0 //./.7 *s "un+es os, sin e tan //.0 -un+es 1iperb2li as //.7 -un+es >@ponen ial e 3ogaritmo //.7./ * "uno e@p //.7.0 *s "un+es "re@p, lde@p e mod" //.7.7 *s "un+es log e log/K //.9 -un+es po? e sqrt //.9./ *s "un+es po? //.9.0 *s "un+es sqrt
//.; -un+es de *rredondamento para 8Mmeros Inteiros, &alores *bsolutos e 6esto da ,iviso //.;./ *s "un+es eil e "loor //.;.0 *s "un+es "abs //.;.7 *s "un+es "mod //.D 3iga+es e@ternas /0 Controle de "lu@o /0./ Controle de "lu@o /0.0 >@press+es de ondio /0.7 (estes /0.7./ i" /0.7.0 s?it $ /0.7.7 Operador tern#rio "?:" /0.9 3oops /0.9./ ?$ile /0.9././ 3oops in"initos /0.9.0 do ... ?$ile /0.9.7 "or /0.9.9 break e ontinue /0.; Saltos in ondi ionais: goto /0.D (erminando o programa /7 -un+es /7./ O que < "uno /7.0 ,e"inindo uma "uno /7.0./ &alor de retorno /7.0.0 ParNmetros /7.0.7 C$amadas de "un+es /7.7 ,ois e@emplos /7.9 Prot2tipo ou ,e larao de "uno /7.; &ari#veis lo ais versus globais /7.D Passagem de parNmetros por valor e por re"er!n ia /7.E void /7.G 6e ursividade /7.: inline /9 Pr<=pro essador /9./ O pr<=pro essador /9.0 ,iretivas de ompilao /9.0./ Oin lude /9.0.0 Ode"ine /9.0.7 Ounde" /9.0.9 Oi"de" e Oi"nde" /9.0.; Oi" /9.0.D Oelse /9.0.E Oeli" /9.7 Bsos omuns das diretivas /9.9 Con atenao /; Libliote as /;./ Libliote as /;.0 O arquivo= abeal$o /;.7 Compilao da bibliote a /;.7./ 8o PCC /;.7.0 8o QS &isual CCC
/;.9 Compilao do programa /D >ntrada e saHda em arquivos /D./ (rabal$ando om arquivos /D.0 *brindo e "e $ando um arquivo /D.0./ >@emplo /D.0.0 *rquivos pr<=de"inidos /D.7 >s revendo em arquivos /D.7./ "?rite /D.7.0 "put /D.9 3endo de arquivos /D.9./ "get /D.9.0 "gets /D.9.7 "s an" /D.9.9 "s an" /D.9.; "read /D.; Qovendo pelo arquivo /D.;./ "seek /D.;.0 re?ind /D.;.7 "eo" /D.D Outras "un+es /D.D./ "error e perror /E >@er H ios -inais /G &etores /G./ &etores /G././ *breviando as de lara+es /G./.0 >@emplo de *pli ao de &etores /G.0 &etores multidimensionais Imatri'esJ /G.7 *rgumentos na "uno main /G.7./ >@emplo de uso de parNmetros na "uno main /: Strings /:./ Strings /:.0 -un+es da bibliote a padro /:.0./ strlen /:.0.0 str pR /:.0.7 str at /:.0.9 str mp /:.0.; strr $r /:.0.D mem pR /:.0.E memset /:.0.G sprint" 0K Ponteiros 0K./ L#si o 0K././ O que < um ponteiroS 0K./.0 ,e larando e a essando ponteiros 0K./.7 Ponteiro e 8B33 0K./.9 Qais opera+es om ponteiros 0K.0 Intermedi#rio 0K.0./ Ponteiro de estrutura 0K.0.0 Ponteiros omo parNmetros de "un+es 0K.0.7 Ponteiros e vetores 0K.0.9 Inde@ao estran$a de ponteiros 0K.0.; Comparando endereos
0K.7 *vanado 0K.7./ Ponteiros para ponteiros 0K.7.0 Passando vetores omo argumentos de "un+es 0K.7.7 Ponteiros para "un+es 0/ Passagem de Parametros 00 (ipos de dados de"inidos pelo usu#rio 00./ (ipos de dados de"inidos pelo usu#rio 00.0 >struturas 00.0./ ,e"inindo o tipo 00.0.0 ,e larando 00.0.7 Ini iali'ador designado 00.0.9 * essando 00.0.; &etores de estruturas 00.0.D *tribuio e 2pia 00.0.E Passando para "un+es 00.7 Bni+es 00.9 >numera+es 00.9./ Bso 00.; Campo de bits 07 >numerao 07./ >numerations IenumJ 07.0 Criando um novo tipo de dados 09 Bnio 09./ Bnions 09.0 ,e larao 09.7 Bnions om estruturas 09.9 *nonRmous unions T estruturas om unions 0; >struturas 0;./ Stru tures 0;.0 ,e larar uma estrutura 0;.7 Qatri'es de estruturas 0;.9 ,e larar instNn ias Iob.etosJ da estrutura 0;.; * essar as vari#veis membro das estruturas 0;.D Ini iar uma estrutura 0;.E Ponteiros para estruturas 0;.G Passando estruturas omo argumento de "un+es 0;.: >struturas anin$adas 0D Qais sobre vari#veis 0D./ tRpede" 0D.0 si'eo" 0D.7 Converso de tipos 0D.7./ Casting: onverso manual 0D.9 *tributos das vari#veis 0D.9./ onst 0D.9.0 volatile 0D.9.7 e@tern 0D.9.9 stati 0D.9.; register 0E Peren iamento de mem2ria 0E./ *lo ao dinNmi a 0E././ mallo e "ree 0E./.0 allo
0E./.7 reallo 0E./.9 *lo ao ,inNmi a de &etores 0E./.; *lo ao ,inNmi a de Qatri'es 0G So kets 0G./ *bstra+es 0G.0 -un+es da bibliote a padro 0G.7 -amHlias de endereo 0G.9 >struturas de endereo 0: Qake"iles 0:./ Qake"ile 0:././ Sinta@e de riao do arquivo 0:./././ 6egras omplementares 0:././.0 ,e"inir &ari#veis 0:././.7 &ari#veis Personali'adas 0:././.9 &ari#veis internas 0:././.; *s regras de inter"er!n ia 0:././.D Sub Qake"iles 0:././.E Qake install 7K 3ista de palavras reservadas 7/ SeqU!n ias de es ape 70 3ista de "un+es 77 3ista de bibliote as 77./ 3iga+es e@ternas 79 ,i as de programao em C 79./ Conven+es tipogr#"i as 79.0 * "uno print" < a mel$or amiga de um programador 79.7 (e le / para rodar 7; 3istas en adeadas 7;./ Primitivas 7;.0 3ista en adeada linear 7;.7 Ini iar uma lista 7;.9 Insero 7;.9./ Insero no inH io 7;.9.0 Insero no "im 7;.; 6emoo 7;.;./ 6emoo no inH io 7;.;.0 6emoo no "im 7;.D >@ibio 7;.D./ ,o "im para a rai' 7;.D.0 ,a rai' para o "im 7D Pil$a 7D./ Pil$a 7D.0 Construo do prot2tipo de um elemento da lista. 7D.7 Ini iali'ao 7D.9 Inserir um elemento na pil$aIpus$J 7D.; 6etirar um elemento da pil$a IpopJ 7D.D Imprimir os elementos da pil$a 7E Vrvores bin#rias 7E./ *rvore bin#ria 7E.0 Stru t 7E.7 Ini iar 7E.9 Insero
7E.; 6emoo 7E.;./ >m ordem 7E.;.0 Pr<=ordem 7E.;.7 P2s=ordem 7E.D Contar n2s 7E.E Contar "ol$as 7E.G *ltura da #rvore 7E.: >strutura Completa 7G *lgoritmos de ordenao 7: Insertion sort 9K Sele tion sort 9/ Lubble sort 9/./ C2digo da -uno 9/.0 C2digo da -uno Qel$orado 90 *lgoritmo de alo ao 90./ "irst "ist 90.0 best "it 90.7 ?orst "it 90.9 8e@t -it 90.; LuddR SRstem 97 >studo 97./ Sum#rio 97././ Introduo 97./.0 P*6(> I = L#si o 97./.7 P*6(> II = Con eitos intermedi#rios e avanados 97.0 *p!ndi es 97.0./ Con eitos e@tras 97.0.0 *lgoritmos e >struturas de dados 97.7 Colaborao 97.9 &er tamb<m 99 Constantes 99./ Constantes 99.0 ,>-I8>, CO8S(*8(S IO,>-I8>J 99.7 ,e lared onstants I onstJ 9; Condi ionais 9D 3ista de autores 9D./ 3ista de autores 9E Capa 9G Porque aprender a linguagem
preo upar om a atribuio de mem2ria ou om apontadores. Peralmente isso < bom, uma ve' que < bastante trabal$oso lidar om a alo ao de mem2ria quando es revemos apli a+es om algoritmos de alto nHvel. 8o entanto, quando lidamos om tare"as de bai@o=nHvel omo aquelas que um nM leo IkernelJ tem obrigao de desempen$ar, omo a de opiar um on.unto de bRtes para uma pla a de rede, torna=se altamente ne ess#rio um a esso direto F mem2ria X algo que no < possHvel "a'er om Wava. C pode ser diretamente ompilado em 2digo de m#quina, e por isso < r#pido e e"i iente. *l<m disso, C permite personali'ar omo implementar ada oisa b#si o, omo alo ao de mem2ria, permitindo adapta+es para mel$orar desempen$o. &ale lembrar que os so"t?ares interpretadores de s ript ou bRte ode, omo Wava e PRt$on, so es ritos em linguagens omo C e CCC. Ser# uma surpresa que C se.a uma linguagem to popularS Como num e"eito domin2, a pr2@ima gerao de programas segue a tend!n ia dos seus an estrais. Sistemas opera ionais desenvolvidos em C sempre t!m bibliote as de sistema desenvolvidas em C. >ssas bibliote as so usadas para riar bibliote as de programa I omo Ylib, OpenP3 ou P(4J, e seus desenvolvedores geralmente de idem usar a mesma linguagem das bibliote as de sistema. ,esenvolvedores de apli ao usam bibliote as de programa para desenvolver pro essadores de te@to, .ogos, to adores de mHdia, et . Quitos vo de idir trabal$ar om a mesma linguagem que a bibliote a "oi es rita, e assim o pro esso ontinua... C < uma das linguagens de programao mais populares para se es rever sistemas opera ionais, omo o Qi roso"t Windo?s, o Qa OS Y e o P8BA3inu@. Sistemas opera ionais omuni am=se diretamente om o $ard?areZ no $# nen$uma amada mais bai@a para mediar seus pedidos. Originalmente, os sistemas opera ionais eram es ritos na linguagem *ssemblR, o que resultava em um 2digo muito r#pido e e"i iente. >ntretanto, es rever um sistema opera ional em *ssemblR < um pro esso tedioso IlentoJ, e produ' um 2digo que "un ionar# somente em uma arquitetura de CPB, tal omo o @GD ou *6Q. >s rever um sistema opera ional em uma linguagem de alto nHvel, tal omo C, possibilita que os programadores readaptem o sistema opera ional a v#rias arquiteturas sem pre isar rees rever todo o 2digo. O nM leo IkernelJ 3inu@ < um e@emplo de sistema opera ional es rito em C, om apenas algumas se+es do 2digo es ritas em *ssemblR, para poder e@e utar instru+es que s2 e@istem em uma ou outra arquitetura e para algumas otimi'a+es.
Histria da Linguagem C
>sta p#gina pre isa ser re i lada Idis utaJ. *o mel$or#=la, vo ! estar# a.udando o Wikilivros.
Histria
Desenvolvimentos iniciais
4ennet$ ($ompson IF esquerdaJ e ,ennis 6it $ie IF direitaJ, os riadores da linguagem C O desenvolvimento ini ial da linguagem C o orreu nos laborat2rios Lell da *(5( entre /:D: e /:E7. Segundo 6it $ie, o perHodo mais riativo o orreu em /:E0. ,eu=se o nome %C% F linguagem porque muitas das suas ara terHsti as derivaram de uma linguagem de programao anterior $amada %L%. 1# v#rios relatos que se re"erem F origem do nome %L%: 4en ($ompson d# r<dito F linguagem de programao LCP3, mas ele tamb<m riou uma outra linguagem de programao $amada )Bon, em $onra da sua mul$er Lonnie. Por volta de /:E7, a linguagem C tin$a se tornado su"i ientemente poderosa para que grande parte do nM leo de B8IY, originalmente es rito na linguagem de programao P,P=//A0K *ssemblR, "osse rees rito em C, tornando=se um dos primeiros nM leos de sistema opera ional implementado em uma linguagem sem ser o *ssemblR. Como e@emplos anteriores pode=se itar o sistema Qulti s Ies rito em P3AIJ e (6IPOS Ies rito em LCP3J.
C de
!"
>m /:EG, 6it $ie e 4ernig$an publi aram a primeira edio do livro The C Programming Language. >sse livro, on$e ido pelos programadores de C omo %456%, serviu durante muitos anos omo uma espe i"i ao in"ormal da linguagem. * verso da linguagem C que ele des reve < usualmente re"erida omo %C de 456%. I* segunda edio do livro obre o posterior padro *8SI C, des rito abai@o.J 456 introdu'iram as seguintes ara terHsti as na linguagem: (ipos de dados struct (ipos de dados long int (ipos de dados unsigned int O operador [C "oi alterado para C[, e assim su essivamente Ia an#lise l<@i a do ompilador on"undia o operador [C. Por e@emplo, i [C /K e i [ C/KJ.
C de 456 < "requentemente onsiderado a parte mais b#si a da linguagem u.o suporte deve ser assegurado por um ompilador C. ,urante muitos anos, mesmo ap2s a introduo do padro C *8SI, ele era onsiderado o %menor denominador omum% em que programadores de C se apoiavam quando uma portabilidade m#@ima era dese.ada, .# que nem todos os ompiladores eram atuali'ados para suportar na Hntegra o padro C *8SI, e o 2digo C de 456 ra'oavelmente bem es rito < tamb<m v#lido em relao ao C *8SI. 8os anos que se seguiram F publi ao do C 456, algumas ara terHsti as %no=o"i iais% "oram adi ionadas F linguagem, suportadas por ompiladores da *(5( e de outros vendedores. >stas in luHam:
-un+es void e tipos de dados void * -un+es que retornam tipos struct ou union Campos de nome struct num espao de nome separado para ada tipo struct *tribuio a tipos de dados struct \uali"i adores const para riar um ob.eto s2 de leitura Bma bibliote a=padro que in orpora grande parte da "un ionalidade implementada por v#rios vendedores >numera+es O tipo de ponto="lutuante de pre iso simples
C((
*p2s o pro esso *8SI de padroni'ao, as espe i"i a+es da linguagem C permane eram relativamente est#ti as por algum tempo, enquanto que a linguagem CCC ontinuou a evoluir. I>m /::;, a 8ormative *mmendment / riou uma verso nova da linguagem C mas esta verso raramente < tida em onta.J Contudo, o padro "oi submetido a uma reviso nos "inais da d< ada de /::K, levando F publi ao da norma ISO :G:::/::: em /:::. >ste padro < geralmente re"erido omo %C::%. O padro "oi adotado omo um padro *8SI em Qaro de 0KKK. *s novas ara terHsti as do C:: in luem: -un+es em lin$a 3evantamento de restri+es sobre a lo ali'ao da de larao de vari#veis I omo em CCCJ *dio de v#rios tipos de dados novos, in luindo o long long int Ipara minimi'ar a dor da transio de )*+,its para -.+,itsJ, um tipo de dados boolean e@pli ito e um tipo complex que representa nMmeros omple@os ,isposi+es de dados de omprimento vari#vel Suporte o"i ial para oment#rios de uma lin$a ini iados por //, emprestados da linguagem CCC &#rias "un+es de bibliote a novas, tais omo snprintf() &#rios arquivos= abeal$o novos, tais omo stdint.h
O interesse em suportar as ara terHsti as novas de C:: pare e depender muito das entidades. *pesar do PCC e v#rios outros ompiladores suportarem grande parte das novas ara terHsti as do C::, os ompiladores mantidos pela Qi roso"t e pela Lorland no, e estas duas ompan$ias no pare em estar muito interessadas adi ionar tais "un ionalidades, ignorando por ompleto as normas interna ionais.
"esumo em ingl/s
>m /:9E, tr!s ientistas do 3aborat2rio (ele"onia Lell, William S$o kleR, Walter Lrattain, e Wo$n Lardeen riaram o transistor.* omputao moderna teve inH io. >m /:;D no QI( o primeiro omputador ompletamente baseado em transistores "oi on luHdo, t$e (Y=K. >m /:;G na (e@as Instruments, Wa k 4ilbR onstruiu o primeiro ir uito integrado. Qas mesmo antes do primeiro ir uito integrado e@istir, a primeira linguagem de alto nHvel .# tin$a sido es rita. >m /:;9 -ortran, a -ormula (ranslator, "oi es rito. Comeou omo -ortran I em /:;D. -ortran veio a ser *lgol ;G, o *lgorit$mi 3anguage, em /:;G. *lgol ;G veio a ser *lgol DK em /:DK. *lgol DK veio a ser CP3, o Combined Programming 3anguage, em /:D7. CP3 veio a ser LCP3, Lasi CP3, em /:DE. LCP3 veio a ser L em /:D:. L veio a ser C em /:E/. L "oi a primeira lHngua da lin$agem C diretamente, tendo sido riado no Lell 3abs por 4en ($ompson. L era uma linguagem interpretada, utili'ada no inH io, em vers+es internas do sistema opera ional B8IY. ($ompson e ,ennis 6it $ie, tamb<m da Lell 3abs, mel$orou L, $amando=8LZ novas prorroga+es para 8L riaram C, uma linguagem ompilada. * maioria dos B8IY "oi rees rito em 8L e C, o que levou a um sistema opera ional mais port#til. L "oi, naturalmente, o nome de LCP3 e C "oi o seu su essor l2gi o. * portabilidade do B8IY "oi a ra'o prin ipal para a popularidade ini ial de ambos, B8IY e CZ rat$er t$an reating a ne? operating sRstem "or ea $ ne? ma $ine, sRstem programmers ould simplR ?rite t$e "e? sRstem dependent parts required "or t$e ma $ine, and ?rite a C ompiler "or t$e ne? sRstemZ and sin e most o" t$e sRstem utilities ?ere ?ritten in C, it simplR made sense to also ?rite ne? utilities in t$e language.
Pr+requisitos
] pr<=requisito para um bom aprendi'ado de qualquer linguagem de programao on eitos sobre l2gi a de programao. *l<m disso, para programar em C, vo ! pre isa de um editor de te@tos e um ompilador, dis utidos a seguir.
Editor
Para editar o 2digo de um programa, < apenas ne ess#rio um editor de te@tos, qualquer um, at< mesmo o Llo o de 8otas do Windo?s. 8o entanto, $# diversos editores que apresentam re ursos que "a ilitam a edio de programas, omo: destaqueA olorao de sinta@e, omplementao de 2digo, "ormatao IindentaoJ autom#ti a, a.uda integrada, omandos integrados para ompilar et . >ntre todos eles podemos desta ar o &im e o >ma s, ambos om vers+es para Windo?s, 3inu@ e Qa OS. >m sistemas P8BA3inu@, a maioria dos editores de te@to .# possuem re ursos para "a ilitar a edio de programas em C. Prin ipalmente, devido ao "ato da maioria deles Idos programasJ e boa parte do sistema
terem sido programados utili'ando C ou CCC. >ntretanto, o editor apenas edita o 2digo. Para trans"orma=lo em linguagem de m#quina e o e@e utar, pre isaremos de um ompilador.
Compilador
O 2digo em linguagem C onsiste em instru+es que o omputador dever# seguir. O ompilador reali'a o trabal$o de tradu'ir essas instru+es para linguagem de m#quina, de "orma a poderem ser e@e utadas pelo omputador.
Ligador ou lin0er
* ligao de arquivos onsiste na onstruo de uma imagem mem2ria que ont<m partes de 2digo ompilados separadamente. >m outras palavras ele une os arquivos ob.etos e as bibliote as Iest#ti as, dinNmi asJ para "ormar uma nova bibliote a ou um e@e ut#vel.
#,tendo um compilador
>@istem diversos ompiladores disponHveis: Para 1indo2s ou D#' 3in41 Iantigo ming2)*J: uma esp< ie de gcc para Windo?s. ] o ompilador in luHdo om o Dev+C55, da Lloods$ed. O ,ev=CCC < um I,> Isigla em ingl!s para *mbiente Integrado de ,esenvolvimentoJ que "a ilita a edio e ompilao de programas. (em traduo para Portugu!s do Lrasil. 6orland C55: a Lorland disponibili'ou um ompilador gratuito que "un iona em lin$a de omando, omo alternativa ao I,> omer ial. D74PP: porte do gcc para ,OS. (amb<m "un iona no Windo?s, mas se o ob.etivo "or rodar no Windo?s, re omenda=se o uso do mingw, que pode usu"ruir de todos os re ursos do Windo?s. 3icroso8t Visual C55: ompilador omer ial da Qi roso"t, que tamb<m tem um I,>. O -rame?ork .8>(, gratuito, tamb<m in lui o ompilador Iem lin$a de omandoJ do &isual CCC. 6loods9ed DEV+C55: ambiente de desenvolvimento integrado livre que utili'a os ompiladores do pro.eto P8B para ompilar programas para o sistema opera ional Qi roso"t Windo?s. Para Linu:/;ni:+li0e gcc: < um on.unto de ompiladores o"i iais do pro.eto P8B, de 2digo aberto. Costumam vir instalados na maioria das distribui+es P8BA3inu@ e est# disponHvel para diversas plata"ormas, prin ipalmente para as baseadas em sistemas do tipo uni@. 4&; lin0er: < o ligador do pro.eto P8B o nome do programa < %ld% e "a' parte do pa ote P8B LinarR Btilities.
Lin0s e:ternos
CodeLlo ks: p#gina para do?nload do CodeLlo ks, uma I,> para C ao estilo do ,ev=CCC, por<m, mais nova. ,ev=CCC: p#gina para do?nload do ,ev=CCC. ,WPPP: p#gina o"i ial, om in"orma+es e links para do?nload. PCC: p#gina o"i ial do ompilador para diversas plata"ormas.
;tili<ando um compilador
Compiladores= viso geral
Bm ompilador <, geralmente, um programa de modo te@to, que deve ser operado diretamente da lin$a de omando, sem nen$uma inter"a e gr#"i a. >ssa < uma das ra'+es pelas quais muitas pessoas pre"erem usar I,>s. 8o entanto, saber um pou o sobre omo usar o ompilador pela lin$a de omando pode vir a ser Mtil, por e@emplo quando vo ! no tiver um I,> F disposio. 8o < nen$um bi $o=de=sete= abeas, e a sinta@e da maioria dos ompiladores < semel$ante. Para e@e utar o ompilador, vo ! pre isa abrir um terminal Iou %prompt de omando%, omo ostuma ser $amado no Windo?s, ou ainda onsoleJ. ] l2gi o que se vo ! estiver em um sistema sem ambiente gr#"i o I omo o ,OSJ, vo ! no pre isa "a'er isso. O Windo?s s2 tem um terminal nativo, que < o interpretador de omandos dele I md.e@e ou ommand. omJ. Pa otes omo o CRg?in e o QSRs Ido mesmo pro.eto que o QinPWJ in luem terminais alternativos que "un ionam basi amente F maneira do 3inu@. 8o 3inu@, al<m dos terminais de modo te@to, $# v#rios emuladores de terminal, entre os quais esto o Y(erm, o 4onsole I4,>J e o (erminal do Pnome. O uso de todos eles < id!nti o.
gcc
Com o g , ompilador da P8B utili'ado prin ipalmente no sistema opera ional linu@ ou de tipo uni@, vo ! pode e@e utar a ompilao e a montagem separadamente ou om um Mni o omando. Se vo ! tem v#rios arquivos="onte, < mais re omend#vel e@e utar as duas etapas separadamente: se vo ! atuali'ar apenas um arquivo, s2 pre isar# re ompilar o que atuali'ou e depois remontar. 8o entanto, se vo ! est# desenvolvendo um pro.eto grande, < re omend#vel usar "erramentas de automao do pro esso de ompilao, omo o make. "esumo=
gcc [OPES nome!do!"r#uivo
*qui so listadas algumas das op+es do g : $c: Compila o 2digo "onte mas no "a' as liga+es. * saHda < um arquivo ob.eto. $o: serve para dar um nome ao arquivo de saHda. $O%: ativa otimi'ao no nHvel 0 $g: salva os sHmbolos de depurao Io que permite usar um depuradorJ $&"ll: ativa todos os avisos do ompilador $ped"ntic: ativa os avisos ne ess#rios para que o 2digo este.a estritamente de a ordo om os
Para gerar o e@e ut#vel %programa binario% bin ou %programa.e@e% no Windo?sA,OS a partir do 2digo= ob.eto:
gcc [OPES $o progr"m"[.'in progr"m".o
Visual C55
>ste m2dulo pre isa ser revisado por algu<m que on$ea o assunto Idis utaJ.
>m alguma verso no espe i"i ada do &isual CCC, para ompilar o arquivo %programa. %, gerando o 2digo=ob.eto %programa.ob.%:
cl /c progr"m".c
&o>$es de compila>o
Esta pgina um esboo de informtica !mp"iando#a $oc% a&udar a me"horar o 'i(i"i$ros
Compila>o
(odo o 2digo em linguagem C que es revermos deve ser salvo em um arquivo, em "ormato te@to, om a e@tenso %. %. >sse 2digo no tem signi"i ado nen$um para a unidade de pro essamentoZ para que o pro essador possa e@e utar nosso programa, este deve ser tradu'ido para a linguagem de m#quina. >ssa traduo se $ama compila>o e < "eita pelo programa denominado ompilador. O ompilador l! todo o 2digo e ria um arquivo e@e ut#vel, em linguagem de m#quina, espe H"i a para uma arquitetura de pro essadores e para um tipo de sistema opera ional, o que signi"i a que um programa ompilado no Windo?s, por e@emplo, no rodar# nativamente no 3inu@ se simplesmente opiarmos o e@e ut#vel. ,evemos, para isso, re ompilar o 2digo="onte do programa.
8o Windo?s, os arquivos e@e ut#veis so aqueles om e@tenso %.e@e%. 8o 3inu@, os e@e ut#veis so simplesmente arquivos om o atributo %e@e ut#vel%.
Etapas da compila>o
O pro esso que $amamos orriqueiramente de ompilao na verdade < um on.unto de etapas: o preprocessamento, etapa em que o pr<=pro essador Iprograma Fs ve'es a oplado ao ompiladorJ l! o 2digo="onte e "a' algumas substitui+es para que o programa possa ser ompilado. >m C, o prepro essador tem diversos usos: ompilao ondi ional Ipor e@emplo, usar tre $os di"erentes do 2digo para sistemas opera ionais di"erentesJ, ma ros, substituio de sHmbolos e in luso de arquivos e@ternos que de laram "un+es e vari#veis. a veri8ica>o sint?tica, que pro ura por eventuais erros nos 2digos dos programas: par!nteses no "e $ados, "alta de ponto=e=vHrgula no "inal da instruo, et . (odos esses problemas so alertados e ausam a interrupo da ompilao. a compila>o propriamente dita, que trans"orma o 2digo prepro essado em um programa#ob&eto, que est# em linguagem de m#quina por<m no pronto para ser e@e utado. a lin0edi>o I"in(ing, em ingl!sJ dos programas=ob.eto e bibliote as ne ess#rias em um Mni o e@e ut#vel, "eita pelo "in(editor I"in(erJ. >m C, pode=se distribuir um programa em v#rios arquivos="onte, o que a.uda na organi'ao e permite ompilar apenas a parte do programa orrespondente quando < ne ess#rio reali'ar alguma mudana. 8a montagem, todas as partes onstituintes do programa so deslo adas eAou ortadas on"orme ne ess#rio para que ten$amos um programa e@e ut#vel.
;m programa em C
;m programa em C
] omum que o primeiro programa es rito em uma linguagem de programao se.a um programa que es reve %1ello ?orld^% I%Ol# mundo^%J. *presentamos o 2digo e, a seguir, analisaremos ada uma de suas lin$as. 8o se preo upe se no entender ainda alguns aspe tos, tudo ser# abordado detal$adamente mais adiante. 8ote que o nMmero das lin$as < dado apenas para "a ilitar a re"er!n iaZ se "or opiar o 2digo, lembre=se de tirar os nMmeros de lin$a.
+. %. /. 0. 2. 8. :. /* o meu primeiro progr"m" */ ,include -stdio.h. int m"in() 1 printf (3Ol45 mundo63)7 return (9)7 ;
O te:to do programa tamb<m < on$e ido omo 2digo do programa ou simplesmente cdigo 8onte. O 2digo "onte < o programa es rito na linguagem de programao. >m nosso aso a ima, $amamos 2digo C ou simplesmente 2digo.
&o ! deve opiar o 2digo a ima em um editor de te@to omo notepad e salv#=lo omo ola@c Isem a entoJ. 3embre=se de remover os nMmeros das lin$as. Caso ontr#rio o 2digo no ir# ompilar. >sse arquivo agora representa o 2digo "onte do programa es rito em C. Salvando o 2digo a ima em um arquivo om a e@tenso %. % e seguindo as instru+es de ompilao do do apHtulo de utili'ao de ompilador, vo ! dever# ver omo resultado um %Ol#, mundo^% na tela. * seguir vamos a an#lise do 2digo. * primeira lin$a < um comentrio, que para o ompilador no tem nen$um signi"i ado. \ualquer te@to que este.a entre as mar a+es /* e */, podendo in lusive o upar v#rias lin$as, ser# onsiderado omo oment#rio e ser# ompletamente ignorado pelo ompilador. ] muito Mtil omo do umentao, e@pli ando o que as pr2@imas lin$as de 2digo "a'em. * lin$a 0 pede que se.a inserido o onteMdo do arquivo stdio h Ique est# num lugar .# on$e ido pelo ompiladorJ. >sse arquivo ont<m re"er!n ias a diversas "un+es de entrada e saHda de dados Istdio < abreviao de )tandard *nput+,utput, ou >ntrada e SaHda Padroni'adasJ, de modo que vo ! pre isar# dele em prati amente todos os programas _ ele < o meio de quase toda omuni ao om o te lado, om a tela e om arquivos.`/a Os programas em C so organi'ados em "un+es _ todo 2digo em C deve "a'er parte de uma "uno. >m parti ular, todo programa deve ter uma "uno $amada main, pela qual ser# ini iada a e@e uo do programa. * "uno < de"inida, no nosso e@emplo, na lin$a 7, e delimitada pelas $aves 1 ;. * palavra= $ave int signi"i a que a "uno devolve um valor inteiro Ivo ! pode pensar nesse valor e@atamente omo o valor de uma "uno em matem#ti aJ. 8a lin$a ;, e@e utamos a "uno printf, que imprime na tela os parNmetros que l$e "oram passados _ no nosso e@emplo, passamos a seqU!n ia de ara teres %Ol#, mundo^% omo parNmetro. >ssa < uma das "un+es de"inidas em um abeal$o da bibliote a C, o arquivo stdio h. &ote o ponto=e=vHrgula no "inal da lin$a: todas as instru+es em C devem terminar om um ponto=e= vHrgula. I>ssa < uma ausa muito omum de erros de ompilaoJ. 8a lin$a D, di'emos que a "uno main deve devolver Iou retornarJ o valor K e terminar sua e@e uo. I>sse < o valor inteiro que dissemos que Hamos retornar na lin$a 7.J O padro da linguagem C di' que a "uno main deve devolver um valor inteiro, e esse valor di' se o programa "oi e@e utado om su esso ou no. O valor 'ero indi a que o programa "oi "inali'ado sem nen$um erro, e valores di"erentes de 'ero podem indi ar di"erentes erros. &o ! no pre isar# se preo upar om isso no inH io do seu estudo em C _ o valor devolvido por um programa < geralmente usado em s ripts, quando Ipor e@emploJ um omando s2 pode ser e@e utado se o anterior tiver o orrido om su esso.
Compilando o programa
Linu:
* maioria das distribui+es linu@ .# possuem ompilador C na instalao padro. Para ompilar o programa a imaIola. J abra um terminal, entre na pasta onde o arquivo se lo ali'a e digite o seguinte omando:
gcc $o ol" ol".c
O ompilador ir# gerar o arquivo e@e ut#vel $amado ola que pode ser e@e utado da seguinte "orma:
./ol"
/. b >sse omando < uma direti$a do pr#processadorZ vo ! aprender# mais sobre esses omandos na seo Pr<=pro essador.
Conceitos ,?sicos
&o ! .# viu um programa b#si o em C. *ntes de omear a se dedi ar ao estudo de C, < bom que vo ! ompreenda alguns termos e alguns aspe tos da linguagem, o que "a ilitar# sua ompreenso dos apHtulos seguintes. * seguir, "ormali'aremos alguns aspe tos da estrutura b#si a da linguagem.
Estrutura ,?sica
Bm programa em C < basi amente estruturado em ,locos de 2digo. Llo os nada mais so que on.untos de instru+es, e devem ser delimitados om $aves I1 ... ;J. Bm blo o tamb<m pode onter outros blo os. Bma instru>o geralmente orresponde a uma ao e@e utada, e deve sempre terminar om ponto=e=vHrgula I7J. O ompilador ignora espaos, tabula+es e quebras de lin$a no meio do 2digoZ esses ara teres so $amados generi amente de espa>o em ,ranco IwhitespaceJ. Ou se.a, os tr!s tre $os a seguir so equivalentes:
printf(3Ol4 mundo3)7return 97 printf (3Ol4 mundo3)7 return 97 printf( 3Ol4 mundo3 )7 9 7 return
8o entanto, vo ! a $ar# muito mais "# il de ler um estilo de 2digo mais pare ido om o segundo e@emplo. Costuma=se usar Imas no abusar deJ espaos e tabula+es para organi'ar o 2digo. * linguagem < sensHvel F utili'ao de maiMs ulas e minMs ulas. Por e@emplo, se vo ! es revesse Printf no lugar de printf, o orreria um erro, pois o nome da "uno < totalmente em minMs ulas.
Escopo
Peralmente, em programao, no queremos que outras "un+es usem as vari#veis que estamos manipulando no momento. O on eito de escopo est# .ustamente rela ionado a isso. Escopo < o nHvel em que um dado pode ser a essadoZ em C $# dois nHveis: local e glo,al. Bma vari#vel g"oba" pode ser a essada por qualquer parte do programaZ vari#veis "ocais podem ser a essadas apenas dentro do blo o
onde "oram de laradas Iou nos seus sub=blo osJ, mas no "ora dele Iou nos blo os que o ont!mJ. Isso possibilita que vo ! de lare v#rias vari#veis om o mesmo nome mas em blo os di"erentes. &e.a um e@emplo:
int "7 1 int "7 int '7 ; 1 int '7 ;
*s duas vari#veis $amadas b so di"erentes e s2 podem ser a essadas dentro do pr2prio blo o. * primeira vari#vel a < global, mas s2 pode ser a essada no segundo blo o, pois a vari#vel lo al a no primeiro blo o o ulta a vari#vel global de mesmo nome. 8ote que isso < possHvel em C, e tome uidado para no ometer erros por ausa disso.
Introdu>o As 8un>$es
Bun>$es so muito usadas, no s2 em C, mas em linguagens de programao em geral. Bma "uno < basi amente um blo o de 2digo que reali'a uma erta tare"a. \uando queremos reali'ar aquela tare"a, simplesmente "a'emos uma chamada de fun-o para a "uno orrespondente. Bma "uno pode pre isar que o programador d! ertos dados para reali'ar a tare"aZ esses dados so $amados argumentos. * "uno tamb<m pode retornar um valor, que pode indi ar se a tare"a "oi reali'ada om su esso, por e@emploZ esse valor < o valor de retorno. Podemos "a'er uma analogia om as "un+es matem#ti as: as vari#veis independentes so os argumentos e o valor num<ri o da "uno < o valor de retorno. >m C, para $amar uma "uno, devemos es rever o seu nome, seguido da lista de argumentos Iseparados por vHrgulaJ entre par!nteses, mesmo que no $a.a nen$um argumento. 3embre que a $amada de "uno tamb<m < uma instruo, portanto devemos es rever o ponto=e=vHrgula no "inal. *lguns e@emplos de $amadas de "un+es:
func"o("rg+5 "rg%5 "rg/)7 func"o()7
Se quisermos saber o valor de retorno de uma "uno, podemos arma'en#=lo numa vari#vel. &ari#veis sero introdu'idas logo adiante, mas a sinta@e < muito "# il de aprender:
v"lor!de!retorno < func"o("rg+5 "rg%)7
printf(3>n?igite um numero) 3)7 sc"nf(3@d35 Anum'er)7 result < s#u"re(num'er)7 printf(3O Bu"dr"do de @d eh) @d35 num'er5 result)7 return 97 ;
>m C, todo o 2digo Ie@ eto as de lara+es de vari#veis e "un+esJ deve estar dentro de "un+es. (odo programa deve ter pelo menos uma "uno, a "uno main, que < por onde omea a e@e uo do programa.
E:press$es
Bm on eito muito importante em programao < o de e.press-o. >@press+es so on.untos de valores, vari#veis, operadores e $amadas de "un+es que so a$a"iados ou interpretados para resultar num erto valor, que < $amado o valor da e@presso. Por e@emplo: / * 0 C D < uma e@presso de valor 0/Z " C / * ' < uma e@presso equivalente F e@presso matem#ti a a / 0bZ foo() < uma e@presso u.o valor < o valor de retorno da "uno foo.
Coment?rios
Quitas ve'es < bastante Mtil olo ar oment#rios no 2digo, por e@emplo para es lare er o que uma "uno "a', ou qual a utilidade de um argumento, et . * maioria das linguagens de programao permite oment#riosZ em C, eles podem apare er de duas maneiras:
/* Eoment4rios #ue podem ocup"r v4ri"s linh"s. */
e
// Eoment4rios de um" linh" sF5 #ue englo'"m // tudo desde "s du"s '"rr"s "tG o fin"l d" linh".
(udo que estiver entre as mar as /* e */ ou entre // ser# ignorado pelo ompilador. 8ote que os oment#rios de uma lin$a s2 Iini iados por //J "oram in orporados ao padro da linguagem apenas em /:::, e portanto alguns ompiladores podem no os suportar. *s vers+es mais re entes do PCC no tero problema em suportar esse tipo de oment#rio.
Vari?veis
Vari?veis
>m um programa, e@iste a ne essidade de se guardar valores na mem2ria, e isso < "eito atrav<s de vari?veis, que podem ser de"inidas simpli"i adamente omo nomes que se re"erem a lugares na mem2ria onde so guardados valores. *o de lararmos uma vari#vel, no apenas estamos reservando um espao de
mem2ria, omo tamb<m estamos asso iando um nome a ele, o identi8icador. *o inv<s de utili'armos o endereo da vari#vel na mem2ria, que seria geralmente notado na "orma $e@ade imal, omo por e@emplo 9x99+%HE?0, re"erimo=nos ao endereo apenas pelo seu nome. *penas para dei@ar laro, a pr2pria notao em $e@ade imal .# < uma simpli"i ao, pois omputadores na verdade trabal$am om bin#rio. >m C, para utili'ar uma vari#vel, ela deve ser primeiramente declarada, ou se.a, devemos requisitar o espao ne ess#rio para essa vari#vel. *p2s reservar um espao na mem2ria, o omputador ir# asso iar a ele o nome da vari#vel. Se vo ! no de larar uma vari#vel e tentar utili'#=la, o ompilador ir# avis#=lo disso e no ontinuar# a ompilao.
Declarando vari?veis
Peneri amente, para de larar uma vari#vel, usamos a seguinte instruo:
tipo!d"!v"ri4vel nome!d"!v"ri4vel7
Por e@emplo, para de larar uma vari#vel do tipo int om o nome a, podemos es rever
int "7
] sempre ne ess#rio indi ar o tipo da vari#vel, pois ada tipo tem um taman$o di"erente, ou se.a, o upa mais ou menos espao na mem2ria do omputador. Qais adiante introdu'iremos os tipos de vari#vel.
%tri,uindo valores
Se quisermos asso iar um valor a uma vari#vel, usamos o operador < IigualJ:
" < 27
8esse aso, estamos pedindo que o omputador guarde o valor ; no espao alo ado F vari#vel a. #,serva>o= *pesar de este operador se assemel$ar ao igual da matem#ti a, sua "uno < di"erente. Para veri"i ar a igualdade de dois valores, usamos o operador de omparao %<<% Idois iguaisJ. ] possHvel tamb<m atribuir um valor a uma vari#vel ao mesmo tempo que ela < de larada, o que < $amado de inicia"i1ar a vari#vel. Por e@emplo:
int " < 27
] possHvel tamb<m de larar mais de uma vari#vel de um mesmo tipo em uma Mni a instruo, separando os nomes por vHrgulas. (amb<m < possHvel ini iali'ar as vari#veis dessa maneira:
int "5 '5 c5 d7 int e < 25 f < 87 int g5 h < %5 i < :5 *7
Como o pr2prio nome .# di', o valor e@istente numa vari#vel pode ser mudado, da mesma maneira que ele < normalmente atribuHdo. Se tivermos:
int "7 " < %7 " < /7
E:emplo de erro
a [ 0;Z Qesmo sabendo que < um e@emplo de erro, es reva o 2digo a ima em um arquivo . e tente ompilar para se "amiliari'ar om as mensagens de erro do ompilador, assim vo ! saber# o que "a'er quando elas o orrerem. 8o e@emplo a ima no "oi de larada a vari#vel a, ao tentar ompilar o ompilador in"orma que o sHmbolo a no "oi de"inido.
&omes de vari?veis
>@istem algumas restri+es quanto ao nome que podemos dar a vari#veis. >ssas regras se apli am tamb<m para nomear "un+es e estruturas. Os nomes de vari#veis devem ser Mni os no mesmo es opo: no podemos ter duas vari#veis om o mesmo nome. O nome pode ser igual ao de outra vari#vel .# e@istente em es opo superior, por<m < re omendado "ortemente que no se use vari#veis iguais sob pena de tornar o 2digo do programa in ompreensHvel ou de di"H il an#liseZ O C, assim omo muitas outras linguagens de programao, < sensHvel F utili'ao de maiMs ulas e minMs ulasIcase sensiti$eJ. Portanto, o 2digo a seguir seria v#lido e geraria tr!s vari#veis di"erentes:
int nome7 int IOJE7 int Iome7
>m nomes de vari#veis, podemos usar letras maiMs ulas ou minMs ulas Ide * a c, sem a entosJ, algarismos ar#bi os IK=:J e o ara tere sublin$ado IdJ, mas o primeiro ara tere deve ser uma letra ou o sublin$ado. *lgumas palavras no podem ser usadas para nomes de vari#veis por serem palavras reservadas Ipalavras que t!m signi"i ado espe ial na linguagemJ. O padro C atual espe i"i a que nomes de at< 7/ ara teres devem ser a eitos. *lguns ompiladores podem at< a eitar nomes maiores que isso, mas no onsidere isso uma regra e no use nomes to longos.
-requentemente so usados os termos %saHda padro% Istandard output, stdoutJ e %entrada padro% Istandard input, stdinJ. >les se re"erem, na maioria das ve'es, ao monitor e ao te lado, que so os meios b#si os de interao om o usu#rio. 8o entanto, os sistemas opera ionais permitem redire ionar a saHda e a entrada de programas para outros dispositivos ou arquivos. *s "un+es de entrada e saHda na linguagem C trabal$am om 8lu:os Istreams, em ingl!sJ de dados, que so uma "orma de abstrao de dados de maneira sequen ial. *ssim, toda entrada e saHda < "eita da mesma maneira, om as mesmas "un+es, no importando o dispositivo om o qual estamos nos omuni ando Ite lado, terminal, arquivo, et .J. *s mesmas 8un>$es que descrevem o acesso aos arquivos podem ser utili<adas para se acessar um terminal de vCdeo. >m C, as "un+es da bibliote a padro para entrada e saHda esto de laradas no abeal$o stdio@9. Bma delas .# "oi introdu'ida em se+es anteriores: print8DE. * seguir daremos mais detal$es sobre essa "uno e introdu'iremos outras.
puts() e putchar()
puts signi"i a %put string% I olo ar stringJ, utili'ado para % olo ar% uma string na saHda de dados. putc9ar signi"i a %put $ar% I olo ar ara tereJ, utili'ado para % olo ar% um ara tere na saHda de dados. So as "un+es mais simples do abeal$o stdio h. *mbas enviam Iou %imprimem%J F saHda padro os ara teres "orne idos a elasZ putch"r() manda apenas um ara tere, e puts() manda uma sequ!n ia de ara teres Iou stringJ. >@emplo:
puts (3Est" G um" demonstr"KLo d" funKLo puts.3)7 putch"r (MNM)7
8ote que .unto om a "uno puts devemos usar literais de string I om aspas duplasJ, e om putch"r devemos usar literais de ara tere I om aspas simplesJ. Se vo ! tentasse ompilar algo omo putch"r (3O3), o ompilador daria uma mensagem de erro. 3embre=se que %(% < di"erente de )(). Podemos tamb<m olo ar ara teres espe iais, omo a tabulao I>tJ e a quebra de lin$a I>nJ:
puts (3Primeir" linh">nSegund" linh">te um gr"nde esp"Ko3)7 putch"r (M>nM)7 // apenas envia uma quebra de linha
Observe que a "uno puts() sempre olo a uma quebra de lin$a ap2s imprimir a string. W# om as "un+es putch"r() e printf() Ivista a seguirJ, isso no o orre. O 2digo abai@o, por e@emplo:
putch"r(McM)7 putch"r(MhM)7 putch"r(M>nM)7 puts(3String.3)7 puts(3Outr" string.3)7
Observe que os ara teres ) ) e )$) so e@ibidos na mesma lin$a, pois no "oi inserida uma quebra de lin$a
entre eles. W# as strings %String.% e %Outra string.% so e@ibidas em lin$as di"erentes, pois a "uno putsIJ insere uma quebra de lin$a ap2s ada string, mesmo que no $a.a um ara tere )en) nas literais de string do 2digo. Os outros ara teres espe iais so introdu'idos adiante. 8ote que o argumento deve ser uma sequ!n ia de ara teres. Se vo ! tentar, por e@emplo, imprimir o nMmero 90 desta maneira:
puts(0%)7
8a verdade o que o ompilador tentar# "a'er < imprimir a sequ!n ia de ara teres que omea na posio 90 da mem2ria Iprovavelmente ele ir# alert#=lo sobre isso se vo ! tentar ompilar esse 2digoJ. Se vo ! tentar e@e utar esse 2digo, provavelmente o orrer# uma "al$a de segmentao Ierro que o orre quando um programa tenta a essar mem2ria que no l$e perten eJ. * maneira orreta de imprimir o nMmero 90 seria olo #=lo entre aspas duplas:
puts(30%3)7
printf()
print8 vem de %print "ormatted% Iimprimir "ormatadoJ. f primeira vista, a "uno print"IJ pode pare er id!nti a F putsIJ. 8o entanto, ela < muito mais poderosa. >la permite "a ilmente imprimir valores que no so sequ!n ias de ara teres, al<m de poder "ormatar os dados e .untar v#rias sequ!n ias de ara teres. Por isso, a "uno print"IJ < muito mais usada que a putsIJ. >la pode ser usada e@atamente omo a "uno putsIJ, se "orne ermos a ela apenas uma sequ!n ia de ara teres:
printf(3Este G um progr"m" em E3)7
Qas e se pre isarmos imprimir o onteMdo de uma vari#velS * "uno printf tamb<m pode "a'er isso^ &o ! deve, obviamente, espe i"i ar onde o valor da vari#vel deve ser impresso. Isso < "eito atrav<s da espe i"i ao de "ormato @d, aso a vari#vel se.a do tipo int Isequ!n ias para outros tipos sero dadas adianteJ. &o ! tamb<m pre isar#, logi amente, espe i"i ar qual vari#vel imprimir. Isso < "eito dando=se mais um argumento F "uno print"IJ. O 2digo dever# "i ar assim:
int teste7 teste < 0%7 printf (3P v"ri4vel MtesteM contGm o n=mero @d.35 teste)7
&amos supor que vo ! queira imprimir um nMmero no inteiro. &o ! teria que tro ar %gd% por @f. >@emplo:
flo"t pi7 pi < /.+0+27 printf (3O v"lor de pi G @f.35 pi)7
&o ! pode imprimir quantos valores quiser, bastando para isso olo ar mais argumentos e mais espe i"i a+es de "ormato, lembrando de olo ar na ordem erta. *lguns ompiladores, omo o g , mostram um aviso aso o nMmero de argumentos se.a di"erente do nMmero de espe i"i a+es de "ormato, o que provavelmente ausaria resultados indese.ados. * sinta@e geral da "uno print"IJ <:
printf (3string de form"t"KLo35 "rg+5 "rg%5 ...)7
Supon$a que vo ! tem um programa que soma dois valores. Para mostrar o resultado da onta, vo ! poderia "a'er isso:
int "5 '5 c7 ... // leitura dos dados c < " C '7 // c o resultado da soma printf (3@d C @d < @d35 "5 '5 c)7
* seguir mostramos os espe i"i adores de "ormato para v#rios tipos de dados.
Especi8ica>$es de 8ormato
* do umentao mais t< ni a os $ama de %espe i"i adores de onverso%, pois o que o orre na maioria das ve'es <, de "ato, a onverso de um valor num<ri o em uma sequ!n ia de ara teres que representa aquele valor. Qas o nome %"ormato% no dei@a de estar orreto, pois eles espe i"i am em que formato Iinteiro, real et .J est# o argumento orrespondente. Cdigo @d @u @o @x @Q Converso/Bormato do argumento 8Mmero de imal inteiro IintJ. (amb<m pode ser usado @i omo equivalente a @d. 8Mmero de imal natural Iunsigned intJ, ou se.a, sem sinal. 8Mmero inteiro representado na base o tal. >@emplo: 9/7DE I orresponde ao de imal /E/97J. 8Mmero inteiro representado na base $e@ade imal. >@emplo: 90"E I orresponde ao de imal /E/97J. Se usarmos @Q, as letras sero maiMs ulas: 90-E. 1e@ade imal om letras maiMs ulas
@f
8Mmero de imal de ponto "lutuante. 8o aso da "uno print", devido Fs onvers+es implH itas da linguagem C, serve tanto para 8loat omo para dou,le. 8o aso da "uno s an", @f serve para 8loat e @lf serve para dou,le. 8Mmero em notao ientH"i a, por e@emplo 2.D:e$+%. Podemos usar g> para e@ibir o > maiMs ulo I2.D:E$+%J. 8Mmero em notao ientH"i a om o %e%maiMs ulo >s ol$e automati amente o mais apropriado entre g" e ge. 8ovamente, podemos usar gP para es ol$er entre g" e g>. Ponteiro: e@ibe o endereo de mem2ria do ponteiro em notao $e@ade imal. Cara tere: imprime o ara tere que tem o 2digo *SCII orrespondente ao valor dado. Sequ!n ia de ara teres Istring, em ingl!sJ. Imprime um g
@e @E @g @p @c @s @@
8uma sequ!n ia de ontrole, < possHvel tamb<m indi ar a largura do ampo, o nMmero de asas de imais, o taman$o da vari#vel e algumas op+es adi ionais. O "ormato geral <:
@[opes][largura do campo][.preciso][tamanho da varivel]tipo de dado
* Mni a parte obrigat2ria < o tipo de dado. (odas as outras podem ser omitidas. #p>$es *s op+es so parNmetros op ionais que alteram a "ormatao. &o ! pode espe i"i ar 'ero ou mais delas, olo ando=as logo ap2s o sinal de por entagem: 9: o taman$o do ampo deve ser preen $ido om 'eros F esquerda quando ne ess#rio, se o parNmetro orrespondente "or num<ri o. $ I$H"enJ: o valor resultante deve ser alin$ado F esquerda dentro do ampo Io padro < alin$ar F direitaJ. IespaoJ: no aso de "ormatos que admitem sinal negativo e positivo, dei@a um espao em bran o F esquerda de nMmeros positivos. C: o sinal do nMmero ser# sempre mostrado, mesmo que se.a positivo. M Iaspa simplesAap2stro"eJ: nMmeros de imais devem ser e@ibidos om separador de mil$ares aso as on"igura+es regionais o espe i"iquem. >ssa opo normalmente s2 "un iona nos sistemas Bni@. Largura do campo Como o pr2prio nome .# di', espe i"i a qual a largura mHnima do ampo. Se o valor no o upar toda a
largura do ampo, este ser# preen $ido om espaos ou 'eros. Por e@emplo, podemos imprimir um 2digo de at< ; dHgitos preen $ido om 'eros, de maneira que os valores /, 0E, 9K: e ;;/:0 apaream omo KKKK/, KKK0E, KK9K: e ;;/:0. * largura deve ser espe i"i ada logo ap2s as op+es, se presentes, e pode ser um nMmero _ que espe i"i a a largura _ ou um asteris o, que di' que a largura ser# espe i"i ada pelo pr2@imo argumento Iou se.a, o argumento anterior ao valor a ser impressoJ. 8este e@emplo, o ampo ter# largura igual ao valor de num e o valor impresso ser# 7KK:
printf (3@*d35 num5 /99)7
O ampo < impresso de a ordo om as seguintes regras: Se o valor "or mais largo que o ampo, este ser# e@pandido para poder onter o valor. O valor nun a ser# ortado. Se o valor "or menor que o ampo, a largura do ampo ser# preen $ida om espaos ou 'eros. Os 'eros so espe i"i ados pela opo 9, que pre ede a largura. O alin$amento padro < F direita. Para se alin$ar um nMmero F esquerda usa=se a opo $ I$H"en ou sinal de menosJ antes da largura do ampo. Por e@emplo, ompare as tr!s maneiras de e@ibir o nMmero /;:
printf (3@2d35 +2)7 printf (3@92d35 +2)7 printf (3@$2d35 +2)7 // exibe " !" // exibe """" !" // exibe " ! "
Preciso * pre iso pode ter quatro signi"i ados di"erentes: Se a onverso soli itada "or inteira Id, i, o, u, @, YJ: o nMmero mHnimo de dHgitos a e@ibir Iser# preen $ido om 'eros se ne ess#rioJ. Se a onverso "or real Ia, *, e, >, ", -J: o nMmero de asas de imais a e@ibir. O valor ser# arredondado se a pre iso espe i"i ada no "ormato "or menor que a do argumento. Se a onverso "or em nota>o cientC8ica Ig, PJ: o nMmero de algarismos signi"i ativos. O valor ser# arredondado se o nMmero de algarismos signi"i ativos pedido "or maior que o do argumento. Se a onverso "or de uma sequ/ncia de caracteres IsJ: o nMmero m#@imo de ara teres a e@ibir. *ssim omo a largura do ampo, a pre iso pode ser espe i"i ada diretamente por um nMmero ou om um asteris o, mas deve ser pre edida por um ponto. *lguns e@emplos:
printf printf printf printf (3@.2d35 (3@.2f35 (3@.2g35 (3@.2s35 /+0)7 // exibe """$ %" %.0)7 // exibe "&.%""""" %/028:TD9+%/02)7 // exibe "&.$%!'e( $" 3Uom di"3)7 // exibe ")om d"
] laro que podemos ombinar a largura om a pre iso. Por e@emplo, g/K.9" indi a um ampo de nMmero real de omprimento total de' e om 9 asas de imais. 8ote que, na largura do ampo, o valor
inteiro < levado em onta, in lusive o ponto de imal, e no apenas a parte inteira. Por e@emplo, essa "ormatao apli ada ao nMmero 7.9; ir# resultar nisto:
3 /.02993
Faman9o da vari?vel ] importante ressaltar que quando so usados modi"i adores de taman$o de tipos, a maneira omo os dados so arma'enados pode tornar=se di"erente. *ssim, devemos in"ormar F "uno print"IJ pre isamente qual o tipo da vari#vel u.o valor dese.amos e@ibir. * "uno print"IJ admite in o prin ipais modi"i adores de taman$o de vari#vel: hh: indi a que a onverso inteira orresponde a uma vari#vel ch"r. Por e@emplo, poderHamos usar o "ormato @hhd para e@ibir uma vari#vel do tipo ch"r na base de imal. h: indi a que a onverso inteira orresponde a uma vari#vel short. l: indi a que a onverso inteira orresponde a uma vari#vel long. ll: indi a que a onverso inteira orresponde a uma vari#vel long long. L: indi a que a onverso de nMmero real orresponde a uma vari#vel long dou'le. \uando o tipo da vari#vel no tem modi"i adores de taman$o Ilong ou shortJ, no se usa nen$um modi"i ador de taman$o da vari#vel na "uno print"IJ.
'equ/ncias de escape
'equ/ncias de escape so ombina+es de ara teres que t!m signi"i ado espe ial, e so sempre ini iadas por uma barra invertida I>J. &o ! pode us#=las em qualquer literal de ara tere ou string. Por e@emplo, a string 3linh" +>nlinh" %3 equivale a:
linh" + linh" %
pois a sequ!n ia >n indi a uma quebra de lin$a. Como "oi itado anteriormente, a "uno printf(), di"erentemente de puts(), no imprime automati amente uma quebra de lin$a no "inal da string. O 2digo abai@o, por e@emplo:
printf(3string +3)7 printf(3string %3)7
Imprimiria isto:
string +string %
Isso pode ser Mtil, pois Fs ve'es < dese.#vel permane er na mesma lin$a. * seguir apresentamos a tabela om as sequ!n ias de es ape suportadas pela linguagem C: 'equ/ncia >n >t \uebra de lin$a I"ine feed ou 3-J (abulao $ori'ontal 'igni8icado
>' >r >" >f >v >3 >M >> >9 >I >xI
6etro ede o ursor em um ara tere Iba kspa eJ 6etorno de arro Icarriage return ou C6J: volta o ursor para o omeo da lin$a sem mudar de lin$a >mite um sinal sonoro *limentao de "ormul#rio Iform feed ou --J (abulao verti al Iem impressorasJ *spa dupla *spa simples Larra invertida Cara tere nulo I ara tere de valor 'ero, usado omo terminador de stringsJ O ara tere u.a representao o tal < 8 IdHgitos de K a EJ O ara tere u.a representao $e@ade imal < 8 IdHgitos de K a : e de * a -J
"epresenta>o octal e 9e:adecimal (amb<m < possHvel tro ar uma sequ!n ia de es ape pelo seu valor em o tal ou $e@ade imal. &o ! pode, por e@emplo, tro ar o ara tere %en% pelo valor o tal %e/0% ou $e@ade imal %e@K*%. &e.amos mais alguns e@emplos.
Vex"decim"l >x99 >x9P >x9? >x9: >x9T >x9U Oct"l >99 >+% >+2 >9: >+9 >+/ E"r"cter >9 >n >r >" >' >v
scanf()
* "uno scan8DE l! dados da entrada padro Ite ladoJ e os guarda em vari#veis do programa. *ssim omo para print"IJ, usamos uma string de "ormatao para espe i"i ar omo sero lidos os dados. * sinta@e de s an"IJ < esta:
sc"nf (3string de form"t"KLo35 A"rg+5 A"rg%5 ...)7
Como vo ! pode ver, a sinta@e < quase igual F de print"IJ, om e@ eo do > omer ial I5J. &o ! entender# mel$or o seu uso nas se+es seguintes, mas adiantamos que ele < um operador que retorna o endereo de uma vari#vel. Isso < ne ess#rio pois a "uno s an"IJ deve modi"i ar as vari#veis, e quando no usamos o operador de endereo, passamos apenas o valor de uma vari#vel para a "uno. Isso ser# e@pli ado mel$or no apHtulo sobre ponteiros. O "ato de s an" re eber endereos de vari#veis Iem ve' de seus valoresJ tamb<m e@pli a por que ele pre isa ser in"ormado da di"erena entre g" I"loatJ e gl" IdoubleJ enquanto que o print" no pre isa.
O que este e@emplo "a' < de larar uma vari#vel e aguardar o usu#rio digitar algo. Os dados s2 sero pro essados quando o usu#rio apertar >nter. ,epois disso, os ara teres digitados pelo usu#rio sero onvertidos para um valor inteiro e esse inteiro ser# guardado no endereo que orresponde F vari#vel a. Se o valor digitado no puder ser onvertido Iporque o usu#rio no digitou nen$um algarismo v#lidoJ, a vari#vel no ser# modi"i ada. *ssim omo na "uno print"IJ, podemos re eber quantos valores quisermos, bastando usar v#rios espe i"i adores de onverso:
int "7 ch"r '7 flo"t c7 sc"nf (3@d @c @f35 A"5A'5Ac)7
,essa maneira, se o usu#rio digitar +%9 W +:.8/, teremos a igual a /0K, b igual ao ara tere )') e c igual ao nMmero /E,D7. Se o usu#rio tentar digitar mais de um espao entre os dados ou simplesmente nen$um espao, ainda assim o programa obter# os dados ertos. Por e@emplo, +%9W+:.8/ tamb<m dar# o mesmo resultado. *gora uma questo um pou o mais di"H il: vamos supor que espe i"i amos um "ormato inteiro e o usu#rio digitou um nMmero real, omo por e@emplo +%.2. O que dever# a onte erS
,include -stdio.h. int m"in () 1 int "7 printf (3?igite um n=mero) 3)7 sc"nf (3@d35 A")7 printf (3>nO n=mero digit"do foi @d35 ")7 return (9)7 ;
Se vo ! testar om o valor +%.2, vai ver que o programa retornar# o nMmero /0, pois a "uno sc"nf() apenas interpreta os ara teres v#lidos para aquele "ormato. Os espe i"i adores de onverso so prati amente os mesmos que os da "uno print"IJ, om algumas mudanas. * maioria deles pula espaos em bran o, e@ eto dois. %i no < mais sinhnimo de gd. O que gi "a' < interpretar o valor digitado omo $e@ade imal, se ini iar=se por 9x ou 9QZ omo o tal, se ini iar=se por 9Z ou omo de imal, aso nen$uma dessas ondi+es se.a veri"i ada. %a, %e/%E e %g so sinhnimos de @f. %lf deve ser usado para vari#veis do tipo dou,le. %s l! uma sequ!n ia de ara teres no=bran os Iqualquer ara tere e@ eto espao, tabulao, quebra de lin$a et .J, ou se.a, uma palavra. %c l! uma sequ!n ia de ara teres, sem ignorar espa>os. O padro < ler um ara tere, se no "or espe i"i ada a largura do ampo.
%[...] l! uma sequ!n ia de ara teres, sem ignorar espa>os, espe i"i ando entre ol $etes quais ara teres devem ser a eitos, ou, se o primeiro ara tere dentro dos ol $etes "or um a ento ir un"le@o IiJ, quais no devem ser a eitos. *l<m disso, se olo armos um trao entre dois ara teres, todos os ara teres entre os dois sero in luHdos no padro. Por e@emplo, se quisermos in luir qualquer letra minMs ula, poderi#mos es rever @["$W Z se quis<ssemos tamb<m in luir as maiMs ulas, olo arHamos @["$WP$N . * leitura p#ra quando "or en ontrado um ara tere que no oin ide om o padro espe i"i ado. W# os modi"i adores "un ionam de maneira bastante di"erente: O modi"i ador * Iasteris oJ espe i"i a que o valor atual deve ser lido da maneira espe i"i ada, mas no ser# guardado em nen$uma vari#vel, e portanto no deve $aver um ponteiro orrespondente a esse valor. Por e@emplo, poderi#mos ter um programa que espera ler uma palavra e depois um nMmero, mas no importa qual palavra <. 8esse aso usarHamos o modi"i ador j: sc"nf (3@*s @d35 Anumero). O programa leria a palavra e guardaria o nMmero na vari#vel numero. Como na "uno print"IJ, e@iste o espe i"i ador de largura do ampo, que deve apare er antes do espe i"i ador de onverso, mas em s an"IJ ele espe i"i a a largura m?:ima. Se a largura m#@ima "oi de"inida omo n, s an"IJ pular# para o pr2@imo ampo se .# tiver lido n ara teres. Por e@emplo, sc"nf (3@0d35 Anum) ler# um nMmero de at< quatro algarismos. Se o usu#rio digitar mais, o e@ edente ser# no ser# lido por essa $amada, mas poder ser "ido por uma pr3.ima chamada a scanf. Qais detal$es sobre os espe i"i adores de onverso e os modi"i adores podem ser en ontrados na do umentao da bibliote a padro.
Valor de retorno
* "un o sc"nf() retorna o nMmero de onvers+es reali'adas om su esso. Isso < Mtil pois, se o valor ontido numa vari#vel ap2s a $amada de s an"IJ "or igual ao valor anterior, no < possHvel saber se o valor digitado "oi o mesmo que .# $avia ou se no "oi "eita a onverso. Para obter esse nMmero de onvers+es reali'adas, vo ! deve guardar o resultado numa vari#vel do tipo int. &e.a omo pro eder:
int "5 '7 int num7 num < sc"nf(3@d@d35 A"5 A')7
>ste e@emplo l! dois nMmeros inteiros e os guarda nas vari#veis a e b. O nMmero de onvers+es reali'adas < guardado na vari#vel num. Se ap2s o s an", num "or di"erente de 0, < sinal de que o usu#rio digitou algo in ompatHvel om o "ormato dese.ado. 8ote que aqui introdu'imos um on eito novo: o valor de retorno de uma "uno. >le pode ser obtido simplesmente asso iando o valor de uma vari#vel F $amada da "uno. >le ser# detal$ado na seo -un+es, mas .# < possHvel ompreender um pou o sua utili'ao.
gets() e getchar()
gets() e getchar(), assim omo s an"IJ, l!em da entrada padro. *ssim omo puts() e putch"r(), no suportam "ormatao. Como o nome sugere, getch"r() l! apenas um ara tere, e gets() l! uma string at< o "inal da lin$a ou at< que no $a.a mais dados para ler, e adi iona o terminador de string 3>93.
* notao ch"r 'uffer[+9 , que ainda no "oi introdu'ida Ie ser# detal$ada na seo &etores IarraRsJJ, pede que se.a reservado um espao para /K ara teres para a string buffer. Portanto, se usu#rio digitar mais de : ara teres Ipois o terminador de string < adi ionado ao que o usu#rio digitouJ, os ara teres e@ edentes adi ionais sero olo ados na #rea de mem2ria subsequente F o upada pela vari#vel, es revendo uma regio de mem2ria que no est# reservada F string. >ste e"eito < on$e ido omo %estouro de bu""er% e pode ausar problemas imprevisHveis. Por isso, no se deve usar a 8un>o getsDEZ mais tarde introdu'iremos a "uno "getsIJ, que no apresenta esse problema e que deve ser usada no lugar de getsIJ.
sprintf() e sscanf()
sprintf e ssc"nf so semel$antes a printf e sc"nf. Por<m, ao inv<s de es reverem na saHda padro ou lerem da entrada padro, es revem ou l!em em uma string. * Mni a mudana nos argumentos < a ne essidade de espe i"i ar a string que deve ser lida ou atribuHda no inH io. &e.a os e@emplos para entender mel$or.
,include -stdio.h. int m"in() 1 int i7 ch"r string+[/9 7 printf(3Entre um v"lor inteiro) 3)7 sc"nf(3@d35 Ai)7 sprintf(string+5 3X"lor de i < @d35 i)7 puts(string+)7 return 97 ;
8esse e@emplo, a mensagem que querHamos e@ibir na tela "oi primeiramente salva em uma string, e depois essa string "oi enviada para a tela. Se vo ! ol$ar bem, se vo ! tivesse alo ado um valor menor para string4, tamb<m o orreria um estouro de bu""er. Para evitar esse problema, e@iste a "uno snprintf, que tem mais um argumento: o taman$o da string Ideve ser olo ado depois da string onde a mensagem ser# gravadaJ.
,include -stdio.h. int m"in() 1
int i5 *5 (7 ch"r string+[ < 3+9 %9 /937 ssc"nf(string+5 3@d @d @d35 Ai5 A*5 A()7 printf(3X"lores lidos) @d5 @d5 @d35 i5 *5 ()7 return 97
8esse e@emplo, usamos a "uno ssc"nf para interpretar os valores ontidos na string e guard#=los nas vari#veis num<ri as.
Os operadores aritm<ti os b#si os so ;: C IadioJ, = IsubtraoJ, j Imultipli aoJ, A IdivisoJ e g Iresto de diviso inteiraJ. Outro e@emplo:
int " < +27 int ' < :%7 int c < " * '7
/* c valer
!+'& */
Podemos usar mais de um operador na mesma e@presso. * pre ed!n ia < igual F usada na matem#ti a omum:
" < % C 0 * +97 " < % C 09 / % C 27 /* retornar %&, o mesmo que -& ( -% * ".. */ /* retornar &', o mesmo que -& ( -%" / &. ( !. */
8ote que uma operao entre nMmeros inteiros sempre retornar# um nMmero inteiro. Isso < evidente para a adio, subtrao e multipli ao. Qas em uma diviso de inteiros, por e@emplo //%, a e@presso retornar# apenas a parte inteira do resultado, ou se.a, /. Se quisermos um resultado no=inteiro, um dos operandos deve ser no=inteiro. 8esse e@emplo, poderHamos usar /.9/% ou //%.9, ou mesmo /./% ou (+.9 * /)/%, pois, em C, uma operao envolvendo um nMmero no=inteiro sempre ter# omo resultado um nMmero real. &ote que em C o separador de imal < o ponto e no a vHrgula. O seguinte e@emplo poderia surpreender, pois o programa dir# que o valor de f ontinua sendo 7.
,include -stdio.h. int m"in()
int i < 27 int * < %7 flo"t f < /.97 f < f C * / i7 printf(3O v"lor de f G @f35 f)7 return 97
Qas, segundo a pre ed!n ia dos operadores, * / i deveria ser al ulado primeiro, e omo ambos os valores so do tipo inteiro, o valor dessa e@presso < 'ero. ] importante que vo ! grave um arquivo . "un ionamento om os pr2prios ol$os. om o 2digo a ima e e@e ute usando o ompilador para ver o
%,revia>$es
*lguns tipos de atribui+es so bastante omuns, e por isso "oram riadas abrevia+es. Por e@emplo, < muito omum in rementar em uma unidade o valor de uma vari#vel Iem loops, por e@emploJ. >m ve' de es rever v"r < v"r C +, podemos es rever simplesmente v"rCC. ,a mesma maneira, e@iste o operador de de remento, que decrementa em uma unidade o valor da vari#vel: v"r$$ Iequivalente a v"r < v"r $ +J. Os operadores de de remento e in remento tamb<m podem ser utili'ados antes do nome da vari#vel. Isso signi"i a que estas duas instru+es so equivalentes:
v"rCC7 CCv"r7
*gora vamos supor que vo ! use em seu programa uma vari#vel que aumenta de /K em /K unidades. ] laro que usar v"rCC de' ve'es no abreviaria nada. >m ve' disso, e@iste a abreviao v"r C< +9. Peneri amente, para qualquer dos in o operadores aritm<ti os op, vale a abreviao:
v"r < v"r op num7 v"r op< num7
>sse resultado mostra que CCv"r e v"rCC no so a mesma coisa se usados omo uma e@presso. \uando usamos os operadores na "orma pre"i@al Iantes do nome da vari#velJ, o valor < retornado depois de ser in rementadoZ na "orma su"i@al, o valor < retornado e depois in rementado. O mesmo vale para o operador de de remento. > o que a onte eria se vo ! es revesse algo omo o seguinteS
printf(3@d>n35 " / CC")7
* resposta <: no sabemos. Segundo o padro C, o resultado disso < inde"inido Io que signi"i a que pode variar de um ompilador para outroJ. 8o e@iste uma regra sobre avaliar primeiro o numerador ou o denominador de uma "rao. Ou se.a, no use uma vari?vel mais de uma ve< numa e:presso se usar operadores que a modi8icam. (alve' vo ! ten$a a $ado estran$a a lin$a:
" < ' < 27
Isso < possHvel porque atribui+es so "eitas da direita para a esquerda e uma instruo de atribuio < tamb<m uma e@presso que retorna o valor atribuHdo. Ou se.a, a e@presso ' < 2 retornou o valor ;, que "oi usado pela atribuio " < (' < 2), equivalente a " < 2.
Bun>$es Frigonomtricas
%s 8un>$es acos e asin
* "uno "cos retorna o ar o= osseno dos seus argumentos em radianos, e a "uno "sin retorna o ar o=seno dos seus argumentos em radianos. (odas as "un+es esperam por argumentos que este.am no intervalo `=/,C/a. O ar o= osseno retorna valores no intervalo `K,kaZ o ar o=seno retorna valores no intervalo `=kA0,CkA0a.
,include -m"th.h.
flo"t "sinf(flo"t x)7 /* EDD */ flo"t "cosf(flo"t x)7 /* EDD */ dou'le "sin(dou'le x)7 dou'le "cos(dou'le x)7 long dou'le "sinl(long dou'le x)7 /* EDD */ long dou'le "cosl(long dou'le x)7 /* EDD */
Bun>$es Hiper,licas
*s "un+es cosh, sinh and t"nh omputam o oseno $iperb2li o, o seno $iperb2li o e a tangente $iperb2li a respe tivamente. Para as "un+es de seno e oseno $iperb2li o, um erro de ...
,include -m"th.h. flo"t coshf(flo"t x)7 /* EDD */ flo"t sinhf(flo"t x)7 /* EDD */ flo"t t"nhf(flo"t x)7 /* EDD */ dou'le cosh(dou'le x)7 dou'le sinh(dou'le x)7 dou'le t"nh(dou'le x)7 long dou'le coshl(long dou'le x)7 /* EDD */ long dou'le sinhl(long dou'le x)7 /* EDD */ long dou'le t"nhl(long dou'le x)7 /* EDD */
%s 8un>$es sqrt
*s "un+es s#rt omputam a rai' positiva de x e retornam o resultado. Bm %domain error% o orre se o argumento "or negativo.
,include -m"th.h. flo"t s#rtf(flo"t x)7 /* EDD */ dou'le s#rt(dou'le x)7 long dou'le s#rtl(long dou'le x)7 /* EDD */
%s 8un>$es fa s
*s "un+es f"'s omputam o valor absoluto do nMmero real x e retornam o resultado.
,include -m"th.h. flo"t f"'sf(flo"t x)7 /* EDD */ dou'le f"'s(dou'le x)7 long dou'le f"'sl(long dou'le x)7 /* EDD */
%s 8un>$es fmod
*s "un+es fmod omputam o resto de x/Y e retornam o valor x = i j Y, pra algum nMmero inteiro i
onde, se Y "or um nMmero di"erente de 'ero, o resultado tem o mesmo sinal de x e magnitude menor que a magnitude de Y. Se Y "or 'ero, dependendo da implementao da "uno, o orrer# um %domain error% ou a "uno fmod retornar# 'ero.
,include -m"th.h. flo"t fmodf(flo"t x5 flo"t Y)7 /* EDD */ dou'le fmod(dou'le x5 dou'le Y)7 long dou'le fmodl(long dou'le x5 long dou'le Y)7 /* EDD */
Liga>$es e:ternas
Libliote a de re"er!n ia CCC ICCC 6e"eren e 3ibrarRJ = mat$ Imat$.$J
Controle de 8lu:o
Controle de 8lu:o
,i"i ilmente um programa em C ir# e@e utar sempre as mesmas instru+es, na mesma ordem, independentemente do que ten$a a onte ido anteriormente ou do valor que "oi "orne ido. ] muito omum que algu<m queira que um pedao de 2digo s2 se.a e@e utado se uma erta ondio "or verdadeiraZ tamb<m < omum querer que um pedao de 2digo se.a repetido v#rias ve'es, de tal maneira que simplesmente opiar o 2digo no resolveria o problema ou seria trabal$oso demais. Para asos omo esses, e@istem as estruturas de controle de 8lu:o. >m C, e@istem v#rias instru+es rela ionadas ao ontrole de "lu@o: if, que e@e uta um blo o apenas se uma ondio "or verdadeiraZ switch, que e@e uta um blo o de a ordo om o valor de uma e@presso ou vari#velZ for, que e@e uta um blo o repetidas ve'es enquanto uma ondio "or verdadeira, e@e utando uma instruo Igeralmente de in remento ou de remento de uma vari#velJ ap2s ada e@e uoZ while, que e@e uta um blo o enquanto uma ondio "or verdadeiraZ do, semel$ante ao Zhile, mas a ondio < avaliada ap2s a e@e uo Ie no antesJZ goto, que simplesmente pula para um lugar pr<=de"inido. Por<m, antes de entrar no estudo dessas estruturas, vo ! deve saber omo es rever uma ondio. ] o que e@pli amos a seguir.
E:press$es de condi>o
Bma e@presso de ondio < uma e@presso normal em C que, quando avaliada, ser# interpretada omo verdadeira ou "alsa. >m C, na verdade, esse valor < um valor inteiro que sendo K I'eroJ signi"i a "also, sendo qualquer outro nMmero signi"i a verdadeiro. Peralmente em e@press+es ondi ionais usamos os operadores re"acionais, ou se.a, que avaliam a relao entre seus dois operandos. >@istem seis deles: #perador 'igni8icado
maior que maior ou igual a menor que menor ou igual a igual a di"erente de
(odos esses operadores so bin#rios, ou se.a, trabal$am om dois valores ou operandos. >sses operadores sempre omparam o valor da esquerda om o da direita, ou se.a, a e@presso " . ' signi"i a %a < maior que b%. &ote que para saber se dois nMmeros so iguais devemos usar dois sinais de igual. Bm erro muito omum < esque er de um deles, trans"ormando a omparao numa atribuio X por e@emplo:
if (x < +)
...
O que a onte e aqui < que a vari#vel . re ebe o valor /, de modo que a e@presso entre par!nteses tamb<m ter# o valor / X tornando a n ondioo sempre verdadeira. Similarmente, se us#ssemos o nMmero 'ero, a e@presso sempre seria "alsa. Portanto, sempre tome uidado om esse tipo de omparao. * maneira erta de omparar om um nMmero <:
if (x << +)
...
(amb<m < omum que ombinemos ondi+es. Por e@emplo, podemos querer que um nMmero se.a menor que /K ou maior que ;K. Como o operador %ou% < %[[%, es reverHamos: n - +9 [[ n . 29. * seguir vo ! v! os operadores l2gi os: #perador 'igni8icado %% && $ ou IO6J e I*8,J no I8O(J
*lgumas e@pli a+es sobre os operadores l2gi os: O operador InoI < un#rio, ou se.a, < uma operao que envolve apenas um valor. O que ele "a' <
inverter o valor de seu operando: retorna "also se a e@presso "or verdadeira e vi e=versa. ,eve=se usar par!nteses ao negar uma e@presso: 6(x . 8), por e@emplo. O operador IouI retorna %verdadeiro% se pelo menos um dos operandos "or verdadeiroZ retorna %"also% apenas se ambos "orem "alsos. O operador IeI retorna %verdadeiro% apenas se ambos os seus operandos "orem verdadeiros. #,serva>o Se vo ! quer saber se um nMmero est# entre outros dois, a sinta@e matem#ti a I+9 n - 29J no "un ionar#. Se vo ! usar esse 2digo, na verdade primeiramente ser# avaliada a e@presso +9 - n, que poder# resultar em K ou /. Portanto, a e@presso equivale a (9 ou +) 29, o que < sempre verdadeiro.
* omparao orreta envolveria o operador %e% IAAJ: +9 - n AA n - 29. Pelo "ato de todo valor di"erente de 'ero ser avaliado omo verdadeiro e 'ero omo "also, e@istem as seguintes equival!n ias Iapenas quando estas e@press+es so usadas omo ondi+esJ:
(x << 9) e#uiv"le " (6x) (x 6< 9) e#uiv"le " (x)
Festes
Festes so estruturas de ontrole que e@e utam ertos blo os de 2digo apenas se uma erta ondio "or verdadeira. >@istem tr!s estruturas desse tipo em C:
if
O teste i8 avalia uma ondio e, se ela "or verdadeira, e@e uta um blo o de 2digo. * sinta@e orrespondente a isso <:
if (condiKLo) 1 ... /* 'loco " ser execut"do se " condiKLo for verd"deir" */ ;
Qas tamb<m podemos espe i"i ar um blo o a ser e@e utado aso a ondio "or "alsa. 8esse aso, es revemos:
if (condiKLo) 1 ... /* 'loco " ser execut"do se " condiKLo for verd"deir" */ ; else 1 ... /* 'loco " ser execut"do se " condiKLo for f"ls" */ ;
*s $aves podem ser omitidas aso $a.a apenas uma instru>o no blo o. Por e@emplo:
if (x << 2) printf (3x G igu"l " 2.>n3)7
Per eba que, se esque ermos as $aves, o ompilador no dever# dar nen$um erroZ no entanto, tudo que e@ eder a primeira instruo ser# e@e utado in ondi ionalmente, mesmo que esteJa na mesma lin9a^ 8o e@emplo a seguir, a "rase %@ < igual a ;% seria e@ibida mesmo que o nMmero no "osse ;^
Podemos avaliar diversas ondi+es om os testes i", bastando para isso olo ar um novo teste no blo o else. (amb<m < possHvel anin$ar blo os if, ou se.a, olo ar um dentro de outro:
if (x . D) 1 printf (3x G m"ior #ue D.>n3)7 ; else if (x .< 2) 1 printf (3x G m"ior ou igu"l " 25 m"s nLo m"ior #ue D.>n3)7 ; else 1 if (x << 9) 1 printf (3x G igu"l " Wero.>n3)7 ; else 1 printf (3x G nLo$nulo e menor #ue 2.>n3)7 ; ;
switch
O teste s2itc9 ompara uma e@presso om diversos valores que podem estar asso iados a blo os de 2digos di"erentes, e e@e uta o blo o de 2digo orrespondente ao valor en ontrado. &o ! tamb<m pode espe i"i ar um blo o que deve ser e@e utado aso nen$um dos outros valores se.a en ontrado: < o blo o def"ult I%padro% em ingl!sJ.
sZitch (expressLo) 1 c"se v"lor+) instruK\es7 're"(7 c"se v"lor%) instruK\es7 're"(7 ... def"ult) instruK\es7 ;
8ote que no teste s2itc9 no pre isamos usar $aves em volta dos blo os, a menos que de laremos vari#veis neles. Bm e@emplo da utili'ao de s2itc9 seria a riao de um menu:
int opc"o7 printf (3[+ E"d"str"r cliente>n3 3[% Procur"r cliente>n3 3[/ ]nserir pedido>n3 3[9 S"ir>n>n3 3?igite su" escolh") 3)7 sc"nf (3@d35 Aopc"o)7 sZitch (opc"o) 1 c"se +) c"d"str"!cliente()7 're"(7 c"se %) procur"!cliente()7 're"(7 c"se /) insere!pedido()7 're"(7 c"se 9)
* instruo ,rea0 indi a que deve=se ontinuar a e@e uo ap2s o "inal do blo o sZitch Ipulando o que estiver no meioJ. Se ela no "osse usada, para um erto valor en ontrado, seriam e@e utadas tamb<m as instru+es de todos os valores abai@o dele. >m alguns asos, podemos omitir inten ionalmente a instruo break. Por e@emplo, no e@emplo a ima, no olo amos uma instruo 're"( para o valor 'ero, pois quando retornamos de uma "uno Ireturn 9J o blo o s?it $ .# < abandonado. (amb<m podemos querer que uma instruo se.a e@e utada para mais de um valor. &amos supor que no nosso menu as duas primeiras op+es "ossem %Cadastrar pessoa "Hsi a% e %Cadastrar pessoa .urHdi a%, e tHvessemos uma "uno que "a' o adastro di"erentemente dependendo do valor da vari#vel pesso"!fisic". PoderHamos "a'er um 2digo assim:
sZitch (opc"o) 1 c"se +) /* pesso" f^sic" */ pesso"!fisic" < +7 c"se %) c"d"str"()7 're"(7 ... ;
8esse aso, para qualquer uma das duas op+es seria e@e utada a "uno c"d"str", mas se sele ionarmos %pessoa "Hsi a% a vari#vel ser# atribuHda antes.
8ote que, ao ontr#rio de i8, ao usarmos o operador ondi ional _) pre isamos sempre prover tanto o valor para o aso de a ondio ser "alsa quanto o valor para o aso de ela ser verdadeira. O operador ondi ional pode ser usado em situa+es omo essa:
int hor"P'ertur" < (di"Sem"n" << ?OJ]I`O) _ ++ ) D7 printf (3P'rimos as @d hor"s35 hor"P'ertur")7
Ou se.a, se o dia da semana "or domingo, a vari#vel hora!bertura ser# de"inida para //Z aso ontr#rio, ser# de"inida para :. Outro e@emplo:
if (numJens"gens . 9) 1 printf (3XocR tem @d mens"ge@s35 numJens"gens5 (numJens"gens . +) _ 3ns3 ) 3m3)7 ;
8este aso, o programa utili'aria %mensagens% aso $ouvesse mais de uma mensagem, e %mensagem% aso $ouvesse apenas uma mensagem.
Loops
3oops so on.untos de instru+es que devem ser e@e utadas repetidas ve'es, enquanto uma ondio "or verdadeira. >m C $# 7 tipos de loops: Zhile, do ... Zhile e for.
while
O loop while testa uma ondioZ se ela "or verdadeira, o blo o orrespondente < e@e utado e o teste < repetido. Se "or "alsa, a e@e uo ontinua logo ap2s o blo o. * sinta@e de Zhile <:
Zhile (condiKLo) 1 ... ;
Por e@emplo:
Zhile (" - ') 1 printf (3@d G menor #ue @d35 "5 ')7 "CC7 ;
>ste 2digo seria e@e utado at< que a "osse igual a bZ se a "osse igual ou maior que b, nada seria e@e utado. Por e@emplo, para b [ /K e a < /K, a Mltima mensagem que o usu#rio veria < %: < menor que /K%. 6epare que o loop 29ile < omo "osse um i8, ou se.a, o blo o < e@e utado se a ondio "or verdadeira. * di"erena < que ao "inal da e@e uo, o ?$ile < e@e utado novamente, mas o i" no. 8o loop 29ile Iassim omo nos loops do e 8orJ tamb<m podemos usar a sinta@e abreviada para apenas uma instruo:
Zhile (" - ') "CC7
Loops in8initos &o ! pode "a'er loops in"initos om 29ile, usando uma ondio que < sempre verdadeira, omo %/ [[ /% ou simplesmente %/% Ique, omo qualquer valor no=nulo, < onsiderado %verdadeiro%J:
Zhile (+) 1 ... ;
&o ! pode sair de um loop _ in"inito ou no _ om a instruo 're"(, que vo ! .# viu no teste s2itc9 e ser# e@pli ada mais abai@o.
do @@@ while
O loop Ido @@@ whileI < e@atamente igual ao I29ileI e@ eto por um aspe to: a ondio < testada depois do blo o, o que signi"i a que o blo o < e@e utado pelo menos uma ve'. * estrutura do ... Zhile e@e uta o blo o, testa a ondio e, se esta "or verdadeira, volta para o blo o de 2digo. Sua sinta@e <:
do 1 ... ; Zhile (condiKLo)7
8ote que, ao ontr#rio das outras estruturas de ontrole, necess?rio colocar um ponto+e+vCrgula ap2s a ondio.
do 1
Bm e@emplo de utili'ao de do ... Zhile < em um menu. PedirHamos que o usu#rio es ol$esse uma opo at< que ele es ol$esse uma opo v#lida:
,include -stdio.h. int m"in () 1 int i7 do 1 printf (3Escolh" " frut" pelo n=mero)>n>n3)7 printf (3>t(+) J"mLo>n3)7 printf (3>t(%) P'"c"xi>n3)7 printf (3>t(/) b"r"n*">n>n3)7 sc"nf(3@d35 Ai)7 ; Zhile (i - + [[ i . /)7 sZitch (i) 1 c"se +) printf (3XocR escolheu m"mLo.>n3)7 're"(7 c"se %) printf (3XocR escolheu "'"c"xi.>n3)7 're"(7 c"se /) printf (3XocR escolheu l"r"n*".>n3)7 're"(7 ; return 97
for
O loop for < nada mais que uma abreviao do loop 29ile, que permite que alguma ini iali'ao se.a "eita antes do loop e que um in remento Iou alguma outra aoJ se.a "eita ap2s ada e@e uo sem in luir o 2digo dentro do blo o. * sua "orma geral <
for (inici"liW"KLo7 condiKLo7 incremento) 1 instruK\es7 ;
> equivale a
inici"liW"KLo7 Zhile (condiKLo) 1 instruK\es7 incremento7 ;
puts (3Iumero de volt"s previst"s D.3)7 printf(3Iumero de loop ou volt" ) @i 35 " )7 printf(3X"lor de " ) @i 35 " )7
8esse e@emplo, primeiro de"inimos o valor de a omo /Z depois, o 2digo I...J < repetido enquanto a "or menor que de', in rementando em uma unidade o valor de a ap2s ada e@e uo do 2digo. *nalisando essas ondi+es, vo ! podera per eber que o 2digo ser# e@e utado nove ve'es: na primeira e@e uo, temos " < +Z ap2s a nona e@e uo, a < igual a /K, e portanto o blo o no ser# mais repetido. (amb<m podemos dar mais de uma instruo de ini iali'ao ou de in remento Iseparadas por vHrgulaJ, al<m de poder usar naturalmente ondi+es ompostas om o uso dos operadores l2gi os:
for (" < +5 ' < +7 " - +9 AA (' / ") - %97 "CC5 ' *< %) 1 ... ;
8esse e@emplo, %a% e %b% so ini iali'ados om o valor /. * ada loop, o valor de %a% < in rementado em uma unidade e o de %b% < dobrado. Isso o orre enquanto %a% "or menor que /K e a ra'o entre %b% e %a% "or menor que 0K. Se vo ! onstruir uma tabela om os valores de ada vari#vel a ada loop Iou olo ar algum ontador dentro do loopJ, ver# que o orrem oito e@e u+es. *ssim omo 29ile, o loop 8or testa a ondioZ se a ondio "or verdadeira ele e@e uta o blo o, "a' o in remento e volta a testar a ondio. >le repete essas opera+es at< que a ondio se.a "alsa. Podemos omitir qualquer um dos elementos do 8or se dese.armos. Se omitirmos a ini iali'ao e o in remento, o omportamento ser# e@atamente igual ao de 29ile. Se omitirmos a ondio, "i aremos om um loop in"inito:
for (inici"liW"KLo7 7 incremento) 1 ... ;
Podemos tamb<m omitir o blo o de 2digo, se nos interessar apenas "a'er in rementos ou se quisermos esperar por alguma situao que < estabele ida por uma "uno e@ternaZ nesse aso, usamos o ponto=e= vHrgula ap2s os par!nteses de 8or. Isso tamb<m < valido para o loop 29ile:
for (inici"liW"KLo7 condiKLo7 incremento) 7 Zhile (condiKLo) 7
Por e@emplo, supon$a que temos uma bibliote a gr#"i a que tem uma "uno $amada grap$i s6eadRIJ, que indi a se podemos e@e utar opera+es gr#"i as. >ste 2digo e@e utaria a "uno repetidas ve'es at< que ela retornasse %verdadeiro% e ento pud<ssemos ontinuar om o programa:
Zhile (6gr"phicsce"dY()) 7
rea) e continue
&o ! .# viu rea) sendo usado para sair do teste s2itc9Z no entanto, ele "un iona tamb<m nos loops _ Zhile, do e for. 8os tr!s asos, ele sai do Mltimo loop ini iado Imesmo que $a.a mais de umJ. Por e@emplo:
Zhile (+) 1 if (" . ') 're"(7 "CC7 ;
,rea0 sempre "a' om que a e@e uo do programa ontinue na primeira instruo seguinte ao loop ou blo o. * instruo continue < pare ida om ,rea0, por<m ao e@e ut#=la saltamos para a pr2@ima iterao loop ao inv<s de termin#=lo. Bsar continue equivale a $egar ao "inal do blo oZ os in rementos so reali'ados Ise estivermos em um loop 8orJ e a ondio < reavaliada Iqualquer que se.a o loop atualJ.
,include -stdio.h. int m"in() 1 int opc"o < 97 Zhile (opc"o 6< 2) 1 printf(3Escolh" um" opKLo entre + e 2) 3)7 sc"nf(3@d35 Aopc"o)7 /* se " opKLo for inv4lid"5 volt" "o in^cio do loop */ if (opc"o . 2 [[ opc"o - +) continue7 sZitch (opc"o) 1 c"se +) printf(3>n $$. Primeir" opc"o..3)7 're"(7 c"se %) printf(3>n $$. Segund" opc"o..3)7 're"(7 c"se /) printf(3>n $$. Oerceir" opc"o..3)7 're"(7 c"se 0) printf(3>n $$. Bu"rt" opc"o..3)7 're"(7 c"se 2) printf(3>n $$. P'"ndon"ndo..3)7 're"(7 ;
; ;
return 97
>sse e@emplo re ebe uma opo do usu#rio. Se ele digitar uma opo inv#lida Iou se.a, no "or um nMmero de / a ;J, a instruo continue voltar# ao omeo do loop e o programa pedir# novamente a entrada do usu#rio. Se ele digitar uma opo v#lida, o programa seguir# normalmente.
Os nomes de r2tulo so identi"i adores su"i@ados por dois=pontos I)J, no omeo de uma lin$a Ipodendo ser pre edidos por espaosJ. Por e@emplo:
nome!do!rFtulo) ... goto nome!do!rFtulo7
Quitos programadores evitam usar o goto pois a maioria dos saltos pode ser "eita de maneira mais lara om outras estruturas da linguagem C. 8a maioria das apli a+es usuais, pode=se substituir o goto por testes, loops e $amadas de "un+es.
Ferminando o programa
O programa pode ser terminado imediatamente usando a "uno e.it:
void exit (int codigo!de!retorno)7
Para utili'#=la deve=se olo ar um in lude para o arquivo de abeal$o stdlib.$. >sta "uno aborta a e@e uo do programa. Pode ser $amada de qualquer ponto no programa e "a' om que o programa termine e retorne, para o sistema opera ional, o 2digoddedretorno. * onveno mais usada < que um programa retorne 'ero no aso de um t<rmino normal e retorne um nMmero no nulo no aso de ter o orrido um problema.
,include -stdio.h. ,include -stdli'.h. /* P"r" " funKLo exit() */
int m"in (void) 1 H]bE *fp7 ... fp<fopen (3exemplo.'in353Z'3)7 if (6fp) 1 printf (3Erro n" "'ertur" do "r#uivo. Him de progr"m".3)7 exit (+)7 ; ... return 97 ;
Bun>$es
>ste m2dulo pre isa ser revisado por algu<m que on$ea o assunto Idis utaJ.
# que 8un>o
Bma 8un>o < um pedao de 2digo que "a' alguma tare"a espe H"i a e pode ser $amado de qualquer parte do programa quantas ve'es dese.armos. Podemos tamb<m di'er que "un+es agrupam opera+es em um s2 nome que pode ser $amado em qualquer parte do programa. >ssas opera+es so ento e@e utadas todas as ve'es que $amamos o nome da "uno. Btili'amos "un+es para obter: Clare<a do cdigo: separando pedaos de 2digo da "uno mainIJ, podemos entender mais "a ilmente o que ada parte do 2digo "a'. *l<m disso, para pro urarmos por uma erta ao "eita pelo programa, basta bus ar a "uno orrespondente. Isso torna muito mais "# il o ato de pro urar por erros.
"eutili<a>o: muitas ve'es queremos e@e utar uma erta tare"a v#rias ve'es ao longo do programa. 6epetir todo o 2digo para essa operao < muito trabal$oso, e torna mais di"H il a manuteno do 2digo: se a $armos um erro nesse 2digo, teremos que orrigi=lo em todas as repeti+es do 2digo. C$amar uma "uno diversas ve'es ontorna esses dois problemas. Independ/ncia: uma "uno < relativamente independente do 2digo que a $amou. Bma "uno pode modi"i ar vari#veis globais ou ponteiros, mas limitando=se aos dados "orne idos pela $amada de "uno. * ideia "un+es < permitir vo ! en apsular v#rias opera+es em um s2 es opo que pode ser invo ado ou $amado atrav<s de um nome. *ssim < possHvel ento $amar a "uno de v#rias partes do seu programa simplesmente usando o seu nome. >@emplo:
,include -stdio.h. int m"in(void) 1 imprime!p"r(/50)7 imprime!p"r($%5T)7 return 97 ;
8o e@emplo a ima, a "uno imprimeKpar "oi usada para e@e utar o pedao de programa que imprime um par de nMmeros. * saHda do programa a ima ser#:
1/50; 1$%5T;
* de"inio de "un+es em C devem ser "eitas antes do uso das mesmas. Por isso em nosso e@emplo de"inimos a "uno imprimeKpar antes de us#=la dentro do main. * lin$a que de"ine ou de lara a "uno tamb<m < on$e ida omo assinatura da "uno. 8ormalmente as assinaturas das "un+es so de"inidas dentro de arquivos de abeal$o @9
Para o nome da "uno e dos parNmetros valem as mesmas regras que "oram dadas para os nomes de vari#veis. 8o podemos usar o mesmo nome para "un+es di"erentes em um programa. (odas as "un+es devem ser de"inidas antes da "uno main, ou deve ser "eito o prottipo da "uno, que veremos mais adiante. O 2digo deve estar obrigatoriamente dentro das $aves e "un iona omo qualquer outro blo o.
Valor de retorno
-reqUentemente, uma "uno "a' algum tipo de pro essamento ou #l ulo e pre isa retornar o resultado desse pro edimento. >m C, isso se $ama valor de retorno e pode ser "eito om a instruo return. Para poder retornar um valor, pre isamos espe i"i ar seu tipo I $ar, int, "loat, double e varia+esJ. Para e"etivamente retornar um valor, usamos a instruo return seguida do valor de retorno, que pode ou no vir entre par!nteses. Bm e@emplo bem simples de "uno que retorna um valor inteiro:
int tres() 1 return /7 ;
O tipo de retorno, al<m dos tipos normais de vari#veis I $ar, int, "loat, double e suas varia+esJ, pode ser o tipo espe ial void, que na verdade signi"i a que no $# valor de retorno. &ota Quitos livros di'em que a "uno m"in tem tipo de retorno void, o que no est# orreto. Segundo o padro da linguagem C, a "uno m"in deve ter retorno do tipo int. Compiladores omo o g daro mensagens de erro aso a "uno mainIJ no se.a de"inida orretamente.
ParLmetros
Como .# "oi dito, um parNmetro < um valor que < "orne ido F "uno quando ela < $amada. ] omum tamb<m $amar os parNmetros de argumentos, embora argumento este.a asso iado ao valor de um
parNmetro. Os parNmetros de uma "uno podem ser a essados da mesma maneira que vari#veis lo ais. >les na verdade "un ionam e@atamente omo vari#veis lo ais, e modi"i ar um argumento no modi"i a o valor original no onte@to da $amada de "uno, pois, ao dar um argumento numa $amada de "uno, ele < opiado omo uma vari#vel lo al da "uno. * Mni a maneira de modi"i ar o valor de um parNmetro < usar ponteiros, que sero introdu'idos mais adiante. Para de larar a presena de parNmetros, usamos uma "ista de par5metros entre par!nteses, om os parNmetros separados por vHrgulas. Cada de larao de parNmetro < "eita de maneira semel$ante F de larao de vari#veis: a "orma geral < tipo nome. Por e@emplo:
int func"o (int "5 int ') flo"t func"o (flo"t preco5 int #u"ntid"de) dou'le func"o (dou'le "ngulo)
Para espe i"i ar que a "uno no usa nen$um parNmetro, a lista de parNmetros deve onter apenas a palavra= $ave void. 8o entanto, ela < "reqUentemente omitida nesses asos. Portanto, vo ! poderia es rever qualquer uma destas duas lin$as:
void func"o (void) void func"o ()
8ote que os nomes dos parNmetros so usados apenas na pr2pria "uno Ipara distinguir os argumentosJZ eles no t!m nen$uma relao om as vari#veis usadas para $amar a "uno.
C9amadas de 8un>$es
Para e@e utar uma "uno, "a'emos uma c9amada de 8un>o, que < uma instruo omposta pelo nome da "uno, seguido pela lista de argumentos entre par!nteses:
nome!d"!funKLo ("rg+5 "rg%5 ...)7
Os argumentos podem ser qualquer tipo de e@presso: podem ser vari#veis, valores onstantes, e@press+es matem#ti as ou at< mesmo outras $amadas de "uno. 3embre que vo ! deve sempre dar o mesmo nMmero de argumentos que a "uno pede. *l<m disso, embora algumas onvers+es de tipo se.am "eitas automati amente pelo ompilador, vo ! deve atender aos tipos de argumentos. 8ote que o valor dos argumentos < copiado para a "uno, de maneira que as vari#veis originais "i am inalteradas mesmo que na "uno tentemos alter#=las. * isso $amamos passagem de argumentos por $a"or Iao ontr#rio de por refer%nciaJ. &eremos omo modi"i ar as vari#veis originais na seo Ponteiros. * pr2pria $amada de "uno tamb<m < uma e@presso u.o valor < o valor de retorno da "uno, bastando olo #=la no lado direito de um sinal de igual para guardar o valor numa vari#vel. Por e@emplo, se a "uno %quadrado% retorna o quadrado de um nMmero inteiro, podemos "a'er assim para al ular o quadrado de // na vari#vel .:
int x < #u"dr"do (++)7
Dois e:emplos
,include -stdio.h. int #u"dr"do (int x) 1 return (x * x)7 ; void s"ud"c"o (void) 1 printf (3Ol46>n3)7 ; void despedid" (void) 1 printf (3Him do progr"m".>n3)7 ; int m"in () 1 int numero5 result"do7 s"ud"c"o ()7 printf (3?igite um n=mero inteiro) 3)7 sc"nf (3@d35 Anumero)7 result"do < #u"dr"do (numero)7 printf (3O #u"dr"do de @d G @d.>n35 numero5 result"do)7 despedid" ()7 return 97 ;
6epare que, ao $egar na $amada de uma "uno, o programa passa o ontrole para essa "uno e, ap2s seu t<rmino, devolve o ontrole para a instruo seguinte na "uno original. Qais um e@emplo, om uma "uno de 7 argumentos:
,include -stdio.h. /* Jultiplic" / numeros */ void mult (flo"t "5 flo"t '5 flo"t c) 1 printf (3@f35"*'*c)7 ; int m"in () 1 flo"t x5 Y7 x < %/.27 Y < +%.D7 mult (x5 Y5 /.T:)7 return 97 ;
8esses asos, podemos declarar uma "uno antes de de"ini=la. Isso "a ilita o trabal$o de usar diversas "un+es: vo ! no pre isar# se importar om a ordem em que elas apare em nos arquivos. * de larao de "uno Itamb<m $amada de prot2tipo de "unoJ nada mais < que a de"inio da "uno sem o blo o de 2digo. Como uma instruo, ela deve ser seguida de um ponto=e=vHrgula. Portanto, para de larar a "uno:
int #u"dr"do (int x) 1 return (x * x)7 ;
es reverHamos:
int #u"dr"do (int x)7
8uma de larao, tamb<m podemos omitir os nomes dos parNmetros, .# que estes so ignorados por quem $ama a "uno:
int #u"dr"do (int)7
PoderHamos, por e@emplo, reorgani'ar o inH io do programa=e@emplo dado um pou o a ima, o que permitiria olo ar as "un+es em qualquer ordem mesmo que $ouvesse interdepend!n ia entre elas:
,include -stdio.h. int #u"dr"do (int x)7 void s"ud"c"o (void)7 void despedid" (void)7 // seguem "s funK\es do progr"m"
8ote que a de"inio da "uno no deve ontradi'er a de larao da mesma "uno. Se isso o orrer, uma mensagem de erro ser# dada pelo ompilador.
,entro de uma "uno -ora de todas as "un+es in lusive a mainIJ. *s primeiras so as designadas omo lo ais: s2 t!m validade dentro do blo o no qual so de laradas. *s Mltimas so as globais, elas esto vigentes em qualquer uma das "un+es. \uando uma "uno tem uma vari#vel lo al om o mesmo nome de uma vari#vel global a "uno dar# pre"er!n ia F vari#vel lo al. ,aqui on lui=se e bem que, podemos ter vari#veis om o mesmo nome, o que ontradi' o que n2s dissemos no apitulo das vari#veis. >nto re"ormulamos: *penas na situao em que temos 0 vari#veis lo ais < que < olo ada a restrio de termos nomes di"erentes aso ontr#rio no onseguirHamos distinguir uma da outra. %largo% e %alto% so vari#veis internas "a'em parte de %min$a-un ionIJ%.
/*esp"nhol p"r" incultos ))*/ -<< Eoment4rios d" funKLo void minh"Huncion() 1 dou'le l"rgo < 27 dou'le "lto < 87 ;
*s vari#veis largo e alto no esto de"inidas aqui abai@o, isto quer di'er que elas nao tem nem um valor. > no podemos usar os valores de"inido dentro da %min$a-un ion%, pois no $# nen$uma instruo que de"ina que valor usar. 3embre=se: O omputador no vai adivin$ar qual valor usar. ,eve=se de"inir ada instruo.
void c"lcul"r() /*ILo houve definiKLo de v"lor entre p"renteses*/ 1 long superficie < l"rgo * "lto7 /*Error 'ip 'ip v"lor n"o definido*/ return(superficie)7 ;
8esse e@emplo abai@o, poderemos usar o valor das vari#veis e@ternas dentro de todas as "un+es. >@emplo:
,include -stdio.h. /* X"ri"veis extern"s */ long l"rgo < +97 long "lto < %97 void H!som" () 1 /*som" G um" v"ri"vel intern" e l"rgo e "lto s"o v"ri"veis extern"s */ long som" < l"rgo C "lto 7 printf(3l"rgo C "lto < @i >n35 som")7 ; long c"lcul"r() 1 long superficie < l"rgo * "lto7 return superficie7 ; int m"in(void) 1 H!somm" ()7
Curiosidade * palavra reservada %auto% serve para di'er que uma vari#vel < lo al, mas a utili'ao de auto no < mais ne ess#ria pois as vari#veis de laradas dentro de um blo o .# so onsideradas lo ais.
\uando a "uno mainIJ < e@e utada, ela $ega a meio e v! uma $amada para a "uno quadradoIJ e onde < passado o parNmetro %num%. >la .# estava a espera, pois %viu% o prot2tipo. >la ento vai e@e utar a "uno que est# depois da "uno do mainIJ. > o que a onte e < que o %num%, vai "i ar om o dobro do valor. >sse valor do mainIJ vai entrar novamente no mainIJ. > < asso iado # vari#vel %res%. ,epois temos a impresso da vari#vel %num% e %res%. Ora o que a onte e < que o valor do %num% "i a igual ao valor antes de entrar na "uno. -a'emos a mesma oisa agora om a vari#vel %a% e %b%, e vemos que agora a "uno a < alterada. 6esumindo, o valor vari#vel quando entra numa outra "uno no < alterado Ina passagem por valorJ. \uando o valor do parNmetro < alterado denominamos $amada Iou passagemJ por re8er/ncia. O C no "a' $amadas por re"er!n ia. Qas podemos simular isto om outra arma do C que so os ponteiros, que sero mel$or e@pli ados mais adiante.
void
Como dissemos, uma "uno retorna um valor. > pode re eber parNmetros. O void < utili'ado da seguinte "orma:
8o e@emplo a ima, a palavra void de"ine que: no vai re eber parNmetrosZ e no vai retornar qualquer valor. Ou mel$or, void < uma e@pli itao do programador que aquela "uno no vai re eber ou retornar nen$um valor. O valor da "uno < ignorado, mas a "uno realmente retorna um valor, por isso para que o resultado no se.a interpretado omo um erro e bom de larar void. &ota 8o se pode utili'ar void na "uno prin ipal main, apesar de e@istirem e@emplos om void em algumas bibliogra"ias. In"eli'mente, alguns ompiladores a eitam void mainIJ. O mainIJ < espe ial e tem de retornar um int. Bma e@e uo bem su edida do programa ostuma retornar K I'eroJ e, em aso de erro, retorna / IumJ.
"ecursividade
Bma "uno pode $amar a si pr2pria. Bma "uno assim < $amada 8un>o recursiva. 1# v#rias opera+es matem#ti as re ursivas, das quais e@emplos bem on$e idos so a seqU!n ia de -ibona i e o "atorial. ,aremos o e@emplo do #l ulo do "atorial de um nMmero, de"inido omo o produto de todos os nMmeros naturais Ino nulosJ menores ou iguais a ele _ por e@emplo, ;^ Il!=se % in o "atorial%J < igual a . *teno F onveno .
E:emplo * =
,include -stdio.h. ,include -stdli'.h. unsigned long fi'(unsigned int n)1 if (n << 9 [[ n << +) return n7 else return fi'(n $ +) C fi'(n $ %)7 ; int m"in()1 int n7 printf(3>n>n?igite um v"lor p"r" n) 3)7 sc"nf(3@d35 An)7 printf(3>n H(@d) < @d >n 35n5 fi'(n))7 return 97 ;
&amos introdu'ir o valor ; para este programa. So "eitas as seguintes $amadas re ursivas. Observe a estrutura upside=do?n I#rvore de abea para bai@oJ riada pelas $amadas re ursivas.
Hi'on"cci(2) / > / > / > / > / > H(0) C H(/) / > / > / > / > / > / > / > / > / > / > H(/) C H(%) H(%) C H(+) /> /> [ > > / > / > [ > > / > / > [ > > / > / > [ > > H(%) C H(+) H(+) C H(9) H(+) C H(9) + /> [ [ [ [ [ / > [ [ [ [ [ / > [ [ [ [ [ / > [ [ [ [ [ H(+) C H(9) + + 9 + 9 [ [ [ [ [ [ [ [ + 9
Cada ve' que a sub=rotina $ama a si mesmo, ela deve arma'enar o estado atual da sub=rotina Ilin$a atual que est# sendo e@e utada, os valores de todas as vari#veis, et J em uma estrutura de dados $amada de %pil$a%. Se vo ! usar a re ursividade durante um longo perHodo de tempo, a pil$a vai "i ar muito grande e o programa dar# uma mensagem de aviso.
inline
Bma "uno inline, em ve' de ser $amada, ser# movida para o lo al de $amada no momento da ompilao. Se "i'ermos um paralelismo om as diretivas de ompilao, omo Ode"ine, ela vai substituir ada $amada da "uno pela pr2pria "uno, < omo "osse uma ma ro. Qas isto s2 tem vantagens para 2digos pequenos e para quem ne essite muito da velo idade no pro essamento. *lguns ompiladores .# "a'em isto automati amente. Para tornar uma "uno inline basta pre eder a de larao da "uno om o nome inline.
inline [tipo!de!retorno 1 //cFdigo ; [nome!d"!funKLo ("rgumentos)
Pr+processador
# pr+processador
O pr<=pro essador C < um programa que e@amina o programa "onte es rito em C e e@e uta ertas modi"i a+es nele, baseado nas diretivas de compila>o Iou direti$as do pr#processadorJ. *s diretivas de ompilao so omandos que no so ompilados, sendo dirigidos ao pr<=pro essador, e@e utado pelo ompilador antes da e@e uo do pro esso de ompilao propriamente dito. Portanto, o pr<=pro essador modi"i a o programa "onte, que ainda no estaria pronto para ser entregue ao ompilador. (odas as diretivas de ompilao so ini iadas pelo ara tere O Is$arpJ. *s diretivas podem ser olo adas em qualquer parte do programa, mas no podem ser olo adas na mesma lin$a que outra diretiva ou instruo. *s prin ipais diretivas de ompilao so: Oin lude Ode"ine Ounde" Oi"de" Oi"nde" Oi" Oelse Oeli" Oendi"
Diretivas de compila>o
*include
* diretiva *include di' ao pr<=pro essador para in luir naquele ponto um arquivo espe i"i ado. Sua sinta@e <:
,include 3nome0do0arquivo3
ou
,include -nome0do0arquivo.
* di"erena entre se usar 33 e -. < somente a ordem de pro ura nos diret2rios pelo arquivo espe i"i ado. Se vo ! quiser in"ormar o nome do arquivo om o amin$o ompleto, ou se o arquivo estiver no diret2rio de trabal$o, use 3"r#uivo3. Se o arquivo estiver nos amin$os de pro ura pr<=espe i"i ados do ompilador, isto <, se ele "or um arquivo do pr2prio sistema I omo < o aso de arquivos omo stdio h, string h, et ...J, use -"r#uivo..
*define
* diretiva *define tem duas utilidades. Bma delas < apenas de"inir um sHmbolo que pode ser testado mais tarde. Outra < de"inir uma onstante ou ainda uma ma ro om parNmetros. *s tr!s maneiras de usar a diretiva so:
,define nome+do+s,m olo ,define nome+da+constante valor0da0constante ,define nome+da+macro(p"remetros) expresso0de0substituio
(oda ve' que o pr<=pro essador en ontrar nome6da6constante no 2digo a ser ompilado, ele deve substituH=lo por $a"or6da6constante. (oda ve' que o pr<=pro essador en ontrar nome6da6macroIpar5metrosJ, ele deve substituir por e.press-o6de6substitui-o, tamb<m substituindo os parNmetros en ontrados na e@presso de substituioZ "un iona mais ou menos omo uma "uno. &e.a o e@emplo para entender mel$or. E:emplo M=
,include -stdio.h. ,define P] ,define XEcSPO /.+0+8 3%.9%3
int m"in () 1 printf (3Progr"m" versLo @s>n35 XEcSPO)7 printf (3O numero pi v"le) @f>n35 P])7 ; return 97
E:emplo *=
,define m"x(P5 U) ((P . U) _ (P) ) (U)) ,define min(P5 U) ((P - U) _ (P) ) (U)) ... x < m"x(i5 *)7 Y < min(t5 r)7
*qui, a lin$a de 2digo: x < m"x(i5 *)7 ser# substituHda pela lin$a: x < ((i) . (*) _ (i) ) (*))7. Ou se.a, atribuiremos a . o maior valor entre i ou &. \uando vo ! utili'a a diretiva ,define, nun a deve $aver espaos em bran o no identi"i ador Io nome da ma roJ. Por e@emplo, a ma ro ,define Pc]IO (i) printf(3 @d >n35 i) no "un ionar# orretamente porque e@iste um espao em bran o entre Pc]IO e (i).
Nunde8
* diretiva ,undef tem a seguinte "orma geral:
,undef nome+da+macro
>la "a' om que a ma ro que a segue se.a apagada da tabela interna que guarda as ma ros. O ompilador passa a partir deste ponto a no on$e er mais esta ma ro.
*ifdef e *ifndef
O pr<=pro essador tamb<m tem estruturas ondi ionais. 8o entanto, omo as diretivas so pro essadas antes de tudo, s2 podemos usar omo ondi+es e@press+es que envolvam onstantes e sHmbolos do pr<= pro essador. * estrutura ifdef < a mais simples delas:
,ifdef nome+do+s,m olo c1digo ... ,endif
O 2digo entre as duas diretivas s2 ser# compi"ado se o sHmbolo Iou onstanteJ nome0do0s2mbolo .# tiver sido de"inido. 1# tamb<m a estrutura ifndef, que e@e uta o 2digo se o sHmbolo no tiver sido de"inido. 3embre que o sHmbolo deve ter sido de"inido atrav<s da diretiva ,define.
*if
* diretiva *if tem a seguinte "orma geral:
,if express-o c1digo ... ,endif
* sequ!n ia de de lara+es ser# ompilada apenas se a e@presso "orne ida "or verdadeira. ] muito importante ressaltar que a e@presso "orne ida no pode onter nen$uma vari#vel, apenas valores onstantes e sHmbolos do pr<=pro essador.
*else
* diretiva *else "un iona omo na estrutura de blo o if (condiKLo) 1...; else 1...;:
,if express-o /* ou ,ifndef express-o */ c1digo /* ser4 execut"do se " expressLo for verd"deir" */ ,else c1digo /* ser4 execut"do se " expressLo for f"ls" */ ,endif
Bm e@emplo:
,define &]I?O&S ... /* cFdigo */ ...
,ifdef &]I?O&S ,define EPUEEPbVO 3ZindoZs!io.h3 ,else ,define EPUEEPbVO 3unix!io.h3 ,endif ,include EPUEEPbVO
*elif
* diretiva *elif serve para implementar uma estrutura do tipo if (condiKLo) 1...; else if (condiKLo) 1...;. Sua "orma geral <:
,if expressLo!+ c1digo ,elif expressLo!% c1digo ,elif expressLo!/ c1digo . . . ,elif expressLo!n c1digo ,endif
Podemos tamb<m misturar diretivas ,elif om ,elseZ obviamente, s2 devemos usar uma diretiva ,else e ela deve ser a Mltima Iantes de ,endifJ.
Se o arquivo ainda no tiver sido in luHdo, ao $egar na primeira lin$a do arquivo, o pr<=pro essador no en ontrar# o sHmbolo EPUEEPbVO!V, e ontinuar# a ler o arquivo, o que l$e "ar# de"inir o sHmbolo. Se tentarmos in luir novamente o arquivo, o pr<=pro essador pular# todo o onteMdo pois o sHmbolo .# "oi de"inido.
Concatena>o
O prepro essador C o"ere e duas possibilidades para manipular uma adeia de ara teres . * primeira < usando o operador O que permite substituir a gra"ia de um parNmetro .
,include-stdio.h.
int m"in (void) 1 /* m"d e#uiv"le " 3m"d3 */ ,define String(m"d) ,m"d printf ( String( Estou "#ui ) 3>n3 )7 ;
* segunda < usando o operador OO que serve para on atenar v#rios parNmetros . >@: banOOana < igual a banana .
,include-stdio.h. int m"in (void) 1 int teste < +999 7 ,define EOIEPO(x5 Y) x,,Y /* igu"l " 3tes3 C 3te3 */ printf (3 @i >n35 EOIEPO ( tes5 te ) )7 ;
6i,liotecas
6i,liotecas
6i,liotecas so on.untos de "un+es que "oram "eitas por algu<m e que podem ser usadas por outros programas sem que nos preo upemos om o 2digo dessas "un+es. *l<m da vantagem de organi'ar o 2digo, bibliote as tamb<m t!m a vantagem de poderem ser utili'adas em v#rios programas sem ne essidade de opiar grandes tre $os de 2digoZ basta di'er ao ompilador que queremos adi ionar aquela bibliote a ao e@e ut#vel. Por e@emplo, vamos tentar riar a nossa pr2pria bibliote a, om duas "un+es: uma para gerar nMmeros Ipseudo=Jaleat2rios e uma para al ular o valor de pagamento de uma amorti'ao om .uros ompostos. (amb<m in luiremos uma "uno para gerar um nMmero ini ial a partir da $ora atual, o que "ar# om que as seqU!n ias de nMmeros no se.am sempre as mesmas. C$amaremos a bibliote a de testeM.
,include -m"th.h. ,include -time.h. int r"nd!seed < +97 /* `er"dor de n=meros pseudo$"le"tFrios */ int r"nd () 1 r"nd!seed < r"nd!seed * ++9/2+2%02 C +%/027 return (unsigned int) (r"nd!seed / 822/8) @ /%:8T7 ;
void init!seed () 1 r"nd!seed < time (Igbb)7 ; /* E4lculo do v"lor de c"d" p"g"mento de um" "mortiW"KLo * ?"dos) vp < v"lor presente7 * n < n=mero de p"g"mentos7 * i < t"x" de *uros (em form"to decim"l) */ dou'le vf (dou'le vp5 int n5 dou'le i) 1 return (vp * i * poZ (+ C i5 n $ +) / (poZ (+ C i5 n) $ +))7 ;
*s lin$as a ima so o arquivo do 2digo da nossa bibliote a. *bai@o est# o 2digo de um programa que testar# essa bibliote a. 3embre=se de que os dois tre $os devem estar em arquivos separados.
,include -stdio.h. int m"in() 1 int r+5 r%5 n!pgtos7 dou'le "!vist"5 *uros5 v!pgto7 r+ < r"nd ()7 r% < r"nd ()7 printf (3I=meros "le"tFrios) @d5 @d>n>n35 r+5 r%)7 printf (3 X"lor a vist") 3)7 sc"nf (3@lf35 A"!vist")7 printf (3I=mero de p"g"mentos) 3)7 sc"nf (3@d35 An!pgtos)7 printf (3 O"x" de *uros) 3)7 sc"nf (3@lf35 A*uros)7 *uros /< +997 /* converte " porcent"gem em n=mero */ v!pgto < vf ("!vist"5 n!pgtos5 *uros)7 printf (3X"lor de c"d" p"g"mento) @lf>n35 v!pgto)7 return 97 ;
*lgo que vo ! deve ter notado < que nesse arquivo no demos nen$uma in"ormao sobre as "un+es $f e rand nele usadas. 6ealmente, se vo ! tentar ompilar o 2digo omo est#, o ompilador dar# um avisoZ mas ao tentar riar o e@e ut#vel, o montador no poder# ontinuar pois no re ebeu nen$uma in"ormao sobre onde as "un+es esto. Para isso, pre isamos reali'ar tr!s passos adi ionais antes de ompilar o programa teste: /. -a'er um arquivo= abeal$o om in"orma+es sobre as "un+es. >sse arquivo ser# in luido om a diretiva 7inc"ude, da mesma maneira que abeal$os padro omo %stdio.$% ou %mat$.$%. 0. Compilar a bibliote a separadamente. 7. Instruir o ompiladorAmontador a pro urar pela bibliote a ao ompilar o programa teste.
# arquivo+ca,e>al9o
*rquivos= abeal$o so arquivos que ont<m in"orma+es que servem para o ompilador re on$e er
"un+es I%&>6: onven+es para $amadas a "un+es ou alling onvention%J, ma ros, tipos de dados e vari#veis que no esto no arquivo sendo ompilado. >sses arquivos ostumam ter a e@tenso %.$% _ < o aso, por e@emplo, dos abeal$os padro stdio h e math h. * letra 1 < usada pois < a ini ial de header I abeal$o em ingl!sJ. >m uma bibliote a, os abeal$os ont!m, os prot2tipos das "un+es disponibili'adas pela bibliote a e, quando ne ess#rio, sobre os tipos de estruturas usados. Libliote as mais omple@as ostumam dividir essas "un+es entre v#rios arquivos. Para "a'er nosso pr2prio abeal$o, pre isamos olo ar as de lara+es das "un+es disponHveis na bibliote a:
int r"nd ()7 void init!seed ()7 dou'le vf (dou'le5 int5 dou'le)7
Se vo ! se lembra da Mltima lio, poder# sugerir que oloquemos algumas lin$as a mais:
,ifndef !OESOE+!V ,define !OESOE+!V int r"nd ()7 void init!seed ()7 dou'le vf (dou'le5 int5 dou'le)7 ,endif
*gora, sempre que pre isarmos usar a bibliote a teste4, basta in luir o arquivo teste4 h no inH io do nosso programa:
,include 3teste+.h3
8ote que se o abeal$o estiver instalado nos diret2rios padro do ompilador ou do sistema, vo ! deve tro ar as aspas pelos sinais de menorAmaior I< ... pJ.
Compila>o da ,i,lioteca
(endo salvo o 2digo da bibliote a no arquivo teste4 c, vo ! deve ompilar a bibliote a.
&o 4CC
Compile o arquivo="onte normalmente, mas sem gerar o e@e ut#vel:
gcc $c teste+.c $o li'teste+.o
Crie o arquivo da bibliote a om o omando ar. &o ! ainda no o on$e e, mas a sinta@e < simples: basta digitar "r rv, seguido do nome do arquivo da bibliote a e depois dos nomes dos arquivos=ob.eto a serem in luHdos Iseparados por espaosJ. 8o PCC, as bibliote as est#ti as ostumam ter o nome %libnome.a%.
"r rv li'teste+." li'teste+.o
para Windo?s. 8ele, os omandos orrespondentes aos dois passos a ima so:
cl /c teste+.c li' /out)teste+.li' teste+.o'*
Compila>o do programa
*p2s riar o arquivo ob.eto libteste/.o om o omando I gcc $c teste+.c $o li'teste+.o J e a bibliote a est#ti a om o omando %ar% , vo ! deve instruir o ompilador om as op+es de edio de links para poder in luH=la no seu programa: 8o PCC:
gcc m"in.c $b. $l li'teste+." $o m"in.'in $lm
8ote as op+es que vo ! no on$e ia: $b e $l . * primeira indi a em que diret2rio deve ser pro urada a bibliote aZ o ponto indi a o diret2rio atual. Se essa opo "or omitida, o ompilador pro urar# apenas nos diret2rios padro. * segunda < uma opo do editor de links indi ando uma bibliote a a ser in luHdaZ o ompilador pro urar# pelo arquivo adi ionando o pre"i@o "ib e a e@tenso a, daH a ne essidade de dar o nome %libteste/.a% F bibliote a. Qais bibliote as podem ser in luHdas omo a $lm que neste aso serve para $amar a bibliote a mat$ do mat$.$, sem este omando ele poder# apresentar um erro na $ora da ompilao. 8o &isual CCC:
lin( /out)m"in.exe m"in.o'* teste+.li'
8ote que nesse aso simplesmente espe i"i amos os arquivos que devem ser montados. O diret2rio de pro ura pode ser espe i"i ado pela opo /li'p"th)diret1rio.
>m ambientes ,OSAWindo?s, ao ler arquivos bin#rios Ipor e@emplo, programas e@e ut#veis ou ertos tipos de arquivos de dadosJ, deve=se adi ionar o ara tere %b% ao "inal da string de modo Ipor e@emplo, %?b% ou %rCb%J para que o arquivo se.a lidoAgravado orretamente.
Isso < ne ess#rio porque no modo te@to Io padro quando no < adi ionado o bJ o orrem algumas tradu+es de ara teres Ipor e@emplo, a terminao de lin$a %eren% < substituHda apenas por %en% na leituraJ que poderiam a"etar a leituraAgravao dos arquivos bin#rios Iindevidamente inserindo ou suprimindo ara teresJ. O valor de retorno da "uno "openIJ < muito importante^ >le < o identi"i ador do "lu@o que vo ! abriu e < s2 om ele que vo ! onseguir# ler e es rever no arquivo aberto. Se $ouver um erro na aberturaA riao do arquivo, a "uno retornar# o valor Igbb. O erro
geralmente a onte e por duas ra'+es: O arquivo no e@iste, aso ten$a sido requisitado para leitura. O usu#rio atual no tem permisso para abrir o arquivo om o modo de a esso pedido. Por e@emplo, o arquivo < somente=leitura, ou est# bloqueado para gravao por outro programa, ou perten e a outro usu#rio e no tem permisso para ser lido por outros. *o terminar de usar um arquivo, vo ! deve "e $#=lo. Isso < "eito pela "uno fclose(): int 8close I-I3> jf"u.oJZ O Mni o argumento < o identi"i ador do "lu@o Iretornado por "openJ. O valor de retorno indi a o su esso da operao om o valor 'ero. -e $ar um arquivo "a' om que qualquer ara tere que ten$a permane ido no %bu""er% asso iado ao "lu@o de saHda se.a gravado. Qas, o que < este %bu""er%S \uando vo ! envia ara teres para serem gravados em um arquivo, estes ara teres so arma'enados temporariamente em uma #rea de mem2ria Io %bu""er%J em ve' de serem es ritos em dis o imediatamente. \uando o %bu""er% estiver $eio, seu onteMdo < es rito no dis o de uma ve'. * ra'o para se "a'er isto tem a ver om a e"i i!n ia nas leituras e grava+es de arquivos. Se, para ada ara tere que "hssemos gravar, tiv<ssemos que posi ionar a abea de gravao em um ponto espe H"i o do dis o, apenas para gravar aquele ara tere, as grava+es seriam muito lentas. *ssim estas grava+es s2 sero e"etuadas quando $ouver um volume ra'o#vel de in"orma+es a serem gravadas ou quando o arquivo "or "e $ado. * "uno e@itIJ "e $a todos os arquivos que um programa tiver aberto. * "uno ""lus$IJ "ora a gravao de todos os ara teres que esto no bu""er para o arquivo.
E:emplo
Bm pequeno e@emplo apenas para ilustrar a abertura e "e $amento de arquivos:
,include -stdio.h. int m"in() 1 H]bE *fp7 fp < fopen (3cEP?JE35 3Z3)7 if (fp << Igbb) 1 printf (3Vouve um erro "o "'rir o "r#uivo.>n3)7 return +7 ; printf (3Pr#uivo cEP?JE cri"do com sucesso.>n3)7 fclose (fp)7 return 97 ;
%rquivos pr+de8inidos
8a bibliote a padro do C, e@istem alguns "lu@os pr<=de"inidos que no pre isam Inem devemJ ser abertos nem "e $ados: stdin: dispositivo de entrada padro Igeralmente o te ladoJ stdout: dispositivo de saHda padro Igeralmente o vHdeoJ stderr: dispositivo de saHda de erro padro Igeralmente o vHdeoJ stdau:: dispositivo de saHda au@iliar Iem muitos sistemas, asso iado F porta serialJ stdprn: dispositivo de impresso padro Iem muitos sistemas, asso iado F porta paralelaJ
Escrevendo em arquivos
Para es rever em arquivos, $# quatro "un+es, das quais tr!s so an#logas Fs usadas para saHda padro: 'aCda padro %rquivos put $ar puts print" 8A* "put "puts "print" "?rite E:plica>o Imprime apenas um ara tere. Imprime uma string diretamente, sem nen$uma "ormatao. Imprime uma string "ormatada. Prava dados bin#rios para um arquivo.
* seguir apresentamos os prot2tipos dessas "un+es: void 8putc Iint caractere, -I3> jf"u.oJZ
int 82rite Ivoid jdados, int tamanho6do6e"emento, int num6e"ementos, -I3> jf"u.oJZ Sinta@e quase igual F de print"IJZ s2 < ne ess#rio adi ionar o identi"i ador de "lu@o no inH io.
82rite
>sta "uno envolve os on eitos de ponteiro e vetor, que s2 sero abordados mais tarde. * "uno "?riteIJ "un iona omo a sua ompan$eira "readIJ, por<m es reve no arquivo. Seu prot2tipo <:
unsigned fZrite(void *'uffer5int numero!de!'Ytes5int count5H]bE *fp)7
* "uno retorna o nMmero de itens es ritos. >ste valor ser# igual a ount a menos que o orra algum erro. O e@emplo abai@o ilustra o uso de "?rite e "read para gravar e posteriormente ler uma vari#vel "loat em um arquivo bin#rio.
,include -stdio.h. ,include -stdli'.h. int m"in() 1 H]bE *pf7 flo"t pi < /.+0+27 flo"t pilido7 if((pf < fopen(3"r#uivo.'in35 3Z'3)) << Igbb) /* P're "r#uivo 'in4rio p"r" escrit" */ 1 printf(3Erro n" "'ertur" do "r#uivo3)7
exit(+)7 ; if(fZrite(Api5 siWeof(flo"t)5 +5pf) 6< +) /* Escreve " v"ri4vel pi */ printf(3Erro n" escrit" do "r#uivo3)7 fclose(pf)7 /* Hech" o "r#uivo */ if((pf < fopen(3"r#uivo.'in35 3r'3)) << Igbb) /* P're o "r#uivo nov"mente p"r" leitur" */ 1 printf(3Erro n" "'ertur" do "r#uivo3)7 exit(+)7 ; if(fre"d(Apilido5 siWeof(flo"t)5 +5pf) 6< +) /* be em pilido o v"lor d" v"ri4vel "rm"Wen"d" "nteriormente */ printf(3Erro n" leitur" do "r#uivo3)7 printf(3>nO v"lor de P]5 lido do "r#uivo eM) @f35 pilido)7 fclose(pf)7 return 97 ;
8ota=se o uso do operador si'eo", que retorna o taman$o em bRtes da vari#vel ou do tipo de dados.
8putc
* "uno "put < a primeira "uno de es rita de arquivo que veremos. Seu prot2tipo <:
int fputc (int ch5 H]bE *fp)7
>s reve um ara tere no arquivo.O programa a seguir l! uma string do te lado e es reve=a, ara tere por ara tere em um arquivo em dis o Io arquivo arquivo.t@t, que ser# aberto no diret2rio orrenteJ.
,include -stdio.h. ,include -stdli'.h. int m"in() 1 H]bE *fp7 ch"r string[+99 7 int i7 fp < fopen(3"r#uivo.txt353Z3)7 /* Pr#uivo PSE]]5 p"r" escrit" */ if(6fp) 1 printf( 3Erro n" "'ertur" do "r#uivo3)7 exit(9)7 ; printf(3Entre com " string " ser gr"v"d" no "r#uivo)3)7 gets(string)7 for(i<97 string[i 7 iCC) putc(string[i 5 fp)7 /* `r"v" " string5 c"r"ctere " c"r"ctere */ fclose(fp)7 return 97 ;
,epois de e@e utar este programa, veri"ique o onteMdo do arquivo arquivo.t@t Ivo ! pode usar qualquer editor de te@tosJ. &o ! ver# que a string que vo ! digitou est# arma'enada nele.
Lendo de arquivos
8ovamente, $# quatro "un+es, das quais tr!s se assemel$am Fs usadas para a saHda padro: 'aCda padro %rquivos E:plica>o
6e ebe apenas um ara tere. 3! uma string Igeralmente uma lin$a inteiraJ. 6e ebe uma string "ormatada. 3! dados bin#rios de um arquivo.
int 8read Ivoid jdados, int tamanho6do6e"emento, int num6e"ementos, -I3> jf"u.oJZ
Este m3du"o tem a seguinte tarefa pendente: riar e@emplos de uso das "un+es
8getc
>st# "uno requer omo parNmetro o indi ador de "lu@o do arquivo, retorna um ara tere do arquivo ou >O-, aso o orra um erro ou o "inal do arquivo se.a atingido, podendo ser veri"i ado respe tivamente por ferror e feof. >@emplo:
,include -stdio.h. ,include -stdli'.h. int m"in() 1 H]bE *fl7 int c7 if((fl < fopen(3c"minho/do/"r#uivo35 3r3)) << Igbb) 1 perror(3Erro) fopen3)7 exit(EQ]O!HP]bgcE)7 ; Zhile((c < fgetc(fl)) 6< EOH) printf(3E"r"ctere lido) @c>n35 c)7 if((c << EOH) AA (feof(fl) << 9) AA (ferror(fl) 6< 9)) perror(3Erro) fgetc3)7
8gets
*o $amar a "uno "getsIJ, vo ! deve "orne er o ponteiro para a string onde os dados lidos devem ser guardados, al<m do taman$o m#@imo dos dados a serem lidos Ipara que a mem2ria reservada F string no se.a ultrapassadaJ. Para se ler uma string num arquivo podemos usar "getsIJ u.o prot2tipo <:
ch"r *fgets (ch"r *str5 int t"m"nho5H]bE *fp)7
* "uno re ebe 7 argumentos: a string a ser lida, o limite m#@imo de ara teres a serem lidos e o ponteiro para -I3>, que est# asso iado ao arquivo de onde a string ser# lida. * "uno l! a string at< que um ara ter de nova lin$a se.a lido ou taman$o=/ ara teres ten$am sido lidos. Se o ara ter de nova lin$a I)en)J "or lido, ele "ar# parte da string, o que no a onte ia om gets. * "uno "gets < semel$ante F "uno getsIJ, por<m, al<m dela poder "a'er a leitura a partir de um arquivo de dados e in luir o ara ter de nova lin$a na string, ela ainda espe i"i a o taman$o m#@imo da string de entrada. Como vimos, a "uno gets no tin$a este ontrole, o que poderia a arretar erros de %estouro de bu""er%. Portanto, levando em onta que o ponteiro "p pode ser substituHdo por stdin, omo vimos a ima, uma alternativa ao uso de gets < usar a seguinte onstruo:
fgets (str5 t"m"nho5 stdin)7
8scan8
Sinta@e quase igual F de s an"IJZ s2 < ne ess#rio adi ionar o identi"i ador de "lu@o no inH io.
8scan8
* "uno "s an"IJ "un iona omo a "uno s an"IJ. * di"erena < que "s an"IJ l! de um arquivo e no do te lado do omputador. Prot2tipo:
int fsc"nf (H]bE *fp5ch"r *str5...)7 ,include -stdio.h. ,include -stdli'.h. int m"in() 1 H]bE *p7 ch"r str[T9 5c7 printf(3>n>n Entre com um nome p"r" o "r#uivo)>n3)7 "r#uivo " ser "'erto) */ gets(str)7 if (6(p < fopen(str53Z3))) erro n" "'ertur" do "r#uivo..*/ 1 "utom"tic"mente */ printf(3Erro6 ]mpossivel "'rir o "r#uivo6>n3)7 exit(+)7 ; fprintf(p53Este e um "r#uivo ch"m"do)>n@s>n35 str)7 fclose(p)7 imprime no "r#uivo5 fech" ...*/
8read
>ssa "uno envolve os on eitos de ponteiro e vetor, que s2 sero abordados mais tarde. Podemos es rever e ler blo os de dados. Para tanto, temos as "un+es "readIJ e "?riteIJ. O prot2tipo de "readIJ <:
unsigned fre"d (void *'uffer5 int numero!de!'Ytes5 int count5 H]bE *fp)7
O bu""er < a regio de mem2ria na qual sero arma'enados os dados lidos. O nMmero de bRtes < o taman$o da unidade a ser lida. ount indi a quantas unidades devem ser lidas. Isto signi"i a que o nMmero total de bRtes lidos <:
numero!de!'Ytes*count
* "uno retorna o nMmero de unidades e"etivamente lidas. >ste nMmero pode ser menor que ount quando o "im do arquivo "or en ontrado ou o orrer algum erro. \uando o arquivo "or aberto para dados bin#rios, "read pode ler qualquer tipo de dados.
O parNmetro origem determina a partir de onde os numbRtes de movimentao sero ontados. Os valores possHveis so de"inidos por ma ros em stdio.$ e so:
Nome SEEh!SEO SEEh!Egc SEEh!EI? Valor 9 + % Significado ]n^cio do "r#uivo Ponto corrente no "r#uivo Him do "r#uivo
(endo=se de"inido a partir de onde ir# se ontar, numbRtes determina quantos bRtes de deslo amento sero dados na posio atual.
re2ind
&olta para o omeo do arquivo de um "lu@o
8eo8
>O- I%>nd o" "ile%J indi a o "im de um arquivo. fs ve'es, < ne ess#rio veri"i ar se um arquivo $egou ao "im. Para isto podemos usar a "uno "eo"IJ. >la retorna no='ero se o arquivo $egou ao >O-, aso ontr#rio retorna 'ero. Seu prot2tipo <:
int feof (H]bE *fp)7
Outra "orma de se veri"i ar se o "inal do arquivo "oi atingido < omparar o ara tere lido por get om >O-. O programa a seguir abre um arquivo .# e@istente e o l!, ara ter por ara ter, at< que o "inal do arquivo se.a atingido. Os ara teres lidos so apresentados na tela:
,include -stdio.h. ,include -stdli'.h. int m"in() 1 H]bE *fp7 ch"r c7 fp < fopen(3"r#uivo.txt353r3)7 /* Pr#uivo PSE]]5 p"r" leitur" */ if(6fp) 1 printf( 3Erro n" "'ertur" do "r#uivo3)7 exit(9)7 ; Zhile((c < getc(fp) ) 6< EOH) /* En#u"nto nLo cheg"r "o fin"l do "r#uivo */ printf(3@c35 c)7 /* imprime o c"r"cter lido */ fclose(fp)7 return 97 ;
&eri"ique o e@emplo.
,include -stdio.h. ,include -stdli'.h. ,include -string.h. int m"in() 1 H]bE *p7 ch"r c5 str[/9 5 fr"se[T9 < 3Este e um "r#uivo ch"m"do) 37 int i7 printf(3>n>n Entre com um nome p"r" o "r#uivo)>n3)7 gets(str)7 /* be um nome p"r" o "r#uivo " ser "'erto) */ if (6(p < fopen(str53Z3))) /* E"so ocorr" "lgum erro n" "'ertur" do "r#uivo..*/ 1 printf(3Erro6 ]mpossivel "'rir o "r#uivo6>n3)7 exit(+)7 /* o progr"m" "'ort" "utom"tic"mente */ ; strc"t(fr"se5 str)7 for (i<97 fr"se[i 7 iCC) putc(fr"se[i 5p)7 fclose(p)7 /* Se n"o houve erro5imprime no "r#uivo e o fech" ...*/ p < fopen(str53r3)7 /* P're nov"mente p"r" leitur" */ c < getc(p)7 /* be o primeiro c"r"cter */ Zhile (6feof(p)) /* En#u"nto nLo se cheg"r no fin"l do
#utras 8un>$es
Bun>o E:plica>o
8error e perror
Prot2tipo de "error:
int ferror (H]bE *fp)7
* "uno retorna 'ero, se nen$um erro o orreu e um nMmero di"erente de 'ero se algum erro o orreu durante o a esso ao arquivo. se torna muito Mtil quando queremos veri"i ar se ada a esso a um arquivo teve su esso, de modo que onsigamos garantir a integridade dos nossos dados. 8a maioria dos asos, se um arquivo pode ser aberto, ele pode ser lido ou gravado. Por<m, e@istem situa+es em que isto no o orre. Por e@emplo, pode a abar o espao em dis o enquanto gravamos, ou o dis o pode estar om problemas e no onseguimos ler, et . Bma "uno que pode ser usada em on.unto om "errorIJ < a "uno perrorIJ Iprint errorJ, u.o argumento < uma string que normalmente indi a em que parte do programa o problema o orreu.
,include -stdio.h. ,include -stdli'.h. int m"in() 1 H]bE *pf7 ch"r string[+99 7 if((pf < fopen(3"r#uivo.txt353Z3)) <<Igbb) 1 printf(3>nI"o consigo "'rir o "r#uivo 6 3)7 exit(+)7 ; do 1 printf(3>n?igite um" nov" string. P"r" termin"r5 digite -enter.) 3)7 gets(string)7 fputs(string5 pf)7 putc(M>nM5 pf)7 if(ferror(pf)) 1 perror(3Erro n" gr"v"c"o3)7 fclose(pf)7 exit(+)7 ; ;Zhile (strlen(string) . 9)7 fclose(pf)7 ;
E:ercCcios Binais
Programar em CA>@er H ios -inais
Vetores
Vetores
Vetores, tamb<m $amados arrays Ido ingl!sJ ou arran.o ou ainda matri<es, so uma maneira de arma'enar v#rios dados num mesmo nome de vari#vel atrav<s do uso de Hndi es num<ri os. >m C, vetores devem sempre onter dados do mesmo tipo de vari#vel. ,e laramos vetores de maneira muito semel$ante F de larao de vari#veis normais. * Mni a di"erena < que depois do nome da vari#vel deve ser in"ormada a quantidade de elementos do vetor. Para de larar um vetor $amado $etor, om in o elementos inteiros, es revemos:
int vetor[2 7
8ote que a quantidade de elementos de um vetor no pode ser alterada depois que o vetor "or de larado. Para riar vetores de taman$o dinNmi o, podemos usar ponteiros, que sero abordados mais adiante. ,a mesma maneira que podemos ini iali'ar uma vari#vel .unto om sua de larao, podemos usar as $aves I1;J para ini iali'ar um arraR.
int vetor[2 < 1+:5 0%5 D5 //5 +%;7
Para "a'er re"er!n ia a um valor de um elemento ontido em um vetor, usamos a notao vetor[^ndice , que serve tanto para obter quanto para de"inir o valor de um elemento espe H"i o, dada sua posio. 8ote que os elementos so numerados a omear do 'ero, e, portanto, se o nMmero de elementos < , o Hndi e ou posio do Mltimo elemento ser# .
6epare em que a Mltima lin$a ont<m um erro: ela re"eren ia um elemento do vetor que no e@iste. 8o entanto, o ompilador no se re usar# a ompilar esse 2digoZ dar# apenas um aviso. Se essa lin$a "or e@e utada, a vari#vel 9 re eber# um valor que no tem nada a ver om o vetor.
%,reviando as declara>$es
*o ini iali'ar um vetor om v#rios valores, pode ser trabal$oso ontar todos os valores para olo ar o taman$o do vetor na de larao. Por isso, em C podemos omitir o nMmero de elementos quando os valores so ini iali'adosZ o taman$o do vetor ser# o nMmero de valores ini iali'ados. Por e@emplo, as duas nota+es abai@o so equivalentes:
int v"lores[2 < 1+5 %5 /5 05 2;7 int v"lores[ < 1+5 %5 /5 05 2;7
Zhile (i - 2) /*Este l"co comp"r" c"d" elemento do vetor*/ 1 if (vetor[i . x) 1 x < vetor[i 7 ; iCC7 ; printf(3>n O m"ior numero #ue voce digitou foi @d .>n35x)7 getch ()7 return 97 ;
*teno que: qndi e mais F direita varia mais rapidamente que o Hndi e F esquerda. 8o esque er os Hndi es variam de 'ero ao valor de larado menos um. Podemos ter ainda on.unto de vari#veis multidimensionais.
tipo!d"!v"ri4vel nome!d"!v"ri4vel [t"m+ [t"m% ... [t"mI 7
Podemos, em alguns asos, ini iali'ar matri'es das quais no sabemos o taman$o a priori. O ompilador C vai, neste aso veri"i ar o taman$o do que vo ! de larou e onsiderar omo sendo o taman$o da matri'. Isto o orre na $ora da ompilao e no poder# mais ser mudado durante o programa
'trings
Esta pgina um esboo de informtica !mp"iando#a $oc% a&udar a me"horar o 'i(i"i$ros
'trings
'trings IIngl!sJ so adeias ou seqU!n ias ordenadas de ara teres. 8a verdade .# trabal$amos om strings neste livro, mas pre"erimos dei@ar maiores e@pli a+es para um momento em que .# tivesse sido introdu'ido o on eito de vetor. * linguagem C, ao ontr#rio de outras linguagens de programao, no possui um tipo de dados orrespondente Fs stringsZ no lugar, usam=se vetores Ie ponteiros, omo veremos mais adianteJ. >m C, strings so vetores de ara teres terminados pelo ara tere nulo IM>9MJ. Por e@emplo:
ch"r nome[ < 1MPM5 MeM5 MdM5 MrM5 MoM5 M>9M;7
8o entanto, es rever strings dessa maneira < muito trabal$osoZ por isso, "oi riada uma notao abreviada que equivale F notao a ima e elimina a ne essidade de olo ar o ara tere terminador:
ch"r nome[ < 3Pedro37
*ssim omo nos vetores, podemos a essar e modi"i ar elementos individuais de uma string. Podemos tamb<m diminuir o taman$o de uma string: uma ve' que a Mni a mar ao do taman$o < o terminador > 9, olo ar um terminador em outro lo al determinar# o novo "inal da string. 8o entanto, aumentar o taman$o da string < mais di"H ilZ isso "i ar# para outra seo. *teno ao usar=se acentos numa string. Como e@istem di"erentes "ormas de odi"i ar ara teres a entuados, o tratamento de uma string do tipo:
ch"r nome[ < 3SoLo37
pode ser di"erente de uma m#quina para outra. 8este apHtulo no sero tratados a entos, este assunto ser# abordado mais adiante.
strlen
strlen retorna o taman$o, em ara teres, de uma string dada. 8a verdade o strlenIJ pro ura o terminador de string e al ula a distNn ia dele ao inH io da string. Por e@emplo:
ch"r nome[+2 < 3J"ri" d" Silv"37 int s < strlen (nome)7 // s conter4 o v"lor +0
Aj(3)jA
strcpO
strcp. opia o onteMdo de uma string para outra e olo a um terminador de string. Sua sinta@e < strcpY (destino5 origem).
ch"r nome[ ch"r nome%[ < 3El"rice bispector37 < 3OsZ"ld de Pndr"de37
(ome uidado om str pRIJ, pois se a string a ser opiada "or maior que a string de destino, provavelmente vo ! gravar# dados em lugares indese.ados X um problema on$e ido omo estouro de ,u88er. Para evitar esse problema, use a "uno strncp., que re ebe um ter eiro argumento que orresponde ao nMmero m#@imo de ara teres a serem opiados:
ch"r msg[ < 3Uom di"637 ch"r nome[ < 3J"ri" d" Silv"37 strncpY (msg5 nome5 strlen(msg))7 // "gor" msg conter4 3J"ri" d"3
strcat
strcat on atena duas strings, adi ionando o onteMdo da segunda ao "inal da primeira, al<m do terminador I>9J. 8ote que a primeira string deve ter espao su"i iente para onter a segunda, para que no o orra um %estouro de bu""er%. Por e@emplo:
ch"r nome[29 < 3J"ri"37 ch"r so'renome[ < 3 d" Silv"37 strc"t (nome5 so'renome)7 // "gor" nome contGm 3J"ri" d" Silv"3
*nalogamente F "uno strncpY, e@iste tamb<m a "uno strncat, onde o nMmero m#@imo de ara teres a serem opiados < o ter eiro argumento.
strcmp
Se vo ! tentar riar duas strings om o mesmo onteMdo e ompar#=las omo "aria omo nMmeros, ver# que elas %no so iguais%. Isso o orre porque, na verdade, o que est# sendo omparado so os endereos de mem3ria onde esto guardadas as strings. Para omparar o conte:do de duas strings, vo ! deve usar a "uno strcmp Iou suas variantesJ: int strcmp I $ar js4, $ar js;JZ O valor de retorno <: menor que 'ero se s4 "or menor que s;Z igual a 'ero se s4 e s; so iguaisZ maior que 'ero se s4 "or maior que s;. Costuma pare er estran$o di'er que uma string < menor ou maior que outraZ na verdade essa omparao < entre a primeira letra que di"ere nas duas strings. *ssim, se tivermos s+ < 3"'c3 e s% < 3"'d3, diremos que s; < maior que s4, pois na primeira posio em que as duas strings di"erem, a letra em s; < %maior%. ] importante notar que a omparao "eita por strcmp distingue maiMs ulas de minMs ulas. Isto <, as strings %*LC% e %ab % no so iguais para essa "uno. *s variantes mais usadas de strcmp so: strncmp = ompara apenas os n primeiros ara teres das duas strings, sendo n um ter eiro argumento. stricmp = ompara duas strings sem distino entre maiMs ulas e minMs ulas. * sinta@e < igual F de strcmp. >ssa "uno no "a' parte da bibliote a padro, mas < omumente en ontrada omo e@tenso parti ular de v#rias delas.
strrc9r
strrchr 6etorna um ponteiro sobre a ultima o orr!n ia de de uma string apontada por s se no retorna 8B33 . Sua sinta@e < strrchr(const ch"r *s5 int c)7. >@emplo:
ch"r p"th[29 < 3/teste/string37 ch"r *p < strrchr(p"th5 M/M)7
memcpO
Sinta@e:
,include -string.h. void *memcpY (void *dest5 const void *srce5 siWe!t n)7
,es rio: Copiar um blo o de n o tetos de sr e para dest. *teno:Se as regi+es de sr e e dest se sobreporem o omportamento da "uno < imprevisHvel. &alor de retorno : mem pR retorna o valor de dest . >@:
,include -stdio.h. ,include -string.h. int m"in() 1 int t"'[% [2 < 1 1 +5 %5 /5 05 25 1++5 +%5 +/5 +05 +2; ;7 int temp[% [2 7 memcpY(temp5 t"'5 siWeof(t"'))7 puts(3cesult"do)>n3)7 printf(3temp[+ [0 < @d>n35 temp[+ [0 )7 return 97 ;
memset
Sinta@e:
,include -string.h. void *memset (void *'uffer5 int c5 siWe!t n)7
,es rio: memset ini iali'a n o tetos do bu""er om o inteiro . &alor de retorno : O valor do bu""er. >@:
,include -stdio.h. ,include -string.h. int m"in() 1 ch"r 'uf[ < 3&.].h.].37
printf(3Uuf "ntes MmemsetM) @s>n35 'uf)7 memset('uf5 M*M5 strlen('uf))7 printf(3Uuf depois MmemsetM) @s>n35 'uf)7 return 97
sprint8
,es rio: * di"erena entre print" e sprint" e que print" retorna o resultado para a saHda padro ItelaJ, enquanto sprint" retorna o resultado em uma vari#vel. Isto < muito onveniente, porque vo ! pode simplesmente digitar a "rase que vo ! quer ter e sprint" lida om a pr2pria onverso e olo a o resultado na string que vo ! dese.a. Sinta@e:
,include -stdio.h. int sprintf(ch"r *s5 const ch"r *form"to5 ...)7
>@:
,include -stdio.h. ,include -string.h. int m"in() 1 ch"r v"r[%28 7 ch"r so'renome[ < 3Simpson37 ch"r nome[ < 3Vomer37 int id"de < /97 sprintf(v"r5 3@s @s tem @d "nos35so'renome5 nome5 id"de)7 printf (3cesult"do ) @s>n35 v"r)7 return 97 ;
Ponteiros
PoderHamos es rever um livro inteiro sobre ponteiros, pois o onteMdo < demasiadamente e@tenso. Por esse motivo este assunto "oi dividido em ,?sico, intermedi?rio e avan>ado, assim o leitor poder# "a'er seus estudos on"orme suas ne essidades. ] re omend#vel para quem est# vendo programao pela primeira ve' aqui que no se preo upe om o avanado sobre ponteiros por enquanto.
6?sico
# que um ponteiroP
Bm ponteiro < simplesmente uma vari#vel que arma'ena o endereo de outra vari#vel. Bm e@emplo : O que < o ponteiro de um rel2gioS ] o que aponta para as $oras, minutos ou segundos. Bm ponteiro aponta para algo. >m programao, temos as vari#veis arma'enadas na mem2ria, e um ponteiro aponta para um endereo de mem2ria.
*magine as $ari$eis como documentos< a mem3ria do computador como pastas para guardar os documentos< e o ponteiro como ata"hos para as pastas. 8o se desespere aso no onsiga entender num primeiro momento, o on eito "i a mais laro om a pr#ti a.
(ome uidado ao de larar v#rios ponteiros em uma lin$a, pois o asteris o deve vir antes de cada nome de vari?vel. 8ote os tr!s e@emplos:
int p5 #5 r7 // est"mos " decl"r"r trRs v"ri4veis comuns int *p5 #5 r7 // cuid"do6 "pen"s p ser4 um ponteiro6 int *p5 *#5 *r7 // "gor" sim temos trRs ponteiros
>squema de um ponteiro Para a essar o endereo de uma vari#vel, utili'amos o operador & I> omer ialJ, $amado %operador de re"er!n ia% ou %operador de endereo%. Como o nome sugere, ele retorna o endereo na mem2ria de seu operando. >le < unrio e deve ser es rito antes do seu operando. Por e@emplo, se uma vari#vel nome "oi guardada no endereo de mem2ria /KKK, a e@presso Anome valer# /KKK. Com isso, "i a laro o esquema ao lado: a vari#vel a ont<m o valor /079 e o ponteiro p ontem o endereo de a IA"J. Para atribuir um valor ao ponteiro, usamos apenas seu nome de vari#vel. >sse valor deve ser um endereo de mem2ria, portanto obtido om o operador A:
int "7 int *p7 p < A"7
8os dois asos, o ponteiro p ir# apontar para a vari#vel a. Qas, omo o ponteiro ont<m um endereo, podemos tamb<m atribuir um valor F vari#vel guardada nesse endereo, ou se.a, A vari?vel apontada pelo ponteiro. Para isso, usamos o operador / Iasteris oJ, que basi amente signi"i a %o valor apontado por%. >@:
CuidadoQ &o ! nunca deve usar um ponteiro sem antes ini iali'#=loZ esse < um erro omum. Ini ialmente, um ponteiro pode apontar para qualquer lugar da mem2ria do omputador. Ou se.a, ao tentar ler ou gravar o valor apontado por ele, vo ! estar# manipulando um lugar des on$e ido na mem2ria^
int *p7
*p < D7
8esse e@emplo, estamos a manipular um lugar des on$e ido da mem2ria^ Se vo ! tentar ompilar esse 2digo, o ompilador dever# dar uma mensagem de avisoZ durante a e@e uo, provavelmente o orrer# uma "al$a de segmentao Ierro que o orre quando um programa tenta a essar a mem2ria al$eiaJ. Bm e@emplo mais elaborado:
,include -stdio.h. int m"in() 1 int i < +9 7 int *p 7 p < Ai 7 *p < 2 7 printf (3@d>t@d>t@p>n35 i5 *p5 p)7 return 97
Primeiramente de laramos a vari#vel i, om valor /K, e o ponteiro p, que apontar# para o endereo de i. ,epois, guardamos o valor ; no endereo apontado por p. Se vo ! e@e utar esse e@emplo, ver# algo pare ido om:
2 2 99%%HH:0
] laro que os valores de i e de *p sero iguais, .# que p aponta para i. O ter eiro valor < o endereo de mem2ria onde est# i Ie, onsequentemente, < o pr2prio valor de pJ, e ser# di"erente em ada sistema. CuidadoQ Os operadores un#rios A e * no podem ser on"undidos om os operadores bin#rios %&D bit a bit e multiplica>o, respe tivamente.
Ponteiro e &;LL
Bma "al$a de segmentao ou em ingl!s Isegmentation "aultJ o orre quando um programa tenta a essar um endereo na mem2ria que est# reservado ou que no e@iste.8os sistemas Bni@ quando a onte e este tipo de erro o sinal SIPS>P& < enviado ao programa indi ando uma "al$a de segmentao. *qui o ponteiro ontem null, de"inido om o endereo IK@KKKKKKKKJ que ausa uma "al$a de segmentao .
/*EndereKo inv"lido*/ ,define null ( (ch"r*) 9 ) int m"in(void)1 int " < 27 int *p < null7 *p < "7 ;
>sse programa termina anormalmente. &o ! esta tentando olo ar o valor ; em um endereo inv#lido. Para que isso no a ontea o ponteiro deve ser ini iali'ado om um endereo valido. >@emplo :
,include -stdio.h. ,include -errno.h. ,include -stddef.h. int m"in(void)1 int " < 27 int *p < Igbb7 p < A"7 /* P oper"KLo nLo G permitid" */ if(p << Igbb) return $EPEcJ 7 else1 printf(3EndereKo " disposiKLo)@p>n35 p )7 *p < "7 /* Pode coloc"r 2 */ ; ;
8B33 est# de"inido dentro do abeal$o stdde".$ . *qui vo ! no espera que o programa a abe om algum tipo de m#gi a, se 8B33 < igual ao valor do ponteiro isso signi"i a que no "oi en ontrado nem um endereo a essHvel, ento vo ! para. Caso ontrario vo ! estar# e@e utando uma operao que no < permitida. Ou olo ar ; em IK@KKKKKKKKJ .
>sse primeiro e@emplo "ar# om que p4 aponte para o mesmo lugar que p;. Ou se.a, usar p4 ser# equivalente a usar p; ap2s essa atribuio.
*p+ < *p%7
8esse segundo aso, estamos a igualar os valores apontados pelos dois ponteiros: alteraremos o valor apontado por p4 para o valor apontado por p;. *gora vamos dar mais alguns e@emplos om o ponteiro p:
pCC7
*qui estamos a in rementar o ponteiro. \uando in rementamos um ponteiro ele passa a apontar para o pr:imo valor do mesmo tipo em relao ao valor para o qual o ponteiro aponta. Isto <, se temos um ponteiro para um inteiro e o in rementamos, ele passa a apontar para o pr2@imo inteiro. &ote que o incremento no ocorre ,Ote+a+,OteQ
(*p)CC7
*qui, olo amos *p entre par!nteses para espe i"i ar que queremos alterar o valor apontado por p. Ou se.a, aqui iremos in rementar o onteMdo da vari#vel apontada pelo ponteiro p.
*pCC
8este aso, o e"eito no < to laro quanto nos outros e@emplos. * preced%ncia do operador CC sobre o operador * "a' om que a e@presso se.a equivalente a (*p)CC. O valor atual de p < retornado ao operador *, e o valor de p < in rementado. Ou se.a, obtemos o valor atual do ponteiro e .# o "a'emos apontar para o pr2@imo valor.
x < *(p C +2)7
>sta lin$a atribui a uma vari#vel . o onteMdo do d< imo=quinto inteiro adiante daquele apontado por p. Por e@emplo, supon$amos que tiv<ssemos uma s<rie de vari#veis i=, i4, i;, r i4> e que p apontasse para i=. 8ossa vari#vel . re eberia o valor de i4>. (ente a ompan$ar este e@emplo dos dois tipos de atribuio de ponteiros:
int *"5 *'5 c < 05 d < %7 " < Ac7 // a "pont"r4 p"r" c ' < Ad7 // "pont"r4 p"r" d *' < T7 // "ltero o v"lor existente n" v"ri"vel d *" < *'7 // copio o v"lor de d ("pont"do por ) // p"r" c ("pont"do por a) *" < +7 // "ltero o v"lor d" v"ri4vel c ' < "7 // "pont" p"r" o mesmo lug"r #ue a5 // ou se*"5 p"r" c *' < 97 // "ltero o v"lor de c
Intermedi?rio
Ponteiro de estrutura
Para omear e dei@ar mais laro de"inimos uma estrutura simples om dois ampos.
struct 1 int i7 dou'le f7 ; minh"!estrutur"7
* partir do ponteiro podemos ter a esso a um ampo da estrutura usando um seletor %=p% Iuma "le $aJ.
p!minh"!estrutur"$. i < +7 p!minh"!estrutur"$. f < +.%7
O operador ast tamb<m e bastante utili'ado para estruturar #reas de estoque tempor#rios Ibu""erJ. Os tipos dentro da estrutura devem ser o mesmo do arran.o para evitar problemas de alin$amento. * seguir um pequeno e@emplo:
,include -stdio.h. tYpedef struct estrutur"r1 ch"r " 7 ch"r ' 7 ;7 int m"in() 1 ch"r 'uffer[% < 1+:5 0;7 estrutur"r *p7 p < (struct estrutur"r*) A'uffer7 printf(3") @i ') @i35 p$."5p$.')7 getch"r()7 return 97 ;
>sse e@emplo "un ionar# e@atamente omo esperado: primeiramente ele imprimir# %; /K% e depois ele imprimir# %/K ;%. Qas e se quisermos tro ar v#rias ve'es o valor de duas vari#veisS ] muito mais onveniente riar uma "uno que "aa isso. &amos "a'er uma tentativa de implementao da "uno
8o entanto, o que queremos no ir# a onte er. &o ! ver# que o programa imprime duas ve'es %; /K%. Por que isso a onte eS 3embre=se do es opo das vari#veis: as vari#veis a e b so lo ais F "uno mainIJ, e quando as passamos omo argumentos para s?apIJ, seus valores so opiados e passam a ser $amados de i e &Z a tro a o orre entre i e &, de modo que quando voltamos F "uno mainIJ nada mudou. >nto omo poderHamos "a'er issoS Como so retornados dois valores, no podemos usar o valor de retorno de uma "uno. Qas e@iste uma alternativa: os ponteiros^
,include -stdio.h. void sZ"p (int *i5 int **) 1 int temp7 temp < *i7 *i < **7 ** < temp7 ; int m"in () 1 int "5 '7 " < 27 ' < +97 printf (3>n>nEles v"lem @d5 @d>n35 "5 ')7 sZ"p (A"5 A')7 printf (3>n>nEles "gor" v"lem @d5 @d>n35 "5 ')7 return 97 ;
8este e@emplo, de"inimos a "uno s?apIJ omo uma "uno que toma omo argumentos dois ponteiros para inteirosZ a "uno "a' a tro a entre os $a"ores apontados pe"os ponteiros. W# na "uno mainIJ, passamos os endereos das $ari$eis para a "uno s?apIJ, de modo que a "uno s?apIJ possa modi"i ar vari#veis lo ais de outra "uno. O Mni o possHvel in onveniente < que, quando usarmos a "uno, teremos de lembrar de olo ar um A na "rente das vari#veis que estivermos passando para a "uno. Se vo ! pensar bem, .# vimos uma "uno em que passamos os argumentos pre edidos de A: < a "uno scanf?@^ Por que "a'emos issoS ] simples: $amamos a "uno s an"IJ para que ela pon$a nas nossas vari#veis valores digitados pelo usu#rio. Ora, essas vari#veis so lo ais, e portanto s2 podem ser alteradas
por outras "un+es atrav<s de ponteiros^ \uando uma "uno re ebe omo parNmetros os endereos e no os valores das vari#veis, di'emos que estamos a "a'er uma c9amada por re8er/nciaZ < o aso desse Mltimo e@emplo. \uando passamos diretamente os valores das vari#veis para uma "uno, di'emos que < uma c9amada por valorZ "oi o aso do segundo e@emplo.
Ponteiros e vetores
>m C, os elementos de um vetor so sempre guardados sequen ialmente, a uma distNn ia "i@a um do outro. Com isso, < possHvel "a ilmente passar de um elemento a outro, per orrendo sempre uma mesma distNn ia para "rente ou para tr#s na mem2ria. ,essa maneira, podemos usar ponteiros e a aritm<ti a de ponteiros para per orrer vetores. 8a verdade, vetores s-o ponteiros X um uso parti ular dos ponteiros. * ompan$e o e@emplo a seguir.
,include -stdio.h. int m"in () 1 int i7 int vetorOeste[/ < 105 :5 +;7 int *ptr < vetorOeste7 printf(3@p>n35 vetorOeste)7 printf(3@p>n35 ptr)7 printf(3@p>n35 Aptr)7 for (i < 97 i - /7 iCC) 1 printf(3O endereKo do ^ndice @d do vetor G @p>n35 i5 Aptr[i )7 printf(3O v"lor do ^ndice @d do vetor G @d>n35 i5 ptr[i )7 ; return 97
Comeamos de larando um vetor om tr!s elementosZ depois, riamos um ponteiro para esse vetor. Qas repare que no colocamos o operador de endere>o em vetor(esteZ "a'emos isso porque um vetor .# representa um endereo, omo vo ! pode veri"i ar pelo resultado da primeira $amada a print"IJ. Como vo ! .# viu anteriormente neste apHtulo, podemos usar a sinta@e *(ptr C +) para a essar o inteiro seguinte ao apontado pelo ponteiro ptr. Qas, se o ponteiro aponta para o vetor, o pr2@imo inteiro na mem2ria ser# o pr2@imo elemento do vetor^ ,e "ato, em C as duas "ormas *(ptr C n) e ptr[n so equivalentes. 8o < ne ess#rio riar um ponteiro para usar essa sinta@eZ omo .# vimos, o vetor em si .# < um ponteiro, de modo que qualquer operao om ptr ser# "eita igualmente om $etorTeste. (odas as "ormas abai@o de a essar o segundo elemento do vetor so equivalentes:
vetorOeste[+ 7 *(vetorOeste C +)7 ptr[+ 7 *(ptr C +)
int m"in() 1 int num'ers[2 7 int *p7 int n7 p < num'ers7 *p < +97 pCC7 *p < %97 p < Anum'ers[% 7 *p < /97 p < num'ers C /7 *p < 097 p < num'ers7 *(p C 0) < 297 for (n < 97 n - 27 nCC) cout -- num'ers[n -- 35 37 return 97 ;
>ssa inde@ao, apesar de estran$a, "un iona orretamente e sem aviso na ompilao. >la < pr#ti a, mas, para os ini iantes, pode pare er ompli ada. ] s2 treinar para entender.
Comparando endere>os
Como os endereos so nMmeros, eles tamb<m podem ser omparados entre si. &e.a o e@emplo a seguir, om e"eito equivalente ao primeiro e@emplo da seo anterior:
,include -stdio.h. int m"in() 1 int vetorOeste[/ < 105 :5 +;7 int *ptr < vetorOeste7
int i < 97 Zhile (ptr -< AvetorOeste[% ) 1 printf(3O endereKo do ^ndice @d do vetor G @p>n35 i5 ptr)7 printf(3O v"lor do ^ndice @d do vetor G @d>n35 i5 *ptr)7 ptrCC7 iCC7 ; return 97 ;
>sse programa in rementa o ponteiro enquanto esse endereo "or igual Iou menorJ ao endereo do Mltimo elemento do vetor Ilembre=se que os Hndi es do vetor so K, / e 0J.
%van>ado
>ste m2dulo pre isa ser revisado por algu<m que on$ea o assunto Idis utaJ.
Este m3du"o tem a seguinte tarefa pendente: mover o que < de CCC para o livro de CCC
,include -stdli'.h. ,include-stdio.h. int int int int int v]nt < +97 *p]nt < Av]nt7 **p]nt% < Ap]nt7 ***p]nt/ < Ap]nt%7 x<97
int m"in(void)1 printf(3C$$$$$$$$$$$$$$$$$C>n3)7 printf(3[ v]nt [>n3)7 printf(3C$$$$$$$$$$$$$$$$$C>n3)7 printf(3[@+:d[>n35v]nt)7 printf(3[@+:p[-$C>n35Av]nt)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7 printf(3[ p]nt [ [>n3)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7 printf(3[@+:p[$$C>n35p]nt)7 printf(3[@+:p[-$C>n35Ap]nt)7 printf(3[@+:d[ [>n35*p]nt)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7 printf(3[ p]nt% [ [>n3)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7
printf(3[@+:p[$$C>n35p]nt%)7 printf(3[@+:p[-$C>n35Ap]nt%)7 printf(3[@+:d[ [>n35**p]nt%)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7 printf(3[ p]nt/ [ [>n3)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7 printf(3[@+:p[$$C>n35p]nt/)7 printf(3[@+:p[>n35Ap]nt/)7 printf(3[@+:d[>n35***p]nt/)7 printf(3C$$$$$$$$$$$$$$$$$C>n3)7 ***p]nt/ < :87 printf(3C$$$$$$$$$$$$$$$$$C>n3)7 printf(3[ v]nt [>n3)7 printf(3C$$$$$$$$$$$$$$$$$C>n3)7 printf(3[@+:d[>n35v]nt)7 printf(3[@+:p[-$C>n35Av]nt)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7 printf(3[ p]nt [ [>n3)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7 printf(3[@+:p[$$C>n35p]nt)7 printf(3[@+:p[-$C>n35Ap]nt)7 printf(3[@+:d[ [>n35*p]nt)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7 printf(3[ p]nt% [ [>n3)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7 printf(3[@+:p[$$C>n35p]nt%)7 printf(3[@+:p[-$C>n35Ap]nt%)7 printf(3[@+:d[ [>n35**p]nt%)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7 printf(3[ p]nt/ [ [>n3)7 printf(3C$$$$$$$$$$$$$$$$$C [>n3)7 printf(3[@+:p[$$C>n35p]nt/)7 printf(3[@+:p[>n35Ap]nt/)7 printf(3[@+:d[>n35***p]nt/)7 printf(3C$$$$$$$$$$$$$$$$$C>n3)7 //G import"nte ress"lt"r #ue o v"lor de v]nt foi modific"do pois " indireKLo m=ltipl" " modoficou. printf(3C$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ C3)7 printf(3[ PcO`cPJP HE]OO POc ) ?PI]Eb EPJPOS ?]I]N $ diniWdcigm"il.com [>n3)7 printf(3C$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ C3)7 return 97 ;
Per eba que temos dois %nHveis%: c aponta para b, e b aponta para a. *ssim, para a essar a usando o ponteiro c, < ne ess#rio usar duas ve'es o operador *: uma para obter o valor de b I u.o endereo est# guardado em cJ, e a outra para obter o valor de a, apontado por b. Bma apli ao de ponteiros para ponteiros est# nas strings, .# que strings so vetores, que por sua ve' so ponteiros. Bm vetor de strings seria .ustamente um ponteiro para um ponteiro.
Este m3du"o tem a seguinte tarefa pendente: Criar 2digo e@emplo sobre ponteiro para ponteiro
6epare que passamos dois parNmetros para as "un+es: /. O %nome% do vetor, que representa o seu endereo na mem2ria. I(emos 7 maneiras para passar o endereo do vetor: diretamente pelo seu %nome%, via um ponteiro ou pelo endereo do primeiro elemento.J 0. Bma onstante, que representa o nMmero de elementos do vetor. Isso < importante pois o C no guarda in"orma+es sobre o taman$o dos vetoresZ vo ! no deve tentar alterar ou a essar valores que no perten em ao vetor. ] laro que devemos passar o endereo do vetor Ipor %re"er!n ia%J, pois os seus valores so alterados pela "uno atribui&alores. ,e nada adiantaria passar o vetor por valor, pois o valor s2 seria alterado lo almente na "uno I omo .# vimos no aso de tro a do valor de duas vari#veisJ. Por ausa dessa equival!n ia entre vetores e ponteiros, podemos "a'er uma pequena alterao no prot2tipo Itanto na de larao quanto na de"inioJ das "un+es atribui&alores e mostra&alores, sem pre isar alterar o 2digo interno dessas "un+es ou a $amada a elas dentro da "uno main S tro ando
void "tri'uiX"lores(int[ 5 int)7 void mostr"X"lores(int[ 5 int)7
por
Para o ompilador, vo ! no "e' mudana alguma, .ustamente por onta dessa equival!n ia. >m ambos os asos, "oi passado o endereo do vetor para as "un+es.
&e.a que riamos uma "uno que retorna a soma dos dois inteiros a ela "orne idosZ no entanto, ela no < $amada diretamente. >la < $amada pela "uno operacao, atrav<s de um ponteiro. * "uno main passa a "uno soma omo argumento para operacao, e a "uno operacao $ama essa "uno que l$e "oi dada omo argumento. 8ote bem o ter eiro argumento da "uno operacao: ele < um ponteiro para uma 8un>o. 8esse aso, ele "oi de larado omo um ponteiro para uma "uno que toma dois inteiros omo argumentos e retorna outro inteiro. O * indi a que estamos de larando um ponteiro, e no uma "uno. #s par/nteses em torno de /func so essenciais, pois sem eles o ompilador entenderia o argumento omo uma fun-o 8ue retorna um ponteiro para um inteiro. * "orma geral para de larar um ponteiro para uma "uno <:
tipo+retorno (*nome0do0ponteiro)(lista0de0argumentos)
Para $amar a "uno apontada pelo ponteiro, $# duas sinta@es. * sinta@e original <
(*nome0do0ponteiro)(argumentos)7
Se ptr < um ponteiro para uma "uno, "a' bastante sentido que a "uno em si se.a $amada por *ptr. 8o entanto, a sinta@e mais moderna permite que ponteiros para "un+es se.am $amados e@atamente da mesma maneira que "un+es:
nome0do0ponteiro(argumentos)7
Por "im, para ini iali'ar um ponteiro para "uno, no pre isamos usar o operador de endereo Iele .# est# implH itoJ. Por isso, quando $amamos a "uno operacao, no pre isamos es rever Asom". &e.a mais um e@emplo _ na verdade, uma e@tenso do e@emplo anterior:
,include -stdio.h. int som"(int "5 int ') 1 return ("C')7 ; int su'tr"c"o(int "5 int ') 1 return ("$')7 ; int (*menos)(int5 int) < su'tr"c"o7 int oper"c"o(int x5 int Y5 int (*func)(int5int)) 1 int g7 g < func(x5 Y)7 return (g)7 ; int m"in() 1 int m5 n7 m < oper"c"o(:5 25 som")7 n < oper"c"o(%95 m5 menos)7 printf(3@d>n35 n)7 return 97 ;
*qui, riamos mais uma "uno, subtracao, al<m de riar um outro ponteiro para ela Iuma esp< ie de %atal$o%J, menos. 8a "uno main, re"erimo=nos F "uno de subtrao atrav<s desse atal$o. &e.a tamb<m que aqui usamos a sinta@e moderna para a $amada de ponteiros de "un+es, ao ontr#rio do e@emplo anterior.
Passagem de Parametros
Programar em CAPassagem de Parametros
estruturas IstructJZ uni+es IunionJZ enumera+es IenumJ. *s estruturas e uni+es so ompostas por v#rias vari#veis Ies ol$idas pelo programadorJ, por isso so ditos definidos pe"o usurio. W# as enumera+es so, resumidamente, tipos u.os valores devem perten er a um on.unto de"inido pelo programador.
Estruturas
Bma estrutura Iou structJ < um tipo de dados resultante do agrupamento de v#rias vari#veis nomeadas, no ne essariamente similares, numa s2Z essas vari#veis so $amadas membros da estrutura. Para de larar uma estrutura, usamos a palavra= $ave struct, seguida do nome que se dese.a dar F estrutura Iao tipo de dadosJ e de um blo o ontendo as de lara+es dos membros. &e.a um e@emplo:
struct mYstruct 1 int "5 '5 c7 dou'le d5 e5 f7 ch"r string[%2 7 ;7
>ste e@emplo ria um tipo de dados denominado m9struct, ontendo sete membros Ia, b, c, d, e, f, stringJ. 8ote que o nome m9struct < o nome do tipo de dados, no de uma vari#vel desse tipo. Bm e@emplo simples de apli ao de estruturas seria uma "i $a pessoal que ten$a nome, tele"one e endereoZ a "i $a seria uma estrutura. Ou, mais amplamente, uma estrutura seria uma representao de qualquer tipo de dado de"inido por mais de uma vari#vel. Por e@emplo, o tipo H]bE* < na verdade um ponteiro para uma estrutura que ont<m alguns dados que o sistema usa para ontrolar o a esso ao "lu@oAarquivo. 8o < ne ess#rio, para a maioria dos programadores, on$e er a estrutura do tipo -I3>.
De8inindo o tipo
* de"inio de um tipo de estrutura < "eita om a palavra= $ave struct, seguida do nome a ser dado ao tipo e de um blo o ontendo as de lara+es dos elementos da estrutura:
struct nome!do!tipo 1 tipo!elem "7 tipo!elem '5 c7 ... ;7
Declarando
Para de larar uma vari#vel de um tipo .# de"inido, "orne emos o nome do tipo, incluindo a palavra+ c9ave struct:
struct0nome+do+tipo variavel7
(amb<m < possHvel ondensar a de"inio do tipo e a de larao em um passo, substituindo o nome do tipo pela de"inio, sem o ponto=e=vHrgula:
struct mYstruct 1 int "5 '5 c7 dou'le d5 e5 f7 ch"r string[%2 7 ; v"ri"vel7
(amb<m < possHvel ini iali'ar uma estrutura usando as $aves 1; para envolver os elementos da estrutura, separados por vHrgulas. Os elementos devem estar na ordem em que "oram de larados, mas no < obrigat2rio ini iali'ar todosZ no entanto, para ini iali'ar um elemento, todos os anteriores devem ser ini iali'ados tamb<m. Por e@emplo, poderHamos de larar valores ini iais para a vari#vel a ima da seguinte maneira:
struct mYstruct v"ri"vel < 105 85 25 /.+05 %.:+T5 9.D25 3Oeste3;7 struct mYstruct v% < 1D5 25 :;7
Iniciali<ador designado
Para quem usa o C:: om o ompilador P8B. ,urante a ini iali'ao de um estrutura < possHvel espe i"i ar o nome do ampo om ).nomeddod ampo [) antes do valor. >@emplo:
struct mYstruct v% < 1."<D5.'<25.c<:;7
%cessando
Para a essar e modi"i ar os membros de uma estrutura, usamos o operador de seleo. IpontoJ. f esquerda do ponto deve estar o nome da vari#vel IestruturaJ e F direita, o nome do membro. Podemos usar os membros omo vari#veis normais, in lusive passando=os para "un+es omo argumentos:
v"ri"vel." < 27 v"ri"vel.f < 8.+:7 strcpY (v"ri"vel.string5 3Uom di"3)7 printf (3@d @f @s>n35 v"ri"vel."5 v"ri"vel.f5 v"ri"vel.string)7
Vetores de estruturas
Sendo as estruturas omo qualquer outro tipo de dados, podemos riar vetores de estruturas. Por e@emplo, supon$a algum programa que "un ione omo um servidor e permita at< /K usu#rios one tados simultaneamente. PoderHamos guardar as in"orma+es desses usu#rios num vetor de /K estruturas:
struct info!usu"rio 1 int id7 ch"r nome[%9 7 long endereco!ip7 time!t hor"!conex"o7 ;7 struct info!usu"rio usu"rios[+9 7
>, por e@emplo, para obter o $or#rio em que o 0s usu#rio usu#rio se one tou, poderHamos es rever usu"rios[+ .hor"!conex"o.
%tri,ui>o e cpia
Podemos "a ilmente opiar todos os ampos de uma estrutura para outra, "a'endo uma atribuio simples omo a de inteiros:
struct int int ;7 ... struct struct ' < "7 // "gor" o ponto b t"m'Gm tem coorden"d"s (%5 /) ponto 1 x7 Y7 ponto " < 1%5 /;7 ponto ' < 125 T;7
8o entanto, devemos ter uidado se a estrutura ontiver ampos ponteiros, pois, nesses asos, o que ser# opiado < o endereo de mem2ria Ie no o onteMdo daquele endereoJ. Por e@emplo, se tivermos uma estrutura que omporta um inteiro e uma string, uma 2pia sua onter# o mesmo inteiro e um ponteiro para a mesma string, o que signi"i a que altera+es na string da 2pia sero re"letidas tamb<m no original^
8o entanto, $# dois possHveis problemas nisso: *ltera+es nos membros da estrutura s2 tero e"eito dentro da "uno $amada, mas no na "uno que a $amou. Isso o orre pois a estrutura < passada por valor Ie no por re"er!n iaJ. \uando a estrutura ontiver muitos elementos, a passagem por valor tornar=se=# um pro esso de 2pia de muitos dados. Por isso, < de ostume passar estruturas por re"er!n ia I omo ponteirosJ, mesmo que a estrutura em questo se.a pequena.
;ni$es
;ni$es so pare idas om estruturas, mas $# uma di"erena "undamental: nas uni+es, todos os elementos
o upam o mesmo espao de mem2ria. Por isso, s2 < possHvel a essar um elemento por ve', .# que uma mudana em um elemento ausar# mudana em todos os outros. * de"inio e a de larao de uni+es < igual F das estruturas, tro ando a palavra struct por union. 1# prin ipalmente dois usos para as uni+es: economia de espa>o, .# que guardam=se v#rias vari#veis no mesmo espaoZ representa>o de uma in8orma>o de mais de uma maneira. Bm e@emplo disso so os endereos IP, que na bibliote a de so kets podem ser representados omo um grupo de 9 o tetos Ich"rJ ou omo um Mni o valor inteiro IintJ. Isso < "eito om uma unio pare ida om esta:
union ip!"ddress 1 int s!long7 ch"r s!'Yte[0 7 ;7
,essa maneira, o endereo pode ser "a ilmente representado de maneira $umanamente legHvel I om 9 o tetosJ, sem di"i ultar o pro essamento interno I om o valor inteiroJ.
Enumera>$es
Enumera>o IenumJ ou tipo enumerado < um tipo de dados que tem omo on.unto de valores possHveis um on.unto "inito de identi"i adores InomesJ determinados pelo programador. >m C, ada identi"i ador em uma enumerao orresponde a um inteiro. >numera+es so de"inidas de maneira similar Fs estruturas e uni+es, om algumas di"erenas. * palavra $ave usada < enum.
enum nome!enumer"KLo 1 ]?EIO]H]EP?Oc!+5 ]?EIO]H]EP?Oc!%5 ... ]?EIO]H]EP?Oc!n ;7
8ote as di"erenas: no $# ponto=e=vHrgula no "inal ou no meio das de lara+es Imas ainda $# no "inal do blo oJ, e no $# de larao de tipos. Com essa de larao, ao I,>8(I-IC*,O6d/ ser# atribuido o valor K, ao I,>8(I-IC*,O6d0 ser# atribuHdo o valor /, e assim por diante. Podemos tamb<m e@pli itar os valores que quisermos olo ando um sinal de igual e o valor dese.ado ap2s o identi"i ador. Caso no $a.a valor determinado para o primeiro identi"i ador, ele ser# 'ero. Para os demais identi"i adores, o padro < seguir a ordem dos nMmeros, a partir do valor do identi"i ador anterior. Podemos misturar identi"i adores de valor determinado om identi"i adores de valor implH ito, bastando seguir a regra a ima. Por e@emplo:
enum cores 1 XEcJEbVO5 PNgb < 25 XEc?E5 PJPcEbO5 JPccOJ < +9 ;7 /* /* /* /* /* " */ ! */ / */ ' */ " */
;so
,a mesma maneira que riamos uma vari#vel de um tipo struct ou union, podemos riar vari#veis de um tipo enumerado IenumJ:
enum cores cor!fundo7
Para atribuir valores a uma vari#vel enumerada, podemos usar omo valor tanto o identi"i ador quanto o valor orrespondente. Seriam equivalentes, portanto:
cor!fundo < XEc?E7 cor!fundo < 87
8a verdade, vari#veis enumeradas agem de maneira quase igual aos inteirosZ < possHvel, assim, atribuir valores que no orrespondem a nen$um dos identi"i adores.
Campo de ,its
8a linguagem o ampo de bits Ibit"ieldsJ < uma estrutura um pou o estran$a , em ve' de usar vari#veis om tipos di"erentes os ampos so "ormados om as partes de um inteiro. O taman$o de um ampo de bits no pode ser maior que o tipo usado , aqui um s$ort .
tYpedef struct 1 unsigned c"mpo!+) c"mpo!%) c"mpo!/) c"mpo!0) c"mpo!2) ;U]O!H]Eb?!+7
>ssa estrutura esta "ormada por um tipo que tem o taman$o de um s$ort esse mesmo tipo ser# divido em por+es menores. 8o e@emplo a ima os ampos tem os taman$os D,D,/,/,0 igual a /D bits que < o taman$o de um unsigned s$ort . Para a essar os ampos usamos o mesmo m<todo que usamos om estruturas normais .
U]O!H]Eb?!+ meu!c"mpo7 meu!c"mpo.c"mpo!+ < +87 meu!c"mpo.c"mpo!0 < 97
Enumera>o
>sta p#gina pre isa ser re i lada Idis utaJ. *o mel$or#=la, vo ! estar# a.udando o Wikilivros.
Enumerations DenumE
*qui vamos retornar a um t2pi o antigo. >numerations so um outro m<todo de de"inir onstantes. 6e ordam=seS (Hn$amos o:
* maneira mais simples de interpretar uma enumeration < imagina=la omo uma matri' de apenas uma lin$a. (emos o nome da lin$a de temos as v#rias <lulas na lin$a. Cada onstante enumerada Imuitas ve'es $amado de enumeratorJ tem um valor inteiro Icaso no seJa especi8icado ele come>a em <eroJ >@emplo: bla k blue green Ran purple Rello? ?$ite K / 0 7 9 ; D
"i arHamos om a nossa lin$a do tipo: \uadrado 6e tNngulo (riangulo Cir ulo >lipse ; D 0E 0G 0:
reparem nos valores dos nMmeros. * vantagem em termos enumera+es < que se uma vari#vel < de larada tipo enumerao, tem um tipo Mni o e os seus valores esto limitados e podero ser veri"i ados durante a ompilao. ] tal omo as estruturas riar tipos de vari#veis.
,include -stdio.h. /*?efinindo o c"'eK"lho*/ enum cores 1 PNgb < +5 XEc?E5 UcPIEO5 ;7 /*P#ui um ponto virgul"*/ /*tYpedef tr"nsform"mos % p"l"vr"s em um" $. tipo!cores*/ tYpedef enum cores tipo!cores 7 /*P funKLo def"ult d" li' ou gli'c*/ int m"in(void)
/*Pgor" us"ndo o nosso novo tipo * P#ui sem tYpedef ter^"mos #ue coloc"r enum cores */ tipo!cores cor < XEc?E 7 if(cor << +) 1 printf(3Eor "Wul >n3)7 ; if(cor << %) 1 printf(3Eor verde >n3)7 ; /* printf nLo ser4 execut"do */ if(cor << / ) 1 printf(3Eor 'r"nco >n3)7 ; return 9 7 /*?e um enter depois de ; p"r" evit"r Z"rning */
%qui podemos ver um e:emplo com uma 8un>o Imostrar"esDEI e um s2itc9= >m este e@emplo uma onstante e de"inida e o valor das outra ser# de"inido automati amente.
,include -stdio.h. ,include -stdli'.h. void mostr"rces(int #uem)7 /*P#ui os v"lores ]t"li" < 0 e Ur"sil < 2 sLo increment"dos "utom"tic"mente*/ enum 1 Pc`EIO]IP < /5 ]OPb]P5 UcPS]b ;7 int m"in(void) 1 /*Eoloc"mos 2 se vocR for Prgentino colo#ue / */ int n < UcPS]b 7 mostr"rces(n)7 ; void mostr"rces(int #uem) 1 sZitch(#uem) 1 c"se UcPS]b ) printf( 3Ur"sil invenc^vel como de costume>n3 )7 're"(7 c"se Pc`EIO]IP ) printf(3Prgentin" um di" #uem s"'e>n3) 7 're"(7 c"se ]OPb]P ) printf(3Hoi sorte>n3) 7 're"(7 def"ult ) printf(3Se estou vivo teve erro do sistem" xx >n3) 7 ; printf(3Ohe end 5 h"st" l" vist">n >n3)7 /*?e um enter depois de ; p"r" evit"r Z"rning */ ;
;nio
>sta p#gina pre isa ser re i lada Idis utaJ. *o mel$or#=la, vo ! estar# a.udando o Wikilivros.
;nions
*s unions so muito pare idas om as estruturas, estas guardam vari#veis de v#rios tipos, e portanto guardam ada vari#vel de a ordo om a seu tipo, ie, se tivermos uma vari#vel membro que < um int e outro "loat, ela guarda e@atamente de a ordo om esse tipo. O que se passa aqui < que vai guardar as vari#veis todas om um Mni o tipo, que < aquele que o upa mais espao dentro dos tipos das vari#veis membro, ou se.a, se tivermos uma vari#vel membro int e outra "loat , a union vai guardar estas vari#veis omo "ossem as duas "loat.
Declara>o
union mYtYpes!t 1 int i7 flo"t f7 ; mYtYpes7
mRtRpesdt long l Stru t C$ar C`9a mi@ 6epare que a estrutura no tem nome
union 1 flo"t doll"rs7 int Yens7 ; price7 ; 'oo(7 // estrutur" us"ndo 3"nonYmous union3 struct 1 ch"r title[29 7 ch"r "uthor[29 7 union 1 flo"t doll"rs7 int Yens7 ;7 ; 'oo(7
Se de lararmos uma unio sem nome, ela vai "i ar anhnima e poderemos a essar seus membros diretamente atrav<s dos nomes dos membros.
// gso regul"r 'oo(.price.doll"rs 'oo(.price.Yens // gso "nonimo 'oo(.doll"rs 'oo(.Yens
Estruturas
>sta p#gina pre isa ser re i lada Idis utaJ. *o mel$or#=la, vo ! estar# a.udando o Wikilivros.
'tructures
*s stu tures permitem om que possamos ter vari#veis de v#rios tipos aglomerados sob o mesmo nome. > esse mesmo nome vai passar a ser um novo tipo de dados tal omo o int ou "loat. Qas o uso disto < que podemos ter valores que ten$am alguma relao l2gi a, por e@emplo guardar um int de idade e um string de nome. Isto pode ser atributos de uma pessoa. Ou se.a podemos empa otar v#rias vari#veis de v#rios tipos om o ob.etivo de representar o mundo real e dar um nome a essas vari#veis todas. *o "a'er isto ri#mos um tipo de dados da mesma "orma omo "a'emos em relao ao int ou ao "loat.
*qui o tipo stru t indi a que vamos riar uma estrutura. O nome ou identi"i ador pode ser alunos, "amHlia, et . It!m de ser v#lidos identi"iersJ 8o esque er o ponto e vHrgula nZo no "im da de larao. Campodum e Campoddois so vari#veis membro T member variables T ou ampo da estrutura.
*qui o identi"i ador do tipo %stru t% < %min$adestrutura% dentro dessa estrutura temos tr!s ampos o ultimo < %"ruta% *gora podemos usar esse tipo %stru t% para de"inir vari#veis.
struct minh"!estrutur" nov"!estructur"7
Para ter a esso aos membros de"inidos dentro da estrutura utili'amos um operador de seleao de membro %.%Ium pontoJ.
nov"!estrutur".frut"[9 7
8os d# o primeiro ara ter da palavra ontida dentro do membro %"ruta%. Para ini iali'ar um ampo da estrutura o pro esso < o mesmo que usamos om as vari#veis.
nov"!estrutur".c"mpo!dois < +997
3atri<es de estruturas
Bma estrutura < omo qualquer outro tipo de dado no C. Podemos, portanto, riar matri'es de estruturas. &amos ver omo "i aria a de larao de um vetor de /KK "i $as pessoais:
struct minh"!estrutur" fich"s [+99 7
Pergunta: omo < que < "eito e@atamente os ob.etosS Para ada ob.eto vo ser "eito uma 2pia dos elementos da estrutura. *gora isso signi"i a que os ob.etos so distintos entre si em termos de reserva de mem2riaS ie, F medida que enumero os ob.etos vo ser reservado para ada ob.eto o taman$o @ de bRtesS ou somam=se todos os ob.etos e reserva=se para todos os ob.etos de uma "orma seguidaS Penso que deve ser a /t opo. Se tivermos apenas um ob.eto Iou vari#vel da estruturaJ no < ne ess#rio darmos o nome da estrutura
struct 1 ch"r item[09 7 // n"me of item dou'le cost7 // cost dou'le ret"il7 // ret"il price int on!h"nd7 // "mount on h"nd int le"d!time7 // num'er of d"Ys 'efore resupplY ; temp7
ou se.a
[o'*ecto!estrutur" [mem'er!estrutur"
>@emplo
,include -stdio.h. const int JPQ < /7 struct Person 1 ch"r n"me[+99 7 int height7 ;7 int m"in () 1 Person p[JPQ 7 for (int x < 97 x - JPQ7 xCC) 1 printf(3Enter personMs n"me) 3)7
; printf(3Outputting person d"t">n3)7 printf(3<<<<<<<<<<<<<<<<<<<<<<>n3)7 for (int x < 97 x - JPQ7 xCC)1 printf(3Person ,@dMs n"me is @s "nd height is @d.>n35 x C +5 p[x .n"me5 p[x .height)7 ; return 97 ;
getline(cin5 p[x .n"me)7 printf(3Enter height in meters) 3)7 sc"nf(3@d>n35 Ap[x .height)7
isto basi amente < igual a arraRs, apenas om a di"erena de termos tipos di"erentes. 3ogo a ordem vai interessar, por e@emplo se es rev!ssemos
Person p+ < 1:%5 3Seff hent3;7 //nLo iri" funcion"r$ erro de compil"KLo
//oper"dor $.
Como .# devem ter dedu'ido o operador =p ser# muito similar a pmovie=ptitle < equivalente a IjpmovieJ.title Qas ol$em que < di"erente a:
*pmovie.title #ue e#uiv"lente " *(pmovie.title)
Estruturas anin9adas
* ideia < ter uma estrutura dentro de outra estrutura.
,include -stdio.h. struct ?"te //estrutur" ch"m"d" de d"te 1 int d"Y7 int month7 int Ye"r7 ;7 struct Person 1 ch"r n"me[+99 7 int height7 ?"te '?"Y7 //temos um" nov" v"ri4vel5 m"s notem o tipo ;7 void setX"lues(Person*)7 void getX"lues(const Person*)7 int m"in () 1 Person p+7 setX"lues(Ap+)7 printf(3Outputting person d"t">n3)7 printf(3<<<<<<<<<<<<<<<<<<<<<<>n3)7 getX"lues(Ap+)7 return 97 ; void setX"lues(Person* pers) 1 printf(3Enter personMs n"me) 3)7 fgets(pers.n"me5 +995 stdin)7 printf(3Enter height in inches) 3)7 sc"nf(3@d35 Apers.height)7 printf(3Enter d"Y5 month "nd Ye"r of 'irthd"Y sep"r"ted 'Y sp"ces) 3)7 sc"nf(3@d @d @d>n35 Apers.'?"Y.d"Y5 Apers.'?"Y.month5 Apers.'?"Y.Ye"r )7 ; void getX"lues(const Person* pers) 1 printf(3PersonMs n"me) @s>n35 pers.n"me)7 printf(3PersonMs height in inches is) @d>n35 pers.height)7 printf(3PersonMs 'irthd"Y in dd/mm/YYYY form"t is) @d/@d/@d>n35 pers.'?"Y.d"Y5 pers.'?"Y.month5 pers.'?"Y.Ye"r )7 ;
6eparem que a estrutura ,ate tem de ser de larada antes da estrutura Person, pois aso ontr#rio o ompilador no entenderia o tipo de larado na estrutura Person.
Pergunta: Por que no podemos a res entar mais membros I amposJ nas estruturasS Porque elas so ompiladas estati amente om posio de mem2ria .# alo ada e tipo .# on$e ido em tempo de ompilao Pergunta: *o inv<s de termos apenas vari#veis nas estruturas, poderHamos ter tamb<m "un+esS Sim, omo ponteiros para "un+es.
tOpede8
* instruo t.pedef serve para de"inir um novo nome para um erto tipo de dados X intrHnse o da linguagem ou de"inido pelo usu#rio. Por e@emplo, se "i'<ssemos a seguinte de larao:
tYpedef unsigned0int uint7
poderHamos de larar vari#veis inteiras sem sinal Iunsigned intJ da seguinte maneira:
uint numero7 // equivalente a "unsigned int numero3"
Como se v!, t9pedef ria uma esp< ie de %apelido% para um tipo de dados, permitindo que esse tipo se.a re"eren iado atrav<s desse apelido em ve' de seu identi"i ador normal. Bm dos usos mais omuns de t9pedef < abreviar a de larao de tipos omple@os, omo structs ou estruturas. &e.a este e@emplo:
struct pessoa 1 ch"r nome[09 7 int id"de7 ;7 struct pessoa *o"o7
Observe que, para de larar a vari#vel &oao, pre isamos es rever a palavra struct. Podemos usar t9pedef para abreviar essa es rita:
tYpedef struct 0pessoa 1 ch"r nome[09 7 int id"de7 ; 4essoa7 1essoa *o"o7
Bm %apelido% de tipo < utili'ado om bastante "requ!n ia, embora no ostumemos dar por isso: < o tipo H]bE, usado nas "un+es de entradaAsaHda de arquivos.
tYpedef struct 0iobu5 1 ch"r* !ptr7 int !cnt7 ch"r* !'"se7 int !fl"g7 int !file7 int !ch"r'uf7 int !'ufsiW7 ch"r* !tmpfn"me7 ; 67897
na verdade estamos a de larar um ponteiro para uma estrutura, que ser# preen $ida mais tarde pela "uno fopen. %ten>oQ &o ! no deve tentar manipular uma estrutura do tipo -I3>Z sua omposio "oi apresentada apenas omo e@emplo ou ilustrao.
si<eo8
O operador si'eo" < usado para se saber o taman$o de vari#veis ou de tipos. >le retorna o taman$o do tipo ou vari#vel em bRtes omo uma ontante. ,evemos us#=lo para garantir portabilidade. Por e@emplo, o taman$o de um inteiro pode depender do sistema para o qual se est# ompilando. O si'eo" < um operador porque ele < substituHdo pelo taman$o do tipo ou vari#vel no momento da ompilao. >le no < uma "uno. O si'eo" admite duas "ormas:
siWeof nome!d"!v"ri4vel siWeof (nome!do!tipo)
Se quisermos ento saber o taman$o de um "loat "a'emos si'eo"I"loatJ. Se de lararmos a vari#vel " omo "loat e quisermos saber o seu taman$o "aremos si'eo" ". O operador si'eo" tamb<m "un iona om estruturas, uni+es e enumera+es. Outra apli ao importante do operador si'eo" < para se saber o taman$o de tipos de"inidos pelo usu#rio. Seria, por e@emplo, uma tare"a um tanto ompli ada a de alo ar a mem2ria para um ponteiro para a estrutura "i $adpessoal, riada na primeira p#gina desta aula, se no "osse o uso de si'eo". &e.a o e@emplo:
tYpedef struct 1 const ch"r *nome7 const ch"r *so'renome7 int id"de7 ; Pesso"7 int m"in(void) 1 Pesso" **o"#uim7 *o"#uim < m"lloc(siWeof(Pesso"))7 *o"#uim$.nome < 3So"#uim37 *o"#uim$.so'renome < 3Silv"37 *o"#uim$.id"de < +27 ;
Outro e@emplo:
,include -string.h. ,include -stdio.h. int m"in(void) 1 ch"r *nome7 nome < m"lloc(siWeof(ch"r) * +9)7 sprintf(nome5 3Zi(i'oo(s3)7 printf(3Site) http)//pt.@s.org/35 nome)7 /* ]mprime)
*/ ;
Site) http)//pt.Zi(i'oo(s.org/
* sentena abai@o 8uO "un iona, pois si'eo" < substituHdo pelo taman$o de um tipo em tempo de ompilao.
const ch"r *HcPSE7 HcPSE < 3&i(i'oo(s eh leg"l37 printf(3Eu "cho #ue o t"m"nho d" string HcPSE G @d35 siWeof(HcPSE))7
Converso de tipos
*s atribui+es no C tem o seguinte "ormato:
destino<origem7
Se o destino e a origem so de tipos di"erentes o ompilador "a' uma onverso entre os tipos. Qas nem todas as onvers+es so possHveis. O primeiro ponto a ser ressaltado < que o valor de origem < onvertido para o valor de destino antes de ser atribuHdo e no o ontr#rio. >m C, ada tipo b#si o o upa uma determinada poro de bits na mem2ria, logo, a onverso entre tipos nem sempre < algo nativo da linguagem, por assim di'er. 1# "un+es omo atol e ato" que onvertem string em inteiro longo Ilong intJ e string em double, respe tivamente. Qas em muitos asos < possHvel usar o asting. ] importante lembrar que quando onvertemos um tipo num<ri o para outro, n2s nun a gan$amos pre iso. 82s podemos perder pre iso ou no m#@imo manter a pre iso anterior. Isto pode ser entendido de uma outra "orma. \uando onvertemos um nMmero no estamos introdu'indo no sistema nen$uma in"ormao adi ional. Isto impli a que nun a vamos gan$ar pre iso. *bai@o vemos uma tabela de onvers+es num<ri as om perda de pre iso, para um ompilador om palavra de /D bits:
?e P"r" ]nform"KLo Perdid" unsigned ch"r ch"r X"lores m"iores #ue +%: sLo "lter"dos short int ch"r Os T 'its de m"is "lt" ordem int ch"r Os T 'its de m"is "lt" ordem long int ch"r Os %0 'its de m"is "lt" ordem long int short int Os +8 'its de m"is "lt" ordem long int int Os +8 'its de m"is "lt" ordem flo"t int PrecisLo $ result"do "rredond"do dou'le flo"t PrecisLo $ result"do "rredond"do long dou'le dou'le PrecisLo $ result"do "rredond"do
o resultado ontinua a ser 7 mas desta ve', )GWWWW. Para "a'er diviso que resulte nMmero real, < ne ess#rio "a'er ast para um tipo de ponto "lutuante:
" < (flo"t)+9// " < +9/(flo"t)/
8esse aso, o /K ou o 7 < onvertido para "loat. O outro nMmero ontinua omo inteiro, mas ao entrar na diviso om um "loat, ele < onvertido automati amente para "loat. * diviso < "eita e depois atribuHda F vari#vel a. >m pou as palavras, asting < olo ar um tipo entre par!nteses antes da atribuio de uma vari#vel. * "orma geral para ast <:
(tipo)v"ri4vel (tipo)(expressLo) v"ri"vel!destino < (tipo)v"ri"vel!origem7
6epare que a onverso < "eita de menor para o maior. ] possHvel "a'er a onverso ao ontr#rio de um tipo om mais bits para um om menos bits e isso < trun ar. 8esse aso, o ast e@plH ito < ne ess#rio. *ssim, um nMmero 8loat: 97.K07 ao ser onvertido para int dever# ser % ortado%, "i ando inteiro: .). Se onverter long para s$ort, os bits mais signi"i ativos so perdidos na onverso. O operador ast tamb<m e bastante utili'ado para estruturar #reas de estoque tempor#rios Ibu""erJ. * seguir um pequeno e@emplo:
,include -stdio.h. tYpedef struct estrutur"r1 ch"r " 7 ch"r ' 7 ;7 int m"in() 1 ch"r 'uffer[% < 1+:5 0;7 estrutur"r *p7 p < (struct estrutur"r*) A'uffer7 ch"r* x < (ch"r*)m"lloc(+9)7 printf(3") @i ') @i35 p$."5p$.')7
getch"r()7 return 97 ;
const
O modi"i ador const "a' om que a vari#vel no possa ser modi"i ada no programa. Como o nome .# sugere < Mtil para se de larar onstantes. PoderHamos ter, por e@emplo:
const flo"t P] < /.+0+27
Podemos ver pelo e@emplo que as vari#veis om o modi"i ador onst podem ser ini iali'adas. Qas PI no poderia ser alterado em qualquer outra parte do programa. Se o programador tentar modi"i ar PI o ompilador gerar# um erro de ompilao. Outro uso de const, ali#s muito omum que o outro, < evitar que um parNmetro de uma "uno se.a alterado pela "uno. Isto < muito Mtil no aso de um ponteiro, pois o onteMdo de um ponteiro pode ser alterado por uma "uno. Para proteger o ponteiro ontra altera+es, basta de larar o parNmetro omo onst.
,include -stdio.h. int s#r (const int *num)7 int m"in(void) 1 int " < +97 int '7 ' < s#r(A")7 ; int s#r (const int *num) 1 return ((*num)*(*num))7 ;
8o e@emplo, num est# protegido ontra altera+es. Isto quer di'er que, se tent#ssemos "a'er
*num < +97
volatile
O modi"i ador 4olatile di' ao ompilador que a vari#vel em questo pode ser alterada sem que este se.a avisado. Isto evita %bugs% que poderiam o orrer se o ompilador tentasse "a'er uma otimi'ao no 2digo que no < segura quando a mem2ria < modi"i ada e@ternamente. ,igamos que, por e@emplo, ten$amos uma vari#vel que o LIOS do omputador altera de minuto em minuto Ium rel2gio, por e@emploJ. Seria importante que de lar#ssemos esta vari#vel omo vol"tile.
Bm uso importante de vari#veis vol"tile < em apli a+es om v#rias threads Ilin$as de e@e uoJ, onde a mem2ria < ompartil$ada por v#rios pedaos de 2digo que so e@e utados simultaneamente.
e:tern
O modi"i ador extern di' ao ompilador que a vari#vel indi ada "oi de larada em outro arquivo que no podemos in luir diretamente, por e@emplo o 2digo de uma bibliote a padro. Isso < importante pois, se no olo armos o modi"i ador e:tern, o ompilador ir# de larar uma nova vari#vel om o nome espe i"i ado, %o ultando% a vari#vel que realmente dese.amos usar. > se simplesmente no de lar#ssemos a vari#vel, .# sabemos que o ompilador no saberia o taman$o da vari#vel. \uando o ompilador en ontra o modi"i ador e:tern, ele mar a a vari#vel omo no resolvida, e o montador se en arregar# de substituir o endereo orreto da vari#vel.
extern flo"t sum7 extern int count7 flo"t returnSum (void) 1 countCC7 return sum7 ;
8este e@emplo, o ompilador ir# saber que count e sum esto sendo usados no arquivo mas que "oram de larados em outro. Bma vari#vel e@terna "requentemente usada < a vari#vel errno Ide larada no arquivo= abeal$o errno.$J, que indi a o Mltimo 2digo de erro en ontrado na e@e uo de uma "uno da bibliote a padro ou do sistema.
static
O "un ionamento das vari#veis de laradas omo static depende de se estas so globais ou lo ais. &ari#veis globais st"tic "un ionam omo vari#veis globais dentro de um m2dulo, ou se.a, so vari#veis globais que no so Ie nem podem serJ on$e idas em outros m2dulos IarquivosJ. Isto < util se quisermos isolar pedaos de um programa para evitar mudanas a identais em vari#veis globais. Isso < um tipo de encapsu"amento _ que <, simpli"i adamente, o ato de no permitir que uma vari#vel se.a modi"i ada diretamente, mas apenas por meio de uma "uno. &ari#veis lo ais est#ti as so vari#veis u.o valor < mantido de uma $amada da "uno para a outra. &e.a o e@emplo:
int count (void) 1 st"tic int num < 97 numCC7 return num7 ;
* "uno ountIJ retorna o nMmero de ve'es que ela .# "oi $amada. &e.a que a vari#vel lo al int < ini iali'ada. >sta ini iali'ao s2 vale para a primeira ve' que a "uno < $amada pois num deve manter o seu valor de uma $amada para a outra. O que a "uno "a' < in rementar num a ada $amada e retornar o seu valor. * mel$or maneira de se entender esta vari#vel lo al stati < implementando. &e.a por si mesmo, e@e utando seu pr2prio programa que use este on eito.
register
O omputador pode guardar dados na mem2ria I6*QJ e nos registradores internos do pro essador. *s vari#veis Iassim omo o programa omo um todoJ ostumam ser arma'enadas na mem2ria. O modi"i ador register di' ao ompilador que a vari#vel em questo deve ser, se possHvel, guardada em um registrador da CPB. &amos agora ressaltar v#rios pontos importantes: Porque usar register' &ari#veis nos registradores da CPB vo ser a essadas em um tempo muito menor pois os registradores so muito mais r#pidos que a mem2ria. 8o entanto, a maioria dos ompiladores otimi'antes atuais usa registradores da CPB para vari#veis, ento o uso de register < "reqUentemente desne ess#rio. Em que tipo de vari?vel podemos usar o registerP *ntes da riao do padro *8SI C, register apli ava=se apenas aos tipos int e ch"r, mas o padro atual permite o uso de register para qualquer um dos quatro tipos "undamentais. ] laro que seqU!n ias de ara teres, arraRs e estruturas tamb<m no podem ser guardadas nos registradores da CPB por serem grandes demais. register um pedido que o programador 8a< ao compilador@ >ste no pre isa ser atendido ne essariamente, e alguns ompiladores at< ignoram o modi"i ador register, o que < permitido pelo padro C. register no pode ser usado em vari?veis glo,ais, pois isto impli aria em um registrador da CPB "i ar o tempo todo o upado por essa vari#vel. Bm e@emplo do uso do register < dado a seguir:
int m"in (void) 1 register int count7 for (count < 97 count - +97 countCC) 1 ... ; return 97 ;
O loop a ima, em ompiladores que no guardam vari#veis em registradores por padro, deve ser e@e utado mais rapidamente do que seria se no us#ssemos o register. >ste < o uso mais re omend#vel para o register: uma vari#vel que ser# usada muitas ve'es em seguida.
4erenciamento de memria
%loca>o dinLmica
(odos os dados de um programa so arma'enados na mem2ria do omputadorZ < muito omum ne essitar reservar um erto espao na mem2ria para poder guardar dados mais tarde. Por e@emplo, poderHamos reservar um espao de /KKK bRtes para guardar uma string que o usu#rio viesse a digitar, de larando um vetor de /KKK ara teres. > se quis<ssemos reservar um espao que s2 < on$e ido no tempo de e@e uo do programaS > se o espao "osse muito grande, de modo que de larar vetores de tal taman$o seria
in onveniente Ipois, entre outras oisas, aumenta sem ne essidade o taman$o do e@e ut#velJS Para solu ionar esse problema, e@iste a aloca>o dinLmica de memria, que omo o nome sugere, < uma maneira de alo ar mem2ria F medida que o programa vai sendo e@e utado. *s quatro "un+es rela ionadas om a alo ao dinNmi a sero des ritas a seguir.
malloc e free
>ssas duas "un+es so as mais b#si as para o geren iamento de mem2ria. malloc < respons#vel pela alo ao de um pedao de mem2ria, e free < respons#vel por liberar esse pedao de mem2ria. * "uno mallo IJ serve para alo ar mem2ria e tem o seguinte prot2tipo:
void *m"lloc (unsigned int num)7 void free (void * ptr)7
Para alo ar um espao na mem2ria, pre isamos "orne er F "uno m"lloc o nMmero de bRtes dese.ados. >la alo a na mem2ria e retorna um ponteiro void j para o primeiro bRte alo ado. O ponteiro voidj pode ser atribuHdo a qualquer tipo de ponteiro. Se no $ouver mem2ria su"i iente para alo ar a mem2ria requisitada a "uno mallo IJ retorna um ponteiro nulo. Para saber o taman$o do blo o a alo ar, pre isaremos usar o operador siWeof. >le permite tamb<m saber automati amente o taman$o de structs riadas pelo usu#rio. &e.a um e@emplo de alo ao dinNmi a:
,include -stdio.h. ,include -stdli'.h. int m"in(int "rgc5 ch"r *"rgv[ ) 1 /* ponteiro p"r" memFri" #ue ser4 "loc"d" */ int *p7 int i7 /* "loc"r +9 elementos inteiros5 ou se*"5 ( siWeof (int) * +9 ) */ p < (int *) m"lloc ( siWeof (int) * +9)7 if ( p << Igbb ) 1 printf (3Erro) ILo foi possivel "loc"r memFri">n3)7 exit(+)7 ; for(i < 97 i - +97 iCC) 1 p[i < i * %7 printf (3@d>n35 p[i )7 ; /* li'er" " memFri" "loc"d" por m"lloc */ free (p)7 return 97 ;
Outros e@emplos:
int m"in() 1 int *p5 *#7
p < m"lloc(siWeof(int))7 # < p7 *p < +97 printf(3@d>n35 *#)7 *# < %97 printf(3@d>n35 *#)7 ; int m"in() 1 int *p5 *#7 p < m"lloc(siWeof(int))7 # < m"lloc(siWeof(int))7 *p < +97 *# < %97 *p < *#7 printf(3@d>n35 *p)7 ;
O ompilador a eita jp[jq porque so ambos int. O ompilador a eita tamb<m p[q porque ambos so ponteiros e apontam para o mesmo tipo. Podemos simpli"i ar p [ mallo Isi'eo"IintJJZ por p [ mallo I9JZ mas omo temos sistemas opera ionais de /D,70, D9 bits a primeira de larao torna as oisas mais port#veis.
calloc
* "uno allo IJ tamb<m serve para alo ar mem2ria, mas possui um prot2tipo um pou o di"erente:
void *c"lloc(siWe!t nelem5 siWe!t elsiWe)7
* "uno allo reserva um blo o om o taman$o Inelem @ elsi'eJ o tetos onse utivos, isto <, alo a mem2ria su"i iente para um vetor de num ob.etos de taman$o si'e. ,i"erente de mallo IJ, o blo o reservado < ini iali'ado a K. >ssa "uno retorna um ponteiro voidj para o primeiro bRte alo ado. O ponteiro voidj pode ser atribuHdo a qualquer tipo de ponteiro. Se no $ouver mem2ria su"i iente para alo ar a mem2ria requisitada a "uno allo IJ retorna um ponteiro nulo. >@emplo:
,include -stdio.h. ,include -stdli'.h. /* P"r" us"r c"lloc() */
int m"in ()1 int *p7 int n7 int i7 ... /* ?etermin" o v"lor de n em "lgum lug"r */ p < c"lloc(n5 siWeof(int))7 /* Ploc" n n=meros inteiros p pode "gor" ser tr"t"do como um vetor com n posicoes */ //p < m"lloc(n*siWeof(int))7 /* J"neir" e#uiv"lente us"ndo m"lloc. */ if (6p) 1 printf (3** Erro) Jemori" ]nsuficiente **3)7 exit(9)7 ; for (i<97 i-n7 iCC) /* p pode ser tr"t"do como um vetor com n posicoes */ p[i < i*i7 ... return 97 ;
8o e@emplo a ima, < alo ada mem2ria su"i iente para se olo ar n nMmeros inteiros. O operador si'eo"IJ
retorna o nMmero de bRtes de um inteiro. >le < Mtil para se saber o taman$o de tipos. O ponteiro void j que allo IJ retorna < onvertido para um intj pelo ast e < atribuHdo a p. * de larao seguinte testa se a operao "oi bem su edida. Se no tiver sido, p ter# um valor nulo, o que "ar# om que ^p retorne verdadeiro. Se a operao tiver sido bem su edida, podemos usar o vetor de inteiros alo ados normalmente, por e@emplo, inde@ando=o de p`Ka a p`Ia=/Ja.
realloc
* "uno reallo IJ serve para realo ar mem2ria e tem o seguinte prot2tipo:
void *re"lloc(void *ptr5 siWe!t siWe)7
* "uno reallo a.usta o taman$o de um blo o a si'e o tetos onse utivos. * "uno modi"i a o taman$o da mem2ria previamente alo ada om mallo , allo ou reallo e apontada por ptr para o taman$o espe i"i ado por si1e. O valor de si1e pode ser maior ou menor que o original. Bm ponteiro para o blo o < devolvido porque reallo IJ pode pre isar mover o blo o para aumentar seu taman$o. Se isso o orrer, o onteMdo do blo o antigo < opiado no novo blo o, o blo o antigo < liberado e nen$uma in"ormao < perdida. Se no pre isar mover, o valor retornado < igual a ptr. Se ptr "or nulo, a "uno alo a si'e bRtes e devolve um ponteiro, "un ionando omo mallo IJZ se si1e < 'ero, a mem2ria apontada por ptr < liberada. Se no $ouver mem2ria su"i iente para a alo ao, um ponteiro nulo < devolvido e o blo o original < dei@ado inalterado. >@emplo:
,include -stdio.h. ,include -string.h. ,include -stdli'.h. int m"in() 1 ch"r *str+<Igbb5 *str%<Igbb7 str+ < (ch"r *) m"lloc(++)7 strcpY(str+5 3PUE?EH`V]S3)7 str% < (ch"r *) re"lloc(str%5 %9)7 printf(3EndereKo de str+ ) @p>n35 str+)7 printf(3EndereKo de str% ) @p>n35 str%)7 str+ < (ch"r *) re"lloc(str+5 +99)7 printf(3Iovo endereKo de str+ ) @p>n35 str+)7 printf(3Eonteudo de str+ ) @s>n35 str+)7 free(str+)7 free(str%)7 return 97 ;
; v < c"lloc (n5 siWeof(flo"t))7 /* "loc" if (v << Igbb) 1 printf (3** Erro) Jemori" ]nsuficiente **3)7 return (Igbb)7 ; return (v)7 vetor */ ; flo"t *bi'er"r!vetor!re"l (flo"t *v) 1 if (v << Igbb) return (Igbb)7 free(v)7 return (Igbb)7 ; int m"in (void) 1 flo"t *p7 int "7 ... /* outros inici"liW"c"o de " */ p < Ploc"r!vetor!re"l (")7 ... norm"lmente */ p < bi'er"r!vetor!re"l (p)7 ;
o vetor */
; for ( i < 97 i - m7 iCC ) /* "loc" "s colun"s d" m"triW */ 1 v[i < c"lloc (n5 siWeof(flo"t))7 /* m vetores de n flo"ts */ if (v[i << Igbb) 1 printf (3** Erro) Jemori" ]nsuficiente **3)7 return (Igbb)7 ; ; return (v)7 /* retorn" o ponteiro p"r" " m"triW */ ; flo"t **bi'er"r!m"triW!re"l (int m5 int n5 flo"t **v) 1 int i7 /* v"ri"vel "uxili"r */ if (v << Igbb) return (Igbb)7 if (m - + [[ n - +) 1 /* verific" p"r"metros rece'idos */ printf (3** Erro) P"r"metro inv"lido **>n3)7 return (v)7 ; for (i<97 i-m7 iCC) free (v[i )7 /* li'er" "s linh"s d" m"triW */ free (v)7 /* li'er" " m"triW (vetor de ponteiros) */ return (Igbb)7 /* retorn" um ponteiro nulo */ ; int m"in (void) 1 flo"t **m"t7 /* m"triW " ser "loc"d" */ int l5 c7 /* numero de linh"s e colun"s d" m"triW */ int i5 *7 ... /* outros com"ndos5 inclusive inici"liW"c"o p"r" l e c */ m"t < Ploc"r!m"triW!re"l (l5 c)7 for (i < 97 i - l7 iCC) for ( * < 97 * - c7 *CC) m"t[i [* < iC*7 ... /* outros com"ndos utiliW"ndo m"t[ [ norm"lmente */ m"t < bi'er"r!m"triW!re"l (l5 c5 m"t)7 ... ;
'oc0ets
%,stra>$es
* verso Bni@ LS, 9./ de /:G0 para &*Y "oi a primeira a in luir (CPAIP no kernel do sistema opera ional, o"ere endo ao mesmo tempo uma inter"a e de programao omo abstrao para esses proto olos. Os soquetes ou so kets so uma *PI I*ppli ation Program Inter"a eJ isso quer di'er uma inter"a e entre os programas e a amada de transporte. >@emplo: (CP, B,P. Os soquetes podem usar outros proto olos omo *pple(alk, Y<ro@ Y8S, et . * *PI de so kets "oi desenvolvida para a linguagem C e so uma das prin ipais *PI para sistemas do tipo B8IY. O Windo?s possui uma inter"a e similar on$e ida om o nome de Winso k.
int int int int int ssiWe!t ssiWe!t ssiWe!t ssiWe!t ssiWe!t ssiWe!t int int int int int
connect(int5 const struct soc("ddr *5 soc(len!t)7 getpeern"me(int5 struct soc("ddr *restrict5 soc(len!t *restrict)7 getsoc(n"me(int5 struct soc("ddr *restrict5 soc(len!t *restrict)7 getsoc(opt(int5 int5 int5 void *restrict5 soc(len!t *restrict)7 listen(int5 int)7 recv(int5 void *5 siWe!t5 int)7 recvfrom(int5 void *restrict5 siWe!t5 int5 struct soc("ddr *restrict5 soc(len!t *restrict)7 recvmsg(int5 struct msghdr *5 int)7 send(int5 const void *5 siWe!t5 int)7 sendmsg(int5 const struct msghdr *5 int)7 sendto(int5 const void *5 siWe!t5 int5 const struct soc("ddr *5 soc(len!t)7 setsoc(opt(int5 int5 int5 const void *5 soc(len!t)7 shutdoZn(int5 int)7 soc(et(int5 int5 int)7 soc("tm"r((int)7 soc(etp"ir(int5 int5 int5 int[% )7
BamClias de endere>o
>@istem varias "amHlias de endereo e ada uma orresponde a um proto olo em parti ular. *s "amHlias mais usadas so : %BK;&IX: Proto olo interno do B8IY %BKI&EF: Proto olo Internet %BK&' : Proto olo de Yero@ 8S
Estruturas de endere>o
&arias $amada ao sistema de redes do uni@ pre isam apontar para uma estrutura de endereo de so ket. * de"inio dessas estruturas esta de"inida dentro do abeal$o <sRsAso ket.$p.
struct soc("ddr 1 u!short s"!f"milY 7 ch"r s"!d"t"[+0 7 ; 7
sad"amilR: -amHlia de endereo leva o valor *-d@@@ . saddata: endereo espe i"i o de proto olo . Para a "amHlia internet as estrutura esto de"inidas dentro do abeal$o <netinetAin.$p.
struct in!"ddr 1 u!long s!"ddr 7 ; 7
struct soc("ddr!in 1
3a0e8iles
3a0e8ile
O ob.etivo de Qake"ile < de"inir regras de ompilao para pro.etos de so"t?are. (ais regras so de"inidas em arquivo $amado 3a0e8ile. O programa ma0e interpreta o onteMdo do Qake"ile e e@e uta as regras l# de"inidas. *lguns Sistemas Opera ionais tra'em programas similares ao make, tais omo gmake, nmake, tmake, et . O programa make pode variar de um sistema a outro pois no "a' parte de nen$uma normali'ao . O te@to ontido em um Qake"ile < usado para a ompilao, ligaoIlinkingJ, montagem de arquivos de pro.eto entre outras tare"as omo limpe'a de arquivos tempor#rios, e@e uo de omandos, et . &antagens do uso do Qake"ile: >vita a ompilao de arquivos desne ess#rios. Por e@emplo, se seu programa utili'a /0K bibliote as e vo ! altera apenas uma, o make des obre I omparando as datas de alterao dos arquivos "ontes om as dos arquivos anteriormente ompiladosJ qual arquivo "oi alterado e ompila apenas a bibliote a ne ess#ria.
*utomati'a tare"as rotineiras omo limpe'a de v#rios arquivos riados temporariamente na ompilao Pode ser usado omo linguagem geral de s ript embora se.a mais usado para ompilao *s e@pli a+es a seguir so para o utilit#rio P8B make IgmakeJ que < similar ao make. >nto vamos para a apresentao do Qake"ile atrav<s da ompilao de um pequeno pro.eto em linguagem C. Criar uma pasta om esses 9 arquivos : teste. ,teste.$ , main. , Qake"ile. ,e um nome para a pasta Pro.eto.
/*<<<<<<<<<<<<<<<< teste.c <<<<<<<<<<<<<<<<<<<<<<*/ ,include -stdio.h. ,include -stdli'.h. /*gm" funK"o m"(eOeste()*/ void m"(eOeste(void)1 printf(3O J"(efile G super beg"l>n3)7 ;
/*<<<<<<<<<<<<<<<<<< E"'eK"lho ou he"der <<<<<<<<*/ ,ifndef !V!OESOE ,define !V!OESOE /* P noss" funKLo */ void m"(eOeste(void)7 /* ?e um enter depois de endif*/ /*P"r" evit"r Z"rning*/ ,endif
Para no ter erros os espaos devem ser "eito om a te la (*L. > ompilar < s2 ir dentro da pasta %Pro.eto% apertar -9 es rever make e apertar enter. Bma ve' ompilado podemos modi"i ar teste. . Se teste. "oi modi"i ado ento make modi"i a teste.o e se no dei@a teste.o omo esta. all : ] o nome das regras a serem e@e utadas. teste: teste. .Pode ser interpretado om arquivoddeddestino: arquivoddedorigem. lean: *paga os arquivos intermedi#rios.Se vo ! es rever no onsole make lean ele apaga os arquivos ob.eto da pasta. mrproper: *paga tudo o que deve ser modi"i ado.8o onsole es reva make mrproper
"egras complementares all : ] o nome das regras a serem e@e utadas. lean: *paga os arquivos intermedi#rios. mrproper: *paga tudo o que deve ser modi"i ado. De8inir Vari?veis *s vari#veis servem para "a ilitar o trabal$o. >m ve' de mudar varias lin$as mudamos s2 o valor da vari#vel. ,eve ser por isso que se $ama vari#vel, noS ,e"inimos da "orma seguinte.
IOJE<XPbOc E p"r" utiliW"r est" v"ri4vel coloc"mos entre k() . EntLo el" v"i fic"r "ssim k(IOJE)
&amos para o e@emplo om o nosso Qake"ile. Colo amos em ve' de : 8OQ> S6C > em ve' de &*3O6 main. . > para poder usar vIS6CJ
(odos os lugares do 2digo que ontem o CO8(>w,O da vari#vel so modi"i ados olo ando no lugar respe tivo o 8OQ> da vari#vel. Vari?veis Personali<adas CC[g .,e"inimos CC para nomes de ompiladores de C ou CCC .*qui o g .
C-3*PS[=W =Wall =ansi =pedanti .Serve para de"inir op+es passadas ao ompilador. Para o CC o 8OQ> e CYY-3*PS . 3,-3*PS e utili'ado para editar as op+es de links. >Y>C[teste .>Y>C de"ine o 8OQ> do "uturo programa e@e ut#vel. OLW[teste.o main.o . Para ada arquivo. um arquivo OLW>(O e riado om a e@tenso %.o% arquivo.o . >nto e s2 ol$ar na sua pasta todos os arquivos om a e@tenso %. % e olo ar na vari#vel OLW om a e@tenso%.o% . Outra maneira e mesma oisa. OLW agora e igual a main.o teste.o
ScE < m"in.c teste.c OUS< k(ScE).c<.o)
> super manero a tua id<ia amarada. Qais ten$o 0KK arquivos. e no quero ol$ar o nome de todos um por um. (em outra id<iaSS PoderHamos utili'ar j mais no podemos utili'ar este ara ter .oker na de"inio de uma vari#vel.
>nto vamos utili'ar o omando % ?ild ard % ele permite a utili'ao de ara teres .oker na de"inio de vari#veis. -i a assim.
ScE< k(Zildc"rd *.c) OUS< k(ScE).c<.o)
Observao se quiser "a'er apare er uma mensagem durante a ompilao es reva xe $o %Qin$a mensagem% . > mais tem um monte de mensagens e "i a muito "eio (em outra id<iaSS.. O pessoal vamos parando ZJ no sou uma maquina de id<ias. Para dei@ar as mensagens em modo silen ioso oloque %x% no omeo do omando. -i a assim
ik(EE) $o ki kl
Vari?veis internas
ki kkl k_ k* Iome d" regr". Iome d" primeir" dependRnci" bist" de dependRnci"s bist" de dependRnci"s m"is recentes #ue " regr". Iome do "r#uivo sem sufixo
%s regras de inter8er/ncia 8o disse nada antes porque est#vamos no estado prin ipiantes %noob%. So regras gen<ri as $amadas por de"ault. . .o : .>la signi"i a "a'er um arquivo.o a partir de um arquivo. . g.o: g. .* mesma oisa. * lin$a teste.o: teste. pode ser modi"i ada om essa regra. .P1O8y: .Preste bem ateno. >sta regra permite de evitar on"litos. Por e@emplo % lean:% e uma regra sem nem uma depend!n ia no temos nada na pasta que se $ame lean. *gora vamos olo ar na pasta um arquivo $amado lean. Se vo ! tentar apagar os %arquivos.o% es revendo %make lean% no vai a onte er nada porque make di' que lean no "oi modi"i ado.
Para evitar esse problema usamos a regra .P1O8y : . -i a assim. .P1O8y: lean mrproper .P1O8y: di' que lean e mrproper devem ser e@e utados mesmo se arquivos om esses nomes e@istem. *gora vamos modi"i ar mais uma ve' o nosso Qake"ile om tudo o que sabemos sobre vari#veis.
,P"r" escrever coment4rios ,, ,,,,,,,,,,,,,,,,,,,,,,,,,,,,, J"(efile ,,,,,,,,,,,,,,,,,,,,,,,,,, ,?efinimos " v"ri4vel EE<gcc EHbP`S<$& $&"ll $"nsi $ped"ntic EQEE<teste OUS<teste.o m"in.o "ll) k(EQEE) iecho 3Xou comeK"r " compil"KLo3 ,ILo colo#uei " v"ri4vel OUS p"r" #ue poss"m entender "s v"ri4veis intern"s. ,Se entender"m podem coloc"r k(OUS) no lug"r de teste.o m"in.o teste) teste.o m"in.o , ki < teste)
, kl < teste.o m"in.o k(EE) $o ki kl , teste.o)teste.c @.o) @.c k(EE) $o ki $c k- k(EHbP`S) m"in.o) m"in.c teste.h k(EE) $o ki $c k- k(EHbP`S) .PVOIj) cle"n mrproper cle"n) rm $rf *.o iecho 3Eompil"K"o prontinh"3 mrproper) cle"n rm $rf k(EQEE)
Po legal ZJ pare e at< trabal$o de gente grande. 'u, 3a0e8iles 3er tudo isso s2 para ompilar um programaSS O sub=make"ile e lanado por meio de um %Qake"ile prin ipal% vamos simpli"i ar para o Patro Qake"ile. *onde est#vamosSS...*$ sim, para que serveSS O Qake"ile Prin ipal e@e uta os sub=makes"iles de outras pastas. Como ele "a'SS
gs"mos um" v"ri4vel pre$definid" k(JPhE).
Lao ao trabal$o.. Crie dentro da pasta %Pro.etos% outra pasta om o nome %sub=make%.,entro da pasta sub=make rie um arquivo Qake"ile e um arquivo submake.
*gora retorne na pasta %Pro.eto% vamos modi"i ar o Qake"ile . &amos olo ar a seguinte lin$a:
icd su'$m"(e AA k(JPhE)
>@pli ando: %x% silen ioso % d% para abrir a pasta sub=make %55% e e@e utar make %vIQ*4>J%
&amos "a'er a mesma oisa para % lean:% e %mrproper:% ento ao e@e utar %make lean% no onsole ele vai e@e utar o mesmo omando no sub=make"ile.
,,,,,,,,,,,,,,,,,,,,,,,,,, O J"(efile princip"l ,,,,,,,,,,,,,,,,,,,,,,,,,,3 EE<gcc EHbP`S<$& $&"ll $"nsi $ped"ntic EQEE<teste ScE< k(Zildc"rd *.c) OUS< k(ScE).c<.o) "ll) k(EQEE) iecho 3Eompil"ndo Pro*eto3 iecho 3O p"trLo foi compil"do3 ,P linh" #ue v"i compil"r su'$m"(e icd su'$m"(e AA k(JPhE) teste) k(OUS) ik(EE) $o ki kl @.o) @.c ik(EE) $o ki $c k- k(EHbP`S) m"in.o) m"in.c teste.h ik(EE) $o ki $c k- k(EHbP`S) .PVOIj) cle"n mrproper cle"n) irm $rf *.o *m , E " mesm" cois" #ue d"r um H0 dentro d" p"st" su'$m"(e , e escrever m"(e cle"n icd su'$m"(e AA k(JPhE) ki mrproper) cle"n irm $rf k(EQEE) ,modific"mos "#ui t"m'Gm icd su'$m"(e AA k(JPhE) ki
8o esquea de dar (*L em todas as lin$as que esto em bai@o dos %:% dois pontin$os. O4 agora < s2 dar um -9 dentro da pasta pro.etos e vo ! tem tr!s omandos a disposio. make make lean
make mrproper 3a0e install *utomati'ando a instalao do programa om a regra install: . install: .Colo a o bin#rio ou e@e ut#vel em uma determinada pasta, omo por e@emplo Abin ou AusrAbin no 3inu@. Pode ser em qualquer outra, utili'ando o omando %mv% ou % p% para mover ou opiar. Crie uma pasta bin dentro de %Pro.etos%. ,evem saber que no devem olo ar nada inMtil que ven$a da internet na pasta rai' do linu@. &amos "a'er duas vari#veis: pre"i@[A amin$oAate ondeAestaAPro.etos bindir[vIpre"i@JAbin .Igual a A amin$o ateAPro.etosAdentro de Pro.etos a pasta bin .
> adi ionarmos a regra install:all om seus omandos. Qodi"i ando o make prin ipal.
,,,,,,,,,,,,,,,,,,,,,,,,,, O J"(efile princip"l ,,,,,,,,,,,,,,,,,,,,,,,,,,3 ,Eolo#ue o c"minho "tG Pro*eto "#ui prefix</home/gSEc/Pro*eto 'indir<k(prefix)/'in EE<gcc EHbP`S<$& $&"ll $"nsi $ped"ntic EQEE<teste ScE< k(Zildc"rd *.c) OUS< k(ScE).c<.o) "ll) k(EQEE) iecho 3Eompil"ndo Pro*eto3 iecho 3O p"tr"o foi compil"do3 ,P linh" #ue v"i compil"r su'$m"(e icd su'$m"(e AA k(JPhE) teste) k(OUS) ik(EE) $o ki kl @.o) @.c ik(EE) $o ki $c k- k(EHbP`S) m"in.o) m"in.c teste.h ik(EE) $o ki $c k- k(EHbP`S) ,Ent"o depois e so execut"r m"(e e depois m"(e inst"ll inst"ll)"ll imv k(EQEE) k('indir)/ .PVOIj) cle"n mrproper cle"n) irm $rf *.o *m , E " mesm" cois" #ue d"r um H0 dentro d" p"st" su'$m"(e , e escrever m"(e cle"n icd su'$m"(e AA k(JPhE) ki mrproper) cle"n icd 'in AA rm $rf k(EQEE)
>nto quando vo ! digitar no onsole %make% depois %make install% ele vai olo ar o binario que esta em %Pro.etos% dentro de %bin%. Se vo ! quiser olo ar o binario que esta na pasta %sub=make% na pasta %bin% Copiar e olar no make"ile da %sub=make% as variaveis %pre"i@% e %bindir%e a regra install: om seu omando. > no %Qake"ile prin ipal% em bai@o de %install:% oloque esta lin$a x d sub=make 55 vIQ*4>J vx *qui eu modi"iquei o %mrproper% porque agora os binarios que devem ser apagados om %make mrproper% esto em %bin%. &ou dei@ar vo es modi"i arem o %mrproper% do %sub=make"ile% omo pessoas adultas e responsaveis ZJ &aleu galera. Os omandos no onsole so: make make install make lean
] importante lembrar que todas as palavras reservadas so es ritas em minMs ulo e no podem ser utili'adas para outro prop2sito. *lguns ompiladores in luem outras palavras reservadas omo, asm, cdecl, far, fortran, huge, interrupt, near, pascal, t.peof.
'eqY/ncias de escape
O C tem v#rias seqU!n ias de es ape. >las servem geralmente para inserir um ara tere espe ial numa String. *lgumas dessas seqU!n ias so: ea = *larm, *larme [ (o a o alarme sonoro do sistema eb = La k spa e, 6etro esso [ *paga o ara tere F esquerda do ursor en = 8e?3ine, 8ova lin$a [ Pula uma lin$a et = (abulao $ori'ontal [ >quivale F dar um (*L na string er = Carriage 6eturn, 6etorno do Carro [ &olta para o inH io da lin$a. et = 1or'. (ab, (abulao 1ari'ontal [ Salta F "rente on"orme seus a.ustes de tabulao eK = 8ull, 8ulo [ Cara tere nulo ou 'ero geralmente estabele ido omo "im de string
Lista de 8un>$es
*qui esto as v#rias "un+es presentes em C separadas por abeal$o: stdio.$ print" s an" vsnprint" sprint" vprint" "print" "s an" "eo" ""lus$
allo mallo sRstem gets "gets puts "puts stdlib.$ atoi ato" atol itoa string.$ str mp stri mp strlen strstr str at str pR strn pR strn at str $r strrev signal.$ iso/KD9D.$ time.$ mat$.$ tan sin os atan asin a os po? sqrt abs
Lista de ,i,liotecas
Cabeal$os de bibliote as padro *8SI C ICG:JAISO C IC:KJ: "ssert.h ctYpe.h errno.h flo"t.h limits.h loc"le.h m"th.h set*mp.h sign"l.h std"rg.h stddef.h stdio.h stdli'.h string.h time.h
Cabeal$os adi ionados no ISO C IC::J Isuportados somente em ompiladores mais novosJ: complex.h fenv.h inttYpes.h std'ool.h stdint.h tgm"th.h
Liga>$es e:ternas
($e Open Proup Lase Spe i"i ations Issue E Ienglis$J Libliote a C Ienglis$J
Dicas de programa>o em C
Conven>$es tipogr?8icas
Bma das mel$ores maneiras de obter um 2digo laro e usando identi"i adores oerentes. Por e@emplo < bom poder identi"i ar rapidamente as vari#veis em "uno de suas propriedades . &e.a abai@o algumas delas.
$ $ $ $ ponteiro t"'el" est4tic"(st"tic "rr"Y) t"'el" dinemic" (dYn"mic "rr"Y) c"dei" de c"r"cteres(string) prefixos identific"dores p! "! ou s"! d"! s!
>m um 2digo om a vari#vel %pde@emplo% podemos dedu'ir rapidamente que estamos usando um ponteiro .
,igamos que o programa ten$a sido ompilado om su esso, mas o orra algum erro durante sua e@e uo. Podemos usar o print" para dete tar o erro da seguinte maneira:
int m"in(int "rgc5 ch"r *"rgv[ ) 1 ... printf(3inici"ndo func"o+3)7 func"o+(...)7 printf(3complet" funKLo+5 inici"ndo func"o%3)7 func"o%(...)7 printf(3complet" funKLo%5 inici"ndo func"o/3)7 func"o/(...)7 printf(3complet" funKLo/5 inici"ndo func"o03)7 func"o0(...)7 printf(3complet" funKLo03)7 ... return 97 ;
Isto permite o programador determinar at< que ponto o programa roda antes de dar erro, "a ilitando muito a dete o deste. Outro e@emplo de omo o print" < Mtil na dete o de problemas. Supon$a um programa $eio de laos anin$ados. (al omo:
for(...) 1 Zhile(...) 1 ... for(...) 1 ... ; ; ;
Caso durante a e@e uo o programa entre em um loop in"inito, uma "orma de dete tar em qual dos laos est# o problema <:
for(...) 1 printf(3Oeste +3)7 Zhile(...) 1 printf(3Oeste %3)7 ... for(...) 1 printf(3Oeste /3)7 ... ; ; ;
* impresso que se repetir eternamente < aquela dentro do lao problem#ti o. Bm Mltimo e@emplo de dete o de problemas por meio do print". Supon$a que a resposta dada por um programa no < a esperada, que a resposta onsiste na impresso de uma vari#vel @, a qual re ebe diversas atribui+es ao longo do programa. Podemos identi"i ar o erro dando um print" em @ ap2s ada uma de suas atribui+es:
x<... printf(3primeir" "tri'uic"o de x eh @tipo35 x)7 ... x<... printf(3segund" "tri'uic"o de x eh @tipo35 x)7 ... x<...
Caso o valor de @ dependa do valor de outras vari#veis que no so impressas, imprimi=las pode a.udar na dete o do problema. Para uso omo debug, a linguagem C apresenta duas ma ros que quando utili'adas .unto om o print" so 2timos re ursos. dd-I3>dd [ nome do arquivo. dd3I8>dd [ numero da lin$a de e@e uo. O Compilador g ainda disp+e de uma outra ma ro bastante util:
O tre $o a ima vai te dar uma saida para debug muito util om o seguinte onteudo:
Exemplo) /)hello.c)m"in
Com do...?$ile
int m"in(int "rgc5 ch"r *"rgv[ )
1 short int rod"ndo7 do /*Este l"co m"ntem o progr"m" rod"ndo en#u"nto o usu"rio dese*"r*/ 1 ... printf(3>n?igite + p"r" m"nter o progr"m" rod"ndo. 3)7 sc"nf(3@d35 Arod"ndo)7 ;Zhile(rod"ndo<<+)7 return 97 ;
Com o goto
int m"in(int "rgc5 ch"r *"rgv[ ) 1 JPcEP) ... H]J) int Y7 printf(3Oecle + p"r" continu"r rod"ndo o progr"m". Oecle 9 p"r" encerr"r o progr"m">n3)7 sc"nf(3@d35AY)7 if(Y<<+) 1 goto JPcEP7 ; if(Y6<+ AA Y6<9) 1 goto H]J7 ; return 97 ;
Listas encadeadas
3istas en adeadas so estruturas de dados lineares e dinNmi as, a grande vantagem que elas possuem em relao ao uso de vetor < o "ato de terem taman$o m#@imo relativamente in"inito Io taman$o m#@imo < o da mem2ria do omputadorJ, ao mesmo tempo que podem ter o taman$o mHnimo de / elemento evitando o desperdH io de mem2ria.
Primitivas
8o e@iste nen$uma normali'ao quanto as primitivas usadas para a manipulao de uma lista. *bai@o vo ! pode ver uma lista om algumas delas . Colo ar o Hndi e sobre o primeiro elemento da lista. Colo ar o Hndi e sobre o Mltimo elemento da lista . Colo ar o Hndi e sobre o elemento que segue o elemento atual . Colo ar o Hndi e sobre o elemento que pre ede o elemento atual . &eri"i ar se a lista est# va'ia : Se a lista estiver va'ia retorna verdadeiro, se no, "also. &eri"i ar se < o primeiro elemento : 6etorna verdadeiro se o elemento atual < o primeiro, se no, "also. &eri"i ar se < o Mltimo elemento : 6etorna verdadeiro se o elemento atual < o Mltimo, se no, "also.
&eri"i ar o nMmero de elementos da lista : 6etorna o nMmero de elementos da lista. *di ionar um elemento no inH io : *di ionar um elemento antes do primeiro elemento da lista . *di ionar um elemento no "im : *di ionar um elemento depois do Mltimo elemento da lista . Insero : Inserir um elemento antes do elemento atual . (ro a : (ro ar o elemento atual . 6emoo : 6emover o elemento atual . 3istar todos os elementos da lista .
Inser>o
>@istem 7 tipos de insero em uma lista, pode=se inserir no omeo, no "inal ou entre dois elementos da lista.
Inser>o no inCcio
int inserir!Io!]nicio(struct Io **p!c"iW5 ch"r *p!String)1 struct Io *p!Iovo7 /** Ploc"KLo dinemic" d" memori" */ if((p!Iovo < (struct Io *) m"lloc(siWeof(struct Io))) << Igbb )1 puts( 3H"lt" Jemori">n3)7 return $+ 7 ; p!Iovo$.p!d"dos < p!String7 p!Iovo$.p!prox < *p!c"iW7 *p!c"iW < p!Iovo7
Inser>o no 8im
int inserir!Io!Him(struct Io **p!c"iW5 ch"r *p!String)1 struct Io *p!Iovo7 if(( p!Iovo < (struct Io *) m"lloc(siWeof(struct Io))) << Igbb )1 puts( 3H"lt" Jemori">n3)7 return $+ 7 ;
p!Iovo$.p!d"dos < p!String7 p!Iovo$.p!prox < Igbb7 if(*p!c"iW << *p!c"iW < else1 struct Io e!"tu"l < Igbb) p!Iovo7 *e!"tu"l7 *p!c"iW7 /*i Elemento "tu"l*/ /*i Primeiro elemento*/
; ;
"emo>o
*ssim omo na insero tamb<m e@istem 7 tipos de remoo, no inH io, no "im ou entre dois elementos da lista.
"emo>o no inCcio
void remover!Io!]nicio(struct Io **p!c"iW)1 if(*p!c"iW << Igbb) printf(3>nP list" *" est" v"Wi">n3)7 else1 struct Io *p!"tu"l7 p!"tu"l < *p!c"iW7 *p!c"iW < (*p!c"iW)$.p!prox7 free(p!"tu"l)7
; ;
"emo>o no 8im
void remover!Io!Him(struct Io **p!c"iW)1 if(*p!c"iW << Igbb) printf(3>nP list" *" est" v"Wi"3)7 else1 struct Io *p!"tu"l5 *p!"nterior 7 p!"tu"l < *p!c"iW7 Zhile(p!"tu"l$.p!prox 6< Igbb)1 p!"nterior < p!"tu"l 7 p!"tu"l < p!"tu"l$.p!prox7 ; p!"nterior$.p!prox < Igbb7 free(p!"tu"l)7 ; ;
E:i,i>o
Do 8im para a rai<
void mostr"r!?o!Him!P"r"!c"iW(struct Io *p!c"iW)1 if(p!c"iW << Igbb) printf(3>nbist" v"Wi"3)7 else1
; ;
struct Io *p!Ptu"l!Eorredor5 *p!Ptu"l!Him7 p!Ptu"l!Eorredor < p!c"iW7 p!Ptu"l!Him < p!c"iW7 Zhile(p!Ptu"l!Him$.p!prox 6< Igbb)1 //ir p"r" o ultimo elemento p!Ptu"l!Him < p!Ptu"l!Him$.p!prox7 ; Zhile(p!Ptu"l!Eorredor 6< p!Ptu"l!Him)1 if(p!Ptu"l!Eorredor$.p!prox << p!Ptu"l!Him)1 printf(3 -$ @s35 p!Ptu"l!Him$.p!d"dos)7 p!Ptu"l!Him < p!Ptu"l!Eorredor7 p!Ptu"l!Eorredor < p!c"iW7 ; else p!Ptu"l!Eorredor < p!Ptu"l!Eorredor$.p!prox7 ; printf(3 -$ @s35 p!Ptu"l!Him$.p!d"dos)7
Pil9a
Pil9a
Pil$a ou sta k < uma lista linear em que todas as inser+es e remo+es de elemento s2 podem ser "eitos em uma e@tremidade $amada topo.*s pil$as tamb<m so $amadas de estruturas 3I-O I3ast In -irst OutJ ou se.a o Mltimo elemento inserido < o primeiro removido.
Iniciali<a>o
void inici"r (boc"liW"r *monte)1 monte$.inicio < Igbb7 monte$.t"m"nho < 97 ;
Zrvores ,in?rias
>ste m2dulo pre isa ser revisado por algu<m que on$ea o assunto Idis utaJ.
%rvore ,in?ria
Bma arvore bin#ria < uma estrutura de dados que pode ser representada omo uma $ierarquia onde ada elemento < $amado de n2. O n2 ini ial ou o primeiro elemento < $amado de rai'. >m uma #rvore bin#ria um elemento pode ter um m#@imo de dois "il$os no nHvel in"erior denominados omo sub=#rvore esquerda e sub=#rvore direita.Bm n2 sem "il$os < $amado de "ol$a. * pro"undidade de um n2 < a distNn ia deste n2 at< a rai' e a distan ia entre a "ol$a mais distante e a rai' < a altura da arvore.Bm on.unto de n2s om a mesma pro"undidade < denominado, nHvel da #rvore.
'truct
tYpedef struct Io1 int numero7 struct Io *es#uerd"7 struct Io *direit"7
;Io7
Iniciar
void cri"rPrvore(Io **pc"iW)1 *pc"iW < Igbb7 ;
Inser>o
void inserir(Io **pc"iW5 int numero)1 if(*pc"iW << Igbb)1 *pc"iW < (Io *) m"lloc(siWeof(Io))7 (*pc"iW)$.es#uerd" < Igbb7 (*pc"iW)$.direit" < Igbb7 (*pc"iW)$.numero < numero7 ;else1 if(numero - (*pc"iW)$.numero) inserir(A(*pc"iW)$.es#uerd"5 numero)7 if(numero . (*pc"iW)$.numero) inserir(A(*pc"iW)$.direit"5 numero)7 ; ;
"emo>o
Io *J"ior?ireit"(Io **no)1 if((*no)$.direit" 6< Igbb) return J"ior?ireit"(A(*no)$.direit")7 else1 Io *"ux < *no7 if((*no)$.es#uerd" 6< Igbb) // se n"o houver ess" verific"c"o5 esse nF v"i perder todos os seus filhos d" es#uerd"6
Io *JenorEs#uerd"(Io **no)1 if((*no)$.es#uerd" 6< Igbb) return JenorEs#uerd"(A(*no)$.es#uerd")7 else1 Io *"ux < *no7 if((*no)$.direit" 6< Igbb) // se n"o houver ess" verific"c"o5 esse nF v"i perder todos os seus filhos d" direit"6 *no < (*no)$.direit"7 else *no < Igbb7 return "ux7 ; ; void remover(Io **pc"iW5 int numero)1 if(*pc"iW << Igbb)1 // est" verific"c"o serve p"r" c"so o numero n"o exist" n" "rvore. printf(3Iumero n"o existe n" "rvore63)7 getch()7 return7 ; if(numero - (*pc"iW)$.numero) remover(A(*pc"iW)$.es#uerd"5 numero)7 else if(numero . (*pc"iW)$.numero) remover(A(*pc"iW)$.direit"5 numero)7 else1 // se n"o eh menor nem m"ior5 logo5 eh o numero #ue estou procur"ndo6 )) Io *pPux < *pc"iW7 // #uem progr"m"r no Em'"rc"dero v"i ter #ue decl"r"r o pPux no inicio do void6 )[ if (((*pc"iW)$.es#uerd" << Igbb) AA ((*pc"iW)$.direit" << Igbb)) 1 // se n"o houver filhos... free(pPux)7 (*pc"iW) < Igbb7 ; else1 // so tem o filho d" direit" if ((*pc"iW)$.es#uerd" << Igbb)1 (*pc"iW) < (*pc"iW)$.direit"7 pPux$.direit" < Igbb7 free(pPux)7 pPux < Igbb7 ; else1 //so tem filho d" es#uerd" if ((*pc"iW)$.direit" << Igbb)1 (*pc"iW) < (*pc"iW)$.es#uerd"7 pPux$.es#uerd" < Igbb free(pPux)7 pPux < Igbb7 ; else1 //Escolhi f"Wer o m"ior filho direito d" su'"rvore es#uerd". pPux < J"ior?ireit"(A(*pc"iW)$.es#uerd")7 //se vc #uiser us"r o Jenor d" es#uerd"5 so o #ue mud"ri" seri" isso) pPux$.es#uerd" < (*pc"iW)$.es#uerd"7 // pPux < JenorEs#uerd"(A(*pc"iW)$.direit")7 pPux$.direit" < (*pc"iW)$.direit"7 (*pc"iW)$.es#uerd" < (*pc"iW)$.direit" < Igbb7 free((*pc"iW))7 *pc"iW < pPux7 pPux < Igbb7 ; ; ; ;
Em ordem
void exi'irEmOrdem(Io *pc"iW)1 if(pc"iW 6< Igbb)1 exi'irEmOrdem(pc"iW$.es#uerd")7 printf(3>n@i35 pc"iW$.numero)7 exi'irEmOrdem(pc"iW$.direit")7 ; ;
Pr+ordem
void exi'irPreOrdem(Io *pc"iW)1 if(pc"iW 6< Igbb)1 printf(3>n@i35 pc"iW$.numero)7 exi'irPreOrdem(pc"iW$.es#uerd")7 exi'irPreOrdem(pc"iW$.direit")7 ; ;
Ps+ordem
void exi'irPosOrdem(Io *pc"iW)1 if(pc"iW 6< Igbb)1 exi'irPosOrdem(pc"iW$.es#uerd")7 exi'irPosOrdem(pc"iW$.direit")7 printf(3>n@i35 pc"iW$.numero)7 ; ;
Contar ns
int cont"rIos(Io *pc"iW)1 if(pc"iW << Igbb) return 97 else return + C cont"rIos(pc"iW$.es#uerd") C cont"rIos(pc"iW$.direit")7 ;
Contar 8ol9as
int cont"rHolh"s(Io *pc"iW)1 if(pc"iW << Igbb) return 97 if(pc"iW$.es#uerd" << Igbb AA pc"iW$.direit" << Igbb) return +7 return cont"rHolh"s(pc"iW$.es#uerd") C cont"rHolh"s(pc"iW$.direit")7 ;
%ltura da ?rvore
int m"ior(int "5 int ')1 if(" . ')
else ;
int "ltur"(Io *pc"iW)1 if((pc"iW << Igbb) [[ (pc"iW$.es#uerd" << Igbb AA pc"iW$.direit" << Igbb)) return 97 else return + C m"ior("ltur"(pc"iW$.es#uerd")5 "ltur"(pc"iW$.direit"))7 ;
Estrutura Completa
, include -iostre"m. , include -#ueue. , include -stl!#ueue.h. using n"mesp"ce std7 cl"ss Io 1 pu'lic ) int v"lor7 Io *direito5 *es#uerdo7 Io ()7 Io (int)7 ;7 Io )) Io () 1 this$.direito < this$.es#uerdo < Igbb7 ; Io )) Io(int v"lor) 1 this$.v"lor < v"lor7 this$.direito < this$.es#uerdo < Igbb7 ; cl"ss PrvoreUin"ri" 1 protected ) Io *r"iW7 int Uusc" (Io*5 int)7 void PreOrdem (Io*)7 void EmOrdem (Io*)7 void PosOrdem (Io*)7 int remove (Io*5int)7 void percursoEmb"rgur"(Io *)7 int Pltur" (Io*)7 int Iivel (Io*5 int5 int)7 pu'lic ) PrvoreUin"ri" ()7 int Pltur" ()7 int Iivel (int)7 'ool X"Wio ()7 int Uusc" (int)7 void insere (int)7 int remove (int)7 void percursoEmb"rgur"()7 Io* noJ"ior(Io*)7 void PreOrdem ()7 void EmOrdem ()7 void PosOrdem ()7 ;7 Io* PrvoreUin"ri" )) noJ"ior(Io *r"iW)1 Io *temp<Igbb7
temp < r"iW7 if(temp$.direito<< Igbb)1 r"iW < r"iW$.es#uerdo7 return temp7 ; else return noJ"ior(r"iW$.direito)7 ; int PrvoreUin"ri" )) Iivel(Io *inicio5 int v"lor5 int nivel) 1 if (6inicio) return $+7 else 1 if (v"lor << inicio$.v"lor) return nivel7 else 1 CCnivel7 if (v"lor - inicio$.v"lor) nivel < Iivel (inicio$.es#uerdo5 v"lor5 nivel)7 else if (v"lor . inicio$.v"lor) nivel < Iivel (inicio$.direito5 v"lor5 nivel)7
; ;
return nivel7 ;
void PrvoreUin"ri" )) percursoEmb"rgur"(Io *inicio)1 Io *temp < Igbb7 #ueue *"uxHil" < Igbb7 if(inicio 6< Igbb)1 // 6inicio "uxHil"$.push(inicio)7 Zhile("uxHil"$.emptY() 6< true)1 temp < "uxHil"$.pop()7 if(temp$.es#uerdo 6< Igbb) "uxHil"$.push(temp$.es#uerdo)7 if(temp$.direito 6< Igbb) "uxHil"$.push(temp$.direito)7 cout -- temp$.v"lor-- endl7 ; ; ; void PrvoreUin"ri" )) percursoEmb"rgur"() 1 return percursoEmb"rgur" (this$.r"iW)7 ; int PrvoreUin"ri" )) Iivel(int v"lor) 1 return Iivel (this$.r"iW5 v"lor5 9)7 ; int PrvoreUin"ri" ))Pltur"(Io *inicio) 1 if (6inicio) return $+7 else 1 int "ltur"es#uerd"5 "ltur"direit"7 "ltur"es#uerd" < Pltur" (inicio$.es#uerdo)7 "ltur"direit" < Pltur" (inicio$.direito)7 if ("ltur"es#uerd" - "ltur"direit") return "ltur"direit" C +7 else return "ltur"es#uerd" C +7
; ;
int PrvoreUin"ri" )) Pltur"() 1 return Pltur" (this$.r"iW)C+7 ; int PrvoreUin"ri" )) Uusc" (Io *inicio5 int v"lor) 1 Zhile (inicio 6< Igbb) 1 if (v"lor << inicio$.v"lor) return inicio$.v"lor7 else if (v"lor - inicio$.v"lor) inicio < inicio$.es#uerdo7 else inicio < inicio$.direito7 ; return 97 ; void PrvoreUin"ri" )) PreOrdem (Io *inicio) 1 if (inicio 6< Igbb) 1 this$.PreOrdem (inicio$.es#uerdo)7 cout -- inicio$.v"lor -- 3 37 this$.PreOrdem (inicio$.direito)7 ; ; void PrvoreUin"ri" )) EmOrdem (Io *inicio) 1 if (inicio 6< Igbb) 1 cout -- inicio$.v"lor -- 3 37 this$.EmOrdem (inicio$.es#uerdo)7 this$.EmOrdem (inicio$.direito)7 ; ; void PrvoreUin"ri" )) PosOrdem (Io *inicio) 1 if (inicio 6< Igbb) 1 this$.PosOrdem (inicio$.es#uerdo)7 this$.PosOrdem (inicio$.direito)7 cout -- inicio$.v"lor -- 3 37 ; ; PrvoreUin"ri" )) PrvoreUin"ri" () 1 this$.r"iW < Igbb7 ; 'ool PrvoreUin"ri" )) X"Wio () 1 return this$.r"iW << Igbb7 ; void PrvoreUin"ri" )) insere (int v"lor) 1 Io *tmp < this$.r"iW7 Io *"nt < Igbb7 Zhile (tmp 6< Igbb) 1 "nt < tmp7 if (tmp$.v"lor - v"lor) 1 tmp < tmp$.direito7 ; else 1 tmp < tmp$.es#uerdo7 ;
; else if ("nt$.v"lor - v"lor) 1 "nt$.direito < neZ Io (v"lor)7 ; else 1 "nt$.es#uerdo < neZ Io (v"lor)7 ;
int PrvoreUin"ri" )) remove (Io *r"iW5 int v"lor)1 Io *temp < Igbb7 if(r"iW << Igbb) return +7 if(v"lor << r"iW$.v"lor)1 temp < r"iW7 if(r"iW$.es#uerdo << Igbb) r"iW < r"iW$.direito7 else if(r"iW$.direito << Igbb) r"iW < r"iW$.es#uerdo7 else1 temp < noJ"ior(r"iW$.es#uerdo)7 r"iW$.v"lor < temp$.v"lor7 ; delete temp7 return 97 ; else if(v"lor - r"iW$.v"lor) return remove(r"iW$.es#uerdo5 v"lor)7 else return remove(r"iW$.direito5 v"lor)7
int PrvoreUin"ri" )) remove (int v"lor)1 return remove (this$.r"iW5 v"lor)7 ; int PrvoreUin"ri" )) Uusc" (int v"lor)1 return Uusc" (this$.r"iW5 v"lor)7 ; void PrvoreUin"ri" )) PreOrdem () 1 PreOrdem (this$.r"iW)7 ; void PrvoreUin"ri" )) EmOrdem () 1 EmOrdem (this$.r"iW)7 ; void PrvoreUin"ri" )) PosOrdem () 1 PosOrdem (this$.r"iW)7 ;
'ool m"rc"dor7 for(i<+7 i-l"rgur"7 iCC) 1 memori" < t"'el"[i 7 cont"dor < i$+7 do 1 m"rc"dor < f"lse7 if(t"'el"[cont"dor . memori") 1 t"'el"[cont"dorC+ < t"'el"[cont"dor 7 cont"dor$$7 m"rc"dor < true7 ; if(cont"dor - 9) m"rc"dor < f"lse7 ; Zhile(m"rc"dor)7 ; t"'el"[cont"dorC+ < memori"7
'election sort
void selectionSort( int vetor?esorden"do[ 5 int t"m"nhoXetor ) //HunK"o selection rece'endo vetor e t"m"nho 1 int i5 *5 posic"oX"lorJinimo7 for (i < 97 i - ( t"m"nhoXetor $ + )7 iCC) //boop p"r" percorrer o vetor 1 posic"oX"lorJinimo < i7 //O v"lor minimo de posiK"o do vetor " ser percorrido e 9 for (* < ( i C + )7 * - t"m"nhoXetor7 *CC)//Percorreremos o vetor d" posiK"o + "te o t"m"nho estim"do 1 if( vetor?esorden"do[* - vetor?esorden"do[posic"oX"lorJinimo ) //Se " posiK"o #ue v"mos verific"r for menos #ue " posiK"o #ue temos em m"os 1 posic"oX"lorJinimo < *7//P v"ri"vel M*M rece'e esse v"lor ; ; if ( i 6< posic"oX"lorJinimo ) 1 troc"rPosic"oX"lores( Avetor?esorden"do[i 5 Avetor?esorden"do[posic"oX"lorJinimo )7//v"mos ch"m"r um" outr" funK"o p"r" troc"r "s posiKoes de lug"res ; ; ; void troc"rPosic"oX"lores( int *posic"oP5 int *posic"oU )//HunK"o p"r" troc"r "s posiKoes #ue est"mos olh"ndo 1 int tempor"rio7 tempor"rio < *posic"oP7 *posic"oP < *posic"oU7 *posic"oU < tempor"rio7 ;
6u,,le sort
O bubble sort, ou ordenao por "lutuao Iliteralmente %por bol$a%J, < um algoritmo de ordenao dos mais simples. * ideia < per orrer o vetor diversas ve'es, a ada passagem "a'endo "lutuar para o topo o maior elemento da sequ!n ia. >ssa movimentao lembra a "orma omo as bol$as em um tanque de #gua pro uram seu pr2prio nHvel, e disso vem o nome do algoritmo.
elementos do vetor. 8o pior aso, so "eitas opera+es. * omple@idade desse algoritmo < de Ordem quadr#ti a. Por isso, ele no < re omendado para programas que pre isem de velo idade e operem om quantidade elevada de dados.
Cdigo da Bun>o
void Uu''leSort(int vetor[ 5 int t"m"nho) 1 int "ux5 i5 *7 for(*<t"m"nho$+7 *.<+7 *$$) 1 for(i<97 i-*7 iCC) 1 if(vetor[i .vetor[iC+ ) 1 "ux<vetor[i 7 vetor[i <vetor[iC+ 7 vetor[iC+ <"ux7 ; ; ; ;
; ;
%lgoritmo de aloca>o
8irst 8ist ,est 8it 2orst 8it
O algoritmo ?orst "it alo a o blo o de mem2ria na regio que tem o maior espao livre. >st# t< ni a por pro urar o upar primeiro as parti+es maiores termina por dei@ar espaos livres que poderiam ser utili'ados para que outros blo os de outros programas as utili'assem, diminuindo eAou retardando a "ragmentao.
Estudo
#,serva>$es: ] pr<=requisito para um bom aprendi'ado de qualquer linguagem de programao on eitos sobre l2gi a de programao.
Etapas de desenvolvimento + [ 8ases \uase nen$um te@to: (e@to em riao: (e@to em maturao: (e@to desenvolvido: (e@to abrangente:
'um?rio
Introdu>o
Capa Por que aprender a linguagem CS 1ist2ria da linguagem C Pr<=requisitos Btili'ando um ompilador 8o+es de ompilao >ste livro tem uma cole>o para a riao de vers+es nos "ormatos 1(Q3IbetaJ, P,-, O,(, cIQ, ePBL ou para en omendas para a PediaPress. ICarregar esta oleo = *.udaJ
P%"FE I + 6?sico
Bm programa em C Con eitos b#si os &ari#veis (ipos de dados Constantes >ntrada e saHda simples Opera+es matem#ti as IL#si oJ Opera+es matem#ti as I*vanadoJ (odos os operadores de C Controle de "lu@o -un+es O pr<=pro essador >@er H ios
%p/ndices
Palavras 6eservadas ou keR?ords SeqU!n ias de es ape 3ista de "un+es
Conceitos e:tras
So kets Qake"iles
Cola,ora>o
3ista de autores
Ver tam,m
Programar em CCC O 2digo 11Hich" do livro;; s2 deve ser olo ado na p#gina prin ipal do livro, .untamente om o seu Hndi e. Por "avor, remova=o desta p#gina I aso ela no se.a o Hndi eJ, ou adeque a estrutura do livro Fs onven+es de nomen latura. * Wikip<dia tem mais sobre este assunto: Linguagem de programao C
Constantes
>sta p#gina pre isa ser re i lada Idis utaJ. *o mel$or#=la, vo ! estar# a.udando o Wikilivros.
Constantes
>m um apHtulo anterior abordamos as vari#veis e agora vamos abordar onstantes. * ra'o < que as oisas esto mais maduras e uma pessoa sabe muito bem o que < uma onstante. \ue < simplesmente um valor que no se altera durante a e@e uo do programa. * questo de no se alterar durante a es rita do programa < realmente a ra'o deste apHtulo. ,evemos separar as #guas entre uma onstante e um literal. O literal < o pr2prio valor. >@istem 7 maneiras para riar onstantes: /. ,define 0. ` onsta `tipo da vari#vela`nome da vari#vela
7. enumerations >sta Mltima vamos dei@ar para mais tarde, pois so uma boa introduo para as lasses.
Se olo armos estas lin$as no $eader, o que vai a onte er < o seguinte: O pr<=pro essador ir# veri"i ar o nosso 2digo "onte e sempre que en ontrar a diretiva Ode"ine ir#, literalmente, substituir ada o orr!n ia do identi"i ador no 2digo "onte pelo valor de"inido. * vantagem disto < que: Podemos ter um identi"i ador ao nosso gosto, e sempre que ne essitarmos do valor es revemos o identi"i ador, em ve' do valor, at< porque se o valor "osse ompli ado poderHamos enganar=nos a es rever. Claro que nos poderHamos enganar tamb<m a es rever o identi"i ador, daH a es ol$ermos um nome "amiliar. > se ne essitarmos de alterar o valor, alteramos apenas / ve', em ve' de todas as ve'es onde apare eria o valor. O "ormato geral <:
,define identific"dor v"lor
6epare que a diretiva de prepro essador no tem o nZo= nponto e vHrgulao no "im^ O que < normal para diretivas de Prepro essador. O que < que a onte e se tivermos o nZo no "imS Ser# que en ontrei um bugS se eu olo ar o Z no Ode"ine 8>W3I8> )en)Z no a onte e nada. &ale lembrar que ada Ode"ine < prepro essador, ou se.a, no pode ser alterado dentro do programa durante sua e@e uo.
// defined const"nts) c"lcul"te circumference ,include -stdio.h. ,define P] /.+0+2D ,define IE&b]IE 3>n3 int m"in ()1 dou'le r<2.97 dou'le circle7 circle < % * P] * r7 printf(3@f35 circle)7 printf(3@s35 IE&b]IE )7 return 97 ; // r"dius // utiliW"mos o Pi e nLo /.
Com o pre"i@o % onst%, di'emos que a vari#vel no poder# alterar o seu valor. 6epare que se "osse uma vari#vel eu poderia ter:
int "<27
e o valor do a "i ava om o valor de DZ *gora om o pre"i@o const eu no poderei alterar o valor, porque onstante < onstante, no pode mudar o valor. >sta maneira < bem mel$or do que a anterior para de larar onstantes, primeiro porque aqui temos a in"ormao do tipo de vari#vel, em segundo porque podemos "a'er este onst int aZ omo uma "uno lo al e no global.
Condicionais
Programar em CACondi ionais
Lista de autores
Lista de autores
>dudobaR = >duardo Sangiorgio ,obaR >vertonS = >verton.S.Laron 3ig$tningspirit ($iago3 Bder Wbrito 6enato6esende Qa@tremus 8oturno:: = Lruno Sampaio Pin$o da Silva
Capa
.ogos, to adores de mHdia, et . Quitos vo de idir trabal$ar om a mesma linguagem que a bibliote a "oi es rita, e assim o pro esso ontinua... C < uma das linguagens de programao mais populares para se es rever sistemas opera ionais, omo o Qi roso"t Windo?s, o Qa OS Y e o P8BA3inu@. Sistemas opera ionais omuni am=se diretamente om o $ard?areZ no $# nen$uma amada mais bai@a para mediar seus pedidos. Originalmente, os sistemas opera ionais eram es ritos na linguagem *ssemblR, o que resultava em um 2digo muito r#pido e e"i iente. >ntretanto, es rever um sistema opera ional em *ssemblR < um pro esso tedioso IlentoJ, e produ' um 2digo que "un ionar# somente em uma arquitetura de CPB, tal omo o @GD ou *6Q. >s rever um sistema opera ional em uma linguagem de alto nHvel, tal omo C, possibilita que os programadores readaptem o sistema opera ional a v#rias arquiteturas sem pre isar rees rever todo o 2digo. O nM leo IkernelJ 3inu@ < um e@emplo de sistema opera ional es rito em C, om apenas algumas se+es do 2digo es ritas em *ssemblR, para poder e@e utar instru+es que s2 e@istem em uma ou outra arquitetura e para algumas otimi'a+es.
Programar em C Obtido em %$ttp:AApt.?ikibooks.orgA?Ainde@.p$pStitle[ProgramardemdCAImprimir5oldid[007KGD% Categorias: 3ivros om verso para impresso 3ivroAProgramar em C >sboos de In"orm#ti a ^(are"as pendentes
3enu de navega>o
Berramentas pessoais
Criar uma onta *utenti ao
Espa>os nominais
Q2dulo ,is usso
Variantes
Vistas
3er *ltera+es pendentes >ditar >ditar 2digo="onte &er $ist2ri o
%c>$es Pesquisa
Pesquisar Ir
&avega>o
P#gina prin ipal Libliote a P#gina aleat2ria 3ivro aleat2rio *.uda ,onativos
ProJecto
Portal omunit#rio ,i#logos omunit#rios Qudanas re entes Wiki.Mnior
Imprimir/e:portar
Criar uma oleo ,es arregar omo P,-
Berramentas
P#ginas a"luentes *ltera+es rela ionadas Carregar "i $eiro P#ginas espe iais 3igao permanente In"orma+es da p#gina
&outras lCnguas
,euts $ >nglis$ >spazol >esti -ranais Italiano Polski Suomi 8ederlands Svenska Palego {|}}~
>sta p#gina "oi modi"i ada pela Mltima ve' FIsJ /9$;7min de E de .ul$o de 0K//. >ste te@to < disponibili'ado nos termos da li ena Creative Commons *tribuio= Compartil$amento pela mesma 3i ena 7.K BnportedZ pode estar su.eito a ondi+es adi ionais. Consulte as Condi+es de Bso para mais detal$es. PolHti a de priva idade Sobre o Wikilivros >@onerao de responsabilidade Programadores &erso m2vel