melhor apostila de c

Upload: fernandocetel

Post on 11-Oct-2015

65 views

Category:

Documents


2 download

TRANSCRIPT

  • )WGVIZIVYQPMZVSRSYQEXEVIJEJGMPRYRGEJSM8SQEXIQTSI\MKITIWUYMWEIHIHMGES'SQSEWIHMXSVEWRSHIWINEQQEMWTYFPMGEVIWXIXXYPSREHEQEMWREXYVEPUYIXIRXEVGSQIVGMEPM^EPSREJSVQEHIEVUYMZSWIQIPLERXIEYQIFSSO1EWIWXEEXMZMHEHIXEQFQXSQEXIQTSII\MKIHIHMGES

    4IRWERHSEWWMQVIWSPZMPMFIVEVIWXIPMZVSTEVEGSRWYPXETFPMGEWIZSGEGLEUYIIWXIPMZVSXIENYHSYIUYMWIVGSPEFSVEVGSQMKSTEWWIRYQEPSXVMGEIHITSWMXISZEPSVUYIEGLEVUYIHIZI

    8IVQMRSYHITEKEVEGSRXEHIPY^XIPIJSRISYKYEIWSFVSYXVSGSZSGTSHIHITSWMXEVREQMRLEGSRXE)YEGVIHMXSUYIRWHSMWTSHIQSWWEMVKERLERHSZSGTSVUYIXIZIEGIWWSEYQFSQQEXIVMEPUYIXIENYHSYIIYGSQSMRGIRXMZSEGSRXMRYEVIWGVIZIRHSPMZVSW'EWSHIGIVXSXEPZI^SWTV\MQSWPMZVSWRIQWINEQTYFPMGEHSWTSVYQEIHMXSVEIIWXINEQPMFIVEHSWHMVIXEQIRXITEVEWYEGSRWYPXE

    5YEPUYIVZEPSVHITSWMXEHSWIVHMVIGMSREHSTEVEEGSRXETSYTEREHSQIYPLSTEVEUYERHSIPIIWXMZIVREQEMSVMHEHIXIVVIGYVWSWTEVEGSQIEVYQRIKGMSTVTVMSRERGMEVWIYWIWXYHSWIXG

    (EHSWTEVEHITWMXS

    1EVGSW%YVIPMS4GLIO0EYVIERS&ERGS'EM\E)GSRQMGE*IHIVEP%KRGME3TIVES'SRXE

    'YVMXMFEHIQEVSHI

  • Marcos Laureano

  • Copyright 2005 por Brasport Livros e Multimdia Ltda. Todos os direitos reservados. Nenhuma parte deste livro poder ser reproduzida, sob qualquer meio, especialmente em fotocpia (xerox), sem a permisso, por escrito, da Editora. Editor: Sergio Martins de Oliveira Diretora Editorial: Rosa Maria Oliveira de Queiroz Assistente de Produo: Marina dos Anjos Martins de Oliveira Reviso: Maria Helena dos Anjos Martins de Oliveira Editorao Eletrnica: Abreu's System Ltda. Capa: UseDesign

    Dados Internacionais de Catalogao na Publicao (CIP) (Cmara Brasileira do Livro, SP, Brasil)

    Laureano, Marcos Programando em C para Linux, Unix e Windows / Marcos Laureano. Rio de

    Janeiro: Brasport, 2005.

    Bibliografia ISBN 85-7452-233-3

    1. C (Linguagem de programao para computadores) 2. LINUX (Sistema operacional de computador) 3. UNIX (Sistema operacional de computador) 4. WINDOWS (Sistema operacional de computador) I. Ttulo

    05-6860 CDD-005.133

    ndices para catlogo sistemtico: 1. C : Linguagem de programao : Computadores :

    Processamento de dados 005.133 BRASPORT Livros e Multimdia Ltda. Rua Pardal Mallet, 23 Tijuca 20270-280 Rio de Janeiro-RJ Tels. Fax: (21) 2568.1415/2568.1507/2569.0212/2565.8257 e-mails: [email protected] e-mails: [email protected] e-mails: [email protected] site: www.brasport.com.br

  • Agradecimentos

    Este trabalho no teria sado se no fosse pelo apoio da minha esposa Marga-rete e do meu querido filho Luiz Otavio. Foram eles que agentaram o meu mau humor aps longas noites de trabalho. Agradeo Brasport pela oportunidade de publicar meu livro sobre um tema onde vrios autores j trabalharam ( claro que este livro tem um diferencial em relao aos demais!). Aos meus colegas professores e alunos que ajudaram a melhorar este material nos ltimos anos.

    Copiar de um autor plgio; copiar de muitos autores pesquisa.

    Wilson Mizner, escritor americano.

  • Sobre o Autor

    Marcos Laureano tecnlogo em Processamento de Dados pela ESSEI, Ps-graduado em Administrao pela FAE Business School e Mestre em Informtica Aplicada pela Pontifcia Universidade Catlica do Paran. Doutorando na Uni-versidade de Lisboa, onde ir desenvolver trabalhos na rea de segurana em mquinas virtuais e sistemas embarcados. Trabalha com programao em C no ambiente Unix (AIX/HP-UX) desde 1997 e Linux desde 2000, sendo especialista em segurana de sistemas operacionais. professor de graduao e ps-graduao, tendo lecionado em vrias instituies nos ltimos anos. autor de vrios guias de utilizao/configurao de vrios aplicativos para os ambientes Unix e Linux. Possui vrios artigos publicados sobre programao e segurana de sistemas. Atualmente leciona disciplinas relacionadas com segurana, programao e sis-temas operacionais nos cursos de graduao e ps-graduao na FAE Centro Universitrio, e atua como consultor na rea de projetos de desenvolvimento e segurana de sistemas. O autor pode ser contactado pelo e-mail [email protected] ou atravs de sua pgina www.laureano.eti.br, onde est disponvel vasto material sobre programao, segurana de sistemas e sistemas operacionais. O autor mantm um frum em seu site para discusso sobre segurana de sistemas, sistemas operacionais e programao.

  • 1

    Introduo

    Ser professor ... ter breves momentos de satisfao num dia-a-dia feito de desgostos !

    (Annimo)

    ste material no pretende ser o guia definitivo sobre programao em C (nem a sua pretenso), mas sim introduzir as informaes necessrias pa-

    ra comear a programar nesta poderosa linguagem e, principalmente, mostrar que a programao em C para o ambiente Linux e Unix mais simples do que parece. recomendvel que o leitor tenha conhecimentos prvios sobre o sistema Li-nux/Unix, principalmente com relao aos comandos bsicos de utilizao. Di-ferente do que muitos pensam, para voc desenvolver programas para o am-biente Linux/Unix necessrio conhecer apenas alguns comandos do sistema operacional (grep, find, ps, ls, mv, cp, rm, rmdir, mkdir, vi, more e claro o gcc/cc). Para a plataforma Linux utilizado o compilador GNU C Compiler ou simples-mente gcc. possvel obter mais detalhes sobre o gcc em http://www.gnu.org ou http://gcc.gnu.org. Para a plataforma Windows utilizado o Borland C++ 5.5 ou simplesmente bcc32. possvel obter mais detalhes sobre o bcc32 em www.borland.com ou http://www.borland.com/products/downloads/download_cbuilder.html.

    E

  • 2 Programando em C para Linux, Unix e Windows

    Ainda para a plataforma Windows utilizado o LCC-Win32, que um ambien-te integrado e simples para escrever programas em C. O LCC-Win32 pode ser encontrado em http://www.cs.virginia.edu/~lcc-win32/. Os trs compiladores podem ser utilizados livremente em seu computador. Os programas exemplos foram testados nos trs compiladores e funcionam de forma idntica (exceto na declarao da funo main e captulos especficos). Embora a linguagem C seja portvel, algumas funes so especficas para ca-da sistema operacional. Do captulo 1 at o 17, as informaes vistas so vli-das para qualquer sistema operacional. A partir do captulo 18 at o 22 so vis-tas informaes a respeito de particularidades do C para o sistema Unix e Linux. O captulo 23 trata de programao para rede. Embora as opes de programao para rede sejam vastas, neste captulo vista apenas uma pe-quena parte (introdutria). No apndice A so vistas questes sobre recursivi-dade, pesquisas e ordenao. Os apndices B e C mostram como obter ajuda no sistema Linux e Unix e como compilar programas em C nestes ambientes. O apndice D mostra como instalar e compilar um programa utilizando o LCC-Win32. O apndice E contm uma relao das funes mais utilizadas no am-biente Unix e Linux. Caso o leitor ache alguma inconsistncia (pode ocorrer, apesar de todas as pre-caues tomadas) peo que me contate atravs do e-mail [email protected].

  • 3

    Informaes Bsicas1

    A programao hoje uma corrida entre os engenheiros de software que lutam para construir programas maiores e mais prova de idiotas enquanto o universo tenta produzir idiotas maiores e

    melhores. At agora, o universo est vencendo. Rick Cook

    1.1 Histria A linguagem de programao C uma linguagem estruturada e padronizada criada na dcada de 1970 por Ken Thompson e Dennis Ritchie para ser usada no sistema operacional Unix. Desde ento espalhou-se por muitos outros sis-temas operacionais e tornou-se uma das linguagens de programao mais u-sadas. A linguagem C tem como ponto forte a sua eficincia e a linguagem de programao de preferncia para o desenvolvimento de aplicaes para sis-temas operacionais, apesar de tambm ser usada para desenvolver aplicaes mais complexas. O desenvolvimento inicial da linguagem C ocorreu nos laboratrios Bell da AT&T entre 1969 e 1973. Deu-se o nome "C" linguagem porque muitas das suas caractersticas derivaram de uma linguagem de programao anterior chamada "B". H vrios relatos que se referem origem do nome "B": Ken Thompson d crdito linguagem de programao BCPL, mas ele tambm cri-ou uma outra linguagem de programao chamada Bon, em honra da sua mu-lher Bonnie. Por volta de 1973, a linguagem C tinha-se tornado suficientemen-te poderosa para que grande parte do ncleo de Unix, originalmente escrito na linguagem de programao PDP-11/20 assembly, fosse reescrito em C. Este foi um dos primeiros ncleos de sistema operacional que foi implementado

  • 4 Programando em C para Linux, Unix e Windows

    numa linguagem sem ser o assembly, sendo exemplos anteriores o sistema Multics (escrito em PL/I) e TRIPOS (escrito em BCPL).

    1.2 C de K&R Em 1978, Ritchie e Brian Kernighan publicaram a primeira edio do livro The C Programming Language. Esse livro, conhecido pelos programadores de C como "K&R", serviu durante muitos anos como uma especificao informal da linguagem. A verso da linguagem C que ele descreve usualmente referida como "C de K&R". K&R introduziram as seguintes caractersticas na linguagem:

    o Tipos de dados struct; o Tipos de dados long int; o Tipos de dados unsigned int; o O operador =+ foi alterado para +=, e assim sucessivamente (o analisa-

    dor lxico do compilador confundia o operador =+. Por exemplo, i =+ 10 e i = +10).

    C de K&R freqentemente considerada a parte mais bsica da linguagem que necessrio que um compilador C suporte. Nos anos que se seguiram publicao do C de K&R, algumas caractersticas "no-oficiais" foram adicio-nadas linguagem, suportadas por compiladores da AT&T e de outros forne-cedores. Estas incluam:

    o Funes void e tipos de dados void *; o Funes que retornam tipos struct ou union; o Campos de nome struct num espao de nome separado para cada ti-

    po struct; o Atribuio a tipos de dados struct; o Qualificadores const para criar um objecto s de leitura; o Uma biblioteca-padro que incorpora grande parte da funcionalidade

    implementada por vrios fornecedores; o Enumeraes; o O tipo de ponto flutuante de preciso simples.

    1.3 C ANSI e C ISO Durante os finais da dcada de 1970, a linguagem C comeou a substituir a linguagem BASIC como a linguagem de programao de microcomputadores mais usada. Durante a dcada de 1980, foi adotada para uso no PC IBM, e a sua popularidade comeou a aumentar significativamente. Ao mesmo tempo, Bjarne Stroustrup, juntamente com outros nos laboratrios Bell, comeou a

  • Informaes Bsicas 5

    trabalhar num projeto onde se adicionava programao orientada a objetos linguagem C. A linguagem que eles produziram, chamada C++, nos dias de hoje a linguagem de programao de aplicaes mais comum no sistema ope-racional Windows da Microsoft, enquanto o C permanece mais popular no mundo Unix. Em 1983, o instituto norte-americano de padres (ANSI) formou um comit, X3j11, para estabelecer uma especificao do padro da lingua-gem C. Aps um processo longo e rduo, o padro foi completo em 1989 e ra-tificado como ANSI X3.159-1989 "Programming Language C". Esta verso da linguagem freqentemente referida como C ANSI. Em 1990, o padro C ANSI, aps sofrer umas modificaes menores, foi adotado pela Organizao Inter-nacional de Padres (ISO) como ISO/IEC 9899:1990. Um dos objetivos do pro-cesso de padronizao C ANSI foi o de produzir um sobreconjunto do C K&R, incorporando muitas das caractersticas no-oficiais subseqentemente intro-duzidas. Entretanto, muitos programas j tinham sido escritos e no compila-vam em certas plataformas, ou com um certo compilador, devido ao uso de bi-bliotecas no-padro (por exemplo, interfaces grficas) alguns compiladores no aderirem ao padro C ANSI.

    1.4 C99 Aps o processo ANSI de padronizao, as especificaes da linguagem C per-maneceram relativamente estticas por algum tempo, enquanto que a lingua-gem C++ continuou a evoluir. Contudo, o padro foi submetido a uma reviso nos finais da dcada de 1990, levando publicao da norma ISO 9899:1999 em 1999. Este padro geralmente referido como "C99". O padro foi adota-do como um padro ANSI em maro de 2000. As novas caractersticas do C99 incluem:

    o Funes em linha ; o Levantamento de restries sobre a localizao da declarao de vari-

    veis (como em C++) ; o Adio de vrios tipos de dados novos, incluindo o long long int (pa-

    ra minimizar a dor da transio de 32-bits para 64-bits), um tipo de da-dos boolean explcito e um tipo complex que representa nmeros com-plexos;

    o Disposies de dados de comprimento varivel; o Suporte oficial para comentrios de uma linha iniciados por //,

    emprestados da linguagem C++; o Vrias funes de biblioteca novas, tais como snprintf; o Vrios arquivos-cabealho novos, tais como stdint.h .

    O interesse em suportar as caractersticas novas de C99 parece depender muito das entidades. Apesar do gcc e vrios outros compiladores suportarem grande

  • 6 Programando em C para Linux, Unix e Windows

    parte das novas caractersticas do C99, os compiladores mantidos pela Micro-soft e pela Borland no, e estas duas companhias no parecem estar muito in-teressadas adicionar tais funcionalidades, ignorando por completo as normas internacionais.

    1.5 Comentrios Os comentrios de um programa devem ser colocados entre /* e */. O com-pilador ANSI C aceita os comentrios entre /* e */. Quaisquer textos colocados entre estes dois smbolos sero ignorados pelo compilador. Um outro ponto importante que se deve colocar um comentrio no incio de cada funo do programa explicando a funo, seu funcionamento, seus pa-rmetros de entrada e quais so os possveis retornos que esta funo pode devolver. Alguns compiladores mais novos (e seguindo a padronizao da linguagem C99) aceitam como comentrios o //. A diferena bsica que com o // possvel fazer comentrios apenas em uma linha. Exemplos: /* Isto um comentrio */ int i; // ndice do vetor de sada float soma; /* Soma dos valores pagos */ char letra; /* este um comentrio de 02 linhas */

    1.6 Constantes Numricas Sempre preciso colocar constantes em um programa. A linguagem C permite a colocao de constantes, exigindo, porm, uma sintaxe diferenciada para que o compilador identifique o tipo da constante e realize o processamento adequado dela. Na linguagem C tem-se os seguintes formatos para as constantes numricas:

    o Nmeros inteiros De uma maneira geral basta colocar o nmero no programa para que o compilador entenda o formato e trabalhe de maneira adequada.

    o Nmeros reais A exceo vale quando se quer colocar uma constante float. Neste caso, preciso indicar o formato atravs da letra F no fi-nal ou utilizar o formato de ponto flutuante (exemplo: 1.0) para que o compilador entenda. Pode-se tambm utilizar o formato cientfico para isto (exemplo: 0.1E+1).

  • Informaes Bsicas 7

    o Nmeros octais Se um nmero iniciar por zero, o compilador ir con-siderar este nmero como OCTAL, mudando o valor final. Exemplo: Se no programa for colocado 010, o compilador entender que foi colo-cado o valor 8 no programa, pois 010 a representao octal do n-mero 8. Outro exemplo: Se colocado 0019 ser gerado um erro de compilao, pois o compilador no aceita os dgitos 8 e 9 em um n-mero octal.

    o Nmeros hexadecimais Uma outra maneira de indicar um nmero para o compilador o formato em hexadecimal. Este formato muito til quando se trabalha com bits e operaes para ligar ou desligar de-terminados bits de uma varivel. Uma constante ser considerada em hexadecimal se a mesma comear por 0x. Neste caso so aceitos os dgitos 0 a 9 e as letras a a f, maisculas ou minsculas.

    Exemplos:

    Constante Tipo 0xEF Constante Hexadecimal (8 bits) 0x12A4 Constante Hexadecimal (16 bits)03212 Constante Octal (12 bits) 034215432 Constante Octal (24 bits) 10 ou 34 Constante inteira 78U Constante inteira sem sinal 20 Constante long 10F ou 1,76E+2 Constante de ponto flutuante

    1.7 Outras Constantes Alm das constantes numricas pode-se colocar constantes do tipo caractere. O compilador identifica estas constantes atravs dos apstrofos. O compilador permite que se coloque um nico caractere entre apstrofo. Existe uma maneira alternativa de se indicar o caractere quando o mesmo um caractere de controle. Para isto basta colocar entre apstrofo a barra inver-tida e o cdigo ASCII do caractere desejado. Por exemplo, para se colocar um A em uma varivel, pode-se colocar \1 e para se colocar um ou utiliza-se a constante \13. Como alguns caracteres de controle so muito usados, existe uma maneira es-pecial de se indicar estes caracteres. A seguir esto alguns formatos interpre-tados pelo compilador:

  • 8 Programando em C para Linux, Unix e Windows

    Cdigo Significado \b Retrocesso (back) \f Alimentao de formulrio (form feed) \n Nova linha (new line) \t Tabulao horizontal (tab) \" Aspas \' Apstrofo \0 Nulo (0 em decimal) \\ Barra invertida \v Tabulao vertical \a Sinal sonoro (beep) \N Constante octal (N o valor da constante) \xN Constante hexadecimal (N o valor da constante)

    De uma maneira geral, toda vez que o compilador encontrar a barra invertida ele no processar o prximo caractere, a no ser que seja um dos indicados antes. O compilador tambm permite a criao de strings de caracteres. Para se colo-car em constantes deste tipo, deve-se colocar a string entre aspas. Podem-se colocar caracteres especiais utilizando o formato visto antes dentro da string, que o compilador ir gerar o cdigo adequado. Exemplos: Caracteres Caractere - a, F, (, 0 Cdigo - \10, \0, \9 Especiais - \n, \t Strings Sistema de Controle\tRelatorio\n

    1.8 Estrutura de um Programa Um programa bsico em C possui os seguintes blocos:

    #include

    Funes de Usurio

    Funo main

    Obrigatrio

    Opcional

    Obrigatrio

  • Informaes Bsicas 9

    Um programa C deve possuir uma certa estrutura para ser vlido. Basicamente tm-se trs blocos distintos nos programas. Inicialmente deve-se ter uma seo onde sero feitos os includes necessrios para o programa (ser visto com mais de-talhes). Por enquanto deve-se colocar a seguinte linha em todos os programas: #include

    O segundo bloco o bloco das funes definidas pelo usurio. Este bloco no obrigatrio e s existir se o usurio definir uma funo. O ltimo bloco, chamado de bloco principal, obrigatrio em qualquer pro-grama C. Nele est definida a funo main, que ser a funo por onde o pro-grama comear a ser executado.

    1.9 Funo main Todo programa em C deve ter uma funo chamada main. por esta funo que ser iniciada a execuo do programa. Deve-se especificar o tipo da sada da funo, que pode ser int ou void. Caso seja colocado int, o valor retornado pela funo main estar disponvel para teste no sistema operacional. Caso o retorno da funo seja declarado como void, nada ser retornado ao sistema operacional. Alguns compiladores podem exigir que o retorno da fun-o main seja declarado como int. Veja o exemplo:

    #include void main () { printf ("Hello World\n"); }

    ou #include int main () { printf ("Hello World\n"); }

  • 10 Programando em C para Linux, Unix e Windows

    ou

    #include int main(void) { printf ("Hello World\n"); }

    1.10 O que main devolve De acordo com o padro ANSI, a funo main devolve um inteiro para o pro-cesso chamador (geralmente o sistema operacional). Devolver um valor em ma-in equivalente a chamar a funo exit (captulo 6) com o mesmo valor. Se main no devolve explicitamente um valor, o valor passado para o processo chamador tecnicamente indefinido. Na prtica, a maioria dos compiladores C devolvem 0 (zero). Tambm possvel declarar main como void se ela no devolve um valor. Al-guns compiladores geram uma mensagem de advertncia (warning) se a fun-o no declarada como void e tambm no devolve um valor.

    1.11 O C "Case Sensitive" H um ponto importante da linguagem C que deve ser ressaltado: o C Case Sensitive, isto , maisculas e minsculas fazem diferena. Se declarar uma va-rivel com o nome soma ela ser diferente de Soma, SOMA, SoMa ou sOmA. Da mesma maneira, os comandos do C if e for, por exemplo, s podem ser es-critos em minsculas pois, seno, o compilador no ir interpret-los como sendo comandos, mas sim como variveis. Veja o Exemplo:

    #include int main () { printf ("Ola! Eu estou vivo!\n"); return(0); }

    Programa 1.1

    Resultado do Programa 1.1 Ola! Eu estou vivo!

  • Informaes Bsicas 11

    A linha #include diz ao compilador que ele deve incluir o arquivo-cabealho stdio.h. Neste arquivo existem declaraes de funes teis para entrada e sada de dados (std = standard, padro em ingls; io = Input/Output, entrada e sada stdio = Entrada e sada padronizadas). Sempre que for uti-lizada uma destas funes deve-se incluir este comando. O C possui diversos arquivos-cabealho. A linha int main() indica que est sendo definida uma funo de nome main. Todos os programas em C tm que ter uma funo main, pois esta funo que ser chamada quando o programa for executado. O contedo da funo delimitado por chaves { }. O cdigo que estiver dentro das chaves ser execu-tado seqencialmente quando a funo for chamada. A palavra int indica que esta funo retorna um inteiro. Este retorno ser visto posteriormente, quan-do estudarmos um pouco mais detalhadamente as funes do C. A ltima li-nha do programa, return(0); , indica o nmero inteiro que est sendo retor-nado pela funo, no caso o nmero 0. A nica coisa que o programa realmente faz chamar a funo printf(), pas-sando a string (uma string uma seqncia de caracteres, que ser visto poste-riormente) "Ola! Eu estou vivo!\n" como argumento. por causa do uso da funo printf() pelo programa que deve-se incluir o arquivo-cabealho stdio.h. A funo printf() neste caso ir apenas colocar a string na tela do computador. O \n uma constante chamada de constante barra invertida. No caso, o \n a constante barra invertida de new line e ele interpretado como um comando de mudana de linha, isto , aps imprimir Ola! Eu estou vivo! o cursor passar para a prxima linha. importante observar tambm que os comandos do C terminam com ; (ponto-e-vrgula).

    1.12 Palavras Reservadas do C Todas as linguagens de programao tm palavras reservadas. As palavras reserva-das no podem ser usadas a no ser nos seus propsitos originais, isto , no pos-svel declarar funes ou variveis com os mesmos nomes. Como o C case sensitive pode-se declarar uma varivel For, apesar de haver uma palavra reservada for, mas isto no uma coisa recomendvel de se fazer, pois pode gerar confuso. A seguir so apresentadas as palavras reservadas do ANSI C: auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while complex _Bool

  • 12

    Tipos de Dados2

    Aprecie as pequenas coisas, pois um dia voc pode olhar para trs e perceber que elas eram as grandes coisas.

    Robert Brault, jornalista.

    2.1 Tipos Bsicos Para criar variveis em um programa C deve-se indicar para o compilador qual o tipo desta varivel. Uma varivel pode ter um tipo bsico, intrnseco lin-guagem C ou tipo estruturado, montado pelo programador. Nesta seo sero vistos os tipos bsicos j existentes na linguagem e como us-los. A linguagem C define os seguintes tipos bsicos de variveis:

    o int Varivel tipo inteira. Deve ser utilizada para se armazenar valor inteiro, com ou sem sinal.

    o char Varivel do tipo caracteres. Servir para se armazenar um nico caractere.

    o float Para valores com casas decimais (reais) deve-se utilizar este ti-po. Ele pode armazenar nmeros reais com at 6 dgitos significativos.

    o double o mesmo que o anterior, s que pode armazenar mais dgi-tos, dando uma preciso maior nos clculos com casas decimais.

    O tipo void deve ser utilizado no para variveis, mas sim para indicar que uma funo no tem nenhum valor retornado ou no possui nenhum parme-tro de entrada.

  • Tipos de Dados 13

    A padronizao ANSI C 99 especifica ainda mais 2 tipos de variveis: o _Bool Varivel tipo booleana (verdadeiro ou falso). Ressalta-se que

    na linguagem C, em comparaes lgicas, 0 (zero) considerado falso e diferente de 0 (zero) considerado verdadeiro.

    o complex Varivel para trabalhar com valores complexos (razes ima-ginrias, por exemplo).

    2.2 Abrangncia e Modificadores de Tipo A linguagem ANSI C determina para cada tipo intrnseco um certo tamanho em bytes. Este tamanho ir determinar a escala de valores que pode ser colo-cada dentro de um determinado tipo. A seguir esto os limites de valores aceitos por cada tipo e o seu tamanho ocu-pado na memria. Tambm nesta tabela est especificado o formato que deve ser utilizado para ler/imprimir os tipos de dados com a funo scanf e printf (vistos com mais detalhes no captulo 3):

    Tipo Nmero de Bits Formato para

    leitura e impresso

    Incio Fim

    _Bool 8 No tem (pode-se utilizar %d) 0 1

    char 8 %c -128 127 unsigned char 8 %c 0 255 signed char 8 %c -128 127 int 32 %i -2.147.483.648 2.147.483.647 unsigned int 32 %u 0 4.294.967.295 signed int 32 %i -2.147.483.648 2.147.483.647 short int 16 %hi -32.768 32.767 unsigned short int 16 %hu 0 65.535 signed short int 16 %hi -32.768 32.767 long int 32 %li -2.147.483.648 2.147.483.647 signed long int 32 %li -2.147.483.648 2.147.483.647 unsigned long int 32 %lu 0 4.294.967.295 float 32 %f 3,4E-38 3.4E+38 double 64 %lf 1,7E-308 1,7E+308 long double 80 %Lf 3,4E-4932 3,4E+4932

  • 14 Programando em C para Linux, Unix e Windows

    Estes limites podem ser verificados no arquivo limits.h do pacote C e so v-lidos para plataformas de 32 bits. Em plataformas de 16 bits, o int era defini-do com 16 bits (o equivalente a short int na plataforma de 32 bits). Em pla-taformas de 64 bits:

    Tipo Nmero de Bits Formato para

    leitura e impresso

    Incio Fim

    long 64 %li -9223372036854775806 9223372036854775807

    unsigned long 64 %lu 0 18446744073709551615

    Pode-se modificar o comportamento de um tipo bsico, tanto no tamanho (espao em memria) como no seu sinal (positivo ou negativo). Os modificado-res de sinais indicam para o compilador considerar ou no valores negativos para o tipo inteiro. Apesar de existir a palavra signed, ela padro, no preci-sando ser colocada, mas pode sofre influncia do sistema operacional. A pala-vra unsigned indica para o compilador no considerar o bit de sinal, estenden-do assim o limite da varivel inteira. Pode-se modificar o tamanho das variveis do tipo int para que ele ocupe so-mente dois bytes na memria, reduzindo assim o limite de abrangncia para 32768 a +32767. Para isto, coloca-se o modificador short na definio da vari-vel, indicando que sero utilizados somente dois bytes de tamanho. Devem-se tomar alguns cuidados com a portabilidade, pois num sistema a varivel pode ser considerada signed e em outros unsigned; em alguns sistemas operacio-nais (variaes de Unix, OS/2 da IBM etc.) as variveis so definidas por padro com unsigned (sem sinal), em outros como signed (com sinal).

    2.3 Nomenclatura de Variveis Toda varivel de um programa deve ter um nome nico dentro do contexto de existncia dela. Para se formar o nome de uma varivel necessrio seguir al-gumas regras impostas pelo compilador. Estas regras so:

    1. O nome de uma varivel deve comear por uma letra ou por um carac-tere _ (underline).

    2. Os demais caracteres de uma varivel podem ser letras, dgitos e _. 3. O compilador reconhece os primeiros 31 caracteres para diferenciar

    uma varivel de outra. 4. Um ponto importante a ser ressaltado que para o compilador C as le-

    tras maisculas so diferentes das letras minsculas.

  • Tipos de Dados 15

    O processo de escolha de nome de uma varivel importante para a legibili-dade de um programa em manutenes posteriores. H algumas regras bsicas que, se seguidas, iro melhorar muito a futura manuteno do programa.

    1. No utilize nomes que no tenham significados com o uso da varivel. Por exemplo: uma varivel cont utilizada para se guardar a soma de um procedimento. Melhor seria utilizar uma varivel com o nome de soma.

    2. Se uma varivel for utilizada para guardar a soma de um valor, por exemplo, total de descontos, alm da funo coloque tambm o contedo da mesma, chamando a varivel de SomaDesconto.

    3. Se desejar, coloque uma letra minscula no incio indicando o tipo da varivel. Isto facilita muito o entendimento na fase de manuteno. Es-ta tcnica chamada de Nomenclatura Hngara. Procure utilizar esta tcnica em todo o programa e mantenha uma nica maneira de se in-dicar o tipo, pois pior que no ter uma indicao de tipos de variveis no seu nome ter duas maneiras diferentes de indicar isto. Pode-se juntar mais de uma letra, caso o tipo de uma varivel seja composta.

    Tipo Prefixos Exemplo

    char (ch) chOpt short (sh) shTipo int (i) iNum long (l) lValor float (f) fImposto double (db) dbGraus string (s) Stela string c/ \0 (sz) szNome structs (definio) (ST_) ST_Monit structs (st) stFile union (definio) (U_) U_Registro union (un) unBuff ponteiros (p)(tipo) pchOpt Variveis Globais (G_)(tipo) G_lValor

    4. Procure usar somente abreviaturas conhecidas, como por exemplo: Vlr, Cont, Tot, Deb, Cred etc. Quando o significado no puder ser abrevia-do, utilize a forma integral. Exemplos: Balanceamento, GiroSemanal etc.

    5. Se a varivel possui mais de uma palavra em seu nome, procure colocar sempre a primeira letra maiscula e as demais minsculas em cada pa-lavra. Exemplos: GiroSemanal, ContContasNegativas, SomaValorSaldo, TotDebitos.

  • 16 Programando em C para Linux, Unix e Windows

    2.4 Definio de Variveis Para se usar uma varivel em C, ela deve ser definida indicando o seu tipo e o seu nome. Para se fazer isto, deve-se usar a seguinte sintaxe:

    tipo nome1 [, nome2]... ;

    Pode-se definir em uma mesma linha mais de uma varivel, bastando para isto colocar os nomes das variveis separados por vrgulas. Isto deve ser usado so-mente quando as variveis so simples e no se precisa explicar o uso das mesmas. Como sugesto deve-se colocar sempre uma nica varivel por linha e, aps a definio da mesma, colocar um comentrio com a descrio mais completa. Exemplos: float fValorSalrio; char cSexo; int i,k,j;

    2.5 Atribuio de Valores s vezes, ao se definir uma varivel, desejvel que a mesma j tenha um va-lor predefinido. A linguagem C permite que quando se defina uma varivel se indique tambm o valor inicial da mesma. Deve-se colocar aps a definio da varivel o caractere = seguido de um valor compatvel com o tipo da vari-vel. Exemplos: float fValorSalrio = 15000; /* Sonhar no paga imposto */ char cSexo = M; int i,k,j;

    2.6 Definio de Constantes s vezes tambm desejvel que, alm de uma varivel possuir um valor pre-definido, este valor no seja modificado por nenhuma funo de um progra-ma. Para que isto acontea, deve-se colocar a palavra const antes da definio da varivel, indicando ao compilador que, quando detectar uma mudana de va-lor da varivel, seja emitida uma mensagem de erro.

  • Tipos de Dados 17

    Este instrumento muito utilizado para documentar a passagem de parme-tros de uma funo, indicando que um determinado parmetro no ser alte-rado pela funo. Exemplos: const float fValorSalrio = 5000; /* Se for constante nunca receberei aumento???*/ const char cSexo = M; /* Com certeza !!! */

    2.7 Converso de Tipos De uma forma geral, pode-se realizar a converso de um tipo para outro da linguagem C, utilizando o que se chama de typecast. Esta tcnica muito utili-zada para se melhorar o entendimento de alguns trechos de programas. Ou-tras vezes utiliza-se o typecast para compatibilizar um determinado tipo de um parmetro na chamada de uma funo para o tipo do parmetro esperado por aquela funo.

    A sintaxe do typecasting a seguinte: (tipo) valor_constante (tipo) varivel

    No primeiro formato, o compilador ir realizar a transformao da constante indicada para o tipo indicado entre parnteses durante o processo de compila-o. No segundo formato, o compilador ir gerar o cdigo adequado para que a converso ocorra em tempo de execuo. Exemplos: int iASCII = (int) E; /* Cdigo ASCII do E */ /* converter o resultado de uma diviso para inteiro */ short int si; float f; int i; i = (int) (f/si);

    2.8 Declarao typedef Na linguagem C pode-se dar um outro nome a um tipo determinado. Isto feito atravs da declarao typedef. Isto muito usado para se manter a com-patibilidade entre os sistemas operacionais e tambm para encurtar algumas definies longas, simplificando o programa. Tambm o typedef muito usado para criar tipos na prpria lngua do pro-gramador, criando-se tipos equivalentes.

  • 18 Programando em C para Linux, Unix e Windows

    Exemplos: typedef unsigned char uchar; typedef unsigned float ufloat; typede sigend int sint; /* Declarando as variveis */ uchar cSexo; ufloat fSalrio; sint i;

    2.9 Operador sizeof Existe um operador em C que indica o tamanho em bytes que uma determina-da varivel est utilizando na memria. Pode-se tambm colocar um determi-nado tipo como parmetro que o resultado ser o mesmo. Este operador muito utilizado para fazer alocaes dinmicas de memria ou movimentaes diretas na memria. Veja o exemplo: #include void main (void) { int a; short int b; long int c; unsigned int d; unsigned short int e; unsigned long int f; float g; long float h; double i; long double j; char k; printf ("Tamanho do a : %d\n", sizeof(a)); printf ("Tamanho do b : %d\n", sizeof(b)); printf ("Tamanho do c : %d\n", sizeof(c)); printf ("Tamanho do d : %d\n", sizeof(d)); printf ("Tamanho do e : %d\n", sizeof(e)); printf ("Tamanho do f : %d\n", sizeof(f)); printf ("Tamanho do g : %d\n", sizeof(g)); printf ("Tamanho do h : %d\n", sizeof(h)); printf ("Tamanho do i : %d\n", sizeof(i)); printf ("Tamanho do j : %d\n", sizeof(j)); printf ("Tamanho do k : %d\n", sizeof(k)); }

    Programa 2.1

  • Tipos de Dados 19

    Resultado do programa 2.1: Tamanho do a : 4 Tamanho do b : 2 Tamanho do c : 4 Tamanho do d : 4 Tamanho do e : 2 Tamanho do f : 4 Tamanho do g : 4 Tamanho do h : 4 Tamanho do i : 8 Tamanho do j : 8 Tamanho do k : 1

    Observaes:

    3 Nas especificaes atuais da linguagem C, o long e o int tm o mesmo tamanho e o modificador long no altera os tamanhos de float e double.

    3 Uma varivel no precisa ter o seu contedo especificado para se obter o seu tamanho.

    3 O operador sizeof pode ser utilizado direto com o tipo da varivel. Por exemplo, uma linha de cdigo com printf(Tamanho de int = , sizeof(int)); resultaria em Tamanho de int = 4.

  • 20

    Entrada e Sada3

    Cada sada a entrada para algum outro lugar. Tom Stoppard, autor de teatro tcheco

    3.1 Funo printf Sintaxe:

    printf(formato, argumentos);

    Para realizar a impresso de textos no terminal, deve-se utilizar a funo printf. Ela possui um nmero variado de parmetros, tantos quantos forem necessrios. O primeiro parmetro da funo printf deve ser uma string indicando o texto a ser mostrado. Nesta string devem ser colocados formatadores de tipo para cada varivel que ser impressa. No texto tambm podem ser colocados alguns caracteres especiais, indicados atravs da barra invertida, a serem impressos na sada. Se a funo printf no possuir nenhum parmetro, no ser necessrio colo-car os formatadores de tipo em seu parmetro de texto. Pode-se tambm colo-car no texto caracteres indicados atravs da barra invertida. Exemplos:

    o Para se imprimir um texto somente: printf (Sistema de Controle de Estoque);

  • Entrada e Sada 21

    o Para se imprimir um valor de uma varivel b do tipo inteiro: printf (%d, b);

    o Misturando texto e valor de variveis: printf (Acumulado:%d Contas %d,iTotAcum, iTotConta);

    o Com caracteres indicados atravs da barra invertida: printf (%d \t-\t %d\n, b, c);

    3.2 Formatadores de Tipos Para cada varivel colocada no comando printf deve-se indicar qual o for-mato desejado de sada. Isto feito colocando-se o caractere % seguido de uma letra dentro do texto informado como primeiro parmetro da funo printf. A funo printf no faz nenhuma verificao entre o tipo real da varivel e o caractere formatador indicado. Tambm no feita a verificao do nmero correto de formatadores, um para cada varivel. Quando isto acontecer, s se-r percebido quando da execuo do programa, gerando resultados imprevis-veis. Os formatadores que podem ser utilizados devem ser os seguintes:

    Formato Tipo da varivel converso realizada %c Caracteres char, short int, int, long int %d Inteiros int, short int, long int %e Ponto flutuante, notao cientfica float, double %f Ponto flutuante, notao decimal float, double %lf Ponto flutuante, notao decimal double %g O mais curto de %e ou %f float, double %o Sada em octal int, short int, long int, char %s String char *, char [] %u Inteiro sem sinal unsigned int, unsigned short

    int, unsigned long int

    %x Sada em hexadecimal (0 a f) int, short int, long int, char %X Sada em hexadecimal (0 a F) int, short int, long int, char %ld Sada em decimal longo Usado quando long int e int

    possuem tamanhos diferentes

    3.3 Indicando o Tamanho Quando feita a sada do valor de uma varivel, alm de se especificar o tipo (formato) que deve ser mostrado, pode-se indicar o tamanho da sada. A indi-

  • 22 Programando em C para Linux, Unix e Windows

    cao do tamanho depende do tipo da varivel. Para os nmeros inteiros (int, short int, long int, unsigned int, unsigned short int e unsigned long int) a especificao do tamanho tem a seguinte sintaxe:

    % [tam].[qtd_dig]d

    Onde:

    o tam Indica o tamanho mnimo que deve ser colocado na sada caso o nmero possua quantidade menor de dgitos. Se o nmero possuir quantidade de dgitos maior que o valor, o nmero no ser truncado.

    o qtd_dig Quantidade de dgitos que deve ser mostrada. Caso o nme-ro possua quantidade menor que o indicado, sero colocados zeros esquerda at se completar o tamanho indicado.

    Para os nmeros reais (float e double), tem-se o seguinte formato:

    % [tam].[casa_dec]f

    Onde: o tam o mesmo que o descrito antes para os nmeros inteiros. Vale

    completar que, neste tamanho, esto consideradas as casas decimais inclusive.

    o casa_dec Nmero de casas decimais que devem ser mostradas. Caso o nmero possua nmero menor de decimais, o nmero ser completado com zeros at o tamanho indicado. Se o nmero possuir um nmero de casas decimais maior que o indicado, a sada ser truncada para o ta-manho indicado.

    Para as variveis do tipo string pode-se indicar o tamanho mnimo e mximo a ser mostrado atravs da seguinte sintaxe:

    %[tam].[tam_max]s

    Neste caso, se a string possuir tamanho menor que o indicado a sada ser completada com brancos esquerda.

    Veja o exemplo:

    #include void main (void) { printf ("|%8.6d|\n", 820); printf ("|%10d|\n", 820);

    Espao reservado de 8 caracteres (mnimo), preenchendo com zeros esquerda at o mximo de 6 caracteres.

    Espao reservado de 10 caracteres.

  • Entrada e Sada 23

    printf ("|%.8d|\n", 820); printf ("|%08d|\n", 820); printf ("|%2.2f|\n", 1223.4432); printf ("|%10.2|f\n", 1223.4432); printf ("|%20f|\n", 1223.4432); printf ("|%.2f|\n", 1223.4432); printf ("|%10s|\n", "abcdefghijklmnopqrstuvxywz"); printf ("|%10.10s|\n", "abcdefghijklmnopqrstuvxywz"); printf ("|%10s|\n", "abcde"); }

    Programa 3.1

    Resultado do programa 3.1: | 000820| | 820| |00000820| |00000820| |1223.44| | 1223.44| | 1223.443200| |1223.44| |abcdefghijklmnopqrstuvxywz| |abcdefghij| | abcde|

    Preenche com zeros esquerda at o mximo de 8 caracteres.

    Mnimo de 10 caracteres.

    Mnimo e mximo de 10 caracteres. Ocorre um truncamento do campo a ser impresso se este for maior que 10 caracteres.

    Mnimo de 10 caracteres. Preenche com espaos em brancos at o limite de 10 caracteres.

    Espao reservado de 2 caracteres (mnimo), com 2 casas decimais (o nmero arredondado).

    Espao reservado de 10 caracteres (mnimo), com 2 casas decimais (o nmero arredondado).

    Espao reservado de 20 caracteres (mnimo), a quantidade de casas decimais especificada pelo nmero a ser impresso.

    A quantidade de caracteres utilizados especificada pelo nmero a ser impresso, com 2 casas decimais (o nmero arredondado).

  • 24 Programando em C para Linux, Unix e Windows

    3.4 Funo putchar Sintaxe:

    putchar(argumento);

    Esta funo uma maneira simplificada de mostrar um nico caractere na tela. O argumento passado ser convertido para caractere e mostrado na tela. Veja o exemplo: #include void main (void) { char cLetra_a = a; short int iCod_ASCII = 65; /* Cdigo ASCII do A */ putchar (cLetra_a); putchar (iCod_ASCII); }

    Programa 3.2

    Resultado do programa 3.2: aA

    Observao: Na linguagem C, a converso ocorre diretamente, ou seja, o valor 65 foi convertido no momento da impresso para o caractere ASCII correspon-dente ao valor 65. O inverso tambm pode ocorrer; se um valor A foi atribu-do a uma varivel inteira, a converso ser feita automaticamente para 65.

    3.5 Funo scanf Sintaxe:

    scanf(formato, endereos_argumentos);

    Para realizar a entrada de valores para as variveis deve ser utilizada a funo scanf. A sintaxe desta funo muito parecida com o printf. Primeiramente, so informados quais os formatos que sero fornecidos no terminal, depois os endereos das variveis que iro receber estes valores. O formato segue a mesma sintaxe do comando printf, sendo obrigatrio co-locar um formato, especificado atravs do caractere %, e a letra indicando o formato. Para especificar o endereo de uma varivel, necessrio para que a funo scanf localize a varivel na memria, deve-se colocar o caractere & antes do

    Converso automtica...

  • Entrada e Sada 25

    nome da varivel, indicando assim que se est passando o endereo da varivel e no o seu valor. Veja o exemplo: #include void main (void) { int a; float b; scanf ("%d %f", &a, &b); printf ("Inteiro %d\n", a); printf ("Real %f\n", b); }

    Programa 3.3

    Resultado do programa 3.3 10 20.0 Inteiro 10 Real 20.000000

    3.6 Funo getchar Sintaxe:

    var = getchar();

    Quando for necessrio realizar a entrada de um nico caractere, pode ser utili-zada esta funo. Ela l um caractere do terminal e devolve o cdigo ASCII do mesmo. Sendo assim, possvel assinalar o valor da funo para uma varivel do tipo caractere (char). Veja o exemplo: #include void main (void) { char cLetra; cLetra = getchar(); printf ("Letra digitada %c\n", cLetra); }

    Programa 3.4

    Resultado do programa 3.4 f Letra digitada f

    Ser lido um valor inteiro.Este valor ser armazenado na varivel a.

    Ser lido um valor real (decimal).Este valor ser armazenado na varivel b.

    Ser impresso um caractere.Neste caso representado pela varivel cLetra.

    Valores digitados separados por espao.

    Valor digitado.

  • 26

    Operadores4

    Se voc pensar sobre isso tempo suficiente, perceber que isso bvio.

    Saul Gorn, professor americano

    4.1 Operadores Aritmticos Operador Operao

    + Adio - Subtrao * Multiplicao / Diviso % Mdulo (resto da diviso)

    Todas estas operaes exigem dois operandos (nmeros).

    4.2 Operadores Unrios Operador Operao

    ++ Incremento -- Decremento

    A posio relativa destes operadores em relao varivel influencia o seu funcionamento. Se os operadores forem colocados antes da varivel em uma expresso, inicialmente ser efetuado o incremento e depois ser utilizado es-te novo valor na expresso.

  • Operadores 27

    Se os operadores forem colocados aps a varivel, primeiro ser utilizado o va-lor atual da varivel na expresso, e aps, ser realizado o incremento ou de-cremento. Veja o exemplo: #include void main (void) { int vlr1 = 10, vlr2 = 5, vlr3 = 8; int resultado; resultado = vlr1++ + 9; printf ("Resultado 1 %d\n", resultado); resultado = --vlr2 + 10; printf ("Resultado 2 %d\n", resultado); resultado = ++vlr3 * ++vlr3; printf ("Resultado 3 %d\n", resultado); resultado = vlr1++ * vlr1++; printf ("Resultado 4 %d\n", resultado); }

    Programa 4.1

    Resultado do programa 4.1: Resultado 1 19 Resultado 2 14 Resultado 3 90 Resultado 4 132

    4.3 Operadores de Atribuio

    Operador Operao += Adio -= Subtrao *= Multiplicao /= Diviso %= Mdulo

    Como comum a atribuio onde uma varivel somada ou diminuda de um valor e o resultado atribudo mesma varivel, a linguagem C disponibiliza uma maneira curta de realizar este tipo de operao. Veja o exemplo:

    Retorna 10 para vlr1 resultado = 10 + 9 vlr1 = vlr1 + 1

    vlr2 = vlr2 1Retorna 4 para vlr2 resultado = 4 + 10

    vlr3 = vlr3 + 1Retorna 9 para vlr3 vlr3 = vlr3 + 1 Retorna 10 para vlr3 resultado = 9 * 10

    Retorna 11 para vlr1 vlr1 = vlr1 + 1 Retorna 12 para vlr1 vlr1 = vlr1 + 1 resultado = 11 * 12

  • 28 Programando em C para Linux, Unix e Windows

    d += 5; equivale a d = d + 5; b -= (c*8); equivale a b = b (c*8); x *= 2; equivale a x = x * 2;

    4.4 Operadores Relacionais

    Operador Operao < Menor que > Maior que = Maior ou igual a == Igual != Diferente

    Os operadores relacionais servem para realizar a comparao de dois valores distintos. A implementao da linguagem C retorna como resultado destas operaes os seguintes valores:

    o 0 Operao obteve o resultado falso; o 1 Operao obteve o resultado verdadeiro.

    Exemplos:

    4 < 5 resulta 1 50 = 43 resulta 0 4 >= 0 resulta 1 4 != 9 resulta 1

    4.5 Prioridade de Avaliao

    Operadores Prioridade ++ -- Prioridade mais alta * / % Prioridade mdia + - Prioridade baixa

    Quando utilizada uma srie de operadores em uma expresso, deve-se sempre ter em mente a prioridade em que o compilador ir realizar essas operaes. Os operadores unrios tm a maior prioridade e sero executados por primei-ro. Depois sero executadas todas as operaes multiplicativas (*, / e %). Por ltimo sero executadas as operaes aditivas (+ e -). Veja o exemplo:

  • Operadores 29

    #include void main (void) { int vlr1 = 10; int resultado; resultado = 10 5 * 8; printf ("Resultado 1 %d\n", resultado); resultado = 7 * --vlr1 4; printf ("Resultado 2 %d\n", resultado); }

    Programa 4.2

    Resultado do Programa 4.2: Resultado 1 -30 Resultado 2 59

    4.6 Operadores Lgicos

    Operadores Prioridade && Operao lgica E || Operao lgica OU ! Operao lgica negao

    Os operadores lgicos consideram dois operandos como valores lgicos (ver-dadeiro e falso) e realizam a operao binria correspondente. A linguagem C considera como valor verdadeiro qualquer valor diferente de zero. O valor fal-so ser indicado pelo valor zero. Estas operaes, quando aplicadas, iro retornar 1 ou zero, conforme o resul-tado seja verdadeiro ou falso. Veja o exemplo: #include void main (void) { int vlr1 = 10; int resultado; resultado = (vlr1 > 8) && (vlr1 != 6);

    Ocorre a multiplicao (5*8=40)Subtrai 10 (10-40=-30)

    Retornar 9 para vlr1. Realiza a multiplicao (7*9=63). Subtrai 4 (63-4 = 59).

    10 > 8? A expresso verdadeira ento retornado 1.

    10 diferente de 6? A expresso verdadeira ento retornado 1.

    A expresso lgica 1 e 1 retorna 1. Lembrando que 0 representa o valor lgico falso e diferente de zero (1,2,3 etc.) representa o valor lgico verdadeiro.

  • 30 Programando em C para Linux, Unix e Windows

    printf ("Resultado: %d\n", resultado); }

    Programa 4.3

    Resultado do Programa 4.3: Resultado: 1

    4.7 Assinalamento de Variveis Para a linguagem C o assinalamento considerado um operador. Isto significa que podem ser colocados assinalamentos dentro de qualquer comando que exija um valor qualquer. Sempre que um assinalamento efetuado, a linguagem C retorna como resul-tado do assinalamento o valor que foi colocado em variveis. Por isso pode-se utilizar este valor retornado pelo operador = e colocar como se fosse um no-vo assinalamento, concatenando os mesmos. Veja o exemplo: #include void main (void) { int i,j,k,w; i = j = k = 20; printf ("Variavel i: %d\n", i ); printf ("Variavel j: %d\n", j ); printf ("Variavel k: %d\n", k ); printf ("Resultado da expressao: %d\n", w = 90); printf ("Variavel w: %d\n", w ); }

    Programa 4.4

    Resultado do Programa 4.4: Variavel i: 20 Variavel j: 20 Variavel k: 20 Resultado da expressao: 90 Variavel w: 90

    Atribuio mltipla de 20 para as variveis i, j e k. Equivalente a: i = 20; j = 20; k = 20;

    Atribui 90 varivel w e depois o contedo da varivel impresso.

  • Operadores 31

    4.8 Parnteses e Colchetes como Operadores Em C, parnteses so operadores que aumentam a precedncia das operaes dentro deles. Colchetes realizam a indexao de matrizes (ser visto mais tar-de). Dada uma matriz, a expresso dentro de colchetes prov um ndice dentro dessa matriz. A precedncia dos operadores em C.

    Maior ( ) [ ] ->

    ! ~ ++ -- -(tipo) * & sizeof

    * / %

    + -

    >

    =

    == !=

    &

    ^

    |

    &&

    ||

    ?

    = += -= *= /=

    Menor ,

    Veja o exemplo:

    #include void main (void) { int w,k; int resultado; printf ("Resultado da expressao 1: %d\n", 9*(w = 90)); printf ("Variavel w: %d\n", w ); printf ("Resultado da expressao 2: %d\n", resultado = (20*(k=50))); printf ("Variavel k: %d\n", k ); printf ("Variavel resultado: %d\n", resultado ); }

    Programa 4.5

    Atribui 90 varivel w. Realiza a multiplicao (9*90=810) Imprime o resultado (810)

    Atribui 50 varivel k. Realiza a multiplicao (20*50=1000). Atribui 1000 varivel resultado. Imprime o contedo da varivel resultado (1000).

  • 32 Programando em C para Linux, Unix e Windows

    Resultado do Programa 4.5: Resultado da expressao 1: 810 Variavel w: 90 Resultado da expressao 2: 1000 Variavel k: 50 Variavel resultado: 1000

    Observao: Embora a linguagem C permita o assinalamento de variveis no meio de expresses, seu uso no recomendado, pois dificulta o entendimen-to do programa.

    4.9 Operador & e * para Ponteiros O primeiro operador de ponteiro &. Ele um operador unrio que devolve o endereo na memria de seu operando. Por exemplo:

    m = &count;

    pe o endereo na memria da varivel count em m. Esse endereo a posio interna da varivel no computador e no tem nenhuma relao com o valor de count. Voc pode imaginar & como significando o endereo de.

    O segundo operador *, que o complemento de &. O * um operador un-rio que devolve o valor da varivel localizada no endereo que o segue. Por exemplo, se m contm o endereo da varivel count:

    q = *m;

    coloca o valor de count em q. Pense no * como significando no endereo de. Observaes:

    3 Cuidado para no confundir * como multiplicao na utilizao de ponteiros e vice-versa;

    3 Cuidado para no confundir & como o operador relacional && e vice-versa. Ser vista com detalhes a utilizao de ponteiros no captulo 11.

  • 33

    Comandos de Seleo5

    Se no fosse para cometer erros, eu no tomaria decises. Robert Wood Johnson, empresrio americano

    5.1 Comando if Sintaxe:

    if (condio) {

    bloco de comandos }

    O comando if funciona da seguinte maneira: primeiramente, a expresso da condio avaliada. Caso o resultado seja verdadeiro (diferente de zero, o que significa verdadeiro em C), o bloco de comandos entre {} executado. Caso a expresso resulte em falso (igual a zero), o bloco de comandos no ser execu-tado. Se o bloco de comandos na realidade representar um nico comando, no ser necessrio colocar {}, bastando o comando aps o if. Veja o exemplo: #include void main (void) { int vlr1; int resultado;

  • 34 Programando em C para Linux, Unix e Windows

    printf ("Entre com um numero :"); scanf ("%d", &vlr1); if ((vlr1 % 2) == 0) { printf ("Numero Par\n"); } }

    Programa 5.1

    Resultado do Programa 5.1: Entre com um numero :20 Numero Par

    5.2 Comando if...else...

    Sintaxe: if (condio) {

    bloco de comandos 1 } else {

    bloco de comandos 2 }

    Podem-se tambm selecionar dois trechos de um programa baseados em uma condio. Para isto utiliza-se a construo if...else.... Este comando inici-almente testa a condio. Caso seja verdadeiro, o bloco de comando ser exe-cutado. Caso a condio resulte em valor falso, ser executado o bloco de co-mandos 2. Veja o exemplo: #include void main (void) { int vlr1; int resultado; printf ("Entre com um numero : "); scanf ("%d", &vlr1); if ((vlr1 % 2) == 0) printf ("Numero Par\n"); else printf ("Numero Impar\n"); }

    Programa 5.2

    Se o resto da diviso for zero, o nmero par. Exemplo: 4 divido por 2 = 2 com resto 0.

    Se o resto da diviso for 1, o nmero mpar. Exemplo: 7 divido por 2 = 3 com resto 1.

    Valor digitado.

    Se o resto da diviso for zero, o nmero par. Exemplo: 4 divido por 2 = 2 com resto 0.

  • Comandos de Seleo 35

    Resultado do Programa 5.2: 1 Execuo Entre com um numero : 21 Numero Impar

    2 Execuo Entre com um numero : 24 Numero Par

    5.3 Operador ? : Sintaxe: (cond? bloco_verd : bloco_falso)

    O operador ? : uma maneira simplificada de escrever um if...else. Apesar de possuir a mesma funcionalidade, no se deve usar este operador quando os comandos envolvidos so complexos. Primeiramente a condio avaliada. Dependendo do resultado o bloco res-pectivo ser executado. Veja o exemplo: #include void main (void) { int vlr1; printf ("Entre com um numero : "); scanf ("%d", &vlr1); printf ((vlr1%2 == 0? "Numero Par\n" : "Numero Impar\n")); }

    Programa 5.3

    Resultado do Programa 5.3 1 Execuo Entre com um numero : 37 Numero Impar

    2 Execuo Entre com um numero : 10 Numero Par

    Esta linha idntica ao programa 5.2

    Valor digitado.

    Valor digitado.

    Valor digitado.

    Valor digitado.

  • 36 Programando em C para Linux, Unix e Windows

    5.4 Comando switch...case Sintaxe:

    switch (expresso) { case const1:{ bloco_1...;break;} case const2:{ bloco_2...;break;} ....... default : { bloco_n... }

    }

    Caso seja necessrio realizar operaes baseadas em um valor de uma expres-so ou varivel, em vez de se construir para isto uma cadeia de if...else...if...else..if...else, pode-se utilizar o comando de seleo mltipla switch...case. Inicialmente o valor da expresso avaliado. Depois feita uma comparao com cada valor colocado na seo case. Caso o valor seja coincidente, o bloco ligado ao case ser executado. Convm ressaltar que a execuo continuar na ordem em que os comandos aparecem, indiferentemente se eles fazem parte de outro case. Para interromper a execuo deve-se utilizar a clusula break, indicando que deve ser interrompida a execuo e passar a executar os co-mandos aps o switch. Existe a possibilidade de colocar uma condio para que, se nenhum case foi selecionado, um bloco seja executado. A palavra default indicar este bloco padro a ser executado. Veja o exemplo: #include void main (void) { int vlr1; printf ("Entre com um numero : "); scanf ("%d", &vlr1); switch (vlr1) { case 1 : { printf ("Um\n"); break;} case 2 : { printf ("Dois\n"); break;} case 3 : { printf ("Tres\n"); break;}

    Aqui vai a varivel a ser avaliada.

    Aqui vai o valor (constante) que ser utilizado na comparao.

  • Comandos de Seleo 37

    case 4 : { printf ("Quatro\n"); break;} case 5 : { printf ("Cinco\n"); break;} case 6 : { printf ("Seis\n"); break;} case 7 : { printf ("Sete\n"); break;} case 8 : { printf ("Oito\n"); break;} case 9 : { printf ("Nove\n"); break;} default : printf ("Valor nao associado\n"); break; } }

    Programa 5.4

    Resultado do Programa 5.4 Entre com um numero : 8 Oito

    Caso no seja utilizado o comando break, todos os demais comandos/instru-es sero executados, at encontrar o prximo comando break, aps a pri-meira condio verdadeira. Veja o exemplo: #include void main (void) { int vlr1; printf ("Entre com um numero : "); scanf ("%d", &vlr1); switch (vlr1) { case 1 : { printf ("Um\n"); break;} case 2 : { printf ("Dois\n"); break;}

    Valor digitado.

    Se nenhuma opo anterior corresponder varivel informada.

    No precisa deste comando aqui, afinal no existem mais condies para serem avaliadas dentro da estrutura switch.

  • 38 Programando em C para Linux, Unix e Windows

    case 3 : { printf ("Tres\n"); break;} case 4 : { printf ("Quatro\n"); break;} case 5 : { printf ("Cinco\n"); break;} case 6 : { printf ("Seis\n"); break;} case 7 : { printf ("Sete\n"); } case 8 : { printf ("Oito\n"); } case 9 : { printf ("Nove\n"); break;} default : printf ("Valor nao associado\n"); break; } }

    Programa 5.5

    Resultado do Programa 5.5:

    1 Execuo: Entre com um numero : 6 Seis

    2 Execuo: Entre com um numero : 7 Sete Oito Nove

    3 Execuo: Entre com um numero : 8 Oito Nove

    Valor digitado.

    Valor digitado.

    Valor digitado.

    No colocado o comando break.Todos os comandos sero avaliados at o prximo comando break.

    No colocado o comando break.Todos os comandos sero avaliados at o prximo comando break.

  • 39

    Comandos de Repetio6

    Como eu disse antes, eu nunca me repito. (Annimo)

    6.1 Comando for Sintaxe:

    for(inicializao; condio de fim; incremento) {

    bloco de comandos }

    Quando se quer executar um bloco de comando um nmero determinado de vezes, deve-se utilizar o comando for. Na sua declarao, o comando for de-termina trs reas distintas. A primeira rea so os comandos que sero execu-tados inicialmente. Deve-se colocar nesta rea comandos de inicializao de variveis. A segunda rea a de teste. A cada interao, as condies colocadas a so testadas e, caso sejam verdadeiras, segue-se com a execuo do bloco de co-mandos. A ltima rea possui comandos que sero executados ao final da interao. Geralmente so colocados nesta rea os comandos de incrementos de vari-veis.

  • 40 Programando em C para Linux, Unix e Windows

    Pode-se omitir os comandos da rea de inicializao e de incremento, bastan-do-se colocar o ponto e vrgula. Veja o exemplo: #include void main (void) { int vlr1; int i; printf ("Contar ate : "); scanf ("%d", &vlr1); for (i=1; i

  • Comandos de Repetio 41

    to, ser executado at que se alcance uma condio falsa. De uma outra ma-neira, o bloco de comando ser executado enquanto a condio for verdadei-ra. Veja o exemplo: #include void main (void) { int vlr1; int i; printf ("Contar ate : "); scanf ("%d", &vlr1); i =1; while (i

  • 42 Programando em C para Linux, Unix e Windows

    #include void main (void) { int vlr1; do { printf ("Entre com um numero diferente de zeros: "); scanf ("%d", &vlr1); } while (vlr1 == 0); printf ("Valor digitado: %d\n", vlr1); }

    Programa 6.3

    Resultado do Programa 6.3 Entre com um numero diferente de zeros: 0 Entre com um numero diferente de zeros: 0 Entre com um numero diferente de zeros: 0 Entre com um numero diferente de zeros: 3 Valor digitado: 3

    6.4 Comando break Sintaxe:

    while (condio) {

    bloco de comandos; break;

    }

    s vezes necessrio quebrar a execuo de um comando repetitivo devido a uma condio determinada. Pode-se programar esta condio no prprio local da condio dos comandos repetitivos ou colocar um teste dentro do bloco de comandos. Caso a condio seja alcanada, pode-se sair do comando repetitivo de uma maneira no usual, terminando a execuo deste comando. Veja o exemplo: #include void main (void) { int vlr1; int i; char resp; printf ("Contar ate : "); scanf ("%d", &vlr1);

    Executa o conjunto de instrues...

    ...enquanto a condio for verdadeira.

    Valores Digitados

  • Comandos de Repetio 43

    i =1; while (i 10 && i < 20)

    Valor digitado.

    Se for respondido Sim...

    ...interrompe a execuo...

    ...desviando o programa para a prxima instruo depois do } (fecha chaves) do while.

    De 1 at 29.

    Se a varivel i estiver entre 11 e 19...

  • 44 Programando em C para Linux, Unix e Windows

    continue; printf ("%d\n", i); } }

    Programa 6.5

    Resultado do Programa 6.5 1 2 3 4 5 6 7 8 9 10 20 21 22 23 24 25 26 27 28 29

    6.6 Comando goto Sintaxe:

    ... goto saida; ... saida: comandos ...

    O comando goto realiza o desvio da execuo para o comando que possuir o label indicado. Apesar de existir este comando, todas as boas tcnicas de pro-gramao dizem que seu uso deve ser evitado. Deve ser usado somente em processamento de exceo, desviando para uma rea especfica caso ocorra al-gum erro grave na execuo de algum comando. Veja o exemplo: #include void main (void) { int vlr_a; int vlr_b;

    ...o comando continue desvia o controledo programa para o comando for.

  • Comandos de Repetio 45

    while (1) { printf ("Valores:"); scanf ("%d %d", &vlr_a, &vlr_b); if (vlr_a == 0) goto fim; if (vlr_b == 0) goto erro; printf ("Divisao : %d\n", vlr_a / vlr_b); } erro: printf ("Divisao por zero\n"); fim: printf ("Fim da execucao do programa\n"); }

    Programa 6.6

    Resultado do Programa 6.6 1 Execuo Valores:23 234 Divisao : 0 Valores:24 2 Divisao : 12 Valores:0 23 Fim da execucao do programa

    2 Execuo Valores:24 0 Divisao por zero Fim da execucao do programa

    6.7 Comando exit Sintaxe:

    exit (valor_de_retorno);

    A funo exit deve ser usada quando se quer terminar a execuo do progra-ma, retornando para o sistema operacional um indicativo. Tanto em Unix/Linux como em Windows/DOS existem maneiras de se obter o nmero retornado. O retorno 0 (zero) indica para o sistema operacional que o programa terminou corretamente, um retorno diferente de 0 (zero) indica um erro. Veja o exemplo: #include #include void main (void)

    Valores Digitados.

    Valores Digitados.

    Valores Digitados.

    Valores Digitados.

    Executado somente se for informado o valor 0 para a varivel vlr_b.

    Esta linha executada sempre, pois todos os comandos aps um label goto sero interpretados. Mesmo que faa parte de outro label goto.

    Caso seja informado 0 para vlr_b, o programa desviado para o label erro atravs do comando goto..

  • 46 Programando em C para Linux, Unix e Windows

    { int vlr_a; int vlr_b; while (1) { printf ("Valores:"); scanf ("%d %d", &vlr_a, &vlr_b); if (vlr_a == 0) exit (0); if (vlr_b == 0) exit (11); printf ("Divisao : %d\n", vlr_a / vlr_b); } }

    Programa 6.7

    Resultado do Programa 6.7 No Unix/Linux: 1 Execuo Valores:24 23 Divisao : 12 Valores:0 12

    $> echo $? 0

    2 Execuo Valores:24 0

    $> echo $? 11

    No Windows: 1 Execuo C:\> echo %errorlevel% 0

    2 Execuo C:\> echo %errorlevel% 11

    Comando no Unix/Linux que mostra o valor retornado pelo programa.

    Comando no Unix/Linux que mostra o valor retornado pelo programa.

    Valor retornado.

    Valor retornado.

    Comando no Windows/DOS que mostra o valor retornado pelo programa.

    Valor retornado. Comando no Windows/DOS que mostra o valor retornado pelo programa.

    Valor retornado.

  • 47

    Definies de Funes7

    Prefiro ser esta metamorfose ambulante do que ter aquela velha opinio formada sobre tudo.

    Raul Seixas, cantor e compositor de rock brasileiro

    7.1 Criao de Funes A boa tcnica de programao diz para, sempre que possvel, evitar cdigos extensos, separando o mesmo em funes, visando um fcil entendimento e uma manuteno facilitada. De acordo com a tcnica, devem-se agrupar cdi-gos correlatos em uma funo. Uma outra utilizao de funo quando um trecho de cdigo ser utilizado muitas vezes no programa. Deve-se colocar este trecho em uma funo e, sem-pre que for preciso, chamar a funo. A Linguagem C possibilita criar funes, sendo possvel passar parmetros para elas e retornar valores, tanto no nome da funo, como em algum parmetro passado.

    7.2 Funo e Prottipo (assinatura da funo) O uso de funes na linguagem C exige certas regras. Primeiramente, a funo deve estar definida, isto , deve-se indicar para o compilador qual o nome da funo e quais so os parmetros esperados.

  • 48 Programando em C para Linux, Unix e Windows

    Uma maneira simples de resolver isso a colocao da funo antes de seu u-so, ou seja, coloca-se a funo dentro do programa fonte antes das posies onde ela chamada. Quando se tm sistemas grandes, no recomendvel ter um nico arquivo fonte, pois a manuteno seria impraticvel. Neste caso possvel ter uma fun-o definida em um programa fonte e seu uso em outro programa fonte. Para resolver este problema, a linguagem C criou uma definio chamada de pro-ttipo. No prottipo de uma funo definido somente o necessrio para o compila-dor no acusar erros. A definio do prottipo geralmente colocada dentro de arquivos header e includa dentro dos programas fontes. No prottipo somente so informados o nome da funo, o seu tipo de retor-no e o tipo de cada parmetro esperado.

    7.3 Definindo Funes Sintaxe:

    tp_ret nome (tipo_par1 nome_par1,tipo_par2 nome_par2) { }

    Para se definir uma funo deve-se indicar o tipo do retorno da funo, seu nome e os parmetros da mesma. Uma funo pode ou no retornar um valor. Se uma funo no retorna ne-nhum valor, seu retorno deve ser definido como void. Os parmetros devem ser definidos, um por um, indicando o seu tipo e nome separado por vrgula. Veja o exemplo: #include int soma (int, int); void main (void) { int vlr_a; int vlr_b; int resultado;

    Declarao da funo (prottipo da funo). Esta declarao indica que a funo soma ir receber 2 valores inteiros e vai retornar 1 valor inteiro.

  • Definies de Funes 49

    printf ("Entre com os valores:"); scanf ("%d %d", &vlr_a, &vlr_b); resultado = soma (vlr_a, vlr_b); printf ("Soma : %d\n", resultado); } int soma (int a, int b) { return a + b; }

    Programa 7.1

    Resultado do Programa 7.1 Entre com os valores:10 20 Soma : 30

    7.4 Comando return Sintaxe:

    return expresso;

    Quando uma funo deve retornar valores, utiliza-se o comando return. Quando este comando executado, o valor indicado retornado para a fun-o e a mesma encerra a sua execuo, independentemente do local onde o return se encontra. Veja o exemplo: #include int le_numero (void); int soma (int, int); void main (void) { int vlr_a; int vlr_b; vlr_a = le_numero(); vlr_b = le_numero(); printf ("Soma : %d\n", soma (vlr_a, vlr_b)); } int le_numero (void) { char ch; int valor;

    Valores digitados.

    Funo soma. Recebe 2 inteiros.

    Retorna 1 valor inteiro.

    Chamada da funo.

    Declarao das funes (prottipos).

    O resultado de uma funo pode ser utilizado diretamenteem outra funo.

  • 50 Programando em C para Linux, Unix e Windows

    printf ("Entre com um numero :"); ch = getchar(); while (ch < '0' || ch > '9') ch = getchar (); valor = 0; while (ch >= '0' && ch

  • Definies de Funes 51

    7.7 Variveis Locais Quando uma varivel definida dentro de uma funo, est sendo defininda uma varivel local funo. Esta varivel utiliza a pilha interna da funo co-mo memria; portanto, ao final da funo, este espao de memria liberado e a varivel no existe mais. A definio da varivel s vlida dentro da fun-o. Os parmetros de uma funo tambm so considerados variveis locais e tambm utilizam a pilha interna para a sua alocao. Veja o exemplo: #include int soma (int, int); int diferenca (int, int); void le_valores(void); int vlr_a; int vlr_b; void main (void) { int resultado; le_valores(); printf ("Soma : %d\n", soma (vlr_a, vlr_b)); printf ("Diferenca : %d\n", diferenca (vlr_a, vlr_b)); } void le_valores(void) { printf ("Entre com os valores:"); scanf ("%d %d", &vlr_a, &vlr_b); } int soma (int a, int b) { int resultado; resultado = a + b; return resultado; } int diferenca (int a, int b) { int resultado;

    Declarando as variveis como pblicas, ou seja, elas estaro disponveis para uso em todo o programa.

    Varivel local e portanto somente disponvel para a funo main.

    Variveis pblicas declaradas anteriormente.

    Variveis pblicas declaradas anteriormente.

    Varivel local e portanto somente disponvel para a funo soma. Importante: no a mesma varivel definida anteriormente.

    Variveis declaradas como parmetros de funo sempre so locais, portanto as variveis a e b esto disponveis para uso somente na funo soma.

    Variveis declaradas como parmetros de funo sempre so locais, portanto as variveis a e b esto disponveis para uso somente na funo diferenca, embora na funo soma tambm tenha sido utilizado o mesmo nome para as variveis.

  • 52 Programando em C para Linux, Unix e Windows

    resultado = a b; return resultado; }

    Programa 7.3

    Resultado do Programa 7.3 Entre com os valores:10 20 Soma : 30 Diferenca : -10

    7.8 Definio extern Quando o sistema separado em vrios programas, pode-se ter o problema de acesso a certas variveis globais, pois a definio da mesma pode estar em um programa fonte e necessrio acessar estas variveis em outro programa fonte. Como na linguagem C deve-se sempre definir uma varivel antes de us-la, quando ocorrer a situao descrita, deve ser indicado no programa que ir u-sar a varivel que a mesma est definida em outro programa. Para fazer isto basta colocar a palavra extern na frente da definio da vari-vel juntamente com a definio do seu tipo e nome. Feito isto, est sendo indi-cado para o compilador o necessrio para que no sejam gerados erros, e indicado que a varivel j foi definida em outro arquivo fonte. Veja o exemplo do programa principal e do programa auxiliar: Programa principal: #include void imprime_soma (void); int vlr_a; int vlr_b; void main (void) { int resultado; printf ("Entre com os valores:"); scanf ("%d %d", &vlr_a, &vlr_b); imprime_soma(); }

    Programa 7.4.1

    Valores digitados.

    Declarao do prottipo da funo. Mesmo que a funo no esteja no mesmo cdigo fonte, importante informar ao compilador que esta funo existe, seno ocorrer erro na compilao.

    Declarando as variveis como pblicas, ou seja, elas estaro disponveis para uso em todo o programa.

  • Definies de Funes 53

    Programa auxiliar: #include extern int vlr_a; extern int vlr_b; void imprime_soma (void) { printf ("Soma %d\n", vlr_a + vlr_b); }

    Programa 7.4.2

    Resultado da execuo do programa 7.4.1 e 7.4.2 Entre com os valores:20 70 Soma 90

    7.9 Definio static Como padro, toda varivel definida dentro de uma funo alocada na pilha interna de execuo da funo. Ao final da funo, a pilha liberada, liberan-do assim a memria alocada pela varivel. Na prxima chamada funo fei-ta uma nova alocao na pilha e assim por diante. Quando for necessrio que uma varivel local de uma funo permanea com o seu valor mantido, mesmo depois que a funo termine, permitindo assim na prxima chamada utilizar o valor anterior, deve-se indicar atravs da palavra static na definio da mesma. Veja o exemplo: #include int somatorio (int, int); void main (void) { int vlr_a; int i;

    i = 1; while (1) { printf ("Entre com um valor:"); scanf ("%d", &vlr_a); if (vlr_a == 0) break;

    Valores digitados.

    Declarando que existem, em outro programa, as variveis pblicas, ou seja, elas estaro disponveis para uso em todo o programa.

    Uso das variveis pblicas.

    Quando o valor for zero, o programa encerrado.

  • 54 Programando em C para Linux, Unix e Windows

    printf ("Somatorio %d\n", somatorio (i++, vlr_a)); } } int somatorio (int cont, int vlr) { static int soma; if (cont == 1) soma = vlr; else soma += vlr; return soma; }

    Programa 7.5

    Resultado do Programa 7.5 Entre com um valor:1 Somatorio 1 Entre com um valor:5 Somatorio 6 Entre com um valor:10 Somatorio 16 Entre com um valor:0

    7.10 Funo atexit Sintaxe:

    int atexit(void (*func)(void))

    Conforme definido no ANSI C, pode-se registrar at 32 funes que sero automaticamente executadas quando um processo termina. Estas funes so chamadas de exit handlers e so registradas atravs da chamada funo atexit(). As funes sero chamadas na ordem inversa ao seu registro. Pode-se registrar a mesma funo mais de uma vez que a mesma ser chamada tantas vezes quantas registradas. A funo a ser registrada no deve esperar nenhum parmetro, bem como no esperado que a funo retorne nenhum valor, devendo ser definida como:

    void funcao(void);

    Valor digitado.

    Na primeira execuo, a varivel soma somente recebe o valor digitado...

    ... nas demais execues, a varivel soma recebe o seu prprio valor somado do contedo da varivel vlr.

    Declara a varivel como static, ou seja, diz ao compilador que o contedo da varivel soma deve ser guardado na memria at o final da execuo do programa.

    Valor digitado.

    Valor digitado.

  • Definies de Funes 55

    Veja o exemplo: include #include void saindo1(void) { printf("\nFinalizando 1."); } void saindo2(void) { printf("\nFinalizando 2."); } int main(void) { printf("\nRegistrando funes.."); atexit(saindo1); atexit(saindo2); printf("\nNo meio do programa..."); exit(0); }

    Programa 7.6

    Resultado do Programa 7.6 Registrando funes.. No meio do programa... Finalizando 2. Finalizando 1.

    A funo no recebe e nem devolve nenhum valor.

    Registro das funes que sero executadas antes do trmino do programa.

    Execuo na ordem inversa.

  • 56

    Pr-Compilao8

    Apenas porque tudo diferente no significa que algo mudou. Irene Peter, escritora americana

    8.1 Fases de uma compilao

    Programa Fonte

    Arquivos headers

    Bibliotecas

    Pr-compilador

    Fonte Expandido

    Compilador

    Cdigo objeto Link Editor

    Cdigo executvel

    O processo de compilao de um programa constitudo de trs fases distin-tas: pr-compilao, compilao e link-edio. Na fase de pr-compilao, o programa fonte lido e, caso encontre comandos do pr-compilador, eles se-

  • Pr-Compilao 57

    ro processados. O pr-compilador gera ento um cdigo intermedirio que ser lido pelo compilador. O compilador interpreta a linguagem deste fonte intermedirio e gera o cdigo objeto, que um cdigo em assembler, pronto para ser utilizado. A ltima fase do processo de compilao a link-edio. Nesta fase, o link-editor l o cdigo objeto gerado e identifica nele quais so as funes do sis-tema que foram utilizadas e busca o cdigo das mesmas nas bibliotecas de sistema. Por fim, o link-editor agrupa todos os cdigos objetos e gera o pro-grama executvel final.

    8.2 Diretiva #include Sintaxe:

    #include #include arquivo.h

    Todos os comandos para o pr-compilador comeam com o caractere #. O comando #include indica para o pr-compilador ler o arquivo indicado e colo-car o mesmo no programa fonte intermedirio. O arquivo includo possui o nome de arquivo header e geralmente possui pro-ttipo de funes a serem utilizadas por todos os programas de um sistema. Possui tambm as declaraes de tipos existentes (typedef) no sistema. Quando um arquivo header pertence ao sistema (ou seja, ao compilador) deve-se colocar o nome dele entre . Se o arquivo header for local (criado pe-lo programador) deve-se colocar o nome dele entre aspas. Na prtica, esta re-gra no precisa ser seguida, pois a utilizao de indica ao compilador pri-meiro procurar o arquivo header no diretrio local e depois nos diretrios do sistema, e o < > indica para o compilador primeiro procurar o arquivo header nos diretrios do sistema e depois no diretrio local. Veja os programas principal, auxiliar e o arquivo header: Programa principal: #include #include "soma.h" int vlr_a; int vlr_b; void main (void) {

    Repare na forma como os arquivos headers foram inseridos. O arquivo header padro do sistema tem o seu nome preenchido entre < > e o arquivo header local tem o seu nome preenchido entre .

  • 58 Programando em C para Linux, Unix e Windows

    int resultado; printf ("Entre com os valores:"); scanf ("%d %d", &vlr_a, &vlr_b); imprime_soma(); }

    Programa 8.1.1

    Programa auxiliar: #include extern int vlr_a; extern int vlr_b; void imprime_soma (void) { printf ("Soma %d\n", vlr_a + vlr_b); }

    Programa 8.1.2

    Arquivo header (soma.h): void imprime_soma (void);

    Resultado dos Programas 8.1.1 e 8.1.2 Entre com os valores:10 50 Soma 60

    8.3 Diretiva #define Sintaxe:

    #define nome_constante valor_constante

    possvel definir constantes para o pr-compilador, fazendo com que ele atri-bua um valor a uma varivel. Um detalhe importante a ressaltar que esta va-rivel uma varivel do pr-compilador e no do programa. Cada vez que o pr-compilador encontrar esta varivel, ele substitura pelo contedo definido anteriormente, no levando em considerao o contexto de compilao. Vale ressaltar que a definio de uma varivel de pr-compilao uma pura substituio de caracteres.

    Valores digitados.

    Esta funo de usurio est declarada no arquivo header soma.h.

    Declarao da funo imprime_soma.

  • Pr-Compilao 59

    Veja o exemplo: #include #define VALOR_MAGICO 34 void main (void) { int vlr_a; while (1) { printf ("Entre com o valor:"); scanf ("%d", &vlr_a); if (vlr_a == VALOR_MAGICO) break; } }

    Programa 8.2 (antes do pr-processamento) void main (void) { int vlr_a; while (1) { printf ("Entre com o valor:"); scanf ("%d", &vlr_a); if (vlr_a == 34) break; } }

    Programa 8.2 (aps o pr-processamento)

    Resultado do programa 8.2 Entre com o valor:20 Entre com o valor:23 Entre com o valor:34

    8.4 Diretivas #if, #else e #endif Sintaxe:

    #if condio bloco de condio verdadeiro

    #else bloco condio falso

    #endif

    Como so definies de pr-processamento....

    ...simplesmente no esto mais disponveis para o compilador.

    A definio VALOR_MAGICO...

    ... substitudo pelo valor 34, definido no incio do programa.

  • 60 Programando em C para Linux, Unix e Windows

    s vezes preciso selecionar um trecho de um cdigo de acordo com uma con-dio preestabelecida, de forma que se compile ou no um trecho do cdigo. Esta tcnica, chamada compilao condicional, muito usada quando se tem um programa que ser usado em diversas plataformas (Linux, Windows etc.) e somente um pequeno trecho de programa difere de um sistema para ou-tro. Como extremamente desejvel que se tenha um nico cdigo, simplifi-cando a manuteno e evitando riscos de alterar em um sistema e esquecer de alterar em outro, utiliza-se compilao condicional nos terchos diferentes. Pode-se selecionar somente um trecho com o #if ou selecionar entre dois tre-chos com o #if...#else. O final do trecho, em qualquer um dos casos, delimitado pela diretiva #endif. Por ltimo, deve-se ressaltar que o #if s ser executado se na fase de pr-compilao for possvel resolver a expresso condicional colocada. Portanto, no possvel fazer compilao condicional baseada em valores de variveis da linguagem C, pois o valor da varivel s estar disponvel quando o pro-grama for executado e no durante a compilao. A varivel do teste pode ser definida internamente ou ser diretamente defini-da quando se chama o comando de compilao, tornando assim bem dinmico o processo. Para se definir um valor para uma varivel ao nvel de comando de compilao deve-se usar a opo a seguir: Plataforma Linux: gcc progxx.c Dvar=valor o progxx Plataforma Windows: LCC-Win32 Colocar no campo #defines (opo compiler) do projeto da aplicao. Veja o exemplo: #include #define PULA 1 void main (void) { int i; for (i=1; i < 30; i++) {

    Qualquer valor pode ser atribudo ao define.

  • Pr-Compilao 61

    #if PULA == 1 if (i > 10 && i < 20) continue; #endif printf ("%d\n", i); } }

    Programa 8.3 (antes do pr-processamento)

    void main (void) { int i; for (i=1; i < 30; i++) { if (i > 10 && i < 20) continue; printf ("%d\n", i); } }

    Programa 8.3 (aps o pr-processamento)

    Resultado do Programa 8.3 1 2 3 4 5 6 7 8 9 10 20 21 22 23 24 25 26 27 28 29

    Todo este trecho estar disponvel para o compilador.

    Repare que somente as diretivas de pr-processamento foram suprimidas

  • 62 Programando em C para Linux, Unix e Windows

    8.5 Diretivas #ifdef e #ifndef Sintaxe:

    #ifdef varivel_pr_definida bloco de condio verdadeiro

    #else bloco de condio falso

    #endif

    ou

    #ifndef varivel_pr_definida bloco de condio verdadeiro

    #else bloco de condio falso

    #endif

    Pode-se implementar tambm a compilao condicional baseada na existncia de uma varivel e no em seu contedo. Para isto utilizada a diretiva #ifdef. Quando a varivel especificada estiver definida, o trecho entre o #ifdef e o #endif ser compilado, caso contrrio, no. Pode-se definir a varivel tambm ao nvel de comando de compilao evitan-do assim a alterao de cdigo quando da gerao de verses diferentes. Usar a seguinte sintaxe para se fazer isto: Plataforma Linux: gcc progxx.c Dvariavel o progxx

    Plataforma Windows: Colocar no campo #defines (opo compiler) do projeto da aplicao. Veja o exemplo: #include void main (void) { int i; #ifdef DOS clrscr(); /* Para DOS, chamar funcao de limpar tela*/ #else #ifdef UNIX /* [ 2 J [ H */ printf ("^[[2J^[[H"); /*LINUX sequencia de caracteres */ #endif

    Verifica se existe uma definio. O valor no testado, embora seja possvel informar um valor no momento da compilao.

  • Pr-Compilao 63

    #endif for (i=1; i < 10; i++) printf ("%d\n", i); }

    Programa 8.4

    void main (void) { int i; clrscr(); for (i=1; i < 10; i++) printf ("%d\n", i); }

    Programa 8.4 (aps pr-processamento compilado no ambiente Windows)

    void main (void) { int i; printf ("^[[2J^[[H"); for (i=1; i < 10; i++) printf ("%d\n", i); }

    Programa 8.4 (aps pr-processamento compilado no ambiente Unix/Linux)

    Resultado do Programa 8.4 1 2 3 4 5 6 7 8 9

    8.6 Diretiva #undef Sintaxe:

    #undef varivel_pr_definida

    Na construo de dependncias pode-se ter uma situao em que seja necess-rio desabilitar alguma varivel de pr-compilao, mesmo que ela seja definida ao nvel de comando de compilao.

    Para isto utilizada a diretiva #undef, que ir retirar a definio da varivel especificada.

  • 64 Programando em C para Linux, Unix e Windows

    Veja o exemplo: #include void main (void) { int i; #ifdef DOS #undef UNIX clrscr(); #endif #ifdef UNIX printf ("^[[2J^[[H"); #endif for (i=1; i < 10; i++) printf ("%d\n", i); }

    Programa 8.5

    void main (void) { int i; printf ("^[[2J^[[H"); for (i=1; i < 10; i++) printf ("%d\n", i); }

    Programa 8.5 (aps pr-processamento compilado no ambiente Unix/Linux)

    void main (void) { int i; clrscr(); for (i=1; i < 10; i++) printf ("%d\n", i); }

    Programa 8.5 (aps pr-processamento compilado no ambiente Windows)

    #include void main (void) { int i; #ifdef DOS clrscr(); #endif #ifdef UNIX printf ("^[[2J^[[H");

    Mesmo que, por engano, sejam especificadas as duas opes de compilao. O compilador ir destruir a segunda definio...

    ... e portanto no estar disponvel aqui.

    Sem a diretiva #undef...

    ..e se esta definio existir...

    ...este comando tambm pode ser considerado.

  • Pr-Compilao 65

    #endif for (i=1; i < 10; i++) printf ("%d\n", i); }

    Programa 8.6 (igual ao programa 8.5, sem a diretiva #undef)

    void main (void) { int i; clrscr(); printf ("^[[2J^[[H"); for (i=1; i < 10; i++) printf ("%d\n", i); }

    Programa 8.6 (aps pr-processamento compilado para os ambientes Unix/Linux e Windows por engano)

    Resultado do Programa 8.5 e 8.6. 1 2 3 4 5 6 7 8 9

    8.7 Diretiva #error Sintaxe:

    #error mensagem

    Esta diretiva deve ser usada quando se quer exigir a definio de uma ou outra varivel ao nvel de compilao ou internamente no programa.

    Veja o exemplo: #include void main (void) { int i;

    Os 2 comandos esto disponveis.

  • 66 Programando em C para Linux, Unix e Windows

    #ifdef DOS clrscr(); /* Para sistemas DOS, chamar funcao de limpar tela*/ #else #ifdef UNIX printf ("^[[2J^[[H"); #else #error Especificar -DUNIX ou -DDOS na compilacao #endif #endif for (i=1; i < 10; i++) printf ("%d\n", i); }

    Programa 8.7

    void main (void) { int i; #error Especificar -DUNIX ou -DDOS na compilacao for (i=1; i < 10; i++) printf ("%d\n", i); }

    Programa 8.7 (aps pr-processamento compilado)

    o Compilando no Unix/Linux sem colocar a definio "p8_7.c", line 12.8: 1540-086: (S) Especificar -DUNIX ou -DDOS

    na compilacao

    o Compilando no Windows sem colocar a definio (LCC-Win32) cpp: c:\marcos\c\p8_7.c:12 #error directive: Especificar -DUNIX

    ou -DDOS na compilacao

    8.8 Variveis predefinidas O pr-compilador disponibiliza uma srie de variveis de pr-compilao para serem utilizadas no programa. Essas variveis geralmente so utilizadas para cdigo de debug ou log a ser gerado por programas. So elas:

    __LINE__ Nmero da linha no arquivo fonte. __FILE__ Nome do arquivo fonte __DATE__ Data da compilao __TIME__ Hora da compilao

    Esta mensagem ir aparecer somente no momento de compilar o programa.

  • Pr-Compilao 67

    Veja o exemplo: #include void main (void) { int i; #ifdef DEBUG printf ("Inicio do programa %s\n", __FILE__); printf ("Versao de %s-%s\n", __DATE__, __TIME__); #endif for (i=1; i < 10; i++) printf ("%d\n", i); #ifdef DEBUG printf("A contagem parou! Estamos na linha %d\n", __LINE__); #endif printf("Fim da execuo\n"); #ifdef DEBUG printf("A ltima linha do programa : %d\n", __LINE__); #endif }

    Programa 8.8

    void main (void) { int i; for (i=1; i < 10; i++) printf ("%d\n", i); printf("Fim da execuo\n"); } Programa 8.8 (aps pr-processamento compilado sem a opo definindo a di-retiva DEBUG)

    void main (void) { int i; printf ("Inicio do programa %s\n", "p8_8.c"); printf ("Versao de %s-%s\n", "Mar 28 2005", "09:57:20"); for (i=1; i < 10; i++) printf ("%d\n", i); printf("A contagem parou! Estamos na linha %d\n", 13);

    A diretiva __LINE__ vai ser sempre substituda pelo compilador por um nmero