Sei sulla pagina 1di 62

PROGRAMAO EM C

SUMRIO

1 A LINGUAGEM C - PRIMEIROS PASSOS . . 1.1 Introduo ao Linux . . . . . . . . . . . . . . 1.1.1 O Linux igual ao Unix? . . . . . . . . . . . 1.1.2 Comandos Bsicos . . . . . . . . . . . . . . 1.1.3 Estrutura de diretrios do Linux . . . . . . . 1.1.4 Como acessar um disquete (oppy) no Linux? 1.1.5 Compilando um programa . . . . . . . . . . 1.1.6 Exerccios . . . . . . . . . . . . . . . . . . . 1.2 Introduo Linguagem C . . . . . . . . . . 1.2.1 Caractersticas Bsicas . . . . . . . . . . . . 1.2.2 Estruturas dos programas em C . . . . . . . . 1.2.3 Primeiro exemplo . . . . . . . . . . . . . . . 1.2.4 Identao de programas . . . . . . . . . . . . 1.2.5 Reviso de termos . . . . . . . . . . . . . . . 1.2.6 Exerccios . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5 5 5 5 5 5 7 7 8 8 8 9 11 11 11 12 12 12 13 14 14 14 14 15 15 16 17 18 19 19 20 21 21

2 INTRODUO AO TRATAMENTO DE VARIVEIS 2.1 Identicadores . . . . . . . . . . . . . . . . . . . . 2.2 Variveis . . . . . . . . . . . . . . . . . . . . . . . 2.3 Tipos de dados . . . . . . . . . . . . . . . . . . . . 2.4 Operador de Atribuio . . . . . . . . . . . . . . . 2.5 Variveis Locais x Variveis Globais . . . . . . . . 2.5.1 Variveis Locais . . . . . . . . . . . . . . . . . . . 2.5.2 Variveis Globais . . . . . . . . . . . . . . . . . . 2.6 Constantes . . . . . . . . . . . . . . . . . . . . . . 2.7 Operadores Aritmticos . . . . . . . . . . . . . . . 2.8 Operadores Relacionais e Lgicos . . . . . . . . . . 2.9 Operadores Bit a Bit . . . . . . . . . . . . . . . . . 2.10 Prioridade das Operaes . . . . . . . . . . . . . . 2.11 Operaes de entrada e sada . . . . . . . . . . . . 2.11.1 printf . . . . . . . . . . . . . . . . . . . . . . . . . 2.11.2 scanf . . . . . . . . . . . . . . . . . . . . . . . . . 2.11.3 sprintf e sscanf . . . . . . . . . . . . . . . . . . . 2.12 Exerccios . . . . . . . . . . . . . . . . . . . . . . .

3 COMANDOS DE CONTROLE E REPETIO 3.1 if/else . . . . . . . . . . . . . . . . . . . . . . . 3.2 while . . . . . . . . . . . . . . . . . . . . . . . 3.3 for . . . . . . . . . . . . . . . . . . . . . . . . 3.4 do/while . . . . . . . . . . . . . . . . . . . . . 3.5 Break e Continue . . . . . . . . . . . . . . . . 3.6 switch/case . . . . . . . . . . . . . . . . . . . 3.7 Expresses Condicionais . . . . . . . . . . . . 3.8 Exerccios: . . . . . . . . . . . . . . . . . . . 4 MATRIZES . . . . . . . . . . . 4.1 Strings . . . . . . . . . . . . . 4.2 Matrizes Bidimensionais . . . 4.3 Matrizes de Strings . . . . . . 4.4 Matrizes Multidimensionais . 4.5 Inicializao de Matrizes . . . 4.6 Exerccios: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23 23 25 25 26 26 26 27 27 29 30 32 33 33 34 34 36 36 38 38 40 41 41 41 42 42 43 43 44 44 45 46 46 47 48 50 52 54 55 55 55 55 55 55

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5 ESTRUTURAS DEFINIDAS PELO USURIO 5.1 Estruturas . . . . . . . . . . . . . . . . . . . . 5.1.1 Exerccios . . . . . . . . . . . . . . . . . . . 5.2 Unies . . . . . . . . . . . . . . . . . . . . . . 5.3 Enumeraes . . . . . . . . . . . . . . . . . . 6 FUNES . . . . . . . . . . . . . . . . . 6.1 Modularidade . . . . . . . . . . . . . . . 6.2 Forma de uma Funo . . . . . . . . . . 6.3 Regras de Escopo . . . . . . . . . . . . . 6.4 Argumentos de Funes . . . . . . . . . 6.5 O Comando return . . . . . . . . . . . . 6.6 Funes do Tipo void . . . . . . . . . . . 6.7 Passagem por Parmetros . . . . . . . . 6.7.1 Chamada por Valor . . . . . . . . . . . 6.7.2 Chamada por Referncia . . . . . . . . 6.7.3 Matrizes como Argumentos de Funes 6.8 Prottipos de Funes . . . . . . . . . . 6.9 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7 APONTADORES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.1 Apontadores: passagem de parmetros por referncia . . . . . . . . . . 7.2 Alocao Dinmica de ponteiros . . . . . . . . . . . . . . . . . . . . . . 7.3 Exerccios: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 ARQUIVOS . . . . . . . . . . 8.1 Introduo . . . . . . . . . . 8.2 Arquivos . . . . . . . . . . . . 8.3 Funes . . . . . . . . . . . . 8.3.1 Ponteiro de Arquivo . . . . . 8.3.2 Abrindo um arquivo (fopen) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8.3.3 Fechando um arquivo (fclose) . . . . . . . . . . . . . 8.3.4 Escrevendo e Lendo um caractere . . . . . . . . . . . 8.3.5 Lidando com Strings (fputs e fgets) . . . . . . . . . . 8.3.6 Lidando com blocos de dados binrios(fread e fwrite) 8.3.7 Realizando Procuras (fseek) . . . . . . . . . . . . . . 8.4 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . 9

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

57 57 58 59 60 61 62

BIBLIOGRAFIA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1 A LINGUAGEM C - PRIMEIROS PASSOS

Esse captulo apresenta uma breve introduco ao Sistema Operacional Linux, suas caractersticas bsicas e seus principais comandos. O objetivo dar suporte para o aluno desenvolver seus programas no ambiente Linux, utilizando o compilador gcc. Uma introduo a Linguagem de Programao C tambm apresentada, atravs do histrico da linguagem e da descrio da estrutura bsica de um programa escrito com ela.

1.1 Introduo ao Linux


Linux um Sistema Operacional que foi inicialmente criado por um estudante, Linus Torvalds, na Universidade de Helsinki na Finlndia. Linus era interessado pelo Minix, um pequeno sistema UNIX, e decidiu desenvolver um sistema que excedesse os padres Minix. Ele iniciou seu trabalho em 1991 e sua verso 1.0 surgiu em 1994. O kernel, o corao dos sistemas Linux, desenvolvido sob o GNU General Public License e seu cdigo fonte disponvel para todos, gratuitamente. 1.1.1 O Linux igual ao Unix? O Linux foi escrito desde o inicio pelo Linus Torvalds e no contm nenhuma linha de cdigo do UNIX. Mas o Linux foi escrito para ser conforme o padro POSIX, que deve ser o padro da API (Application Programming Interface) Unix. 1.1.2 Comandos Bsicos Na Tabela 1.1 esto relacionados os principais comandos do Linux: 1.1.3 Estrutura de diretrios do Linux Na Tabela 1.2 esto relacionados os principais diretrios do Linux. Essa estrutura ser encontrada na maioria das distribuies disponveis. 1.1.4 Como acessar um disquete (oppy) no Linux? Para montar:

Para desmontar:

Obs.: Para acessar o contedo do disquete, copiar, deletar, mover ou qualquer outra tarefa relativa aos arquivos, use os comandos do Linux no diretrio /mnt/oppy, esse diretrio o disquete!

#" !          

Comando man <comando> ls ls -la cd <nome-dir> mkdir <nome-dir> touch <nome-arquivo> rmdir <nome-dir> cp <origem> <destino> mv <origem><destino> mv <nome1> <nome2> rm le ps kill -9 nro pwd cat f more f free passwd

Funo Manual de usurio Linux para os comandos Lista arquivos do diretrio Lista arquivos no diretrio com detalhes Muda para o diretrio Cria o novo diretrio Cria ou atualiza data, se o arquivo j existe Deleta diretrio (deve estar vazio) Copia arquivo Move dado da origem para o destino Renomeia diretrio ou arquivo 1 para 2 Remove arquivo (cuidado!) Imprime o numero dos processos ativos Mata processo nro Imprime diretrio corrente Mostra contedo do arquivo f Mostra contedo do arquivo f tela a tela Exibe memria livre Altera senha do usurio

Tabela 1.1: Comandos bsicos do Linux

Diretrio / bin boot dev etc home lib mnt root sbin tmp usr

Contedo Diretrio raiz do sistema Arquivos executveis(binrios) Arquivos estticos de boot de inicializao(boot-loader) Arquivos de dispositivos de entrada/sada Congurao do sistema da mquina local Diretrio local (home) dos usurios Arquivos das bibliotecas compartilhadas usados freqentemente Ponto de montagem de partio temporrios (oppy, cdrom, etc) Diretrio local do superusurio (root) Arquivos de sistema essenciais Arquivos temporrios gerados por alguns utilitrios Todos os arqs dos diversos aplicativos devem estar aqui Tabela 1.2: Principais diretrios do Linux

1.1.5 Compilando um programa Para compilar um programa e transform-lo em executvel, atravs de linha de comando digite:

onde gcc o comando que dispara o compilador, o argumento, no obrigatrio, , o compilador retornar para entrar com o nome do executvel. Caso seja omitido um nome padro para o executvel igual a . Dvidas sobre o comando podem ser resolvidas digitando . Obs.: Para executar o programa digite antes do nome do executvel. Isso necessrio porque o executvel no est no Path do Sistema Operacional. 1.1.6 Exerccios 1. Logue-se no Linux 2. Abra um Terminal 3. Crie um diretrio aluno 4. Entre neste diretrio aluno 5. Crie, dentro do diretrio aluno, outro diretrio chamado teste e entre nele 6. Crie um arquivo chamado linux.arq 7. Faa uma cpia deste arquivo para linux2.arq 8. Liste os arquivos do diretrio com detalhes 9. Mova estes dois arquivos para o diretrio aluno 10. Volte para o diretrio aluno 11. Apague o diretrio teste

$ %

        !         #"  !   # !

1.2 Introduo Linguagem C


A linguagem "C"foi criada nos laboratrios Bell por Brian W. Kernighan e Dennis Ritchie em 1972. Esta linguagem, teve suas idias iniciais originadas da linguagem BCPL (Basic Combined Programming Language), desenvolvida por Martin Richards. Esta inuncia do BCPL se deu atravs de outra linguagem, chamada "B"e criada por Thompson em 1970 para o primeiro sistema operacional UNIX no PDP-11. A partir de sua criao a linguagem "C" sofreu uma longa evoluo sendo que uma de suas primeiras utilizaes foi a de reescrever o sistema operacional UNIX (1973) que estava escrito em linguagem assembly do PDP-11. Por este motivo que se tem associado a linguagem ao S.O. UNIX, visto que o UNIX composto, quase na sua totalidade, de programas escritos em "C" (Sistema Operacional, utilitrios, compiladores, ...). Entretanto isto no implica que o "C" seja uma linguagem "amarrada"a um sistema operacional ou mquina. Devido evoluo do "C" que seguia apenas o padro descrito por Kernighan e Ritchie, tornou-se necessria uma padronizao mais rgida para a linguagem, permitindo a portabilidade dos softwares escritos nesta linguagem. Isto foi feito pelo ANSI (American National Standard Institute), criando assim o padro C ANSI. 1.2.1 Caractersticas Bsicas O "C" uma linguagem de propsitos gerais e que tem como caractersticas principais:

1.2.2 Estruturas dos programas em C Todo programa C deve ter ao menos uma funo, denominada main(), a qual a primeira funo a ser chamada quando o programa executado. Geralmente, a funo main() contm um esboo do que o programa faz, ou a estrutura geral de controle do programa. Embora main no seja uma palavra reservada da linguagem, no se pode usala para outros ns que no seja o nome da funo principal do programa.

Controle de uxo e estrutura de dados adotando conceitos modernos de linguagens de programao; Poderoso conjunto de operadores e tipos de dados; Permite a gerao de um cdigo bem otimizado e compacto (quase to otimizado quanto o assembly); Grande portabilidade de programas (a maioria dos computadores suportam "C"); uma linguagem de nvel "relativamente baixo", mas com recursos de alto nvel; Apresenta facilidade de manipulao direta do hardware da mquina; Uso de bibliotecas de funes, expandindo as potencialidades da linguagem; Grande "liberdade"para o programador.

/*No incio do programa, declara-se as bibliotecas usadas*/ #include <stdio.h> /* Declaraes globais */ /* Declarao de funes do programador, se for o caso */ /* Declarao da funo principal. Sempre necessria */ tipo_devolvido main (lista de parmetros) { /* variaveis locais ao main, se existirem */ // Isto tambm comentrio at o nal da linha /* seqncia de comandos... */ }

A linguagem C formada por pouco mais de 30 palavras-chave, por isso, normalmente necessria a declarao das bibliotecas que contem funes no nativas na linguagem. Como exemplo podemos citar as funes de entrada e sada de dados presentes na biblioteca padro. Em C, maisculas e minsculas so diferentes por isso preste ateno na hora de digitar o programa fonte. Essa caracterstica chamada de case sensitive. Os smbolos /* (inicio de comentrio) e */ (nal do comentrio) indicam comentrios de cdigo e podem abranger uma ou mais linhas do programa. Para comentar somente uma linha, pode-se utilizar //. Todo programa em C consiste em uma ou mais funes. A nica funo que necessariamente precisa estar presente a denominada main(), que a primeira funo a ser chamada quando a execuo do programa comea. Embora main() no seja tecnicamente parte da linguagem C, tratada como se fosse. No pode ser usada como nome de varivel, porque pode confundir o compilador. 1.2.3 Primeiro exemplo O nico caminho para aprender uma nova linguagem de programao escrever programas nesta linguagem, Normalmente os autores utilizam um exemplo clssico no primeiro programa, o famoso - Oi Mundo! Esse ser o seu primeiro programa, para cria-lo, utilize algum editor de textos para digitar os fontes e um compilador para gerar o executvel.

#include<stdio.h> main() { printf(Oi mundo! n"); } Obs.: Editar esse programa, salv-lo como oi.c, compil-lo (gcc oi.c) e executlo (./a.out). Exerccio: Edite este programa, experimente deixar fora do fonte partes como ; por exemplo, para vericar as mensagens de erro.

10

Um programa C, independentemente de seu tamanho, consiste de uma ou mais "funes que especicam as operaes computacionais que devem ser feita. Funes C so similares aos procedimentos em Pascal. No nosso exemplo main() uma funo. Normalmente voc pode escolher o nome que quiser, menos para main. Um mtodo de comunicao de dados entre funes por argumentos. Os parnteses seguindo o nome da funo envolvem a lista de argumentos, sendo que nesse exemplo, main uma funo sem argumentos. As chaves envolvem os comandos que formam a funo, elas so anlogas ao BEGIN-END do Pascal. Uma funo ativada por seu nome, seguido de uma lista de argumentos entre parnteses. Os parnteses devem estar presentes mesmo quando no h argumentos. A linha: printf (Oi mundo! n); uma chamada de funo, que chama a funo printf, com o argumento Oi mundo! n. printf uma funo de biblioteca que imprime no terminal (a menos que outro destino seja especicado). Nesse caso ela imprime a cadeia de caracteres que compem seu argumento. Uma seqncia de qualquer nmero de caracteres entre aspas ... chamada cadeia de caracteres. A seqncia n na cadeia a notao C para o caractere nova linha, que, quando impresso provoca o avano do cursor do terminal para o inicio da prxima linha. Se voc omitir o n, voc encontrar sua sada no terminada por uma alimentao de linha. printf nunca fornece uma nova linha automaticamente, de forma que mltiplas ativaes pode ser usadas para construir uma linha de sada passo a passo. Nosso primeiro programa poderia ter sido escrito como: #include<stdio.h> main() { printf(Oi"); printf(mundo!"); printf( n"); } O cdigo acima produziria uma sada idntica ao anterior. O n, apresentado no cdigo anterior, representa um nico caractere. Uma seqncia de escape tal como n prov um mecanismo geral e extensvel para a representao de caracteres difceis de obter ou invisveis. Entre outros que C prove, esto: n para quebra de linha,

t para tabulao,

b para retrocesso,

" para a aspa,

para a contra-barra propriamente dita,

0 Nulo,

a Alerta (beep).

11

1.2.4 Identao de programas Os comandos de "C"devem ser escritos em minsculas e devem ser seguidos de um ";", podendo haver mais de um comando na mesma linha, desde que separados por ponto e vrgula (no abuse disto pois torna o cdigo difcil de compreender). A identao do programa no obrigatria, mas aconselhada para deixar cdigo-fonte legvel para outros programadores ou mesmo para o prprio criador. Os blocos so denidos de uma { at a outra } e equivalem aos blocos de Pascal denidos pelo "BEGIN"e "END". Dentro de cada bloco pode-se denir um conjunto de comandos como se fossem um s, sendo que no C pode-se declarar novas variveis (variveis locais ao bloco) independentemente da posio deste bloco no programa. { /* inicio de bloco */ <Comandos> } /* m de bloco */ 1.2.5 Reviso de termos Os termos a seguir sero usados freqentemente nessa apostila. Cdigo-Fonte: o texto um programa que um usurio pode ler; normalmente interpretado como o programa. O cdigo-fonte a entrada para o compilador C. Compilador: programa que l o cdigo-fonte de uma determinada linguagem de programao e converte-o em cdigo objeto. Cdigo-Objeto: traduo do cdigo fonte de um programa em cdigo de mquina que o computador pode ler e executar diretamente. O cdigo objeto a entrada para o linkeditor. Linkeditor: um programa que une funes compiladas separadamente em um programa. Ele combina as funes da biblioteca C padro com o cdigo que voc escreveu. A sada do linkeditor um programa executvel. Biblioteca: o arquivo contendo as funes padro que seu programa pode usar. Essas funes incluem todas as operaes de E/S como tambm outras rotinas teis. 1.2.6 Exerccios a. Crie um cdigo fonte, que imprime seu nome, idade, endereo e telefone em linhas separadas na tela. Compile e Execute b. Altere o cdigo anterior para deixar uma linha em branco entre as linhas e colocar um tab a frente das palavras: Compile e Execute c. Crie um cdigo fonte para imprimir : "exemplo de utilizao de aspas"dia 02 03 2004 Compile e execute

 $

 #!  "#  "    !  

12

2 INTRODUO AO TRATAMENTO DE VARIVEIS

Nesta aula o aluno receber noes do tratamento de variveis em C. Essas noes iniciam pela descrio dos tipos de dados disponiveis em C, variveis locais, globais e constantes.

2.1 Identicadores
Os nomes das variveis, funes, rtulos e outros objetos denidos pelo usurio, so chamados de identicadores. Algumas observaes sobre os identicadores so importantes, como:

2.2 Variveis
Uma varivel uma possio de memria que pode ser identicada atravs de um nome. Estas podem ter seu contedo alterado por um comando de atribuio e aps a atribuio mudam de valor. Toda varivel tem:

O primeiro caractere deve ser uma letra ou um sublinhado. Os caracteres subseqentes devem ser letras, nmeros ou sublinhados. Por exemplo: count, total23 e peso. Podem ter qualquer tamanho, mas os seis primeiros caracteres devem ser signicativos. Em C, letras minsculas e maisculas so tratadas diferentemente, portanto "Aula" diferente de "aula". Case sensitive Um identicador no pode ser igual a uma palavra chave do C.

um nome (identicador) um tipo de dado um valor

13

//... int a,b,c; a = 3; // a recebe o valor 3 b = a * 2; // b recebe o dobro do valor de a c = a + b + 2; // c recebe 11 //...

2.3 Tipos de dados


O C tem 5 tipos bsicos - char, int, oat, void e double: char serve para se guardar caracteres; int serve para se guardar valores inteiros; oat serve para se guardar valores reais de baixa preciso; double o ponto utuante duplo com muito mais preciso; void o tipo vazio, ou um "tipo sem tipo". Para cada um dos tipos de variveis existem os modicadores de tipo, que so quatro: signed, unsigned, long e short. Ao oat no se pode aplicar nenhum e ao double pode-se aplicar apenas o long. Os quatro modicadores podem ser aplicados a inteiros. A inteno que short e long devam prover tamanhos diferentes de inteiros onde isto for prtico. int normalmente ter o tamanho natural para uma determinada mquina. Assim, numa mquina de 16 bits, int provavelmente ter 16 bits. Numa mquina de 32, int dever ter 32 bits. Na verdade, cada compilador livre para escolher tamanhos adequados para o seu prprio hardware, com a nica restrio de que tipos short int e int devem ocupar pelo menos 16 bits, tipos long int pelo menos 32 bits, e short int no pode ser maior que int, que no pode ser maior que long int. O modicador unsigned serve para especicar variveis sem sinal. Um unsigned int ser um inteiro que assumir apenas valores positivos. A seguir so relacionados os tipos de dados permitidos e seus valores mximos e mnimos em um compilador tpico para um hardware de 16 bits. Tambm nesta tabela est especicado o formato (mscara) que deve ser utilizado para leitura e impresso dos tipos de dados.

Tipo hline char int unsigned int long int unsigned long int oat double long double

mascara para e/s Tamanho aproximado(bits) %c 8 %d ou %i 16 %u 16 %ld 32 %ld 32 %f 32 %lf 64 %lf 128

faixa mnima -127 a 127 -32.767 a 32.767 0 a 65.535 -2.147.483.647 a 2.147.483.647 0 a 4.294.967.295 Seis dgitos de preciso Dez dgitos de preciso Dez dgitos de preciso

O tipo long double o tipo de ponto utuante com maior preciso.

14

2.4 Operador de Atribuio


Em C, voc pode utilizar o operador de atribuio dentro de qualquer expresso vlida de C. O simbolo utilizado para atribuio o =. A forma geral do operador de atribuio : nome_da_varivel = expresso;

2.5 Variveis Locais x Variveis Globais


Todas as variveis devem ser declaradas. Estas podem ser declaradas em trs lugares bsicos: dentro de funes, na denio dos parmetros das funes e fora de todas as funes. Estas so chamadas de variveis locais, parmetros ou variveis globais, respectivamente. 2.5.1 Variveis Locais As variveis locais devem ser declaradas dentro das funes nas quais sero utilizadas, ou seja, estas no so acessveis a outras funes do programa. Portanto, s podem ser referenciadas por comandos que esto dentro do bloco no qual as variveis foram declaradas.

func1(void) { int x; x = 10; }

func2(void) { int x; x = -199; }

No exemplo, pode-se vericar que existem duas funes (fun1 e func2). Estas possuem variveis locais com o mesmo nome, x. Dentro da func1, o valor acessvel de x ser 10. Em func2, o valor ser -199. Ou seja, nenhuma funo tem acesso ao valor das variveis locais de outras funes. Ressalva-se que todas as variveis devem ser declaradas no incio das funes, e se forem declaradas no meio do programa/funo, ocorrer um erro no processo de compilao. Outro fator importante que as variveis locais s "existem"ou esto disponveis quando a funo est sendo executada, aps a nalizao da execuo da funo, esta rea de memria liberada e o valor se perde. 2.5.2 Variveis Globais As variveis globais so reconhecidas por todo o programa, e podem ser utilizadas em qualquer trecho de cdigo. O valor destas permanece disponvel por toda a execuo do programa.

15

#include<stdio.h> int total; void contas() { total = total + 3; } main() { int i; total = 0; for(i=0;i<10;i++) contas(); printf(Total = %d n",total); }

Pode-se vericar no cdigo exemplo que a varivel total foi declarada no incio do programa e esta ser acessvel a todo o programa. Tanto que o seu valor inicializado com zero na funo principal e que seu valor tambm pode ser alterado pela funo contas. No nal o programa imprimir na tela: "Total: 27".

2.6 Constantes
Constantes so valores declarados que no podem ser alterados durante a execuo do programa. Portanto, em C as constantes referem-se a valores xos que o programa no pode alterar. Esta podem aparecer dentro das expresses ou podem ser declaradas, como por exemplo: const valor = 10; const taxa = 1.5; const letra = S; Dene A diretiva dene atribui a um identifcador uma string que o substituir toda a vez que for encontrador no arquivo-fonte. Esta associa um identicador a um valor. O padro C ANSI refere-se ao identicador como um nome de macro e ao processo de substituio como substituio de macro (geralmente declarado com letra maiscula, sempre aps a declarao das bibliotecas). O formato utilizado : #dene nome_da_macro valor. Veja os exemplos: #dene VERDADEIRO 1 #dene FALSO 0 #dene MSG "Digite S para Sair"

2.7 Operadores Aritmticos


A lista dos operadores aritmticos de C esto relacionados na tabela abaixo, visto que estes operadores trabalham da mesma forma que na maioria das outras linguagens.

16

Operador Aritmtico + * / % -++

Ao Subtrao Adio Multiplicao Diviso Mdulo da diviso (resto) Decremento Inremento

A sequir, apresentado um cdigo fonte comentado, com operaes aritmticas.

#include<stdio.h> main() { int x,y; x = 5; y = 2; printf(%d n",x/y); printf(%d n",x%y); x ++; printf(%d n",x); }

//mostra 2 (truncado) // mostra 1, o resto da diviso // x foi incrementado em 1 // mostra 6, pois x foi incrementado

2.8 Operadores Relacionais e Lgicos


No termo operador relacional, relacional refere-se as relaes que os valores podem ter uns com os outros. Os operadores relacionais retornam verdadeiro (1) ou falso (0). Para vericar o funcionamento dos operadores relacionais, execute o programa abaixo:

Operador relacional Ao == Igual != Diferente <= Menor ou igual >= Maior ou igual < Menor > Maior

/* O prximo programa ilustra o funcionamento dos operadores relacionais. */

17

#include<stdio.h> main() { int i,j; printf( nEntre com 2 nros inteiros:); scanf(%d %d, &i, &j); printf( n%d == %d e %d n", i, j, i==j); printf( n%d != %d e %d n", i, j, i!=j); printf( n%d <= %d e %d n", i, j, i<=j); printf( n%d >= %d e %d n", i, j, i>=j); printf( n%d < %d e %d n", i, j, i < j); printf( n%d > %d e %d n", i, j, i > j); }

Para fazer operaes com valores lgicos (verdadeiro e falso) temos os operadores lgicos: Operador lgico && || (pipes) ! (exclamao) Ao AND OR NOT

O programa a seguir ilustra o funcionamento dos operadores lgicos. Compile-o e faa testes com vrios valores para i e j:

#include<stdio.h> main() { int i,j; printf( nEntre com 2 nros inteiros (0 ou 1):); scanf(%d %d, &i, &j); printf( n%d AND %d %d n", i, j, i && j); printf( n%d OR %d %d n", i, j, i || j); printf( n NOT %d %d n", i,!i); }

2.9 Operadores Bit a Bit


C suporta um conjunto de operaes bit a bit. Operaes bit a bit refere-se a testar, atribuir ou deslocar os bits efetivos em um byte ou uma palavra, que correspondem aos tipos de dados char, int e variantes do padro C. Estas operaes so aplicadas bit a bit. Abaixo esto relacionados estas operaes.

18

Operador binrio Ao !(exclamao) NOT & AND | (pipe) OR XOR Complemento de 1 Desloca p/direita Desloca pra esquerda Imagine um nmero inteiro de 16 bits, a varivel i, armazenando o valor 2. A representao binria de i, ser: 0000000000000010 (quinze zeros e um nico 1 na segunda posio da direita para a esquerda). Pode-se fazer operaes em cada um dos bits deste nmero. Por exemplo, se zermos a negao do nmero (operao binria NOT, ou operador binrio ! em C), isto , i, o nmero se transformar em 1111111111111101. As operaes binrias ajudam programadores que queiram trabalhar com o computador em baixo nvel. O uso de operaes de deslocamento de bits podem ser teis quando se decodica a entrada de um dispositivo externo. Estes podem realizar operaes de multiplicao e diviso rapidamente. Um deslocamento direita efetivamente multiplica um nmero por dois e um esqueda multiplica. Observe o exemplo de funcionamento na Tabela abaixo: unsigned char x; x = 7; x = x 1; x = x 3; x = x 2; x = x 1; x=x2 x a cada execuo da sentena 00000111 00001110 01110000 11000000 01100000 00011000 Valor de x 7 14 112 192 96 24

2.10 Prioridade das Operaes


As operaes demonstradas possuem prioridades de execuo quando so agrupadas. Abaixo segue a ordem de prioridade das operaes (iniciam pelas maiores prioridades). () [] ! ++ ++ (tipo) * & */% + < <= > >= == != & ! && !! = += -= *= /=

19

2.11 Operaes de entrada e sada


printf scanf sprintf e sscanf As funes que resumem todas as funes de entrada e sada formatada no C so as funes printf() e scanf(). Um domnio destas funes fundamental ao programador. 2.11.1 printf Prottipo: int printf (char *str,...); As reticncias no prottipo da funo indicam que esta funo tem um nmero de argumentos varivel. Este nmero est diretamente relacionado com a string de controle str, que deve ser fornecida como primeiro argumento. A string de controle tem dois componentes. O primeiro so caracteres a serem impressos na tela. O segundo so os comandos de formato. Como j vimos, os ltimos determinam uma exibio de variveis na sada. Os comandos de formato so precedidos de %. A cada comando de formato deve corresponder um argumento na funo printf(). Se isto no ocorrer podem acontecer erros imprevisveis no programa. Abaixo apresentamos a tabela de cdigos de formato: Cdigo %c %d e %i %e %E %f %g %G %o %s %u %x %X %% %p Exemplo: Cdigo printf ("Um %%%c %s",c,"char"); printf ("%X %f %e",107,49.67,49.67); printf ("%d %o",10,10); Imprime Um %c char 6B 49.67 4.967e1 10 12 Formato Um caracter (char) Um nmero inteiro decimal (int) Nmero em notao cientca com o "e"minsculo Nmero em notao cientca com o "e"maisculo Ponto utuante decimal Escolhe automaticamente o melhor entre %f e %e Escolhe automaticamente o melhor entre %f e %E Nmero octal String Decimal "unsigned"(sem sinal) Hexadecimal com letras minsculas Hexadecimal com letras maisculas Imprime um % Ponteiro

possvel tambm indicar o tamanho do campo, justicao e o nmero de casas decimais. Para isto usa-se cdigos colocados entre o % e a letra que indica o tipo de formato. Um inteiro indica o tamanho mnimo, em caracteres, que deve ser reservado para a sada. Se colocarmos ento %5d estamos indicando que o campo ter cinco caracteres de comprimento no mnimo. Se o inteiro precisar de mais de cinco caracteres para ser exibido

20

ento o campo ter o comprimento necessrio para exibi-lo. Se o comprimento do inteiro for menor que cinco ento o campo ter cinco de comprimento e ser preenchido com espaos em branco. Se se quiser um preenchimento com zeros pode-se colocar um zero antes do nmero. Temos ento que %05d reservar cinco casas para o nmero e se este for menor ento se far o preenchimento com zeros. O alinhamento padro direita. Para se alinhar um nmero esquerda usa-se um sinal - antes do nmero de casas. Ento %-5d ser o nosso inteiro com o nmero mnimo de cinco casas, s que justicado a esquerda. Pode-se indicar o nmero de casas decimais de um nmero de ponto utuante. Por exemplo, a notao %10.4f indica um ponto utuante de comprimento total dez e com 4 casas decimais. Entretanto, esta mesma notao, quando aplicada a tipos como inteiros e strings indica o nmero mnimo e mximo de casas. Ento %5.8d um inteiro com comprimento mnimo de cinco e mximo de oito. Exemplo: Cdigo printf("%-5.2f",456.671); printf ("%5.2f",2.671); printf ("%-10s","Ola"); Obs.: O "pipe"( | ) indica o incio e o m do campo mas no sero escritos na tela. 2.11.2 scanf Prottipo: int scanf (char *str,...); A string de controle str determina, assim como com a funo printf(), quantos parmetros a funo vai necessitar. Devemos sempre nos lembrar que a funo scanf() deve receber ponteiros como parmetros. Isto signica que as variveis que no sejam por natureza ponteiros devem ser passadas precedidas do operador &. Os especicadores de formato de entrada so muito parecidos com os de printf(). Os caracteres de converso d, i, u e x podem ser precedidos por h para indicarem que um apontador para short ao invs de int aparece na lista de argumento, ou pela letra l (letra ele) para indicar que que um apontador para long aparece na lista de argumento. Semelhantemente, os caracteres de converso e, f e g podem ser precedidos por l para indicarem que um apontador para double ao invs de oat est na lista de argumento. Cdigo %c %d e %i %hi %li %e %f %lf %s %h %x %p Formato Um caracter (char) Um nmero inteiro decimal (int) Um short it Um long int Nmero em notao cientca Ponto utuante decimal Um double String Inteiro curto Hexadecimal com letras minsculas Ponteiro Imprime |456.67 | | 2.67| |Ola |

21

2.11.3 sprintf e sscanf sprintf e sscanf so semelhantes a printf e scanf. Porm, ao invs de escreverem na sada padro ou lerem da entrada padro, escrevem ou leem em uma string. Os prottipos so: int sprintf (char *destino, char *controle, ...); int sscanf (char *destino, char *controle, ...); Estas funes so muito utilizadas para fazer a converso entre dados na forma numrica e sua representao na forma de strings. No programa abaixo, por exemplo, a varivel i "impressa"em string1. Alm da representao de i como uma string, string1 tambm conter "Valor de i=".

#include<stdio.h> main() { int i; char string1[20]; printf( nEntre com 1 nros inteiros:); scanf(%d, &i); sprintf(string1, Valor de i = %d", i); puts(string1); }

J no programa abaixo, foi utilizada a funo sscanf para converter a informao armazenada em string1 em seu valor numrico:

#include<stdio.h> main() { int i,j,k; char string1[]=10 20 30; sscanf(string1,"%d %d %d", &i, &j, &k); printf("Valores lidos: %d, %d, %d", i, j, k); }

2.12 Exerccios
1. Faa um programa que receba dois valores do tipo inteiro e efetue as quatro operaes bsicas, mostrando o resultado no nal das quatro. 2. Faa um programa que receba o nome do usurio, quatro notas e calcule a mdia do aluno. A frmula da mdia nal : (nota1+2*nota2+3*nota3+4*nota4)/10. 3. Faa um programa que solicite o tamanho do lado de um quadrado e calcule a rea do mesmo, mostrando o resultado.

22

4. Programa para calcular a rea de um tringulo. Receber a informao da base e da altura em centmetros. Ao nal do programa alm de mostrar o resultado da rea calculada, listar tambm o calculo para 5 guras maiores cujas dimenses so o dobro da anterior e 5 guras menores cujas dimenses so a metade da anterior, partindo da base e altura informadas. 5. Faa um programa que solicite a data atual e a data de nascimento do usurio e calcule a sua idade em dias. Obs.: Para saber se um ano bissexto (366 dias), use a segunte formula: _ 6. Programa para converso de moedas. Inicialmente ler o valor da cotao de 1 dolar para Real. A seguir pedir o valor em dolar e responder o valor convertido para Real.

    #"!   !    

)(!  '&$%#   $

23

3 COMANDOS DE CONTROLE E REPETIO

3.1 if/else
Execuo condicional de comandos. A instruo if causa a execuo de uma ou de um conjunto de instrues, dependendo do valor resultante de uma expresso avaliada. Sintaxe: if (expresso) comando1; [else] [comando2; ] Se a expresso for verdadeira, executa o comando1, caso contrrio executa o comando2. Se comando1 ou comando2 tiverem mais de uma instruo deve-se criar blocos usando e . Exemplo: if (n != 0) x = a*b/n; else { n = x*x; x = a*b/n; }

As instrues de execuo condicional dependem da avaliao de uma expresso condicional. Esta expresso composta por vrias operaes, que so efetuadas atravs dos operadores lgicos e relacionais (ou mesmo atribuies e operaes matemticas), devolvendo um valor booleano TRUE ou FALSE. O C no possui o tipo boolean e no atribui conceito abstrato para VERDADEIRO e FALSO. Para o C V ou F representado por um valor inteiro, com o seguinte signicado: 0 - FALSO (FALSE), No Zero - VERDADEIRO (TRUE). Ou seja, para o C, o valor 0 considerado FALSO, enquanto que todos os demais valores (-1, 1, 2, 1000, -1000, etc) so considerados VERDADEIROS. Quando o C precisa CALCULAR uma expresso, atribuindo o conceito de V ou F, ele usar SEMPRE o valor 1 para Verdadeiro e o valor 0 para FALSO. Assim ca fcil entender o que ocorre nestes exemplos:

24

main() { int x, y, r; x = 20; y = 10; r = x > y; /* Sim, o x maior que y. Ento esta sentena considerada como VERDADEIRA. O C ir avaliar ela como tendo resultado 1 (VERDADEIRO). r recebe 1, portanto */ if (x) { // x vale 20. 20 para o C conceito de VERDADEIRO. r = 0; } r = y + ((x>y) && (y > 0)); /* complicou, no? Temos uma sentena AND que ser calculada como sendo VERDADEIRA (1) ou FALSA (0). Como x maior que y (V, 1) e y maior que 0 (V), a sentena (x>y) && (y > 0) VERDADEIRA, valendo 1. y + 1 = 11. r receber 11.*/ }

Devido clausula else ser opcional, pode existir uma ambigidade no uso de ifelse aninhado. O compilador resolve isto associando o else ao ltimo if sem else. Por exemplo: if (n>0) if (a>b) z=a; else z=b;

Se a>b, ento z=a, quando n>0. Se a<=b, ento z=b, quando n>0. Se n<=0, o valor de z no ser alterado nesta poro de cdigo. Entretanto se tivermos: if (n>0) { if (a>b) z=a; } else z=b;

Se a>b, ento z=a, quando n>0. Se n<=0, ento z=b. Se n>0 e a<=b, o valor de z no ser alterado nesta poro de cdigo.

25

3.2 while
Enquanto a condio descrita pela expresso for satisfeita (ou seja, verdadeira), o comando ser repetido. O comando somente ser executado se a expresso condicional for verdadeira. A avaliao da expresso realizada da mesma forma que no comando if. O comando while o nico e o principal comando de repetio realmente necessrio, sendo que pode substituir qualquer outra construo do tipo: for, repeat/until, do/while, goto ...). Sintaxe: while (expresso) comando1; Exemplo: contagem de bits setados na varivel n. bits = 0; while (n != 0) { if (n & 1) bits++; n = 1;

Exemplo: imprimir os nmeros impares de 3 at 21 (inclusive). i = 3; while ( i <= 21 ) { printf(%d n, i); i = i + 2; }

3.3 for
O comando for serve para a execuo de um nmero xo de vezes (ou no), enquanto uma varivel percorre uma determinada faixa de valores. Esta varivel chamada de varivel de ndice. Sintaxe: for (inicio; condio; modic) comando; Onde temos "incio"como sendo uma expresso que ir gerar o valor inicial da varivel de ndice utilizada pelo comando. A "condio"ir indicar uma condio para o prosseguimento do lao (enquanto tal condio for verdadeira ir repetir o lao). E nalmente "modic"ser o comando dado a cada execuo do lao, sendo este realizado ao nal de um lao do for, modicando o valor da varivel de ndice, antes de um novo teste da condio. Cada um destes elementos (incio, condio e comando) pode ainda estar dividido em sries de comandos, como nas expresses do if. Exemplo: nmeros mpares de 3 a 21, com for: for (i = 3; i <= 21; i = i+2) printf("%d n", i);

26

Para criarmos um lao innito (sem m) podemos fazer um comando da seguinte forma: for(;;) - comando sem expresses de controle. O comando for equivalente a seguinte estrutura: while (condio) { comando; modic; }

3.4 do/while
O comando do/while o inverso do comando while, ou seja, o teste executado ao nal deste ao invs de ser no incio. Este comando tambm equivalente ao comando repeat/until (Pascal) s que a expresso avaliada em um estaria negada em relao ao outro. Sintaxe: do comando; } while (expresso); O comando ser executado e depois ser testada a condio dada pela expresso, e caso esta seja verdadeira (TRUE) ser novamente executado o comando.

3.5 Break e Continue


Break causa a sada no meio de um lao (para comandos: for, while, do/while, switch). Provoca a antecipao do m do lao. muito usado com o comando case como ser visto mais adiante. Continue serve para a re-execuo do lao, a partir do teste. Ir causar a reinicializao do lao (no funciona com o switch). Um exemplo prtico do seu uso pode ser visto no exemplo a seguir: while ( x <= valmax) { printf ("Entre com um valor:"); scanf ("%d",&val); if (val < 0) continue; }

3.6 switch/case
Faz uma associao de valores com comandos a executar. Conforme o valor dado, executa um certo nmero de instrues. Serve como uma estrutura mais sosticada que os ifs encadeados. Sintaxe: switch (varivel) { case <valor1> : <comando1>; case <valor2> : <comando2>;

27

<comando3>; ... [ default : comando4; ] } No comando switch no possvel denir intervalos para os quais o comando ser executado, temos que denir os valores textualmente, um a um. Os valores utilizados no case devem ser do tipo inteiro ou char. O uso do comando break muito importante quando associado ao switch, pois caso este no seja usado a cada case, ser feita a execuo de todos os comandos at encontrar o m do switch, sendo executado inclusive o default, se houver. Por isso a estrutura comumente usada em um comando case : case A: x++; break; case b: case B: y++; break; ...

3.7 Expresses Condicionais


As expresses condicionais se apresentam da seguinte forma: expr1 ? expr2 : expr3 Esta expresso equivalente a: se expr1 // Onde: expr1 -> Condio de teste expr2 // expr2/expr3 -> Valor retornado seno expr3 Portanto expr2 ser o valor calculado se expr1 for verdadeiro e expr3 ser o valor calculado se expr1 for falso. Exemplo: b = ((x == y)?x:y);

3.8 Exerccios:
1. Escrever um programa que solicite dois numeros ao usurio. O programa deve comparar os valores e imprimir na tela os dois nmeros digitados, a soma deles, o maior e o menor deles. 2. Escrever um programa que recebe trs numeros inteiros (a, b e cod) e imprima na tela: a+b, se cod >= 0; a-b, se cod < 0. 3. Fazer uma funo que receba um nmero (do teclado) e retorne o fatorial deste nmero (exemplo 5!= 5*4*3*2*1;), usando comandos de repetio (Lembre que os fatoriais de 0 e de 1 so iguais a 1). Deve pedir para o usurio repetir a entrada se o nmero que ele digitou for negativo. Deve ser capaz de calcular fatoriais maiores que 65535, limite para um inteiro.

28

4. Faa um programa completo que leia do teclado 10 nmeros inteiros e depois imprima: a) A soma de todos os elementos b) O maior e o menor elemento 5. Escrever um trecho de cdigo, usando atribuio condicional, que teste o contedo de duas variveis e atribua o maior valor a uma terceira varivel. 6. Faa um programa para calcular o valor de , dado por: onde n fornecido pelo usurio;

Sendo , implemente um programa que calcule o valor de , baseado nos n primeiros elementos dessa srie. O n deve ser informado pelo usurio, quanto maior esse numero, mais preciso ser o valor de . 9. Escreva um programa que apresente a srie de Fibonacci at o n-simo elemento, esse limite deve ser informado pelo usurio. A srie de Fibonacci formada pela sequncia: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... 10. O que faz o trecho de cdigo a seguir? int a,b,c; ... c = (a>=0)?(b>=0):(b<0);



 )(  )( #0 #'

# (53 64  &% 2$#1 " #

8. O valor aproximado de

          

pode ser calculado usando a srie:

7. Escreva um programa que l um valor escreve o valor de , dado por:

inteiro e positivo, logo em seguida, calcule e

  % 


)   

% 


!


29

4 MATRIZES

Uma matriz uma coleo de variveis do mesmo tipo, e esta referenciada por um nome comum. Cada elemento de uma matriz acessado atravs de um ndice. O ndice 0 corresponde ao primeiro elemento de uma matriz, e o ndice mais alto, representa o ltimo elemento de uma matriz. Basicamente existem alguns tipos de matrizes:

A forma geral de se declarar uma matriz unidimensional : tipo nomevar [tamanho]; Por exemplo, se quisermos declarar um vetor (matriz unidimensional) com o nome teste que armazena 10 nmero inteiros, teramos que denir o tipo (int) e o tamanho do vetor (10). Ressalva-se que o primeiro ndice de um vetor em C sempre ser o 0. Ou seja, os ndices deste vetor iriam de 0 a 9, onde tm-se 10 posies. A declarao do vetor caria assim: int teste[10]; Criando um vetor de 3 posies do tipo double, pode-se analisar como fazer o acesso a cada ndice. Vejamos: Exemplo 1: main() { double vetor[3]; vetor[0]=3.9; vetor[1]=4.9; vetor[2]=0.7; printf("O valor do primeiro elemento eh:%lf n",vetor[0]); /*Sera impresso 3.9*/ printf("O valor do ultimo elemento eh:%lf n",vetor[2]); /*Sera impresso 0.7*/ }

Quando o C v uma declarao como esta ele reserva um espao na memria sucientemente grande para armazenar o nmero de clulas especicadas em tamanho. Por exemplo, se declararmos:

Matrizes Unidimensionais: So matrizes de apenas uma dimenso, e so geralmente chamadas de vetores ou listas (estticas). Matrizes Bidimensionais: So matrizes de duas dimenses. Matrizes Multidimensionais: So matrizes de n dimenses.

30

oat exemplo [20]; O compilador C reservar 4x20=80 bytes. Estes bytes so reservados de maneira contgua. Alm disso, C no verica se o ndice que voc usou est dentro dos limites vlidos. Este um cuidado que voc deve tomar. Se o programador no tiver ateno com os limites de validade para os ndices ele corre o risco de ter variveis sobrescritas ou de ver o computador travar. Logo, o programa ir compilar e executar se voc programou algo, como: exemplo[400]=32;. Para vericarmos a funcionalidade dos vetores, vamos analisar mais um exemplo. Exemplo 2: #include <stdio.h> main () { int num[100]; /* Declara um vetor de inteiros de 100 posicoes */ int count=0; int totalnums; do { printf (" nEntre com um numero (-999 p/ terminar):"); scanf ("%d",&num[count]); count++; } while (num[count-1]!=-999); totalnums=count-1; printf (" n Os nmeros que voc digitou foram: n"); for (count=0;count<totalnums;count++) printf ("%d n",num[count]); } No exemplo acima, o inteiro count inicializado em 0. O programa pede pela entrada de nmeros at que o usurio entre com o Flag -999. Os nmeros so armazenados no vetor num. A cada nmero armazenado, o contador do vetor incrementado para na prxima iterao escrever na prxima posio do vetor. Quando o usurio digita o ag, o programa abandona o primeiro loop e armazena o total de nmeros gravados. Por m, todos os nmeros so impressos. bom lembrar aqui que nenhuma restrio feita quanto a quantidade de nmeros digitados. Se o usurio digitar mais de 100 nmeros, o programa tentar ler normalmente, mas o programa os escrever em uma parte no alocada de memria, pois o espao alocado foi para somente 100 inteiros. Isto pode resultar nos mais variados erros no instante da execuo do programa.

4.1 Strings
Strings so vetores de caracteres, chars. As strings so o uso mais comum para os vetores. As strings tm o seu ltimo elemento como um 0. A declarao geral para uma string : char nome-da-string [tamanho];

Uma constante string uma lista de caracteres entre aspas. Por exemplo: Oi Mundo. Neste caso, no necessrio adicionar o nulo no nal das constantes strings manualmente

31

(o compilador faz isso para voc). possvel solicitar ao usurio uma determinada string e sua leitura pode ser feita de duas formas: utilizando a funo scanf ou utilizando a funo gets. Porm, a funo scanf tem alguma diculdade em lidar com os espaos no meio de uma string, por isso vamos utilizar a funo gets. Abaixo segue um exemplo para entrada de strings. Exemplo 3: #include <stdio.h> main () { char string1[100], string2[100]; printf (" n Digite o seu nome: "); gets (string1); printf (" n Digite o seu sobrenome: "); gets (string2); printf (" n Seu nome completo eh: %s %s n",string1,string2); }

Existem diversas funes para trabalharmos com strings, estas necessitam que no cabealho seja declarada a biblioteca <string.h>. A tabela 4.1 apresenta as principais funes de manipulao e tratamento de strings: Nome strcpy(s1,s2) strcat(s1,s2) strlen(s1) strcmp(s1,s2) strchr(s1,ch) strstr(s1,s2) Funo Copia s2 em s1. Concatena s2 ao nal de s1. Retorna o tamanho de s1. Retorna 0 se s1=s2; menor que 0 se s1<s2; maior que 0 se s1>s2. Retorna um ponteiro para a primeira ocorrncia de ch em s1. Retorna um ponteiro para a primeira ocorrncia de s2 em s1. Tabela 4.1: Manipulao de Strings Abaixo segue um exemplo de utilizao de algumas funes, as quais utilizam a biblioteca string.h. Cabe ressaltar que existem ainda diversas funes j desenvolvidas as quais fazem parte da biblioteca. No exemplo, o contedo da string s1 lido do usurio, e o contedo de s2 atribudo atravs da funo strcpy. A funo strlen ir imprimir o tamanho de cada string, e a funo strcmp ir comparar se os contedos de s1 e s2 esto iguais.

32

Exemplo 4: #include<stdio.h> #include<string.h> main() { char s1[80],s2[80]; printf (" n Digite uma string qualquer: "); gets(s1); strcpy(s2,"Programa Exemplo"); printf(s2); printf(" n Tamanho: %d %d",strlen(s1),strlen(s2)); if (!strcmp(s1,s2)) printf(" n As strings so iguais n"); else printf (" n As strings so diferentes! n"); }

4.2 Matrizes Bidimensionais


Quando trabalha-se com C sabe-se que este suporta matrizes multidimensionais. As matrizes bidimensionais so a forma mais simples das matrizes multidimensionais. A forma geral de se declarar uma matriz unidimensional : tipo nomevar [linha][coluna]; muito importante ressaltar que, nesta estrutura, o ndice da esquerda indexa as linhas e o da direita indexa as colunas. Quando vamos preencher ou ler uma matriz no C o ndice mais direita varia mais rapidamente que o ndice esquerda. Mais uma vez bom lembrar que, na linguagem C, os ndices variam de zero ao valor declarado, menos um; mas o C no vai vericar isto para o usurio. Manter os ndices na faixa permitida tarefa do programador. Se declararmos int num[4][3], e inicializarmos toda a matriz com o contedo zero e apenas a posio 1,2 recebesse um valor diferente (num[1][2]=9;), a matriz poderia ser mostrada assim: 0 0 0 0 0 0 0 0 0 9 0 0

Abaixo damos um exemplo do uso de uma matriz, onde a matriz mtrx preenchida, seqencialmente por linhas, com os nmeros de 1 a 200.

33

Exemplo 5: #include <stdio.h> main () { int mtrx [20][10]; int i,j,count; count=1; for (i=0;i<20;i++) for (j=0;j<10;j++) { mtrx[i][j]=count; count++; printf(" n Linha:%d Col:%d INT:%d n",i,j,mtrx[i][j]); } }

4.3 Matrizes de Strings


Matrizes de strings so matrizes bidimensionais. Se zermos um vetor de strings estaremos fazendo uma lista de vetores. Esta estrutura uma matriz bidimensional de chars. Podemos ver a forma geral de uma matriz de strings como sendo: char nome [nrodestrings][compr-das-strings]; Para acessar cada string basta usar apenas o primeiro ndice. Ento, para acessar uma determinada string faa: nome [ndice] Aqui est um exemplo de um programa que l 5 strings e as exibe na tela: Exemplo 6: #include <stdio.h> main () { char strings [5][100]; int count; for (count=0;count<5;count++) { printf (" n Digite uma string: "); gets (strings[count]); } printf (" n As strings que voce digitou foram: n"); for (count=0;count<5;count++) printf ("%s n",strings[count]); }

4.4 Matrizes Multidimensionais


O uso de matrizes multidimensionais na linguagem C simples. Sua forma geral :

34

tipo nome [tam1][tam2] ... [tamN]; Uma matriz N-dimensional funciona basicamente como outros tipos de matrizes. Basta lembrar que o ndice que varia mais rapidamente o ndice mais direita.

4.5 Inicializao de Matrizes


Podemos inicializar matrizes, assim como podemos inicializar variveis. A forma geral de uma matriz como inicializao : tipo nome [tam1][tam2] ... [tamN] = {lista-de-valores}; A lista de valores composta por valores (do mesmo tipo da varivel) separados por vrgula. Os valores devem ser dados na ordem em que sero colocados na matriz. Abaixo vemos alguns exemplos de inicializaes de matrizes: int matrx [3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; char str [10] = { J, o, a, o, 0}; char strvect [3][10] = { "Joao", "Maria", "Jose"};

4.6 Exerccios:
1. A avaliao em um colgio feita atravs de 3 notas. Como a turma pequena, existem apenas 4 alunos inscritos. Faa um programa que receba as notas dos 4 alunos e indique a mdia de cada um deles, mostrando as suas notas individualmente. Depois disso, o programa ainda deve indicar a maior mdia. 2. Faa um programa que tenha um vetor de 20 posies de inteiros positivos. Este deve receber do usurio os valores, valid-los e armazen-los. O programa deve apenas imprimir na tela os nmeros inseridos em posies de ndices mpares do vetor. 3. Faa um programa que recebe 8 nmeros e o armazene em um vetor (entrada). Aps a leitura dos nmeros, deve ser armazenado em outro vetor a raiz quadrada de cada nmero do vetor de entrada. Imprima as raizes na tela. 4. Fazer o programa que leia o nome do usurio e diga quantas letras este nome tem. 5. Fazer um programa que recebe duas palavras e diz se estas strings so iguais. 6. Fazer um programa que recebe quatro nomes e diz quantos deles comeam com a letra L e quantos com a letra T. 7. Fazer um programa que recebe separadamente o primeiro nome, o segundo nome e o ltimo nome de uma pessoa. O programa deve concatenar estes nomes e imprimi-lo no nal. 8. Fazer o programa que leia uma matriz 4x4 e imprima a mdia dos elementos. 9. Fazer o programa que leia uma matriz 6x6 e imprima a mdia dos elementos da diagonal principal (linha=coluna) e tambm a mdia dos elementos da diagonal secundria (linha + coluna == nro_de_linha ). 10. Fazer um programa que recebe uma matriz A 2x2 e uma matriz B 2x2, e crie uma terceira matriz C 2x2, a qual composta pelos elementos multiplicados de AB.

35

11. Fazer uma programa que gere (sem o usurio digit-la) e imprima na tela a seguinte matriz: 1 1 1 1 1 1 1 2 2 2 2 1 1 2 3 3 2 1 1 2 3 3 2 1 1 2 2 2 2 1 1 1 1 1 1 1

36

5 ESTRUTURAS DEFINIDAS PELO USURIO

5.1 Estruturas
Matrizes so estruturas de dados homogneos, isto , podem conter colees de dados do mesmo tipo (todos int, todos oat, todos char). Na vida real encontramos muitas situaes onde temos colees de dados que so de tipos diferentes. Como exemplo temos uma cha de cadastro de funcionrio, uma cdula de identidade, uma inscrio em uma concurso, uma cadastro de usurio em um site, etc. Num cadastro de usurio temos dados como nome, endereo, telefone, e-mail, data de nascimento, entre outros. Pode-se notar que esses dados so de tipos diferentes. Para agrupar esses dados no nos serve uma matriz. H necessidade de uma estrutura de dados heterogneos, denida pelo usurio. As estruturas (struct) so agrupamentos de dados, que denem um novo tipo de dado mais complexo, formado por tipos de dados mais simples. struct nome_do_tipo_da_estrutura { tipo-var nome-var; tipo-var nome-var2; ...}variveis_estrutura;

O nome_do_tipo_da_estrutura o nome para a estrutura. As variveis_estrutura so OPCIONAIS e seriam nomes de variveis que o usurio j estaria declarando e que seriam do tipo nome_do_tipo_da_estrutura. Exemplo: struct data { int dia; int mes; int ano; int dia_ano; char nome-mes[10]; }; struct data hoje;

A utilizao de estruturas no C semelhante ao record do pascal. Referncia a um elemento da estrutura:

37

nome_estrut.elemento > hoje.dia = 23; Exemplo 2: #include <stdio.h> #include <string.h> _____estrutura de endereo: struct tipo_endereco { char rua [50]; int numero; char bairro [20]; char cidade [30]; char sigla_estado [3]; long int CEP; }; *Estrutura cha_pessoal para adicionar os dados pessoais de algum:* struct cha_pessoal { char nome [50]; long int telefone; struct tipo_endereco endereco; };

_____Programa Principal____ void main (void){ struct cha_pessoal cha; strcpy(cha.nome,"Luiz Osvaldo Silva"); cha.telefone=33332234; strcpy(cha.endereco.rua,"Rua dos Flores"); cha.endereco.numero=10; strcpy(cha.endereco.bairro,"Menino Deus"); strcpy(cha.endereco.cidade,"Porto Alegre"); strcpy(cha.endereco.sigla_estado,"RS"); cha.endereco.CEP=90000000; } Esse programa declara uma varivel cha do tipo cha_pessoal e preenche os seus dados. O exemplo mostra como podemos acessar um elemento de uma estrutura: basta usar o ponto (.). Assim, para acessar o campo telefone de cha, escrevemos: cha.telefone = 33332234; Como a struct cha pessoal possui um campo, endereo, que tambm uma struct, podemos fazer acesso aos campos desta struct interna da seguinte maneira: cha.endereco.numero = 10; cha.endereco.CEP=90000000; Desta forma, estamos acessando, primeiramente, o campo endereco da struct cha e, dentro deste campo, estamos acessando o campo numero e o campo CEP. Caractersticas das estruturas:

38

Tambm podem ser declarados matrizes de estruturas, da mesma forma que uma matriz de inteiros ou caracteres. A forma de acesso semelhante: struct data st[10]; /*um vetor da estrutura de 10 elementos */ st[0].dia=2; sprintf(st[0].nome_ms, "Janeiro"); ...

5.1.1 Exerccios a) Faa um programa que dene um tipo para alunos com os seguintes campos: nome (20 caracteres), cdigo (10 caracteres), notas de 3 provas e mdia nal. O programa dever ler da entrada padro os dados de 4 alunos, calcular a mdia individual de cada aluno e a mdia geral dos alunos. b) Modique o exerccio anterior, mas permita que o usurio fornea antes o nmero total de alunos que deseja digitar. c) Considere uma bilhete de passagem de nibbus, conforme mostrado na tabela 5.1. Primeiro - Dena uma estrutura de dados de nome Passagem. Segundo - Considerando uma onibus de 48 lugares, dena um vetor de Passagens.

5.2 Unies
Uma declarao union determina uma nica localizao de memria onde podem estar armazenadas vrias variveis diferentes. A declarao de uma union semelhante declarao de uma estrutura:

No podem ser inicializadas na declarao ou copiadas atravs de atribuio; Podem ser acessadas com o auxlio de pointers. Permitem a criao de listas encadeadas.

VIAO MONTENEGRO S/A Nmero:______ Origem:___________________ Data: __ __ ____ Assento:______ Valor da Passagem: R$____________ Nome da Empresa:___________ Destino:___________________ Horrio:____:____ Distncia: ____km

Tabela 5.1: Bilhete de passagem

39

union nome_do_tipo_da_union { tipo_1 nome_1; tipo_2 nome_2; ... tipo_n nome_n; } variaveis_union;

Como exemplo, vamos considerar a seguinte unio: union angulo { oat graus; oat radianos; };

Nela, temos duas variveis (graus e radianos) que, apesar de terem nomes diferentes, ocupam o MESMO local da memria. Isto quer dizer que s gastamos o espao equivalente a um nico oat. Unies podem ser feitas tambm com variveis de diferentes tipos. Neste caso, a memria alocada corresponde ao tamanho da maior varivel no union. Veja o exemplo: #include <stdio.h> #dene GRAUS G #dene RAD R union angulo { int graus; oat radianos; }; main() { union angulo ang; char op; printf(" n Numeros em graus ou radianos? (G/R):"); scanf("%c",&op); if (op == GRAUS) { ang.graus = 180; printf(" nAngulo: %d n",ang.graus); } else if (op == RAD){ ang.radianos = 3.1415; printf(" nAngulo: %f n",ang.radianos); } else printf(" nEntrada invalida!! n"); }

40

5.3 Enumeraes
Numa enumerao podemos dizer ao compilador quais os valores que uma determinada varivel pode assumir. Sua forma geral : enum nome_do_tipo_da_enumerao { lista_de_valores } lista_de_variveis

Exemplo: #include <stdio.h> enum dias_da_semana { segunda, terca, quarta, quinta, sexta, sabado, domingo}; main() { enum dias_da_semana d1,d2; d1=segunda; d2=sexta; if (d1==d2) printf (O dia o mesmo); else printf (So dias diferentes); }

Voc deve estar se perguntando como que a enumerao funciona. Simples, o compilador pega a lista que voc fez de valores e associa, a cada um, um nmero inteiro. Ento, ao primeiro da lista, associado zero, ao segundo 1 e assim por diante. As variveis declaradas so ento variveis inteiras.

41

6 FUNES

6.1 Modularidade
Modularidade a tcnica de programar, desenvolvendo um programa a partir de pequenas partes ou mdulos. Em C, construir um mdulo signica construir uma funo. Inicialmente, modularizar um programa parece dicultar a programao. Mas o que acontece no desenvolver de qualquer programa o contrrio. As vantagens de se modularizar so: economia de tempo de criao do programa, economia de tempo de manuteno do programa, reutilizao de mdulos, organizao do cdigo e construo de bibliotecas.

6.2 Forma de uma Funo


Funes so blocos de construo de C e o local onde toda atividade ou tarefa do programa se realiza. A forma geral de uma funo :

especicador_do_tipo nome_da_funo (lista de parmetros) { corpo da funo }

O especicador_de_tipo especica o tipo de valor que o comando return da funo ir devolver. Se nenhum tipo especicado, o compilador assume que a funo devolve um inteiro. A lista de parmetros indica o nome das variveis e seus tipos associados. Estas so separadas por vrgula e e indicam os argumentos da funo. A declarao de parmetros uma lista com a seguinte forma geral:

tipo nome1, tipo nome2, ... , tipo nomeN

No corpo da funo as entradas so processadas, sadas so geradas, ou seja, toda a tarefa corresponde desta funo. Abaixo segue um exemplo de criao de uma funo em C. Neste exemplo, a funo recebe um nmero x e imprime a raiz quadrada do mesmo.

42

#include<stdio.h> #include<math.h> void raiz(double x) { printf("%lf",sqrt(x)); } main() { double nro; printf("Digite um numero"); scanf("%lf",&nro); raiz(nro); }

6.3 Regras de Escopo


As regras de escopo de uma linguagem so as regras que governam se uma poro de cdigo conhece ou tem acesso a outra poro de cdigo ou dados. Ou seja, o escopo o conjunto de regras que determinam o uso e a validade de variveis nas diversas partes do programa. Para trabalharmos corretamente com as regras de escopo, cabe lembrar o conceito de variveis locais e variveis globais. Variveis locais so aquelas tm validade dentro do bloco no qual so declaradas, ou seja, s existem enquanto o bloco est sendo executado. No caso de criarmos uma variveil dentro de uma funo, esta s ser acessvel dentro desta funo e poderemos chamar ela de varivel local a funo. J as variveis globais so aquelas declaradas fora das funes do programa, e so acessveis atravs de todos os mdulos do programa. Estas so alocadas no incio do programa, e s so desalocadas no trmino do mesmo.

6.4 Argumentos de Funes


Se uma funo utiliza argumentos, necessrio declarar as variveis que aceitem os valores dos argumentos. Estas variveis so chamadas de parmetros formais da funo, se comportando como variveis locais dentro da mesma. Estas so alocadas no incio de uma funo, e desalocadas na sua sada. importante salientar que os parmentros devem ser passados na ordem respectiva e compatibilidade. Foi implementado um exemplo simples, para vericarmos a importncia da passagem de parmetros. Temos uma funo que calcula a diferenca entre dois nmeros, e imprime na tela. Vejamos o exemplo:

43

#include<stdio.h> void diferenca(int x, int y) { printf("%d",x-y); } main() { diferenca(10,0); /*Imprimir 10 na Tela*/ diferenca(0,10); /* Imprimir -10 na Tela*/ }

6.5 O Comando return


O comando return utilizado dentro das funes visando devolver um determinado valor para a outra funo que chamou a funo corrente. Quando se chega a uma declarao return a funo encerrada imediatamente e, se o valor de retorno informado, a funo retorna este valor. importante lembrar que o valor de retorno fornecido tem que ser compatvel com o tipo de retorno declarado para a funo. Uma funo pode ter mais de uma declarao return. Isto se torna claro quando pensamos que a funo terminada quando o programa chega primeira declarao return. Abaixo est um exemplo de uso do return:

#include <stdio.h> int Square (int a) { return (a*a); } main () { int num; printf ("Entre com um numero: "); scanf ("%d",&num); num=Square(num); printf ("O seu quadrado vale: %d",num); }

6.6 Funes do Tipo void


Um dos usos de void declarar explicitamente funes que no devolvem valores. Podemos analisar a funcionalidade do void observando o programa abaixo:

44

#include <stdio.h> void Mensagem (void) { printf ("Ola! Eu estou vivo."); } int main () { Mensagem(); printf ("Diga de novo:"); Mensagem(); return 0; } No exemplo acima, chama-se duas vezes a funo Mensagem. Esta declarada para retornar um tipo void, ou seja, no retornar valor nenhum, apenas imprimir uma mensagem. Alm disso, dentro da lista de parmetros passamos ainda o tipo void, que siginica que nenhum valor ser passado por parmetro tambm.

6.7 Passagem por Parmetros


Sabemos que as funes em C recebem variveis por parmetros. Existem basicamente duas maneiras de passarmos estes argumentos para as sub-rotinas. 6.7.1 Chamada por Valor Portanto, quando chamamos uma funo os parmetros formais da funo copiam os valores dos parmetros que so passados para a funo. Estes viram variveis locais, assim quaisquer alteraes feitas nestas variveis no tm nenhum efeito nas variveis usadas para cham-la. Isto ocorre porque so passados para a funo apenas os valores dos parmetros e no os prprios parmetros. Vamos analisar o exemplo abaixo: #include <stdio.h> oat sqr (oat num) { num=num*num; return num; } void main () { oat num,sq; printf ("Entre com um numero: "); scanf ("%f",&num); sq=sqr(num); printf ("O numero original e: %f",num); printf ("O seu quadrado vale: %f",sq); } Neste exemplo, a funo sqr eleva ao quadrado o oat num passado por parmetro. A funo utiliza o prprio num (parmetro) para realizar o clculo. Como a passagem por

45

parmetro foi feita por valor, o valor de num no ser alterado quando voltar a funo main. Logo, este parmetro funciona como uma varivel local dentro da funo, pois o valor num da funo principal foi copiado para a varivel num da funo sqr. 6.7.2 Chamada por Referncia Neste tipo de chamado os parmetros podem ser alterados dentro da funo, mantendo este valor para a funo que o chamou. Este nome vem do fato de que, neste tipo de chamada, no se passa para a funo os valores das variveis, mas sim suas referncias (a funo usa as referncias para alterar os valores das variveis fora da funo). O C s faz chamadas por valor. Isto bom quando queremos usar os parmetros formais vontade dentro da funo, sem termos que nos preocupar em estar alterando os valores dos parmetros que foram passados para a funo. Mas isto tambm pode ser ruim s vezes, porque podemos querer mudar os valores dos parmetros fora da funo tambm. O C++ tem um recurso que permite ao programador fazer chamadas por referncia (deve-se utilizar o compilador g++ para isto). H entretanto, no C, um recurso de programao que podemos usar para simular uma chamada por referncia. Quando queremos alterar as variveis que so passadas para uma funo, ns podemos declarar seus parmetros formais como sendo ponteiros. Os ponteiros so a "referncia"que precisamos para poder alterar a varivel fora da funo. O nico inconveniente que, quando usarmos a funo, teremos de lembrar de colocar um & na frente das variveis que estivermos passando para a funo. O que so ponteiros? "Ponteiro uma varivel que contm um endereo de memria. Esse endereo normalmente a posio de uma outra varivel na memria. Se uma varivel contm o endereo de memria da outra, ento a primeira varivel dita apontar para a segunda. " Veja um exemplo: #include <stdio.h> void Swap (int *a,int *b) { int temp; temp=*a; *a=*b; *b=temp; } void main (void) { int num1,num2; num1=100; num2=200; Swap (&num1,&num2); printf ("Eles agora valem %d %d",num1,num2); }

O que est acontecendo que passamos para a funo Swap o endereo das variveis num1 e num2. Estes endereos so copiados nos ponteiros a e b. Atravs do operador * estamos acessando o contedo apontado pelos ponteiros e modicando-o. O contedo

46

nada mais do que os valores armazenados em num1 e num2, que, portanto, esto sendo modicados! 6.7.3 Matrizes como Argumentos de Funes Se declaramos uma matriz de 50 posies, existem basicamente trs maneiras de passarmos ela por parmetro para uma funo, so elas: void func (int matrx[50]); void func (int matrx[]); void func (int *matrx); Nos trs casos, teremos dentro de func() um int* chamado matrx. Ao passarmos um vetor para uma funo, na realidade estamos passando um ponteiro. Neste ponteiro armazenado o endereo do primeiro elemento do vetor. Isto signica que no feita uma cpia, elemento a elemento do vetor. Isto faz com que possamos alterar o valor dos elementos do vetor dentro da funo. Para chamarmos a funo func passando a matriz mt2 de 50 posies, podemos seguir o seguinte exemplo: func(mt2); Muito embora o parmetro mt2 seja declarado como uma matriz de inteiros, o compilador C converte-o para um ponteiro de inteiros. Portanto, seu endereo passado para a funo. Neste caso, o cdigo dentro da funo estar operando com, e potencialmente alterando, o contedo real da matriz usada para chamar a funo.

6.8 Prottipos de Funes


Os prottipos permitem indicar ao compilador indicar a existncia de funes durante o cdigo, e quais os tipos dos argumentos que devem se passados. At agora, nossas funes sempre foram declaradas antes do main , no necessitando a indicao do seu prottipo. A sintaxe de um prottipo de funo : tipo_de_retorno nome_da_funo (declarao_de_parmetros); Vejamos o seguinte exemplo: #include <stdio.h> oat Square (oat a); int main () { oat num; printf ("Entre com um numero: "); scanf ("%f",&num); num=Square(num); printf ("O seu quadrado vale: %f",num); return 0; } oat Square (oat a) { return (a*a); }

47

6.9 Exerccios
1. Desenvolva uma funo, que receba trs notas e devolva a sua mdia. 2. Desenvolva uma funo que receba trs notas (p1, p2 e p3) e devolva a mdia no argumento p3. 3. Construa uma funo C que recebe, por parmetro, um valor n, inteiro e positivo, e escreve os seus divisores. 4. Contrua uma funo que recebe um vetor de x elementos preenchidos, e ordene o vetor. 5. Desenvolva uma funo em C que recebe o gabarito da LOTO e uma aposta (no mximo 10 dezenas) e devolve o nmero de pontos da aposta. 6. Desenvolver um algoritmo com uma funo que recebe um vetor e sua dimensio e devolve o percentual de valores do vetor que so menores do que a mdia dos valores deste vetor. 7. Dado a funo abaixo, responda: int func(int n) { if (n) return n*func(n-1); else return 1; }

O que esta funo faz? O que recursividade?

48

7 APONTADORES

Antes de vermos o que so apontadores e como podem ser utilizados no C, vamos fazer uma rpida reviso sobre o conceito de variveis. Uma varivel mostrada nas disciplinas de algoritmos como se fosse uma caixa com um nome e esta caixa possui um valor qualquer. Teste cont texto 209 34 "exemplo" Bem, esta uma analogia fcil de entender quando lidamos com algoritmos, mas agora devemos entender como as varveis so realmente implementadas pelas linguagens. Uma varivel nada mais que um nome (label) que referencia (aponta) uma posio de memria. A memria pode ser considerada como um array de bytes, sendo que cada palavra tem um endereo nico. Considerando que teste seja do tipo int, cont do tipo char e texto uma string de 10 posies, podemos admitir que os mesmos poderiam estar dispostos da seguinte forma em um trecho de memria hipottico que comea no endereo 200: Endereo 200 201 202 203 204 205 206 207 208 209 210 211 212 213 Valor Nome 209 teste 000 34 cont e texto x e m p l o 0 ? ? ... xx

Temos, ento, que um label, ou seja, um nome de varivel que aponta para o incio de uma rea de memria reservada para si, cujo tamanho depende do tipo. Ou seja, para o tipo int, so reservados 2 bytes (em algumas arquiteturas so 4 ou mesmo 8 bytes), para o tipo char apenas um e para a string texto, so reservados tantos bytes quantos forem

49

necessrios para satisfazer o tamanho requerido. No momento o texto de exemplo no utiliza todos os 10 bytes, sendo que a prxima varivel declarada (xx) ocupar a posio de memria 213 mesmo assim. No desenho tambm est representado o uso do 0 como terminador de uma cadeia de caracteres no C. Anteriormente, no Captulo 6, falamos dos operadores "&"e "*"para manipulao de endereos. Agora podemos entender melhor seu funcionamento. Quando referenciamos a varivel pelo nome, o que nos retornado ser simplesmente o valor contido na memria referenciada pela varivel, ou seja, ao referenciarmos a varivel teste, nos ser retornado o valor 209, ao referenciarmos a varivel cont, nos ser retornado o valor 34. Quando, entretanto, referenciarmos a varivel teste com a seguinte sintaxe: &teste Estamos agora pedindo o endereo ocupado pela varivel, ou seja, receberemos o valor 200 (posio da memria onde a mesma comea). De forma anloga, se usarmos a notao: teste ser retornado o valor contido na memria cujo endereo est na posio de memria apontada por teste! Complicado? Vejamos no exemplo: A posio de memria apontada pela varivel teste contem o valor 209. Quando usamos *teste, queremos o valor da posio 209, ou seja, nos ser retornado o!! Este o conceito de apontadores: variveis cujo valor o endereo de uma outra varivel ou uma rea de memria reservada para tal. Estes exemplos so hipotticos, pois o C no permite usar o operador "*"para variveis que no sejam do tipo pointer. Os apontadores ou pointers so tipos de dados que tem por funo "apontar"(referenciar) variveis atravs de seus endereos fsicos (posio da varivel na memria), permitindo uma maior exibilidade em nossos programas como: acesso indireto por ponteiros, simulao de passagem de parmetros por referncia, alocao dinmica de memria, criao de listas encadeadas e outras estruturas de dados mais complexas. So declarados da seguinte forma: int x,y; // Declarao de dois inteiros int *px; // Declarao de um ponteiro para inteiros double vard, *pd; // um double e um ponteiro para double Os ponteiros so denidos em funo do tipo de varivel ao qual ele ser ligado, so do tipo "aponta para um determinado tipo de dado". Como se usa um apontador: pt = &x; y = *pt; // pt recebe o endereo de x, aponta para x //y recebe o valor apontado por pt

impossvel apontar para registradores e constantes denidas atravs do comando #dene do processador de macros. Um uso muito prtico de ponteiros com os arrays, pois este tipo de dado tem caractersticas que se comportam de maneira muito parecida a eles. Na realidade, um array pode ser visto, na maioria das vezes, como sendo um apontador para uma posio onde se encontram alocados os dados. Por isso temos:

pt = 12; //O endereo dado por pt recebe o valor 12 //Se pt = &x ento *pt = 12 igual a x = 12

50

char car,a[10],*ptr; ptr = a; //ptr aponta para o endereo de a[0] ptr = &(a[0]); //igual ao exemplo anterior a = &a[0] car = *(ptr); //car recebe o contedo de a[0] int var[5],*pint; pint = var; pint = (var+2);

//pint aponta para var[0] //pint aponta para var[2]

Como j pode ser visto, a indexao dos arrays feita na mesma maneira em que se trata com ponteiros. Ento, incrementar um ponteiro signica somar ao endereo atual tantas unidades quanto for o tamanho do tipo de dado apontado, assim como o endereo de um elemento de um array pode ser obtido apenas somando-se tantas unidades quanto for o tamanho do elemento do array. Portanto podemos fazer somas e incrementos com ponteiros operando-os como se fossem meros endereos. Sendo que no caso de incrementos, o acrscimo ser feito de acordo com tipo de dado ao qual o ponteiro atua (soma tantos bytes quanto for o tamanho do tipo). Como foi visto, apontadores acessam diretamente a memria do micro, por isso constituem uma ferramenta poderosa mas ao mesmo tempo perigosa, pois um descuido qualquer pode causar srios danos. Sempre que formos usar um ponteiro ele j dever ter sido inicializado, ou seja, j deve ter sido atribudo algum endereo a ele. Arrays, algumas informaes extras ...

7.1 Apontadores: passagem de parmetros por referncia


Como visto anteriormente, o C s possui passagem de parmetros por valor, atravs da pilha do sistema e no possui passagem por referncia. Esta regra continua sendo verdadeira, mas pode-se simular a passagem por referncia atravs de ponteiros.

A diferena entre um array e um ponteiro que quando denimos um array, uma rea de memria reservada para ele e quando denimos um apontador, no h alocao de memria. Exemplo: char *string -> reserva rea somente para o pointer (2/4 bytes) char string[10] -> reserva rea para 10 caracteres (10 bytes) Arrays so passados como parmetros para funes como sendo um ponteiro para o incio do array. Como conseqncia do modo de alocao de arrays de mais de uma dimenso, quando for passado como parmetro o array, temos que indicar as outras dimenses, exceto a principal. Isto se d pelo fato de que passado apenas o endereo inicial do array, que tratado como um vetor linear. Sem a indicao das outras dimenses no conseguimos distinguir os elementos de uma ou de outra dimenso. Exemplo: funo (a) int a[ ][10];

o primeiro valor opcional o segundo valor obrigatrio

51

int quadrado ( int *a) { a=( a) ( a); return(1); } main () { int a=8; quadrado(&a); printf("A resposta foi %d n", a); }

Observe que a passagem continua sendo por valor porque o que foi passado no o valor inteiro, mas sim o seu endereo, e este endereo no pode ser mudado dentro da funo. Veja pelo exemplo a seguir:

int x=34; int quadrado (int a) { a=( a) ( a); a=&x; printf("A tem o valor %d n", a); return(1); } main () { int a=8; quadrado(&a); printf("A resposta foi %d n", a); }

No exemplo acima, o endereo da varivel "a", passada por parmetro, trocado e a impresso dentro da funo gerar o valor 34 (valor de x), mas quando a funo retornar, o valor do endereo de a (passado por parmetro) restaurado, portanto continua sendo por valor, mas o valor absoluto de "a"foi alterado. Outra observao importante que a manipulao de valores dentro de uma funo dever ser feita sempre com o operador "*". Outro exemplo:

1 1 1 1

//varivel global

1 1 1

52

int x=34; //varivel global int quadrado ( int a) { a=( a) ( a); a=&x; printf("A tem o valor %d n", a); return(1); } main () { int a=8, b; b=&a; quadrado(b); printf("A resposta foi %d n", a); printf("A resposta foi %d n", b); }

No exemplo acima, criou-se uma varivel do tipo apontador para inteiros e fez-se com que ela recebesse o endereo de a. A varivel b j contem o endereo de uma rea de memria e portando a passagem de parmetro feita simplesmente pelo seu nome. Por m, imprimir o valor de a ou o valor da posio apontada por b resultar no mesmo valor, pois b aponta para a. Portanto, sempre que desejar passar algum valor por referncia, deve-se passar o endereo deste valor, se desejar-se passar o prprio endereo por referncia, deve-se passar o endereo do endereo. Mais adiante sero vistos outras utilidades para ponteiros.

7.2 Alocao Dinmica de ponteiros


Um apontador pode referenciar uma rea de memria j alocada, como por exemplo, um inteiro, char ou mesmo um vetor declarado de forma esttica. Entretanto, pode-se reservar uma nova rea de memria e faz-lo apontar para l. Considere um exemplo em que tenhamos que guardar os inteiros digitados pelo usurio para depois imprimi-los todos. Precisamos de um vetor de inteiros para isso, certo? De quantos elementos? Talvez soubssemos de antemo que o usurio ir digitar apenas 20 nmeros, ento, podemos fazer a seguinte declarao: int vetor[20]; Mas se o usurio quiser digitar mais que 20, no ser possvel ao passo que se ele digitar, digamos, apenas cinco, estamos desperdiando espao (15). E se tivermos uma forma de alocar espao quando tivermos certeza qual o tamanho dele? possvel com o uso de apontadores.

1 1 1 1

53

#include <stdio.h> main() { int *vet; int tamanho,i; printf("Quantos elementos vc vai digitar? n "); scanf("%d", &tamanho); vet = (int *)malloc (tamanho * sizeof(int)); if (!vet) { se vetor vazio (not vetor)... printf("Erro na reserva de memria n"); return(0); } /* usa-se vet como vet[0], vet[1], ... vet[tamanho-1] */ } Vetores estticos e dinmicos, como j dito, so praticamente o mesmo para o C, e podem ser manipulados de forma semelhante. Vamos analisar por partes o exemplo acima. Ao criarmos o apontador vet, ele ter algum endereo de memria e podera-mos uslo. Mas, este espao em memria pode estar sendo usado por outro, pois no o reservamos para nosso uso exclusivo (que o que fazemos com int vet[20]). Poderia ser desastrosa a utilizao nestes termos. Reservar um espao em memria de uso exclusivo nosso o que tenta fazer o comando malloc. Digo tenta, porque ele pode no conseguir, por exemplo, caso no haja memria suciente. O malloc s reserva espao em bytes e retorna um apontador para este endereo do tipo void. Por isso que para o compilador aceitar, devemos usar um cast no incio para o tipo que estamos usando (no caso, int). Como a reserva em bytes, devemos reservar a quantidade de bytes que reita a nossa necessidade. No exemplo, temos uma necessidade de tamanho elementos, sendo que cada elemento do tipo int, o espao que precisamos de tamanho sizeof(int). O malloc retorna o endereo reservado se conseguiu ou 0, (NULL) se falhou. extremamente recomendvel testar seu retorno antes de usar. No correto armar que o malloc cria variveis dinmicas, pois ele apenas reserva espao deixando sobre a inteira responsabilidade do programador o gerenciamento desta rea Logo, se o programador zer mal uso, azar o dele!!! Podemos considerar um pssimo uso o exemplo a seguir: #include <stdio.h> main() { int *vet; int tamanho=20,i; vet = (int *)malloc (tamanho * sizeof(int)); if (!vet) { printf("Erro na reserva de memria n"); return(0); } vet = &i; }

54

Na linha em destaque, vet recebe o endereo da varivel i. Ento, o que aconteceu com a rea anteriormente reservada? Continua reservada para ns, mas j no temos como us-la pois no sabemos onde est. Para liberar-mos um espao anteriormente alocado, usamos o comando free(): free(vet); No precisamos, neste caso, indicar o tamanho de memria liberada, pois isso o C controla.

7.3 Exerccios:
1) Implemente a funo my_strcmp(), semelhante a strcmp() mas apenas retornando 0 se forem iguais e diferente de zero se no. 2) Faa uma funo para somar dois vetores. A funo deve receber 3 vetores (os 2 vetores a serem somados e o vetor que receber a soma) e o tamanho dos vetores e deve retornar a mdia dos valores somados (int). 3) Faa uma funo que copie X caracteres para uma outra cadeia de caracteres. A funo dever retornar o nmero de caracteres efetivamente copiados (pode ser <que x que a string origem terminar antes). Chamada: char a[50], b[50], tam; /* atribua um texto qualquer a a */ tam=copia(b,a,10); /* copia no maximo 10 caracteres de a para b. Se a string de a tiver s 5, copia apenas os cinco */ 4) Faa um programa que crie dois vetores dinmicos de mesmo tamanho. O tamanho deve ser passado por parmetro na execuo do programa. O usurio, ao executar o programa, deve digitar todos os elementos de um dos vetores. Depois que todos os elementos foram digitados, os elementos do segundo vetor deve ser calculado da seguinte forma vet2[0]=tamanho-vet1[0], vet2[n]=tamanho-vet1[n]. Finalmente imprima ambos os vetores.

55

8 ARQUIVOS

8.1 Introduo
O padro C ANSI dene um conjunto completo de funes de E/S que pode ser utilizado para ler e escrever qualque tipo de dado. O sistema de arquivos em C projetado para trabalhar com diversos tipos de dispositivos. O sistema de arquivo com buffer transforma-se em um dispositivo lgico chamado de stream. Existem dois tipos de streams: texto e binria. Uma stream de texto uma sequncia de caracteres. J uma stream binria uma sequncia de bytes com alguma correspondncia.

8.2 Arquivos
Deve-se associar uma stream com um arquivo especco e para isso tambm precisamos realizar uma operao de abertura. Depois do arquivo aberto, troca-se informaes entre ele e o programa. Cada stream associada a um arquivo tem uma estrutura de controle do tipo FILE (stdio.h). Alm disso, cada vez que o arquivo aberto, tambm inicializado o indicador de posio no arquivo. Quando um caractere lido ou escrito no arquivo, o indicador de posio incrementado.

8.3 Funes
O sistema de arquivos C ANSI composto de diversas funes inter-relacionadas. As mais comuns so mostradas na Tabela 8.1: 8.3.1 Ponteiro de Arquivo O ponteiro de arquivo um ponteiro para informaes que denem coisas sobre o arquivo (nome, status e posio atual do arquivo). Este indentica um arquivo especco em disco e usado pela stream associada para direcionar as operaes de E/S. Para obter uma varivel ponteiro de arquivo, a sintaxe a seguinte: FILE *fp; 8.3.2 Abrindo um arquivo (fopen) A funo fopen( ) abre uma stream para uso e associa um arquivo a ela, retornando um ponteiro associada ao arquivo. A sintaxe da funo : FILE *fopen(const char* nomearq, const char* modo); Em modo devemos indicar como o arquivo dever ser aberto. Um arquivo pode ser

56

Nome fopen( ) fclose( ) putc( ) fputc( ) getc( ) fgetc( ) fseek( ) fprintf( ) fscanf( ) feof( ) ferror( ) rewind( ) remove( ) fush( )

Funo Abre um arquivo Fecha um arquivo Escrever um caractere em um arquivo O mesmo que putc( ) L um caractere de um arquivo O mesmo que getc( ) Posiciona o arquivo em um byte especco para um arquivo o que um printf( ) para um arquivo o que o scanf( ) para o console Devolve verdadeiro se o m de arquivo for atingido Devolve verdadeiro se ocorreu um erro Recoloca o indicador de posio de arquivo no incio do arquivo Apaga um arquivo Descarrega um arquivo Tabela 8.1: Funes para Arquivos

aberto em modo texto ou binrio. A tabela 8.2 mostra os modos os quais podemos abrir os arquivos. Modo r w a rb wb ab r+ w+ a+ r+b w+b a+b Signicado Abre um arquivo-texto para leitura Cria um arquivo-texto para escrita Anexa a um arquivo-texto Abre um arquivo binrio para leitura Cria um arquivo binrio para escrita Anexa a um arquivo binrio Abre um arquivo-texto para leitura/escrita Cria um arquivo-texto para leitura/escrita Anexa/cria um arquivo texto para leitura/escrita Abre um arquivo binrio para leitura/escrita Cria um arquivo binrio para leitura/escrita Anexa a um arquivo binrio para leitura/escrita

Tabela 8.2: Modos de Abertura para Arquivos Para abrir um arquivo chamado prog4all, pode-se desenvolver o seguinte trecho de cdigo: ... FILE *fp; fp = fopen("prog4all","w"); ... Se quiseres sempre testar se a operao foi realizada com sucesso, mais comum se programa como:

57

... FILE *fp; if((fp=fopen("prog4all","w"))==NULL) { printf("O arquivo no pode ser criado n"); exit(1); } ...

8.3.3 Fechando um arquivo (fclose)

A funo fclose( ) fecha uma stream que foi aberta por meio de uma chamada fopen( ). Portanto, lembre-se sempre que um arquivo for aberto, voc deve fech-lo antes do nal do programa. A sintaxe do fclose ( ) :

int fclose(FILE *fp);

8.3.4 Escrevendo e Lendo um caractere

O padro C ANSI dene duas funes para escrever caracteres: putc( ) e fputc( ). A funo putc( ) escreve caracteres em um arquivo que foi aberto, tendo o seguinte prottipo:

int putc(int ch, FILE *fp);

Onde ch o caracter e o fp o ponteiro para o arquivo. Para ler caracteres de um determinado arquivo podemos usar as funes getc( ) e fgetc( ). A funo getc( ) l caracteres de um arquivo aberto no modo leitura e seu prottipo :

int getc(FILE *fp);

A funo getc( ) ir retornar EOF quando o nal do arquivo for alcanado. Para entendermos melhor o funcionamento destas funes, vamos analisar o seguinte exemplo:

58

#include <stdio.h> #include <stdlib.h> #include <string.h> void main() { FILE *p; char c, str[30], frase[80] = "Este e um arquivo chamado: "; int i; /* Le um nome para o arquivo a ser aberto: */ printf("Entre com um nome para o arquivo: n"); gets(str); if (!(p = fopen(str,"w"))) /* Caso ocorra algum erro na abertura do arquivo..*/ { printf("Erro! Impossivel abrir o arquivo! n"); exit(1); /* o programa aborta automaticamente */ } /* Se nao houve erro, imprime no arquivo e o fecha ...*/ strcat(frase, str); for (i=0; frase[i]; i++) putc(frase[i],p); fclose(p); /* Abre novamente para leitura */ p = fopen(str,"r"); c = getc(p); /* Le o primeiro caracter */ while (!feof(p)) /* Enquanto no se chegar no nal do arquivo */ { printf("%c n",c); /* Imprime o caracter na tela */ c = getc(p); /* Le um novo caracter no arquivo */ } fclose(p); /* Fecha o arquivo */ } No exemplo, primeiro o arquivo aberto para a escrita, e imprime-se algo nele. Em seguida, o arquivo fechado e novamente aberto para a leitura. 8.3.5 Lidando com Strings (fputs e fgets) C suporta funes fputs( ) e fgets( ) que efetuam operaes de leitura e gravao de strings de caracteres para um arquivo em disco. Abaixo esto os prottipos destas funes: int fputs(const char *str, FILE *fp); char *fgets(char *str, int length, FILE *fp); Estas duas funes esto na biblioteca stdio.h. A funo fgets( ) l uma string da stream especicada at que um caractere de nova linha seja lido ou que lenght-1 caracteres tenham sido lidos. Pode-se observar um exemplo que ir inserindo strings num arquivo at a tecla ENTER ser digitada:

59

#include <stdio.h> #include <stdlib.h> int main() { FILE *pf; char string[100]; if((pf = fopen("arquivo.txt","w")) ==NULL) { printf("Nao consigo abrir o arquivo ! n"); exit(1); } do { printf("Digite uma nova string. Para terminar, digite <enter>: n "); gets(string); fputs(string, pf); putc( n, pf); }while (strlen(string) > 0); fclose(pf); }

8.3.6 Lidando com blocos de dados binrios(fread e fwrite) Podemos escrever e ler blocos de dados. Para tanto, temos as funes fread() e fwrite(). O prottipo de fread() : unsigned fread (void *buffer, int numerodebytes, int count, FILE *fp); O buffer a regio de memria na qual sero armazenados os dados lidos. O nmero de bytes o tamanho da unidade a ser lida. Count indica quantas unidades devem ser lidas. Isto signica que o nmero total de bytes lidos : numerodebytes*count. A funo retorna o nmero de unidades efetivamente lidas. Este nmero pode ser menor que count quando o m do arquivo for encontrado ou ocorrer algum erro. Quando o arquivo for aberto para dados binrios, fread pode ler qualquer tipo de dados. A funo fwrite() funciona como a sua companheira fread(), porm escrevendo no arquivo. Seu prottipo : unsigned fwrite(void *buffer, int numerodebytes, int count, FILE *fp); A funo retorna o nmero de itens escritos. Este valor ser igual a count a menos que ocorra algum erro. O exemplo abaixo ilustra o uso de fwrite e fread para gravar e posteriormente ler uma varivel oat em um arquivo binrio.

60

#include <stdio.h> #include <stdlib.h> int main() { FILE *pf; oat pi = 3.1415; oat pilido; if((pf = fopen("arquivo.bin", "wb")) == NULL) /* Abre arquivo binrio para escrita */ { printf("Erro na abertura do arquivo n"); exit(1); } if(fwrite(&pi, sizeof(oat), 1,pf) != 1) /* Escreve a varivel pi */ printf("Erro na escrita do arquivo n"); fclose(pf); /* Fecha o arquivo */ if((pf = fopen("arquivo.bin", "rb")) == NULL) /* Abre o arquivo novamente para leitura */ { printf("Erro na abertura do arquivo n"); exit(1); } if(fread(&pilido, sizeof(oat), 1,pf) != 1) /* Le em pilido o valor da varivel armazenada anteriormente */ printf("Erro na leitura do arquivo n"); printf("O valor de PI, lido do arquivo e: %f n", pilido); fclose(pf); return(0); }

Note-se o uso do operador sizeof, que retorna o tamanho em bytes da varivel ou do tipo de dados. 8.3.7 Realizando Procuras (fseek) Para se fazer procuras e acessos randmicos em arquivos usa-se a funo fseek(). Esta move a posio corrente de leitura ou escrita no arquivo de um valor especicado, a partir de um ponto especicado. Seu prottipo : int fseek (FILE *fp, long numbytes, int origem); O parmetro origem determina a partir de onde os numbytes de movimentao sero contados. Os valores possveis so denidos por macros em stdio.h. Estes esto apresentados na Tabela 8.3. Tendo-se denido a partir de onde ir se contar, numbytes determina quantos bytes de deslocamento sero dados na posio atual.

61

Nome SEEK_SET SEEK_CUR SEEK_END

Valor 0 1 2

Signicado Incio do arquivo Ponto corrente no arquivo Fim do arquivo

Tabela 8.3: Valores do fseek

8.4 Exerccios
1) Fazer um programa que leia do usurio um determinado nmero de caracteres e armazeneos em um arquivo, chamado de "teste.txt". O programa deve parar de ler quando o usurio digitar a letra A. 2) Fazer um programa que simule uma lista telefnica. O usurio poder incluir novos registros (nome + telefone) ou apenas consult-los. importante ressaltar que ao reiniciar o programa, o usurio deve poder visualizar telefones pr-cadastrados. 3) Fazer um programa que solicite ao usurio o nome de um arquivo de entrada. Aps abrir este arquivo o programa deve criar outro arquivo que uma cpia do arquivo de origem. O arquivo destino deve ser uma cpia, com algumas alteraes, so elas: letras a so substitudas por G, letras c so substitudas por H e letras e so substitudas pela palavra lp. 4) Faa uma rotina que recebe uma matriz A(4,4) de inteiros e retorna um vetor apenas com os elementos cuja soma dos ndices par. Faa uma rotina que recebe o vetor gerado na rotina anterior e armazena o vetor em um arquivo binrio. Faa uma rotina para ler o arquivo binrio gravado e imprima as informaes na tela. 5) Faa um programa que permita inserir e visualizar o cadastro dos alunos de uma academia. As informaes a serem armazenada so: nome, idade e peso. As informaes devem ser armazenadas em um arquivo binrio.

62

9 BIBLIOGRAFIA

KRNIGHAN, B.; RITCHIE, D. A Linguagem de Programao C. Campus, Porto Alegre, 1986. SCHILDT, E. C Completo e Total. Makron Books, So Paulo, 1990; http://linux.org http://tlm.conectiva.com.br/ http://www.indiana.edu/ uitspubs/b017/ http://www.labbas.eng.uerj.br/linux/linuxman.html http://www.inf.ufrgs.br/ elgios/ http://www.inf.pucrs.br/ pinho http://www.inf.pucrs.br/ silvia/lapro http://www.inf.unilasalle.edu.br/ barreto/ http://www.cp.cefetpr.br/pessoal/mauricio

Potrebbero piacerti anche