Você está na página 1de 54

Professora ANITA LOPES

Professora ANITA LOPES

FUNDAMENTOS DA LINGUAGEM C
1 A linguagem C 1.1 A linguagem C uma linguagem de nvel intermedirio que utiliza recursos da linguagem de mquina de forma simples. uma linguagem estruturada, com flexibilidade/portabilidade entre sistemas operacionais e tem sido usado para criao de vrios tipos de programas tais como processadores de texto, sistemas operacionais, planilhas, outras linguagens de programao, etc. A linguagem C "Case Sensitive", isto , maisculas e minsculas fazem diferena. 1.2 Estrutura de um programa em C Introduo

main() { printf }

Explicando: #include <stdio.h> instrui o compilador a usar a biblioteca padro de entrada e sada main o nome da funo principal; a palavra inicia a funo imprime na tela a msg aps alimentar linha finaliza a funo

1.2.1 Conjunto de caracteres

Um programa fonte em C um texto no formatado escrito em um editor de textos usando um o conjunto padro de caracteres ASCII.

Um programa em C constitudo de: um cabealho que contem definies de pr-processamento tais como os arquivos de cabealho, as definies de constantes simblicas, declarao de variveis globais, declarao de rotinas, etc. um bloco da funo principal e outros blocos de de funes. comentrios. [ <definies de pr-processamento> ] [ <declarao de variveis globais> ] <tipo de retorno da funo> main( <parmetros>) > { Bloco de comandos } <tipo de retorno da funo> <nome_da_funo1 >( <parmetros>) > { Bloco de comandos da funo1 } ... <tipo de retorno da funo> <nome_da_funon >( <parmetros>) > { Bloco de comandos da funo2 } Exemplo de um programa em C #include <stdio.h> main() { printf("\nPRIMEIRO PROGRAMA EM C"); }
1

Caracteres vlidos: As letras minsculas e maisculas no acentuadas Os algarismos de 0 - 9 +-*/\=|&!?#%(){}[]_.,:<>

Observao: Qualquer outro caracter valido para as strings. 1.2.2 Comentrios

Os comentrios em C podem aparecer em qualquer lugar do programa e tm como objetivo fazer um esclarecimento sobre uma linha ou trecho do programa. Os comentrios tero um /* antes e um */ depois.

Exemplo: /* programar em C eh facil */

1.2.3 Diretivas de Compilao

Na linguagem C, alguns comandos so processados durante a compilao. Estes comandos so chamados de diretivas de compilao e so eles que informam quais bibliotecas e constantes simblicas devero ser anexadas quando for gerado o programa executvel. A diretiva #include diz ao compilador para incluir na compilao do programa outros arquivos. Geralmente estes arquivos contem bibliotecas de funes ou rotinas do usurio. As bibliotecas agrupam funes de acordo com as finalidades. Se no fizssemos uso delas, nossos programas seriam muito extensos e teramos problemas na linkedio. Sintaxes:

#include <nome_da_biblioteca > #include ...nome_da_biblioteca

Professora ANITA LOPES


onde nome_da_biblioteca o nome da biblioteca que se deseja incluir. Estando entre os sinais < e > significa que est no diretrio padro e ficando entre , significa que precisamos fornecer o caminho onde se encontra a biblioteca. Exemplos de bibliotecas: BIBLIOTECA ctype.h Converte para maiscula ou para minscula uma letra toupper(letra) tolower(letra)

Professora ANITA LOPES

BIBLIOTECA stdlib.h Calcula o valor absoluto do inteiro i e do real d, respectivamente abs(int /float) rand()

BIBLIOTECA math.h Calcula o valor absoluto real d fabs(double d) Funes trigonomtricas do ngulo arco, em radianos sin(double arco) cos(double arco) tan(double arco) asin(double arco) acos(double arco) atan(double arco) Funes de arredondamento para inteiro ceil(double num) Ex. ceil(3.2) => 4.0 arredonda pra cima floor(double num) Ex. floor(3.2) => 3.0 arredonda para baixo Funes logartmicas: log() logaritmo natural (base e), log10() logaritmo decimal (base 10) log(double num) log10(double num) Funes: potncia e raiz quadrada pow(double base, double exp); Potenciacao: pow(3.2,5.6) => 3.25.6 sqrt(double num); Raiz quadrada: sqrt(9.0) = >3.0. BIBLIOTECA stdio.h Esvazia o buffer, l e imprime fgetc(stdin); fgets(lixo,100,stdin); scanf(); gets(); getchar(); printf(); putchar(); puts();

BIBLIOTECA string.h Concatena duas strings strcat(str1, str2); Copia o contedo de uma varivel em outra varivel strcpy(str1, str2) /* no permitido: str1 =str2;*/ Fornece o nmero de caracteres de uma string strlen(str1) Compara duas strings devolve nmero menor que 0 se str1 vier antes de str2 strcmp(str1, str2) devolve nmero maior que 0 se str1 vier depois de str2 devolve 0 se str1 for igual str2

2. Sada

Existem varias maneiras de se fazer uma escrita de informaes na linguagem C. Primeiramente, vamos aprender a usar funo printf(). Biblioteca: stdio.h

printf( "expresso de controle ", <lista_de_argumentos > );

A expresso de controle contm uma descrio de tudo que aparecer na tela. Alm das mensagens, estaro presentes tambm os cdigos de controle para impresso dos contedos das variveis, alimentao de linha, tabulao, etc. Cdigo %d %f %c %s %o %u %ld %f %e
3

Significado Inteiro Float Caractere String Constante octal Inteiro sem sinal Longo inteiro float exponencial

%x ou %X Constante hexadecimal

Professora ANITA LOPES


%g %p %+.. %<n>d %<0n>d Formata inteiro preenchendo com 0 as posies no usadas. Os operadores < e > no devero ser colocados na expresso. Eles indicam que o contedo de 0n varivel . Exemplo: %04d Formata real com determinado nmero de casas na parte inteira, inclui o ponto decimal e o nmero de casas na parte fracionria. Os operadores < e > no devero ser colocados na expresso. Eles indicam que o contedo de n varivel. Exemplo: %8.2f Coloca na tela um % Controle/Caracter nulo (null) campainha (bell) retrocesso (backspace) tabulacao horizontal nova linha (new line) tabulacao vertical alimentacao de folha (form feed) retorno de carro (carriage return) aspas (") apostrofo (') interrogacao (?) barra invertida (\) Seqncia de escape \0 \a \b \t \n \v \f \r \" \' \? \\ Formata Inteiro formata com n casas. Os operadores < e > no devero ser colocados na expresso. Eles indicam que o contedo de n varivel. Exemplo: %4d Coloca sinal Ponteiro Usa-se %e ou %f

Professora ANITA LOPES

%<n.f>f

3. Constantes e variveis 3.1 Constantes

%%

O C possui quatro tipos bsicos de constantes: inteiras, de ponto flutuante, caracteres e strings. Constantes inteiras e de ponto flutuante representam nmeros de um modo geral. 3.1.1 Constantes inteiras

As constantes inteiras na linguagem C podem ser escritas no formato decimal (base 10), hexadecimal (base 16) ou octal (base 8). Exemplos: Decimal: 12 Octal : 033 ( em decimal vale 27. O zero antes do nmero caracteriza a constante octal) Hexadecimal: 0xff ( em decimal vale 255. O zero e o x antes do nmero caracterizam a constante hexadecimal)

Exemplos: printf("\nProfessora Anita Lopes\n"); /*sem lista de argumentos */ printf("\nO numero eh: %d", num); /* imprime mensagem e contedo de uma varivel inteira*/
#include <stdio.h> main() { printf("\nletra %c - numero %d ",'A','A'); printf("\n%06d",123); printf("\n%d",-15); printf("\n%+d",123); printf("\n%8.5f", 12.3456); printf("\n%8.0f", 12.3456); }

#include <stdio.h> main() { printf("\ndecimal= %d octal= %o hexadecimal= %X",27,27,27); printf("\ndecimal= %d octal= %o hexadecimal= %X",27,27,27); }

3.1.2 Constantes de ponto flutuante

So nmeros reais com um ponto decimal e (opcionalmente) um expoente. Exemplos:


5

Professora ANITA LOPES


1.876 476.65 1.23e-9 -1.e2 10.6e18 -.853E+67 3.1.3 Constantes caracteres Uma constante caracter uma letra ou smbolo colocado entre plicas. Exemplo: A N I T A As constantes caracter so armazenadas como nmeros inteiros. Estes nmeros correspondem aos valores de cada caracter dentro do cdigo ASCII.

Professora ANITA LOPES

str[1] = 'o'

str[2] = 'a'

No exemplo acima, percebemos que o primeiro caracter se encontra na posio 0( em algumas linguagens, seria a posio 1). Desta forma, se indexarmos com 1, na verdade estaremos nos referindo ao segundo caracter da string; se indexarmos com 2, na verdade estaremos nos referindo ao terceiro caracter da string e assim sucessivamente.

3.1.5 Constantes Simblicas 3.1.4 Constantes strings Uma constante string consiste de um conjunto de caracteres do cdigo ASCII padro ou estendido, colocados entre aspas duplas. Exemplo: UAL! Matemtica APRENDENDO A PROGRAMAR EM C Na linguagem, C uma string um vetor de caracteres terminado com um caracter nulo. O caracter nulo um caracter com valor inteiro igual a zero (cdigo ASCII igual a 0). O terminador nulo tambm pode ser escrito usando a conveno de barra invertida do C como sendo '\0'.

A Matemtica define pi como tendo o valor 3,14159265. Muitas vezes precisaremos definir algumas constantes em nossos programas.

3.1.5.1 Constantes definidas pelo programador

O programador pode definir constantes simblicas em qualquer programa. Sintaxe:

#define <nome> < valor >

char nome_da_string[tamanho];
Como precisamos reservar uma posio para o terminador, sempre iremos declarar o tamanho necessrio mais um. Vamos supor que declaremos uma varivel de nome palavra de 11 posies(char

Onde #define uma diretiva de compilao que diz ao compilador para trocar as ocorrncias do texto nome por valor. Observe que no h ; no final da instruo pois tratase de um comando para o compilador e no para o processador. A instruo #define deve ser escrita antes da instruo de declarao da rotina principal. Exemplo:
#include <stdio.h> #include <math.h> #define quadrado(x) (x*x) #define pi 3.14159265 #define conv(x) (x*pi/180) main() {

palavra[11]; ) e armazenemos a palavra PROGRAMAS nela.

bom ressaltar que a linguagem C no inicializa as variveis e toda clula no usada tm valor indeterminado. No se esquea de inicializar as variveis de seus programas, pois coisas incrveis podem acontecer! As strings so consideradas vetores de caracteres( matriz linha). Como na Matemtica, para se acessar um determinado caracter de uma string, basta "indexarmos".

printf("\nnumero: 12" ); printf("\n\nquadrado= %d", quadrado(12)); printf("\n\nangulo: 30" ); printf("\n\nseno de %.2f eh %4.2f",30.,sin(conv(30)));

Professora ANITA LOPES

Professora ANITA LOPES

Exemplos: int a; float peso; char sexo; int idade1, idade2;

3.2.1 Palavras reservadas

Existem certos nomes que no podero ser usados como identificadores. So chamadas as palavras reservadas e so de uso restrito da linguagem C. O conjunto de palavras reservadas usadas em C o seguinte: O uso da diretiva #define no se restringe apenas para declarar constante(#define pi 3.14159265 ) mas tambm podemos us-la para definir macro instrues(#define conv(x) (x*pi/180) ou #define quadrado(x) (x*x) ). asm class do extern friend interrupt pascal _saveregs static union auto const double _export goto _loadds private _seg struct unsigned

3.2 Variveis A varivel um lugar(endereo) na memria principal que armazena um dado e tem um nome associado para facilitar a programao . Em C, as variveis podem ser declaradas no inicio do programa, mas poderemos tambm declarar dentro de algumas estruturas, diferentemente de outras linguagens. Estas variveis podem ser de vrios tipos: int (inteiro), float (real de simples preciso) , char (caracter nico), double (real de dupla preciso).

break continue _ds far huge long protected short switch virtual 3.2.2 Tipos modificados

case _cs else _fastcall if near public signed template void

cdecl default enum float inline new register sizeof this volatile

char delete _es for int operator return _ss typedef while

Tipo char int float double

Tamanho 1 byte 4 bytes 4 bytes 8 bytes

Intervalo -128 a 127 -2147483648 a 2147483647 3.4e-38 a 3.4e38 1.7e-308 a 1.7e308

Uso nmero muito pequeno e caracter ASCII contador, controle de lao real (preciso de 6dgitos) cientfico (preciso de 10 dgitos)

Alm dos tipos de dados mencionados, existem os modificadores: long, short, signed e unsigned. Tipicamente o modificador long aumenta o nmero de bytes usados para o registro do nmero. O modificador unsigned, usado somente em inteiros, permite que um bit usado para guardar o sinal do nmero seja usado para guardar o valor do nmero.

Quando se define um tipo de varivel, informamos ao computador quanto de memria ser necessria para armazenar este dado e que tipos de operaes podero ser realizadas com este dado. Para se declarar uma varivel, usamos a seguinte sintaxe: < tipo> nome_da_varivel ; O nome de uma varivel deve obedecer algumas regras: 1. O primeiro caracter pode ser uma letra ( maiscula ou minscula) ou o caracter sublinha. Aconselha-se a no usar o caracter sublinha no inicio para no confundir com algumas funes. 2. Os demais caracteres, letras algarismos ou o caracter sublinha.

Tipo unsigned char unsigned int unsigned long int long int short int long double

Tamanho (bytes) 1 2 4 4 2 10

Intervalo 0 a 255 0 a 65 535 0 a 4 294 967 295 -2 147 483 648 a 2 147 483 647 -32768 a 32767 3.4e-4932 a 1.1e4932

3.2.3 Converso de tipo (Casting)

Algumas vezes queremos, momentaneamente, modificar o tipo de dado representado por uma varivel, isto , queremos que o dado seja apresentado em um tipo diferente do qual a varivel foi inicialmente declarada. Por exemplo: ao fazermos uma diviso entre dois inteiros, a linguagem C trunca a parte fracionria e podemos desejar que isto no acontea. Este procedimento chamado de converso de tipo ou casting .
9

10

Professora ANITA LOPES


Sintaxe: (tipo) varivel onde tipo o nome do tipo ao qual queremos converter o dado armazenado em varivel. Exemplo:
#include <stdio.h> main() { printf("\nnumero: 7" ); printf("\n\nDIVIDINDO POR 3\nsem conversao= %d com conversao= %f",7/3, (float)7/3);

Professora ANITA LOPES

LEIA VRIAS VEZES ESTE TRECHO Voc observou que, ao mandarmos mostrar na tela a varivel p, foi mostrado seu contedo que na verdade era o endereo da varivel num que foi exatamente o mesmo valor mostrado na tela quando mandamos mostrar na tela &num, significando ao colocarmos o operador de endereo & antes do nome da varivel num, que desejamos o endereo e no o contedo. Quando mandamos mostrar na tela o contedo da varivel ponteiro que representamos com o *, foi mostrado o contedo da posio de memria que a varivel ponteiro aponta, mostrando o mesmo contedo da varivel num.

3.2.4 Varivel ponteiro Ns j sabemos que uma varivel um endereo na MP que armazena um dado. bom deixar claro que no um nico endereo, pois, dependendo do tipo, poderemos estar alocando 1, 2, 4, 8 ou mais posies para cada varivel como vimos na ltima tabela. Uma varivel ponteiro armazena o endereo de outra varivel. Mais adiante estudaremos este tipo de varivel uma vez que se no trabalharmos bem com este tipo de varivel, no conseguiremos programar bem na linguagem C. Mas, par comearmos logo nos acostumando, vamos observar o programa abaixo:
#include <stdio.h> main() { int num, *p; /*observe o asterisco antes de p indicando que uma varivel ponteiro*/ printf("\nDigite numero: "); scanf("%d",&num); p=&num; /*p recebe o enderereco de num, isto , p aponta para num*/ printf("\n\nEndereco da variavel mostrado pela variavel ponteiro: %u\n\nValor da variavel mostrado pela variavel ponteiro: %d", p, *p); printf("\n\nEndereco da variavel mostrado pela propria variavel: %u\n\nValor da variavel mostrado pela propria variavel: %d", &num, num);

4. Atribuio

Consiste em atribuir um valor a uma varivel. Em C, o comando de atribuio tem a seguinte sintaxe:

< nome_da_varivel > = <contedo> ; Exemplos: a = 12 ;

peso = 65.2; sexo ='f'; idade1 = 21; idade2 = 34;

Observao 1: Em C, possvel declarar e inicializar uma varivel: int a = 12; Observao 2: Em C, possvel inicializar vrias variveis: x =t =s = 0; Na atribuio mltipla as operaes ocorrem da direita para a esquerda, isto , inicialmente o valor 0 atribudo a s, depois o valor de s atribudo a t e, por ltimo, o valor de t atribudo a x.
4.1 Atribuio mltipla.

A linguagem C permite que se atribua um valor a muitas variveis. em uma nica instruo.

11

12

Professora ANITA LOPES


Sintaxe: var_1 = [var_2 = ... ] valor; Exemplo: a = b = 0;
#include <stdio.h> main() {

Professora ANITA LOPES

scanf("%d,%d", &num1, &num2 ); uma vrgula*/

/* l para duas variveis inteiras separadas por

5. Entrada de dados scanf 5.1 Formatada - scanf Biblioteca: stdio.h Sintaxe: scanf( "expresso de controle ", <lista_de_argumentos > ); A funo scanf() permite que o usurio digite dados atravs do dispositivo padro de entrada: teclado. A expresso de controle contm os cdigos de formatao para o tipo de dado que ser lido. A lista de argumentos corresponde aos endereos das variveis. O nome de cada varivel dever ser precedido pelo caracter &. Cdigo %d %f %e %g %c %s %o %x ou %X %u %ld %lf %p L um nmero inteiro L um nmero em ponto flutuante L um nmero em ponto flutuante L um nmero em ponto flutuante L um caracter L uma string L um nmero octal L um nmero hexadecimal L um inteiro sem sinal L um longo inteiro L um longo real(double) L um ponteiro Significado

int n; char resp; printf("\nnumero:" );scanf("%d",&n); printf("\ndecimal= %d octal= %o hexadecimal= %X hexadecimal= %x",n,n,n,n); fgetc(stdin); scanf("%c",&resp);

Observe a funo fgetc(stdin); usada para esvaziar o buffer antes de ser lido o dado para varivel caracter, pois o buffer do teclado demora para esvaziar. 5.2 gets

Funo usada com vetores de caracter. Biblioteca: stdio.h Sintaxe:

gets( <nome do vetor de caracteres> );

Observaes: 1- A funo scanf abandona o armazenamento assim que um espao for encontrado. 2- Como no existe para a funo gets um controle para a quantidade de caracteres digitados, os caracteres podero ser armazenados em reas importantes do sistema, seu programa, etc. 3- Conselho: evite us-la.

5.3 fgets - teclado

Exemplos: scanf("%d", &num); scanf("%d %d", &num1, &num2 ); um espao*/

/* l para uma varivel inteira*/ /* l para duas variveis inteiras separadas por

Funo usada com vetores de caracter. Biblioteca: stdio.h Sintaxe:

13

14

Professora ANITA LOPES


fgets(<nome do vetor de caracteres>,<tamanho mximo>, stdin); Esta funo similar a gets na leitura de uma linha de caarcteres, sendo mais flexvel porque o programador especifica o mximo de caracteres que podem ser armazenados. Para us-lo para entrada via teclado, preciso usar o parmetro stdin. Esta funo l caracteres do teclado at que o enter seja pressionado ou n-1 caracteres tenham sido lidos. Observaes 1: Lembre-se de que dos n caracteres declarados com a varivel vetor de caracteres, o ltimo caracter reservado para finalizar o vetor('/0'). 2: Se o contedo no ultrapassar a n-1 caracteres, ento uma nova linha adicionada ao vetor. Observe os exemplos e abaixo e as linhas que foram colocadas para que voc possa contar com mais facilidade o nmero de caracteres armazenados nas variveis:
#include <stdio.h> #include <string.h> main() {int i;char nome[25],c; printf("\nNome: "); fgets(nome,25,stdin); printf("\n\n1234567890123456789012345678901234567890\n%s",nome); printf("\n\nNome: "); gets(nome); printf("\n\n1234567890123456789012345678901234567890\n%s",nome); scanf("%c",&c); }

Professora ANITA LOPES

printf("\nNome: "); fgets(nome,25,stdin); printf("\n\n1234567890123456789012345678901234567890\n%s",nome); fgets(lixo,100,stdin);/*ATENCAO PARA ESTA LINHA*/ printf("\n\nNome: "); gets(nome); printf("\n\n1234567890123456789012345678901234567890\n%s",nome); scanf("%c",&c); }

Inclumos a linha: fgets(s,100,stdin); ,mas quando executamos novamente e digitamos um nome com menos de 24 caracteres, outro problema: a funo fgets(s,100,stdin); ficou esperando a entrada de dados. Observou?

A sada foi fazer uma proteo com if, fazendo com que esta funo s funcionasse se o tamanho do vetor tivesse atingido o mximo que, neste exemplo era 24. Veja como ficou o programa:

#include <stdio.h> #include <string.h> main() {int i;char nome[25],c,s[100]; printf("\nNome: "); fgets(nome,25,stdin); printf("\n\n1234567890123456789012345678901234567890\n%s",nome); if(strlen(nome)==24 && nome[23]!='\n')fgets(s,100,stdin);/*ATENCAO PARA ESTA LINHA*/ printf("\n\nNome: "); gets(nome); printf("\n\n1234567890123456789012345678901234567890\n%s",nome); scanf("%c",&c); }

Como a entrada de dados estava limitada em 24 caracteres(lembre-se de que um caracter sempre reservado para o finalizador do vetor), os caracteres restantes ficaram armazenados no buffer do teclado e a prxima funo de entrada(gets(nome) ) foi "bypassada" e o que estava no buffer foi armazenado na varivel. Tentamos ento "recolher o lixo".
O QUE FIZEMOS PARA RETIRAR ESTE PROBLEMA?
#include <stdio.h> #include <string.h> main() {int i;char nome[25],c,lixo[100]; 15

16

Professora ANITA LOPES


Pudemos observar que o problema foi quase totalmente resolvido exceto pelo uso da funo gets(...); que armazenou tudo que foi digitado e que poder trazer SRIOS PROBLEMAS. CONCLUSES; 1- Sempre incluir a linha: if(strlen(nome)==<tamanho 1>)fgets(s,100,stdin); 2- Nunca usar gets, pois esta funo armazena os caracteres digitados sem se preocupar com o limite.

Professora ANITA LOPES

operao de potenciao (ab). Existe, porm, uma funo de biblioteca (pow()) que realiza esta operao, ou voc poder criar quando aprender a usar as funes log e exp..

6. Operadores Aritmticos Existem cinco operadores aritmticos em C. Cada operador aritmtico est relacionado a uma operao aritmtica elementar: adio, subtrao, multiplicao e diviso. Existe ainda um operador (%) chamado operador de mdulo cujo significado o resto da diviso inteira. Operador + * / % Sintaxe: operando1 operador operando2 onde operador um dos smbolos mostrados acima e operando uma constante ou um identificador de varivel. Exemplos: 12 + 5 -> 17 12 * 5 -> 60 12 / 5 -> 2 quando se divide dois inteiros, o resultado um inteiro 12 % 5 -> 2 resto da diviso inteira Observao: Se voc precisar dividir dois nmeros inteiros e quiser a resposta em real, existe duas sadas: 1- Coloque um ponto em um dos operandos caso, pelo menos um, seja uma constante: 12 / 5. . 2- Caso os dois operandos sejam variveis, faa: (float) a/b . No existe em C, como existe em outras linguagens, um operador especfico para a
17

#include <stdio.h> main() { int n; char resp; printf("\nnumero:" );scanf("%d",&n); printf("\n\nTUDO POR 5 \n\nsoma= %d subtracao= %d multiplicacao= %d divisao inteira= %d resto= %d",n+5,n-5,n*5,n/5,n%5); fgetc(stdin); /* esvazia o buffer de entrada */ scanf("%c",&resp); }

Operao adio subtrao multiplicao diviso mdulo (resto da diviso inteira)

6.1

Hierarquia das operaes Categoria parnteses funo incremental, lgico aritmtico aritmtico relacional relacional lgico lgico condicional atribuio

Operadores

Prioridade

()

interno externo

nome()

ED

++ -- !

ED

*/%

ED

+-

ED

< > <= >=

ED

== !=

ED

&&

ED

||

ED

?:

ED

= += -= *= /= %=

ED

18

Professora ANITA LOPES


6.2 Muitas vezes queremos alterar o valor de uma varivel realizando alguma operao aritmtica com ela. A linguagem C apresenta instrues otimizadas com o uso de operadores ditos operadores de atribuio aritmtica. Os smbolos usado so (+=, -=, *=, /= , %=). Sintaxes: Operadores de Atribuio Aritmtica

Professora ANITA LOPES

onde var o nome da varivel da qual se quer incrementar ou decrementar um unidade.

var += exp; var -= exp; var *= exp; var /= exp; var %= exp;
onde var o identificador da varivel e exp uma expresso vlida. Estas instrues so equivalentes as seguintes: Exemplos: Atribuio Aritmtica cont += 1; j -= i ; num *= 1 + k; divide /= 5; resto %= 2; Instruo Equivalente cont = cont + 1; j=ji; num = num * (1 + k); divide = divide / 5; resto = resto % 2;

var = var + exp; var = var - exp; var = var * exp; var = var / exp; var = var % exp;

Observe que existe duas sintaxes possveis para os operadores: pode-se colocar o operador como prefixo ou como sufixo. Nos dois casos o valor da varivel ser incrementado (ou decrementado) de uma unidade. Porm se o operador for colocado como sufixo, o valor da varivel ser incrementado (ou decrementado) antes que a varivel seja usada em alguma outra operao. Caso o operador seja colocado como sufixo, o valor da varivel ser incrementado (ou decrementado) depois que a varivel for usada em alguma outra operao.

#include <stdio.h> main() { int n,n1,n2; char resp; printf("\033[2J"); printf("\033[30;47m"); printf("\nnumero:" );scanf("%d",&n); printf("\n\nprefixo++ n1= %d sufixo++ n2= %d",n1=++n, n2=n++); fgetc(stdin); scanf("%c",&resp);

O operador de atribuio aritmtica tem precedncia menor que os outros operadores at aqui discutidos. 6.3 Operadores Incrementais

Observao: No se preocupe com os avisos, pois o objetivo foi mostrar os incrementos pr e ps fixados. Como visto na tabela de hierarquia das operaes, o operador ++ tem hierarquia da direita para esquerda. Desta forma, ele atribui 13 varivel n2 e depois incrementa n. Como a atribuio varivel n1 com prefixo, ele incrementa n outra vez e depois atribui o valor 15 varivel n1.

Em programao existem instrues muito comuns chamadas de incremento e decremento. Uma instruo de incremento adiciona uma unidade ao contedo de uma varivel. Uma instruo de decremento subtrai uma unidade do contedo de uma varivel. Existem, em C, operadores especficos para realizar as operaes de incremento (++) e decremento (--). Eles so genericamente chamados de operadores incrementais. Sintaxe: ++ var; var ++ ; -- var ; var -- ; Instruo Equivalente var = var + 1; var = var + 1; var = var 1; var = var 1;

Os operadores incrementais tem a mais alta precedncia entre todos, sendo superados apenas pelos parnteses que tem precedncia ainda maior. 6.4

Operadores Relacionais e Lgicos

As expresses lgicas usadas nas estruturas de teste so formadas pelos operadores relacionais e lgicos.

6.4.1 Operadores relacionais

Operadores relacionais verificam a relao de magnitude e igualdade entre dois valores. So seis os operadores relacionais em C:

19

20

Professora ANITA LOPES


Operador > < >= <= == != Sintaxe: Significado maior que menor que maior ou igual a menor ou igual a igual a diferente de

Professora ANITA LOPES

TABELA VERDADE DO OPERADOR && Suponha duas perguntas feitas a quatro pessoas. Se a resposta do candidato for negativa, dever falar 0, caso contrrio, falar 1. Suponha tambm que s ser chamado para entrevista o candidato que dominar as duas linguagens. Voc conhece C? 0 0 1 1

Voc conhece PASCAL? 0 1 0 1

SADA 0 0 0 1

expresso_1 operador expresso_2


onde expresso_1 e expresso_2 so duas expresses numricas quaisquer, e operador um dos operadores relacionais. Ao contrrio de outras linguagens, em C no existem tipos lgicos, portanto o resultado de uma expresso lgica um valor numrico: uma expresso avaliada verdadeira recebe o valor 1, uma expresso lgica avaliada falsa recebe o valor 0. Os operadores relacionais de igualdade (== e !=) tem precedncia menor que os de magnitude (>, <, >= e <=). Estes, por sua vez, tem precedncia menor que os operadores aritmticos. 6.4.2 Operadores lgicos So trs os operadores lgicos de C: &&, || e !. Estes operadores tm os mesmos significados dos operadores lgicos Booleanos AND, OR e NOT. Sintaxes:

Neste exemplo, somente o quarto candidato seria chamado para a entrevista, pois o operador && (e), s considera a expresso como verdadeira se todas as expresses testadas forem verdadeiras.

TABELA VERDADE DO OPERADOR || Suponha duas perguntas feitas a quatro pessoas. Se a resposta do candidato for negativa, dever falar 0, caso contrrio, falar 1. Suponha tambm que ser chamado para entrevista o candidato que dominar pelo menos uma linguagem. Voc conhece C++? 0 0 1 1

Voc conhece JAVA? 0 1 0 1

SADA 0 1 1 1

expr_1 && expr_2 expr_1 || expr_2


!expr onde expr_1 , expr_2 e expr so expresses quaisquer. Observe que os operadores lgicos atuam sobre expresses de quaisquer valores. Para estes operadores todo valor numrico diferente de 0 considerado 1. Operador conjuno disjuno negao Matemtica e ^ ou v no | C && || !
21

Neste exemplo, somente o primeiro candidato no seria chamado para a entrevista , pois o operador || (ou), considera a expresso como verdadeira se, pelo menos uma expresso testada for verdadeira. Observao: O Operador && tem precedncia sobre o operador ||. Estes dois tm precedncia menor que os operadores relacionais.

TABELA VERDADE DO OPERADOR ! Suponha uma pergunta feita a duas pessoas. Se a resposta do candidato for negativa, dever falar 0, caso contrrio, falar 1.

Voc No conhece C++? 1 0

SADA 0 1

Observao: O operador ! tem a mesma precedncia que os operadores incrementais.

22

Professora ANITA LOPES

Professora ANITA LOPES

6.5 O operador ternrio (?) usado em expresses condicionais. Este operador necessita de trs operandos. Seu uso poder simplificar a instruo if expresso1; else expresso2;. Sintaxe:

Operador Condicional

Os operadores bit-a-bit encontram aplicaes onde o controle dos bits muito importante tal como na transmisso de dados via modem, multiplicaes e divises por potncias de dois, troca de valores de variveis, etc. Operador & | ^ ~ >> <<

condio ? expresso_1 : expresso_2


Exemplo: ... a=24; b=38; c= (a >b) ?a: b; /* o valor de c seria 38, pois b maior do que a. O operador condicional tem baixa precedncia, precedendo apenas aos operadores de atribuio. Lembra do algoritmo para descobrir o maior entre 3 nmeros? Voc podia fazer de vrias maneiras, mas, com certeza, nunca seria menor da que vai ser mostrada abaixo:
#include <stdio.h> main() {int a,b,c,maior; printf("\ndigite 3 numeros: "); scanf("%d,%d,%d",&a,&b,&c); maior=(a>b && a>c)?a:(b>c)?b:c; printf("\nmaior:%d \n",maior);

Ao AND OR XOR (OR exclusivo) NOT Deslocamento de bits a direita Deslocamento de bits a esquerda

Existem dois operadores AND e dois operadores OR na linguagem C: um AND(&&) e um OR(||) ,operadores lgicos, que s retornam 1 ou 0 e um AND(&) e um OR(|) que podem retornar valores diferentes: Seja, para entendimento a representao do 5 em binrio: 00000101.

Operador and bit-a-bit 00000101 & 00000101 00000101

}
Observao: O operador condicional tem baixa precedncia, precedendo apenas aos operadores de atribuio.

A resposta seria 5, pois a operao bit-a-bit trabalha da seguinte maneira: ser 1 se os dois bits, em posies idnticas nos dois operandos forem 1. O operador & geralmente usado para mascarar um conjunto de bits, enquanto o operador | geralmente usado para ativar bits. Veja o exemplo:

6.6

Operadores bit-a-bit

A linguagem C , por ser uma linguagem de nvel intermedirio, isto , apresenta caractersticas de linguagens de alto nvel, mas tambm suporta operaes que podem ser feitas em linguagem de baixo nvel. Os operadores bit-a-bit s podem ser usados com variveis dos tipos char e int. As operaes realizadas so de deslocamento, atribuio e teste e so feitas em cada bit dos operandos, pois eles so representados em suas formas binrias.

23

24

Professora ANITA LOPES


#include <stdio.h> main() {int x,y; printf("\nDigite 1 numero inteiro: "); scanf("%d",&x); printf("\nDigite 2 numero inteiro: "); scanf("%d",&y); printf("\nValor de x= %d\tValor de b: %d", x,y); /*trocando valores das variaveis usando o operador XOR (^)*/ x^=y; y^=x; x^=y; printf("\n\ntrocando valores das variaveis usando o operador XOR (^)*\nValor de x= %d\tValor de y: %d\n\n", x,y); /*multiplicando por potencias de 2 usando o operador << */ printf("\n\nmultiplicando %d por potencia de 2(8) usando o operador << =%d\n\n",y,y<<3); /*dividindo por potencias de 2 usando o operador >> */ printf("\ndividindo %d por potencia de 2(4), usando o operador >> =%d\n\n",y,y>>2); /*simulando modulo de potencias de 2 usando o operador & */ printf("\nmodulo da divisao de %d por potencia de 2(4), usando o operador & =%d\n\n",y,y&3); /*complemento de um numero ~ */ printf("\ncomplemento do letra A(criptografando, por exemplo) , usando o operador ~ =%c\n\n",~65);

Professora ANITA LOPES

da complexidade de tarefas que ele poder executar. 7.1

Estrutura de deciso - if...else

A estrutura if...else uma estrutura de controle do C muito fcil de ser usada Aps o teste, o fluxo poder seguir dois caminhos, isto , se o teste resultar em uma verdade, ser executado o comando ou bloco de comandos que se encontra aps o fecha parnteses do teste, caso contrrio, se existir, ser executado o comando ou bloco de comandos que se encontra aps o comando else.

7.1.1 Estrutura de deciso com um bloco Sintaxe:

if(condio) {

bloco

onde: condio uma expresso lgica ou relacional. bloco um conjunto de instrues, separadas por ponto-e-vrgula. { e } s sero obrigatrias se tiver mais de uma ao para ser executada.

Se a condio for verdadeira, o bloco executado. Caso contrrio, o bloco no executado. Exemplo:

#include <stdio.h> main() { int idade; printf("\nQuantos anos voce tem? " ); scanf("%d",&idade); if(idade>=18) printf("\nMAIOR DE IDADE" );

}
Quando o operador de deslocamento de bit << for usado,significa que voc ir multiplicar o nmero por uma potncia de 2. Por exemplo: se voc desejar e multiplicar por 8( 2 ), dever fazer trs deslocamentos: i << 3;
3

7. Estruturas de seleo - if / switch

Nossos programas at agora seguiram um mesmo padro: entrava-se com dados, estes eram processados e alguma informao era mostrada na tela. Agindo desta forma, o computador mais parecia uma mquina de calcular. O aprendizado de novos conceitos como a da estrutura de seleo nos dar uma viso maior
25

7.1.2 Estrutura de deciso com dois blocos Sintaxe:

26

Professora ANITA LOPES


if(condio) {

Professora ANITA LOPES

bloco
} else {

if(condio 1) {

bloco 1

bloco
} onde: condio uma expresso lgica ou relacional. bloco 1 e bloco 2 so conjuntos de instrues. Se a condio for verdadeira o bloco 1 executado. Caso contrrio, o bloco 2 executado.

} ... else if(condio N) {

bloco N

} else { }

bloco P

onde: condio 1, condio 2, ... so expresses lgicas ou relacionais. bloco 1 , bloco 2,... so conjuntos de instrues.

Se a condio 1 for verdadeira o bloco 1 executado. Caso contrario, as condies sero avaliadas, sucessivamente at que seja verdadeira ou chegue ao ltimo else, onde o Exemplo
#include <stdio.h> main() { int num; printf("\nDigite numero inteiro: " ); scanf("%d",&num); if(num%2==0) printf("\nPAR" ); else printf("\nIMPAR");

bloco P seria executado. Observe que apenas um dos blocos executado.


Exemplo

#include <stdio.h> main() { int a; printf("\nDigite numero: " ); scanf("%d",&a); if(a<200) printf("\nNUMERO MENOR QUE 200"); else if(a >500) printf("\nNUMERO MAIOR DO QUE 500"); else printf("\nNUMERO NO INTERVALO 200-500");

7.1.3 Deciso de mltiplos blocos (if...else if...) Muitas vezes, nossos programas podero envolver vrias condies excludentes. Programas que envolvem faixas salariais ou faixas de idades so exemplos clssicos do uso da instruo if ... else if ... . Sintaxe: Deciso de mltiplos blocos: 7.2

Estrutura switch...case

A estrutura switch...case, tambm conhecida como alternativa de mltiplas escolhas, uma estrutura que simplifica nossos programas no uso de deciso de mltiplos blocos quando a expresso de controle( a condio) envolver tipos int ou char(de um caracter que tambm considerada inteira). O resultado desta

27

28

Professora ANITA LOPES


expresso comparado ao valor de cada um dos rtulos, e os comandos so executadas a partir desde rtulo. Sintaxe switch(expresso) { case rtulo_1: bloco1; break; case rtulo_2: bloco2 break; ... case rtulo_n: bloco n break; <default: bloco d> } onde:

Professora ANITA LOPES

switch(op) { case 1: printf("\nDOBRO: %f", a*2); break; case 2: printf("\nMETADE: %f", a/2); break; case 3: printf("\nRAIZ CUBICA: %f", pow(a,(1/3.0))); break; default: printf("\nNAO PEDIU NADA"); }

Existir alguma situao que no ser necessrio usar break? Sim.


#include <stdio.h> main() { int t; for (t = 0; t < 10; t ++) switch (t) {

expresso uma expresso inteira ou char de um caracter. rtulo_1,rtulo_2,...rtulo_n e rtulo_d so constantes inteiras ou char de um caracter. bloco 1, bloco 2, ..., bloco n e bloco d so conjuntos de instrues.
Execuo: A expresso avaliada e o fluxo desviado para o conjunto cujo rtulo igual ao resultado da expresso. O bloco abaixo do rtulo executado. Se o valor da expresso no for igual a nenhum rtulo, o bloco do defualt executado. Voc no obrigado a colocar o rtulo do default e por esta razo ele se encontra entre os sinais de menor e maior. Por que usar break? Normalmente, em outras linguagens de programao, aps a avaliao da expresso e a execuo do bloco correspondente, o fluxo do programa passa para a pro'xima instruo, ignorando todos os outros rtulos. Na linguagem C isto no acontece e poder trazer srias conseqncias em seus programas. O uso do break forar a sada do comando switch e a execuo do prximo comando. Exemplo:
#include <stdio.h> #include <math.h> main() { int op; float a; printf("\033[2J\033[30;47m"); printf("\nDigite numero: " ); scanf("%f",&a); printf("\nDigite Opcao: 1 dobro 2 metade 3 raiz cubica: " ); scanf("%d",&op); 29

case 1: printf("Preciso "); break; case 2: printf("estudar "); case 3: case 4: printf("muito "); printf("para poder passar\n"); break; case 5: case 6: printf(" em Programcao II"); break; case 7: case 8: case 9: printf("-"); } }

30

Professora ANITA LOPES

Professora ANITA LOPES

8. Estruturas de repetio Trs so as estruturas de repetio disponveis na linguagem C: for, while e do ... while. Em todas as estruturas estar presente pelo menos uma expresso para controlar a repetio. 8.1 Estrutura de repetio: for A estrutura do for a mais simples estrutura de repetio e usada para repetir um ou vrios comandos tantas vezes quanto desejarmos. a estrutura mais indicada quando o nmero de repeties for conhecido embora, as outras duas estruturas tambm possam ser usadas. O controle do nmero de repeties, na maioria das vezes, feito por uma varivel chamada de varivel contadora. A estrutura do for na linguagem C um pouco diferente das demais linguagens, pois a condio pode no se prender somente a uma varivel contadora. Sintaxes for (inicializao;condio;incremento) declarao; for (inicializao ;condio ;incremento) { bloco de comandos } onde: inicializao uma expresso de inicializao da varivel contadora e s executada uma vez..

#include <stdio.h> #include <math.h> main() { int cont; float num; for(cont=1;cont<=5;cont++) { printf("\nDigite numero: "); scanf("%f",&num); printf("Raiz quadrada: %.4f",sqrt(num)); } }

#include <stdio.h> main() {

condio uma expresso lgica de controle de repetio. incremento uma expresso de incremento da varivel contadora. bloco de comandos um conjunto de instrues a ser executado.
Exemplos
#include <stdio.h> main() { int cont; for(cont=1;cont<=10;cont++) printf("%d ",cont); } #include <stdio.h> main() { int cont; for(cont=0;cont<50;cont+=2) printf("%d ",cont);

int n=1; for(;n<10;printf("\nUNESA!"),n++ ) printf("Informatica-Praca XI\n"); }

31

32

Professora ANITA LOPES

Professora ANITA LOPES

printf("\nDigite numero positivo: "); scanf("%d",&num); while(num>0) { if(num%2==0) printf("\nPAR"); else printf("\nIMPAR"); printf("\nDigite numero positivo: "); scanf("%d",&num); }

8.2 Estrutura de repetio: while A estrutura while uma estrutura "poderosa" da programao. Muitos programadores fazem uso somente desta estrutura. Ela testa primeiro a condio e poder nem executar o bloco caso a condio seja falsa. Logo, a estrutura do while repete enquanto a condio for verdadeira. importante que a varivel presente na condio tenha seu valor alterado dentro da repetio, pois, caso contrrio, entrar em loop. Normalmente, todos os autores mostram simplesmente a sintaxe da estrutura, mas esquecem de informar como na prtica ela dever ser escrita. Abaixo, apresentarei a sintaxe geral e a sintaxe usada na prtica:

8.3

Estrutura de repetio: do...while

Esta estrutura parecida com while. Sua diferena que o bloco executado pelo

menos uma vez, pois testa ao final. Esta estrutura repete enquanto a condio for verdadeira.
Sintaxe do { } while(condio);

bloco de comandos

Sintaxe while(condio) {

Sintaxe na prtica atribuio ou leitura da varivel presente na condio while(condio) {

bloco de comandos
}

onde: condio uma expresso lgica ou numrica. bloco de comandos um conjunto de instrues.

bloco de comandos
atribuio ou leitura da varivel presente na condio } onde: condio uma expresso lgica ou numrica. bloco de comandos um conjunto de instrues. Exemplo

Exemplo

#include <stdio.h> main() { int num; 33

#include <stdio.h> #include <ctype.h> main() { float n1,n2,n3; char op; do { printf("\nMENU\n\nS somar dois numeros\nQ quadrado de um numero"); printf("\nM multiplicar tres numeros\nF finalizar\nOPCAO: "); scanf("%c",&op); op=toupper(op); switch(op)

34

Professora ANITA LOPES


{ case 'S': printf("\nDois numeros separados por virgulas: "); scanf("%f %f",&n1,&n2); printf("\nSoma: %f",n1+n2); break; case 'Q': printf("\nDigite numero: "); scanf("%f",&n1); printf("\nQuadrado: %f",n1*n1); break; case 'M': printf("\nDigite tres numeros separados por espacos: "); scanf("%f %f %f",&n1,&n2,&n3); printf("\nProduto: %f",n1*n2*n3); break; case 'F': printf("\nSAINDO"); break; default:printf("\nOPCAO INEXISTENTE"); } fgetc(stdin); } while(op!='F');

Professora ANITA LOPES

8.4.2 continue

O comando continue pode ser visto como sendo o oposto do break. Ele s funciona dentro de um loop. Quando o comando continue encontrado, o loop pula para a prxima iterao, sem o abandono do loop, ao contrrio do que acontece no comando break.

O exemplo abaixo mostra a eficincia deste comando, pois, logo depois que o teste for executado e se no for encontrado o espao, a varivel a incrementada e testada. #include <stdio.h> #include <string.h> main() { int a,cont=0; char nome[30]; printf("\nNome:"); fgets(nome,30,stdin); for(a=0;a<strlen(nome)-1;a++) { if(nome[a]!=' ')continue; cont++; } printf("\nTotal de partes do nome: %d\n",cont+1); }

9 Estruturas

As estruturas em C podem ser homogneas e heterogneas. Inicialmente, vamos abordar as homogneas, pois so mais familiares uma vez que conhecemos seu conceito da matemtica quando estudamos matrizes. 8.4 Comandos associados As estruturas de repetio podem, mas no devem, sofrer desvios e interrupes em sua seqncia normal. 8.4.1 break Assim como o foi usado para interromper o comando switch, poder ser usado com qualquer um dos trs comandos de repetio.
35

9.1 Estruturas homogneas

Em C, o uso de matrizes de fundamental importncia e existe uma relacionamento estreito entre matrizes e ponteiros que estudaremos mais adiante. A grande novidade que estudaremos ser o uso de matrizes com estruturas heterogneas. As matrizes so tabelas na MP e podem ter uma ou mais dimenso. Quando tem somente uma dimenso, tambm chamamos de vetor.

36

Professora ANITA LOPES


Na linguagem C, como j vimos, uma varivel char ,que precisa armazenar mais de um caracter, faz uso de matriz, pois podemos acessar cada um de seus caracteres em separado, usando o nome da varivel e sua posio entre colchetes. O exemplo abaixo que converte cada um dos caracteres para maiscula exemplifica bem o que queremos demonstrar: #include <stdio.h> #include <ctype.h> main() { int a; char nome[30]; printf("\nNome: "); fgets(nome,30,stdin); for(a=0;a<strlen(nome)-1;a++) nome[a]=toupper(nome[a]); printf("\nNome em maiusculas: %s\n",nome); }

Professora ANITA LOPES

bom voc j ir se acostumando com este conceito de apontamento, pois para se programar bem em C, precisaremos dominar o conceito de ponteiros.

9.1.1 Declarando uma matriz:

tipo nome do conjunto [ ... ] [ ...] ... ;

Exemplos: /* declara uma matriz unidimensional de 5 elementos inteiros */ int num[ 5 ];

/* declara uma matriz bidimensional com 100 linhas e 4 colunas do tipo float */ float notas [ 100 ][ 4 ];

/* declara uma matriz bidimensional com 100 linhas e 30 colunas do tipo char */ char nomes [ 100 ][ 30 ]; Toda matriz para guardar nomes, na linguagem C, bidimensional, pois o primeiro ndice indica a quantidade de nomes e o segundo o nmero de caracteres 1 que sero armazenados em cada nome. Neste exemplo, voc observou a funo toupper que faz parte da biblioteca ctype.h. Esta funo converte um caracter, desde que seja uma letra minscula, para maiscula. Como a varivel nome, chamada em outras linguagens de varivel "string", declarada na linguagem C como um vetor de variveis do tipo char, pudemos acessar cada caracter do conjunto e convert-lo, quando possvel. Voc j imaginou se esta funo no existisse? Observe a linha abaixo e verifique se obteramos o mesmo resultado: if(nome[a] >= 'a' && nome[a] <= 'z') nome[a] = nome[a] - 32; 9.1.2 Armazenamento

O armazenamento na matriz poder ser feito atravs de um comando de leitura ou de atribuio.

Por que ser que na linguagem C a posio do primeiro caracter 0 ? O endereo guardado o do primeiro caracter que chamamos de base, logo qualquer outro caracter ser acessado pelo endereo base mais sua posio. Se o endereo o da primeira posio, somente o 0 poderia ser acrescido para permanecer na mesma posio.

9.1.2.1 Leitura #include <stdio.h> main() { int num[5],a; for(a=0;a<5;a++) { printf("\nNumero %d: ",a+1); scanf("%d",&num[a]);} printf("\n\n\nNumeros armazenados\n\n"); for(a=0;a<5;a++) printf("\n%d",num[a]); printf("\n"); }

Se declararmos pal com tamanho 5, lembre-se de que s podemos usar 4 posies, pois uma reservada para o finalizador \0 que indica o fim do vetor.
37

38

Professora ANITA LOPES


9.1.2.2 Atribuio

Professora ANITA LOPES

#include <stdio.h> main() { int num[3][3],L,c; for(L=0;L<3;L++) for(c=0;c<3;c++) { printf("Numero da linha %d coluna %d: ",L+1,c+1); scanf("%d",&num[L][c]); } printf("\n\n\nNumeros armazenados\n\n"); for(L=0;L<3;L++) { for(c=0;c<3;c++) printf("%d\t",num[L][c]); printf("\n"); } printf("\n"); }

Podemos tambm inicializar as matrizes atravs de atribuies: Exemplos: int vet[4]={6,7,8,9}; float nota[3]={8.5,6.2,9.8}; char nome[12]="Joo Renato"; char nomes[4][30]={"JOO", "MARIA", "PEDRO","FILIPE"}; int mat[][3]={1,2,3,4,5,6,7,8,9}; /* na declarao/atribuio acima, assumido 3 como nmero de linhas */ #include <stdio.h> main() { int L,c; int dias_meses[][13]={0,31,28,31,30,31,30,31,31,30,31,30,31, 0,31, 29,31,30,31,30,31,31,30,31,30,31}; anos nao bissextos, primeira linha e para printf("\n\nPara bissextos, segunda linha\n\n"); for(L=0;L<2;L++) { for(c=1;c<13;c++) printf("%6d", dias_meses[L][c]); printf("\n"); } printf("\n"); }

9.1.3 Operaes

Em relao s matrizes numricas, podemos realizar todas as operaes que j conhecemos com matrizes: produto escalar, soma, subtrao, multiplicao por escalar, multiplicao de matrizes, clculo do determinante, etc.

9.1.4 Ordenao

Vrios so os mtodos de ordenao. Alguns so mais eficientes e mais complicados e outros menos eficientes para um grande conjunto de dados, porm mais simples. Para que possamos ordenar nomes, precisaremos conhecer duas funes que fazem parte da biblioteca string.h:

39

40

Professora ANITA LOPES


Funo strcmp Esta funo tem dois argumentos do tipo vetor de char(ou cadeia de caracteres). Os argumentos so comparados e devolvido um dos resultados: strcmp(arg1,arg2) 0 se os dois argumentos forem iguais. nmero > 0 - se o primeiro argumento vier na ordem alfabtica depois do segundo. nmero < 0 - se o primeiro argumento vier na ordem alfabtica antes do segundo. Observao: Voc deve estar estranhando a necessidade desta funo, mas na linguagem C, como j falamos a varivel vetor de char um endereo, e no tem sentido comparamos endereos. , portanto, expressamente proibido usar operadores relacionais para comparar este tipo de varivel. Funo strcpy Esta funo tem dois argumentos: o primeiro o destino e o segundo, a origem. Copia a origem no destino. strcpy(arg1,arg2); Observao: , portanto, expressamente proibido usar comando de atribuio este tipo de varivel. Exemplo 1: Ordenao por Seleo #include <stdio.h> #include <string.h> #include <ctype.h> main() { char nome[5][30], aux[30]; int l,c,min; for(l=0;l<5;l++) { printf("digite nome %d: ",l+1); fgets(nome[l],30,stdin); for(c=0;c<strlen(nome[l]);c++ ) nome[l][c]=toupper(nome[l][c]); } for(l=0;l<4;l++) { min=l; for(c=l+1;c<5;c++) if(strcmp(nome[c],nome[min])<0) min=c; strcpy(aux,nome[l]); strcpy(nome[l],nome[min]); strcpy(nome[min],aux); } printf("\n\nRelacao dos nomes ordenados\n\n"); for(l=0;l<5;l++) printf("%2d-%s",l+1,nome[l]); printf("\n");
41

Professora ANITA LOPES


}

Exemplo 2: Ordenao por Insero

#include <stdio.h> main() { int num[5],l,c,d,n; for( l = 0 ; l < 5; l++) { printf("\nnumero %d: ",l + 1); scanf("%d",&n); c=0; while( n >= num[c] && c<l) c ++; if(l!=0) for (d= l; d >= c+1; d--) num[d] = num[d-1] ; num[c] = n ; } printf("\n\nVetor Ordenado\n"); for(l=0;l<5;l++) { printf("\n%d",num[l]);} printf("\n"); }

42

Professora ANITA LOPES

Professora ANITA LOPES

9.1.4.2 Binria 9.1.4 Pesquisa 9.1.4.1 Seqencial Este mtodo o mais simples, pois comea no primeiro elemento s para quando encontra ou chega ao final. #include <stdio.h> main() { int mat[5],l,n_mat,pos,achou; for( l = 0 ; l < 5; l++) { printf("\nEntre com a %d matricula: ",l + 1); scanf("%d",&mat[l]); } printf("\nQual a matricula a ser procurada? "); scanf("%d",&n_mat); achou=0; for(l=0;l<5 && achou==0;l++) { if(n_mat!=mat[l])continue; achou=1; pos=l; } if(achou==1) printf("\nMatricula achada na posicao: %d",pos+1); else printf("\nMatricula nao achada"); printf("\n"); }

Este mtodo ser mais eficiente se o conjunto estiver ordenado. Baseia-se em reduzir o espao a ser pesquisado. 1. Inicialmente, aponta-se para o centro da tabela. Como se faz isto? Suponha um vetor de 8 elementos:

centro = (0 + 7) /2; /* valor 3 */

2. Depois, perguntamos se o elemento pesquisado igual ao que est sendo apontado. Se no for, continua-se com a pesquisa. 3. Se continuarmos com a pesquisa, verificamos se o elemento pesquisado maior(menor) do o que est sendo apontado. 4. Se for, calculamos o novo centro:

centro = (posio do apontador +1 +7) /2; Se no for:

centro = (0 + posio do apontador -1) /2;

5. E assim, sucessivamente at acharmos, ou no.

#include <stdio.h> #include <string.h> #include <ctype.h> #define N 5 main() { int L,c,inicio,fim,meio; char vet[N][30],auxs[30],lixo[100]; for(L=0;L<N;L++) { printf("\nDigite elemento %d : ",L+1); fgets(auxs,30,stdin); if(strlen(auxs)==29)
43

44

Professora ANITA LOPES


{ fgets(lixo,100,stdin);auxs[28]='\n';} strcpy(vet[L],auxs); for(c=0;c<strlen(vet[L]);c++) vet[L][c]=toupper(vet[L][c]); } /*ORDENA*/ for(L=0;L<N-1;L++) { char aux[30];int pos; for(pos=L,c=L+1;c<N;c++) if(strcmp(vet[pos],vet[c])>0) pos=c; strcpy(aux,vet[L]); strcpy(vet[L],vet[pos]); strcpy(vet[pos],aux); } printf("\n\n\nVETOR CARACTER ORDENADO\n\n"); for(L=0;L<N;L++) printf("%s",vet[L]); /*PESQUISA BINARIA*/ do { printf("\nDigite nome de procura ou FIM para terminar: "); fgets(auxs,30,stdin); for(c=0;c<strlen(auxs);c++) auxs[c]=toupper(auxs[c]); inicio=0;fim=N-1; do { meio=(inicio+fim)/2; if(strcmp(vet[meio],auxs)<0) inicio=meio+1; else fim=meio-1; } while((inicio<=fim) && (strcmp(vet[meio],auxs)!=0)); if(strcmp(vet[meio],auxs)==0) printf("\nNome encontrado na posicao: %d\n",meio+1); else if(strcmp(auxs,"FIM\n")!=0) printf("\nNome nao encontrado\n"); } while(strcmp(auxs,"FIM\n")!=0); printf("\n\n"); }

Professora ANITA LOPES

9.2 Estrutura heterognea (struct)

Uma estrutura(struct) , na verdade, um conjunto de variveis que podem ter tipos diferentes. Suponha que voc deseje armazenar nome, e duas notas de um aluno. Se voc usar variveis simples, precisar declarar trs variveis simples e, para que fiquem claras que existe uma relao entre elas, precisamos nome-las de uma forma que nos faa entender que elas se relacionam. Usando struct fica mais claro o relacionamento entre elas. Suponha tambm que voc deseje armazenar nome, e duas notas de trs alunos. Se voc usar matrizes, precisar declarar uma matriz para guardar os nomes e uma matriz bidimensional para guardar as notas(pode ser tambm duas matrizes unidmensionais). Se voc usar uma matriz de struct, ser necessria somente uma matriz. As variveis de um struct so chamadas de campos ou membros. Normalmente, costumamos associar um nome estrutura para que possamos definir novos tipos.

9.2.1 Declarando um struct

sintaxe 1 struct { tipo da varivel 1 nome da varivel 1; tipo da varivel 2 nome da varivel 2; tipo da varivel n nome da varivel n;
45

46

Professora ANITA LOPES


}nome do struct1, nome do struct2;

Professora ANITA LOPES

sintaxe 2 struct nome da estrutura { tipo da varivel 1 nome da varivel 1; tipo da varivel 2 nome da varivel 2; tipo da varivel n nome da varivel n; }; struct nome da estrutura nome do struct1, nome do struct2; /* ao fazermos esta declarao, dizemos que os dois structs so do tipo nome da estrutura*/

9.2.2 fazendo referncia a um membro um struct nome do struct. nome do membro -> struct simples Exemplos: scanf("%d",&dados.idade); printf("\n%d", dados.idade); nome do struct[posio]. nome do membro -> matriz de struct Exemplos: scanf("%d",&cad[3].idade); printf("\n%d", cad[3].idade); Exemplo 1: Guardar nome e duas notas de um aluno e imprimir a mdia e o nome. #include <stdio.h> main() { struct { char nome[30]; float nota1,nota2; }aluno; char c; printf("\nNome : "); fgets(aluno.nome,30,stdin); printf("\nNota 1: "); scanf("%f",&aluno.nota1); printf("\nNota 2: "); scanf("%f",&aluno.nota2); printf("\nMedia: %.1f",(aluno.nota1+aluno.nota2)/2); printf("\t%s",aluno.nome); }

Exemplo 2: Guardar nome e duas notas de trs alunos e imprimir a mdia e o nome. #include <stdio.h> main() { char c;int a; struct Cadastro { char nome[30]; float nota1,nota2; }; struct Cadastro aluno[3]; for(a=0;a<3;a++) { printf("\nNome : ");fgets(aluno[a].nome,30,stdin); printf("\nNota 1: "); scanf("%f",&aluno[a].nota1); printf("\nNota 2: "); scanf("%f",&aluno[a].nota2); fgetc(stdin); } printf("\n\nMedia\tNome\n\n"); for(a=0;a<3;a++) {printf("\n%.1f",(aluno[a].nota1+aluno[a].nota2)/2); printf("\t%s",aluno[a].nome); } fgetc(stdin);scanf("%c",&c); }

47

48

Professora ANITA LOPES

Professora ANITA LOPES

Observao: Nos exemplos abaixo, voc ver uma das maiores vantagens de se usar uma matriz de struct, pois quando precisarmos ordenar, no teremos que fazer muitos trechos de troca. A grande vantagem que podemos trocar de lugar todo o struct. Observe que foi criada uma estrutura de nome aux para poder fazer a troca. Exemplo 3: Faa um programa usando matriz de estruturas para armazenar matricula e idade de 5 alunos. Ordene pela matrcula e liste. #include <stdio.h> main() { struct CAD { int mat, idade;}aluno[5],aux; int l,c; for(c=0;c<5;c++) {printf("\nMatricula %d: ", c+1);scanf(%d",&aluno[c].mat); printf("Idade: "); scanf(%d",&aluno[c].idade); } /* ORDENACAO */ for(l=0;l<4;l++) for(c=l+1;c<5;c++) if(aluno[l].mat>aluno[c].mat) {aux=aluno[l]; aluno[l]=aluno[c];aluno[c]=aux;} printf("\n\n\n\nMatr.\tIdade\n\n"); for(c=0;c<5;c++) printf("\n%4d\t%2d",aluno[c].mat,aluno[c].idade); printf("\n\n\n"); }

Exemplo 4: A federao de vlei do Rio de Janeiro gostaria de fazer um programa que pudesse armazenar: nome dos 10 times que participaram do campeonato, nmero de vitrias, nmero de derrotas e nome do tcnico. Faa um programa usando matriz heterognea que possa entrar com todos os dados citados, ordene pelo nmero de vitrias e imprima a listagem ordenada, contendo a classificao final, isto , 1o lugar, 2o lugar, ..., 10o lugar. #include <stdio.h> main() { struct FVRJ { char nomeTime[40],nomeTecnico[40]; int vitorias,derrotas; }times[10],aux; int l,c; for(c=0;c<10;c++) {printf("\nNome do time %d: ", c+1); fgets(times[c].nomeTime,40,stdin); printf("\nNome do tecnico %d: ", c+1); fgets(times[c].nomeTecnico,40,stdin); printf("\nTotal de vitorias: "); scanf("%d",&times[c].vitorias); printf("\nTotal de derrotas: "); scanf("%d",&times[c].derrotas); fgetc(stdin); } /* ORDENACAO */ for(l=0;l <9;l++) for(c=l+1;c<10;c++) if(times[l].vitorias<times[c].vitorias) {aux=times[l]; times[l]=times[c];times[c]=aux;} printf("\n\n\n\nClassificao\tTime\n\n"); for(c=0;c<10;c++) printf("\n%2do lugar \t%s",c+1,times[c].nomeTime); printf("\n\n\n");
}

9.2.3 Declarando ou definindo

A principal diferena que quando se declara, no se aloca espao na MP e quando se define, sim.

9.2.4 Embutindo a definio na declarao

Veja exemplo abaixo: struct Notas {float n1,n2,media;}

49

50

Professora ANITA LOPES


struct { char nome[3]; struct notas notasAluno; }Auno; 10.2 Vantagens

Professora ANITA LOPES

Observao: No primeiro, estamos associando uma etiqueta(nome) ao struct: Notas. Estamos definindo um novo tipo de dado. No segundo, estamos declarando um struct de nome Aluno que tem embutindo uma definio na declarao. Quando precisarmos nos referenciar varivel n1, por exemplo: .... Aluno.notasAluno.n1 Exemplo 5: #include <stdio.h> main() { struct Notas {float n1,n2,media;}; struct { char nome[30]; struct Notas notasAluno; }Aluno; char c; printf("\nNome : "); fgets(Aluno.nome,30,stdin); printf("\nNota 1: "); scanf("%f",&Aluno.notasAluno.n1); printf("\nNota 2: "); scanf("%f",&Aluno.notasAluno.n2); Aluno.notasAluno.media=(Aluno.notasAluno.n1+Aluno.notasAluno.n2)/2; printf("\nMedia: %.1f",Aluno.notasAluno.media); printf("\t%s",Aluno.nome); }

As funes atravs da passagem de parmetros e atravs do seu nome permitem que sejam retornados valores rotina chamadora e desta forma, esses valores podero ser impressos, atribudos a uma varivel ou podem servir em operaes aritmticas entre outras. Os principais objetivos de uma funo so:

Dividir e estruturar um algoritmo em partes logicamente coerentes;

Facilidade em testar os trechos em separados;

O programador poder criar sua prpria biblioteca de funes, tornando sua programao mais eficiente uma vez que poder fazer uso de funes por ele escritas em vrios outros programas com a vantagem de j terem sido testadas;

Maior aumentar a legibilidade de um programa;

Evitar que uma certa seqncia de comandos necessria em vrios locais de um programa tenha que ser escrita repetidamente nestes locais, diminuindo tambm, o cdigo fonte, ;

Tudo isto justifica o uso de funes em nossos programas

10.3. Funes Pr-definidas

O conjunto de funes pr-definidas muito extenso e aqui vamos estudar algumas funes das bibliotecas: math.h, ctype.h, string.h e stdlib.h. Quando estudamos uma funo, temos vrios parmetros a observar. Veja, por exemplo a seguinte funo pr-definida da biblioteca math.h:

double sqrt(double x)

10 Funes 10.1 Conceito Funo um trecho de programa com atribuies especficas, simplificando o entendimento do programa, proporcionando ao programa menores chances de erro e de complexidade. A linguagem C formada de vrias funes.

Este o prottipo da funo, isto , informaes sobre o tipo de retorno da funo e tipos dos parmetros. Esta funo retorna um valor double, seu nome sqrt e o tipo da varivel que recebe o valor passado double. Quando voc criar suas funes, elas precisaro ter uma declarao semelhante a esta. As funes podero ser localizadas antes da funo principal(main) ou depois. Se uma funo for declarada antes, o prottipo da funo no precisar ser declarado na funo main, mas se declarada depois, o prottipo precisar ser declarado na funo main. Declarao de uma funo: tipo int, float, char, void Exemplos:
51

identificador Nome da funo

(lista de parmetros) ( tipo1 nome1, tipo2 nome2 )

52

Professora ANITA LOPES


int quadrado(int l) char maiuscula(char n[] )

Professora ANITA LOPES

10.3.2 Funes que Convertem strings em nmeros Biblioteca: stdlib.h

10.3.1 Funes Numricas Biblioteca: math.h


#include <stdio.h> #include <math.h> #define PI (3.14159265) main() { float f; printf("\nFUNCOES NUMERICAS\n"); printf("\nDigite numero real: "); scanf("%f",&f); printf("\nNumero: %f",f); printf("\nABSOLUTO: %f",fabs(f)); printf("\nCEIL: %f",ceil(f)); printf("\nFLOOR: %f",floor(f)); printf("\nTRUNC: %f",trunc(f)); printf("\nROUND: %ld",lround(f)); printf("\nFMOD: %.f",fmod(f,3)); printf("\nSQRT: %.f",sqrt(f+0.5)); printf("\nSeno de 30: %.2f",sin(30*PI/180)); printf("\nCo-seno de 30: %.2f",cos(30*PI/180)); printf("\nTangente de 30: %.2f",tan(30*PI/180)); printf("\nPotencia de 2 elevado a 3: %f",pow(2,3)); printf("\nLogaritmo de 8 na base neperiana: %.3f",log(8)); printf("\nLogaritmo de 8 na base 10: %.3f",log10(8)); printf("\nLogaritmo 8 na base 2: %.3f",log(8)/log(2)); printf("\nRaiz cubica de 8: %.3f",exp(1./3*log(8))); printf("\n\n");

#include <stdio.h> #include <stdlib.h> main() { char s[30]; printf("\nFUNCOES CHAR-NUMER0\n"); printf("\nDigite numero real: "); scanf("%s",&s); printf("\nNumero: %f",atof(s)); printf("\nDigite numero inteiro: "); scanf("%s",&s); printf("\nNumero: %d",atoi(s)); printf("\nABSOLUTO: %d",abs(atoi(s))); printf("\n\n");

10.3.3 Funes Strings Biblioteca: string.h/ctype.h

#include <stdio.h> #include <string.h> #include <ctype.h> main() {char c,s1[40],s2[30]; printf("\nBIBLIOTECA ctype.h\n"); printf("\nLetra: "); scanf("%c",&c);fgetc(stdin); if(islower(c)) printf("\nConvertida para maiuscula: %c",toupper(c)); else printf("\nConvertida para minuscula: %c",tolower(c)); printf("\n\nBIBLIOTECA string.h\n"); printf("\nPalavra 1: "); fgets(s1,30,stdin);s1[strlen(s1)-1]='\0'; printf("\nPalavra 2: "); fgets(s2,30,stdin);s2[strlen(s2)-1]='\0'; strcat(s1,"FIM"); printf("\n\nConcatenacao: %s",s1); strcpy(s1,s2); printf("\n\nApos copia de toda palavra2: %s",s1); printf("\n\nTamanho de s2: %d",strlen(s2)); printf("\n\nComparando strings\n"); printf("\nDigite PAZ: "); fgets(s1,30,stdin); 53

54

Professora ANITA LOPES


printf("\nDigite PAZ: "); fgets(s2,30,stdin); if(strcmp(s1,s2)==0) printf("\nIGUAIS"); else printf("\nDiferentes"); printf("\nDigite PAZ: "); fgets(s1,30,stdin); printf("\nDigite AMOR: "); fgets(s2,30,stdin); if(strcmp(s1,s2))/*equivale a strcmp(s1,s2)!=0 */ printf("\nDIFERENTES"); else printf("\nIguais"); printf("\n");system("PAUSE");

Professora ANITA LOPES

printf("\nnumero: 12" ); printf("\n\nquadrado= %d", quadrado(12)); printf("\n\nangulo: 30" ); printf("\n\nseno de %.2f eh %4.2f",30.,sin(conv(30))); printf("\n\nneperiano %.11f",NP); }

Exemplo 2: #include <stdio.h> #define AREA(b,h) (b*h) main() { float base,alt; printf("\nBASE: "); scanf("%f",&base); printf("\nALTURA: "); scanf("%f",&alt); printf("\nAREA: %.2f",AREA(base,alt)); printf("\n"); }

Exemplo 3: #include <stdio.h> #include <math.h> #define HIPO(c1,c2) (sqrt(c1*c1+c2*c2)) main() { float cat1,cat2; printf("\nCATETO 1: "); scanf("%f",&cat1); printf("\nCATETO 2: "); scanf("%f",&cat2); printf("\nHIPOTENUSA: %.2f",HIPO(cat1,cat2)); printf("\n"); } 10.4. Diretiva #define Define um identificador e um contedo que ir ser substitudo toda vez que o identificador aparecer em um programa. Esta diretiva pode ser associada a uma string ou a uma macro semelhante a uma funo. Se o tamanho da macro for pequena, substitui com vantagens o uso de funes. Exemplo 1: #include <stdio.h> #include <math.h> #define quadrado(x) ((x)*(x)) #define pi (3.14159265) #define NP (2.71828182846) #define conv(x) ((x)*(pi)/(180)) main() {
55

Exemplo 4: #include <stdio.h> #include <math.h> #define POT(b,e) (exp(e*log(b))) main() { int base, expoente; printf("\nBase: "); scanf("%d",&base); printf("\nexpoente: "); scanf("%d",&expoente); printf("\nPotencia: %.2f",POT(base,expoente)); printf("\n"); }

56

Professora ANITA LOPES


10.5 Chamada da funo No devemos ficar preocupados como isso ir acontecer, pois j fizemos uso de vrios funes internas(funes do tradutor) e, da mesma forma, chamaremos as funes feitas por ns. Quando uma funo chamada, o fluxo de controle desviado para a funo, no momento em que ela ativada no algoritmo principal. Ao terminar a execuo dos comandos da funo, o fluxo de controle retorna ao comando seguinte quele onde ela foi ativada, exatamente como na figura abaixo: main() {... ... } < chamada da funo 1 > ... ... } retorna(...); { ... funcao1( ...) tipo de funo nome da funo parmetros declaraes dos parmetros { variveis locais corpo da funo return( .. ) }

Professora ANITA LOPES

: tipo de dado que a funo dar retorno. Pode ser int, float, charou void : segue as mesmas regras de declarao de variveis : nomes das variveis, seguem as mesmas regras de declarao de variveis : declaraes de variveis da funo(tipo e nome) : incio da funo : declaraes de variveis que sero utilizadas dentro da funo( tipo e nome) : seqncia de comandos : o que vai ser retornado para o algoritmo ou no existe : fim da funo

10.7. Localizao das funes

Ns adotaremos aps a funo principal, mas elas podero ser colocadas antes da funo principal(main).

10.6 Estrutura de uma funo Uma funo um bloco contendo incio e fim, sendo identificada por um nome , pelo qual ser referenciada em qualquer parte e em qualquer momento do programa. A funo serve para executar tarefas menores como ler, calcular, determinar o maior/menor valor entre uma lista de valores, ordenar, converter para maisculas, entre outras. Aps executar estas tarefas menores, a funo retorna, ou no, um determinado valor para a funo chamadora. Quando a funo no retornar nada(nulo) usaremos o tipo void, pois sugerido pelo comit de padronizao ANSI. Dentro da funo, podem ser declaradas variveis que chamamos de variveis locais, pois s so visveis dentro da funo. Sintaxe da funo: <tipo de funo> nome_da_funo (declaraes dos parmetros) { < declarao das variveis locais> comandos que formam o corpo da funcao return(< valor >) ; /* ou return; ou nada */ }
57

main() { prottipo da funcao1; prottipo da funcao2; prottipo da funcao3; ... } funcao1(...) {... } funcao2(...) {... } funcao3(...) {... }

10.8. Dividindo o programa em funes

Ns podemos modularizar nossos programas para que possamos deix-lo mais claro. Se as funes manipulam as mesmas variveis, deveremos declar-las com variveis globais, isto , fora de todas as funes.

58

Professora ANITA LOPES


10.9 Tipos de Funes 10.9.1 Funes void ( no retornam nada) Este tipo de funo no tem nenhum dado de retorno para a funo principal. Ela executa o trecho e retorna para a funo seguinte da sua chamada. A funo pode no ter parmetros e ser do tipo void, tambm. Exemplo: #include <stdio.h> main() {void linha();/*prototipo da funo(tipo de retorno, nome e (argumentos) */ printf("\nUNESA\n"); linha(); printf("\nINFORMATICA - 2 PERIODO\n"); linha(); printf("\nPROGRAMACAO II\n"); linha(); printf("\nPROF. ANITA LOPES\n"); linha(); printf("\n"); } void linha() {int a; for(a=1;a<=50;a++) printf("*"); } 10.9.2 Funes com passagem de valor A linguagem C passa os valores para funes atravs de argumentos das chamadas das funes para os parmetros das funes, na verdade variveis que recebero cpias dos dados. Desta maneira, os dados de origem no so alterados. Uma boa dica: Suponha que voc comprou um livro e descobriu alguns erros. Voc corrige no seu livro, mas no altera o original que, enquanto o autor no corrigir, os erros permanecero.

Professora ANITA LOPES

printf("\nPROGRAMACAO II\n"); linha(14); printf("\nPROF. ANITA LOPES\n"); linha(17); printf("\n"); system("pause");/*soh no Windows*/ } void linha(int x) {int a; for(a=1;a<=x;a++) printf("*"); }

Exemplo 2: Funo linha com nmero variado de asteriscos #include <stdio.h> #include <stdlib.h>/*soh no Windows*/ main() {void linha(int x, char c); /*prototipo da funo(tipo de retorno, nome e (argumentos) */ printf("\nUNESA\n"); linha(5); printf("\nINFORMATICA - 2 PERIODO\n"); linha(23); printf("\nPROGRAMACAO II\n"); linha(14); printf("\nPROF. ANITA LOPES\n"); linha(17); printf("\n"); system("pause");/*soh no Windows*/ } void linha(int x) {int a; for(a=1;a<=x;a++) printf("*"); }

A nica exceo para as matrizes, uma vez que j falamos que matrizes so ponteiros para o primeiro elemento da matriz.
Exemplo 1: Funo linha com asteriscos #include <stdio.h> #include <stdlib.h>/*soh no Windows*/ main() {void linha(int x); /*prototipo da funo(tipo de retorno, nome e (argumentos) */ printf("\nUNESA\n"); linha(5); printf("\nINFORMATICA - 2 PERIODO\n"); linha(23);
59

Exemplo 3: Funo linha com nmero variado de qualquer caracter #include <stdio.h> #include <stdlib.h>/*soh no Windows*/ main() {void linha(int x,char c); /*prototipo da funo(tipo de retorno, nome e (argumentos) */ printf("\nUNESA\n"); linha(5,'#'); printf("\nINFORMATICA - 2 PERIODO\n"); linha(23,'*'); printf("\nPROGRAMACAO II\n"); linha(14,'@'); printf("\nPROF. ANITA LOPES\n"); linha(17,'='); printf("\n"); system("pause");/*soh no Windows*/

60

Professora ANITA LOPES


} void linha(int x,char c) {int a; for(a=1;a<=x;a++) printf("%c",c); }

Professora ANITA LOPES

printf("\nNOME: "); fgets(s,30,stdin); maiuscula(s); printf("\nConvertida para MAIUSCULA: %s",s); scanf("%c",&c); } char maiuscula(char n[]) {int c; n[c]=toupper(n[c]); }

for(c=0;c<strlen(n);c++)
Exemplo 4: funo PA. #include <stdio.h> main() {int PA(int x,int y,int z); /* prototipo da funcao */ int a1,n,r;char c; printf("\nDigite primeiro termo, razao, numero de termos: "); scanf("%d%d%d",&a1,&r,&n); PA(a1,r,n);fgetc(stdin); scanf("%c",&c); } int PA(int x,int y,int z) {int c; for(c=1;c<=z;c++) {printf("%d ",x);x+=y;} return; } Exemplo 5: Funo RAIZ. #include <stdio.h> #include <math.h>

main()
{float RAIZ(float rad,int ind); /* prototipo da funcao */ int I;float r;char c; printf("\nDigite radicando e ndice "); scanf("%f%d",&r,&i); if(r>=0 && I>1) printf("\nRAIZ: %.3f",RAIZ(r,i)); else if(I%2==1 && r<0) printf("\nRAIZ: -%.3f",RAIZ(fabs,i)); else printf("\nNAO POSSO FAZER\n"); fgetc(stdin); scanf("%c",&c); } float RAIZ(float rad,int ind) { return(exp(1./ind*log(rad)));} Exemplo 6: Funo maiuscula #include <stdio.h> #include <ctype.h> #include <string.h> main() {char s[30],maiuscula(char n[]),c;
61

Exemplo 7: Funo maiuscula/Troca/retira\n #include <stdio.h> #include <string.h> #include <ctype.h> main() { char n1[30], n2[30], n3[30],c; char troca1(char x[], char y[]), maiuscula(char n[]),verifica(char n[]); printf("\nDigite nome 1: "); fgets(n1,30,stdin); verifica(n1); maiuscula(n1); printf("\nDigite nome 2: "); fgets(n2,30,stdin); verifica(n2); maiuscula(n2); printf("\nDigite nome 3: "); fgets(n3,30,stdin); verifica(n3); maiuscula(n3); printf("\n\n\nANTES DA TROCA\n%s\n%s\n%s", n1,n2,n3); if(strcmp(n1,n2)>0)troca1(n1,n2); if(strcmp(n1,n3)>0)troca1(n1,n3); if( strcmp(n2,n3)>0 )troca1(n2,n3); printf("\n\n\nDEPOIS DA TROCA\n%s\n%s\n%s", n1,n2,n3); scanf("%c",&c); }

char troca1(char x[], char y[]) { char aux[30]; strcpy(aux,x); strcpy(x,y); strcpy(y,aux); }

char verifica(char n[]) { char lixo[200]; if(strlen(n)==29) { if(n[28]=='\n') n[strlen(n)-1]='\0'; else fgets(lixo,200,stdin); } else n[strlen(n)-1]='\0'; } char maiuscula(char n[]) {int x;

62

Professora ANITA LOPES


for(x=0;x<strlen(n);n[x]=toupper(n[x]),x++); } } Exemplo 8: Funo ordena vetor #include <stdio.h> main() { int vet[5],c, ordena(int v[],int t); char c1; for(c=0;c<5;c++) { printf("\nDigite numero %d: ",c+1); scanf("%d",&vet[c]); } ordena(vet,5); printf("\n\nORDENADO\n"); for(c=0;c<5;c++) printf("\n%d",vet[c]); fgetc(stdin);scanf("%c",&c1); } int ordena(int v[],int t) { int c,l,aux; for(c=0;c<t-1;c++) for(l=c+1;l<t;l++) if(v[c]<v[l]) {aux=v[c];v[c]=v[l];v[l]=aux;} }
}

Professora ANITA LOPES

printf("\n\"TOTAL DE ALGARISMOS\": %d ",totalAlgarismos(a)); fgetc(stdin); scanf("%c",&s);

int totalAlgarismos(long int a) {int c; if(a==0) return(a); else return(1+totalAlgarismos(a/10)); }

Exemplo 2:. Soma algarismos de um nmero.

#include <stdio.h> main() { int a, somaAlgarismos(int a); char s; printf("\nNUMERO: "); scanf("%d",&a); printf("\n\"SOMA DOS ALGARISMOS\": %d ",somaAlgarismos(a)); fgetc(stdin); scanf("%c",&s);

int somaAlgarismos(int a) {int c; if(a==0) return(a); if(a>0) return(a%10+somaAlgarismos(a/10));

} 10.9.2.1 Funes recursivas As funes recursivas, embora mais elegantes que as funes normais, so muito mais lentas e, muitas vezes de difcil compreenso. "Quando uma funo chama a si prpria, as novas variveis locais e os argumentos so alocados na pilha, e o cdigo da funo executado com esses novos valores a partir do incio. Uma chamada recursiva no faz uma nova cpia da funo. Somente os argumentos e as variveis so novos. Quando cada chamada recursiva retorna, as antigas variveis locais e os parmetros so removidos da pilha e a execuo recomea no ponto de chamada da funo dentro da funo dentro da funo. Tendo em vista que o local para os argumentos de funes e para as variveis locais a pilha e que a cada nova chamada criado uma cpia destas variveis na pilha, possvel ocorrer overflow da pilha (stack overflow) e o programa trancar."( FERNANDO CSAR COMPARSI DE CASTRO) Exemplo 1: Conta algarismos de um nmero. #include <stdio.h> main() { int a, totalAlgarismos(int a); char s; printf("\nNUMERO: "); scanf("%d",&a);
63

Exemplo 3:. Multiplica dois nmeros.

#include <stdio.h> main() { int a,b, mult(int m1,int m2); char s; printf("\nMultiplicando: "); scanf("%d",&a); printf("\nMultiplicador: "); scanf("%d",&b); printf("\n\"PRODUTO\": %d ",mult( a,b)); fgetc(stdin); scanf("%c",&s); } int mult(int m1,int m2) {int m; if(m1==0) return(m1); else return(m2+mult(m1-1,m2));

Exemplo 4: Soma os pares em um intervalo de 1 at n-1. #include <stdio.h> main() { int a, somaPares(int n);

64

Professora ANITA LOPES


char s; printf("\nNumero limite: "); scanf("%d",&a); if(a>1) {a--; printf("\n\"SOMA PARES\": %d ",somaPares( a)); } else printf("\nInvalido"); fgetc(stdin); scanf("%c",&s); } } int somaPares(int n) { if(n==0) return(n); else if(n%2==0) return(n+somaPares(n-1)); else return(somaPares(n-1)); } Exemplo 5: Conta algarismos e inverte um nmero.
#include <stdio.h> main() {int a,totalAlgarismos(int a);long int pot10(long int pot),inverte(long int a); char s; printf("\nNUMERO: "); scanf("%d",&a); printf("\n\"TOTAL DE ALGARISMOS\": %d ",totalAlgarismos(a)); printf("\n\"INVERTIDO\": %d ",inverte(a)); fgetc(stdin); scanf("%c",&s); } long int pot10(long int pot) {int inv; if(pot==0) return(1); if(pot>0) return(10*pot10(pot-1)); } int totalAlgarismos(long int a) {int c; if(a==0) return(a); else return(1+totalAlgarismos(a/10)); } long int inverte(long int a) {long int inv; if(totalAlgarismos(a)<1) return(a); else 65

Professora ANITA LOPES

return((a%10)*pot10(totalAlgarismos(a)-1)+ inverte (a/10)

);

Exemplo 6: Potncia de 10. #include <stdio.h> main() { int a, pot10(int x); char s; printf("\nQual potencia de 10: "); scanf("%d",&a); printf("\n\"POTENCIA\": %d",pot10(a)); fgetc(stdin); scanf("%c",&s); } int pot10(int pot) { if(pot==0) return(1); if(pot>0) return(10*pot10(pot-1)); }

Exemplo 7: Fatorial de um nmero. #include <stdio.h> main() { int a, fat(int m1); char s; printf("\nNumero: "); scanf("%d",&a); if(a>=0) printf("\n\"FATORIAL\": %ld ",fat(a)); else printf("\n\"NAO EXISTE FATORIAL\""); fgetc(stdin); scanf("%c",&s); }

long int fat(long int m1) { if(m1==0) return(1); else return(m1*fat(m1-1)); }

10.9.3 Funes com passagem por referncia

Para melhor compreenso deste item, precisaremos estudar PONTEIROS. A linguagem C tem uma dependncia to intensa com ponteiros que se costuma dizer: "quem no conhece ponteiros, no sabe programar em C". Ns j trabalhamos com ponteiros embora, claramente no tenhamos usado esta nomenclatura.

66

Professora ANITA LOPES


Quando estudamos o vetor de char(varivel string em algumas linguagens), fizemos uso de funes de entrada que deixavam claro que no havia necessidade de usar o operador &, operador de endereo: char pal[30]; scanf("%s", pal); gets( pal ); fgets( pal, 30, stdin); Continuando o estudo de matrizes, tomamos conhecimento que ao declaramos uma matriz, era feita uma alocao na MP para todos os elementos da matriz de forma contgua, porm s era guardado o primeiro endereo do primeiro elemento da matriz. Suponha a declarao: int vet[5]; e a tabela criada durante a execuo do programa: Nome da matriz vet No se lembrou ainda? Ento mais uma recordada: quando fazemos referncia a um elemento da matriz, usamos o nome da matriz e, entre pares de colchetes, a posio do elemento dentro da matriz. Tomemos como exemplo a declarao int vet[5]; : vet[0] vet[1] vet[2] vet[3] vet[4] lixo lixo lixo lixo lixo
60000 60001 60002 60003 60004 60005 60006 60007 60008 60009 60010 60011 60012 60013 60014 60015 60016 60017 60018 60019

Professora ANITA LOPES


11 PONTEIROS 11.1 Consideraes

A MP consiste de milhes de posies para armazenamento de dados, SO, programas, etc. O tamanho da MP depende da capacidade instalada em seu computador. Ns j vimos que, ao declaramos uma varivel, o "nome" dado associado a uma posio de memria (endereo) e quanto cada tipo de varivel ocupa na MP. A varivel do tipo struct ocupa o somatrio das variveis que a compe. O ponteiro uma varivel que contem o endereo de outra varivel. O uso de ponteiros nos d uma grande flexibilidade em programao, pois determinadas rotinas em outras linguagens s podem ser feitas em assembly.

Tipo da matriz int

Endereo 60000

Uma boa dica para entender como funciona a varivel ponteiro: voc viu no jornal um anncio de uma loja que vende notebook muito facilitado para alunos que esto cursando Engenharia ou Informtica. Ao ligar para a loja, voc pede o endereo e anota na sua agenda. Voc vai at loja(na linguagem C, &loja) para verificar as condies de pagamento e at dar uma "pechinchada"(na linguagem C, *loja) porque quem sabe voc, com muita choradeira consegue um bom desconto.

A varivel ponteiro precisa ser declarada como qualquer outra varivel.

Como se declara?

Ento podemos concluir que o ndice um deslocamento do endereo bsico (no exemplo, 60000) para chegarmos a outro elemento da matriz. Sendo int uma varivel de tamanho de 4 bytes, chegamos a seguinte frmula para o deslocamento: ndice * 4 + endereo bsico Exemplo: deslocando para o terceiro elemento: 2*4+60000=60008

tipo *nome da vrivel ponteiro ;

O que significa tipo para uma varivel ponteiro?

Quando declaramos uma varivel ponteiro, precisamos informar o tipo de varivel que ser apontada pelo ponteiro.

Quando usamos o operador & antes de uma varivel?

Quando precisarmos informar varivel ponteiro que ela armazenar o endereo de outra varivel. Neste momento, estaremos incializando a varivel ponteiro.

Na linguagem C, o nome de uma matriz sem o ndice, considerado um endereo para o comeo da matriz, portanto se vet representa o endereo bsico e o ndice representa o deslocamento, &vet[2] equivalente vet + 2.

Lembre-se de que sempre precisamos inicializar uma varivel ponteiro.

11.2 Atribuio de ponteiros Exemplo: . int x,*px; px=&x; .

Quando usamos o operador * antes da varivel ponteiro?


67

68

Professora ANITA LOPES


Quando desejarmos o contedo do endereo apontado pela varivel ponteiro. #include <stdio.h> main() {char s='F',x,*ps; ps=&s; x=*ps; printf("\ns= %c\tps= %u\tconteudo %c\tx=%c\n",s,ps,*ps,x); } do endereco apontado por ps=

Professora ANITA LOPES

(*px)++; #include <stdio.h> main() {int x=5,*px; px=&x; printf("\nendereco de x= %u\tconteudo de x= %d\n",&x,x); printf("\nconteudo de px= %u\tconteudo do endereco apontado por px= %d\n",px,*px); (*px)++; printf("\nendereco de px= %u conteudo do endereco apontado por px apos (*px)++ ;= %d\n\n",px,*px); }

Incrementou de 1 o contedo do endereo apontado por px.


11.3 Aritmtica de ponteiros Somente duas operaes so possveis: adio e subtrao. #include <stdio.h> main() {char s='F',x='B',*ps; ps=&s; printf("\nendereco de s= %u\nendereco apontado por ps= %u\nendereco de x= %u\nconteudo do endereco apontado por ps= %c\n\n",&s,ps,&x,*ps); ps--; /* o contedo de ps decrementado de 1 */ printf("\nendereco de s= %u\nendereco apontado por ps= %u\nendereco de x= %u\nconteudo do endereco apontado por ps= %c\n\n",&s,ps,&x,*ps); }

*px++; #include <stdio.h> main() {int x=5,*px; px=&x; printf("\nendereco de x= %u\tconteudo de x= %d\n",&x,x); printf("\nconteudo de px= %u\tconteudo do endereco apontado por px= %d\n",px,*px); *px++; printf("\nendereco de px= %u \n\n",px); }

Incrementou de 4 o endereo armazenado por px. Como a varivel do tipo int cada vez que o ponteiro incrementado de 1 o ponteiro desloca 4 posies.
Observao: No exemplo acima, fizemos uma subtrao(ps--;) e como ps um apontador char, ele apontou uma posio anterior, pois char um byte. Observe as expresses: (*px)++; e *px++; Mais exemplo: #include <stdio.h> main() {int x=5,y,*px; px=&x; y=*px+1; printf("\nconteudo
69

de

x=

%d\tconteudo

de

y=

%d\tconteudo

de

x=

70

Professora ANITA LOPES


%d\n\n",x,y,x); } }

Professora ANITA LOPES

11.4 Ponteiros e Matrizes A relao entre ponteiros e matrizes muita intensa como j falamos anteriormente e, por esta razo, vamos reescrever um programa j visto: #include <stdio.h> main() {int vet[5],l; for(l=0;l<5;l++) {printf("\ndigite %d numero: l+1); scanf("%d",vet+l); } printf("\n\n\nVETOR\n\n"); for(l=0;l<5;l++) printf("\n%d",*(vet+l)); printf("\n\n"); } #include <stdio.h> main() {int s[5],l,*ps; ps=s; ", for(l=0;l<5;l++) {printf("\ndigite %d numero: l+1); scanf("%d",ps+l); } printf("\n\n\nVETOR\n\n"); for(l=0;l<5;l++) printf("\n%d",*(ps+l)); printf("\n\n"); } ",

valor de ps = 2293576/* depois de inicializado */ endereo do primeiro elemento = 2293576 /* igual */ endereo do segundo elemento = 2293580 /*cresceu de 4 */ endereo do terceiro elemento = 2293584 /*cresceu de 4 */ endereo do quarto elemento = 2293588 /*cresceu de 4 */ endereo do quinto elemento = 2293592 /*cresceu de 4 */

LEIA COM ATENO AS CONSIDERAES ABAIXO E ANALISE O PROGRAMA Consideraes: 1. ps=s; ps foi associado ao endereo do primeiro elemento do vetor s(Relembrando que ao usarmos o nome do vetor sem ndice estamos na verdade fornecendo o endereo do comeo do vetor). 2. ps+l como j foi dito, voc pode somar ou subtrair inteiros. Neste caso, o contedo da varivel l, ser o incremento do ponteiro. 3. *( ps + l) o contedo da varivel l ser somado ao endereo bsico apontado por ps. A expresso *( ps + l) representa o contedo do endereo. Como ps um apontador para int, o ponteiro incrementado de 4 bytes, isto , embora ps seja incrementado de 1, em verdade, cada 1, equivale a 4. Veja com muita ateno o exemplo abaixo: #include <stdio.h> main() {int s[5],l,*ps; ps=s; printf("\nvalor de ps= %u",ps); for(l=0;l<5;l++) {printf("\ndigite %d numero: ", l+1);scanf("%d",ps+l); printf("\nvalor de ps=%u",ps+l); } printf("\n\n");
71

Reescrevendo um outro exemplo: #include <stdio.h> main() {int mat[3][2],l,c; for(l=0;l<3;l++) for(c=0;c<2;c++) { printf("\ndigite elemento %d-%d: ", l+1,c+1); scanf("%d",*(mat+l)+c); } printf("\n\n\nMATRIZ\n\n"); for(l=0;l<3;l++) { for(c=0;c<2;c++) printf("%d\t",*(*(mat+l)+c)); printf("\n"); } printf("\n\n"); } #include <stdio.h> main() {int mat[3][2],l,c,*p; p=&mat[0][0]; for(l=0;l<3;l++) for(c=0;c<2;c++) { printf("\ndigite elemento %d-%d: ", l+1,c+1); scanf("%d",(p+2*l+c)); } printf("\n\n\nMATRIZ\n\n"); for(l=0;l<3;l++) { for(c=0;c<2;c++) printf("%d\t",*(p+2*l+c)); printf("\n"); } printf("\n\n"); }

72

Professora ANITA LOPES


LEIA COM ATENO AS CONSIDERAES ABAIXO Consideraes: 1. p=&mat[0][0]; p foi associado ao endereo do primeiro elemento da primeira linha da matriz mat. 2. (p+2*l+c)); como cada vez que o ponteiro incrementado ele desloca tantas posies quanto for o tamanho da varivel que ele aponta, para se chegar ao endereo de um elemento da matriz, usamos a seguinte frmula:
nmero de colunas da matriz * nmero da linha desejada + nmero da coluna na linha

Professora ANITA LOPES

3. *(p+2*l+c) o contedo da varivel l multiplicado por 2(nmero de colunas da matriz), somado com c(nmero da coluna desejada na linha) e somado ao endereo bsico apontado por p A expresso *(p+2*l+c) representa o contedo do endereo.

Exemplo 2: #include <stdio.h> main() {int s[5],l,*ps; ps=s; for(l=0;l<5;l++) {printf("\ndigite numero:"); scanf("%d",ps+l); } printf("\n\n\nVETOR\n\n"); for(l=0;l<5;l++) printf("\n%d",*(ps+l)); printf("\n\n"); }

#include <stdio.h> main() { int *p[5]; int l; for(l=0;l<5;l++) {printf("\nDigite numero: "); scanf("%d",p+l);} printf("\n\nNumeros\n"); for(l=0;l<5;l++) printf("\n%d",p[l]); /* voce poderia usar *(p+l) */ printf("\n");

11.5 Matrizes de Ponteiros No existe nenhum problema de criarmos matrizes para ponteiros e, normalmente fazemos para armazenar mensagens de erros. Para se declarar uma matriz de ponteiros, usamos: tipo *nome_da_matriz_de_ponteiros[ tamanho]; Exemplo 1: #include <stdio.h> main() {int n;char s;void error(int num); do {printf("\n1 msg de erro\n2 msg de erro\n3 msg de erro\n4 msg de erro\n5 Sair\nOpcao: "); scanf("%d",&n); switch(n) {case 1: error(0);break; case 2: error(1);break; case 3: error(2);break; case 4: error(3);break; case 5: printf("\nSAINDO");break; default: printf("\nOPCAO INVALIDA\n"); } }while(n!=5); fgetc(stdin);scanf("%c",&s); } void error(int num) { char *erro[]= { "nao possso abrir o arquivo","erro de leitura","erro de escrita", "falha na midia" }; printf("\n\"%s\"\n",erro[num]); }
73

Exemplo 3: Armazena sexo de 5 pessoas #include <stdio.h> #include <ctype.h> main() { char *p[5]; int l; for(l=0;l<5;l++) {printf("\nDigite sexo: ");scanf("%c",p+l);fgetc(stdin); (int)*(p+l)=toupper((int)*(p+l)); } printf("\nSexo\n"); for(l=0;l<5;l++) printf("\n%c",*(p+l)); printf("\n"); }

74

Professora ANITA LOPES

Professora ANITA LOPES

int c; printf("\nDigite palavra: "); fgets(pal,30,stdin); p=pal; for(c=strlen(pal)-1;c>=0;c--) {*(p+c)=toupper(*(p+c)); printf("%c",*(p+c)); } printf("\n"); }

Exemplo 4: #include <stdio.h> main() {int mat[3][2],l,c; for(l=0;l<3;l++) for(c=0;c<2;c++) { printf("\ndigite elemento %d%d: ", l+1,c+1); scanf("%d",*(mat+l)+c); } printf("\n\n\nMATRIZ\n\n"); for(l=0;l<3;l++) { for(c=0;c<2;c++) printf("%d\t",*(*(mat+l)+c)); printf("\n"); } printf("\n\n"); } }

#include <stdio.h> main() { int *p[3][2]; int l,c; for(l=0;l<3;l++) for(c=0;c<2;c++) { printf("\ndigite elemento %d%d: ", l+1,c+1); scanf("%d",*(p+l)+c); } printf("\nMATRIZ\n"); for(l=0;l<3;l++) {for(c=0;c<2;c++) printf("\%d\t",*(*(p+l)+c)); printf("\n"); }

Vejamos o programa acima usando ponteiro. #include <stdio.h> #include <ctype.h> main() { char *p; int c,t=0; printf("\nDigite palavra: ");fgets(p,30,stdin); for(c=0;p[c];c++) {*(p+c)=toupper(*(p+c));t++;} for(c=t;c>=0;c--) printf("%c",p[c]);/* voce poderia usar *(p+c) */ printf("\n"); } Observao:Um ponteiro tambm pode ser indexado: p[l] idntico a *(p+l), porm mais lento indexar do que usar o operador *.

VIU COMO A MATRIZ TRATADA COMO PONTEIRO NA LINGUAGEM C ?

QUE TAL REFAZER TODOS OS EXERCCIOS DE VETORES, USANDO PONTEIROS? 11.6 Ponteiros e Strings J vimos que a linguagem C trata as strings como vetor de char, logo uma matriz e tem uma relao intensa com os ponteiros como j falamos. Comparao de Ponteiros

#include <stdio.h> #include <string.h> #include <ctype.h> main() { char pal[30],*p;


75

possvel usar operadores relacionais para comparar ponteiros. O resultado ser uma comparao entre a posio dos endereos apontados pelos dois ponteiros. A alocao da variveis na MP feita da direita para esquerda quando declaramos as variveis. No programa, troque a linha: int y=3,x=2,*px,*py; pela linha: int x=2,y=3,*px,*py;

Observe a alterao dos endereos de x e y.

76

Professora ANITA LOPES


#include <stdio.h> main() {int y=3,x=2,*px,*py; px=&x; py=&y; printf("\nendereco de x= %u\tendereco de y= %u\n",px,py); if(px<py) printf("\npx aponta para um endereco menor do que py\n"); else printf("\npx aponta para um endereco maior do que py\n"); printf("\n\n"); }

Professora ANITA LOPES

Exemplo: #include <stdio.h> main() { int p=5,*p1,**p2; p1=&p; p2=&p1; printf("\np= %d\tponteiro %d\n\n",p,*p1,**p2); }

p1=

%d\tponteiro

para

ponteiro

p2=

Observao: Ns teremos oportunidade de estudarmos mais profundamente este tpico quando chegramos em funes.

11.8 Ponteiros para Funes

11.7 Ponteiros para Ponteiros Suponha que uma pessoa muito organizada e tem seus programas armazenados em pastas de acordo com as linguagens de programao que ela domina. Ela tem um arquivo, feito no Word chamado: Linguagens-Programas.doc que contem nomes de vrios arquivos .doc para que ela possa saber em que pasta se encontra cada programa que ela acha importante. Entenda: est anotado no arquivo Linguagens-Programas, o nome do arquivo Programas-C.doc que contem a localizao do arquivo struct.c.

Ns usamos at o momento ponteiros que apontavam para endereos de memrias onde dados estavam armazenados, mas agora vamos estudar que um ponteiro tambm pode apontar para uma funo. Como declarar um ponteiro para funo?

tipo (*nome_do_ponteiro)(lista de argumentos);

Como atribuir o endereo de uma funo para um ponteiro?

nome_do_ponteiro = &nome_da_funo;

declarao: tipo **nome da varivel ponteiro para ponteiro; Sendo assim: Linguagens-Programas.doc **p1 Programas-C.doc *p2 struct.c p

#include <stdio.h> main() { float n1,n2,temp, fun(float a,float b); float (*pt)(float,float);/* declaracao do ponteiro para funo */ char s; pt = &fun; printf("\nNumero 1: "); scanf("%f",&n1); printf("\nNumero 2: "); scanf("%f",&n2); temp = (*pt)(n1,n2); /* eqivale a: temp = fun(10,20);*/ printf("\nQuociente: %.2f",temp); fgetc(stdin);scanf("%c",&s); } float fun(float a,float b){ return(a/b); }
77

78

Professora ANITA LOPES

Professora ANITA LOPES

11.9 Ponteiros para Estruturas Quando se passa uma estrutura para uma funo, gera-se uma sobrecarga da pilha implicando em perda de tempo na transferncia de dados entre uma funo chamadora e funo chamada. Tendo em vista isto, aconselha-se a passar para a funo somente um ponteiro como argumento, pois estaremos passando o endereo da estrutura, tornando a chamada extremamente rpida .

{int vet[5],l; for(l=0;l<5;l++) {printf("\ndigite %d numero: l+1); scanf("%d",&vet[l]); } printf("\n\n\nVETOR\n\n"); for(l=0;l<5;l++) printf("\n%d",vet[l]); printf("\n\n"); }

{int vet[5],l; for(l=0;l<5;l++) ", {printf("\ndigite %d numero: l+1); scanf("%d",vet+l); } printf("\n\n\nVETOR\n\n"); for(l=0;l<5;l++) printf("\n%d",*(vet+l)); printf("\n\n");

",

Existe duas formas de se acessar o elemento atravs do ponteiro: 1. ...(*ptr).elemento 2. ...ptr ->elemento /* mais recomendvel */
Para se atribuir o endereo de uma estrutura a um ponteiro, usamos: ptr= &nome; Veja o exemplo 1 onde passamos para uma funo um ponteiro de estrtura: #include <stdio.h> #include <ctype.h> #include <string.h> struct CADASTRO { char nome[30]; float nota; }; void imp(struct CADASTRO *m); main() {struct CADASTRO aluno,*p; char c; printf("\nNome : "); fgets(aluno.nome,30,stdin); printf("\nNota: "); scanf("%f",&aluno.nota); p=&aluno; imp(p); fgetc(stdin);scanf("%c",&c); } void imp(struct CADASTRO *m) { int c; for(c=0;c<strlen(m->nome);c++) m->nome[c]=toupper(m->nome[c]); printf("\nDENTRO DA FUNCAO\n"); printf("\nNOME: %s",m->nome); printf("\nNOTA: %.1f",m->nota); } Exemplo 2: Observe as duas solues abaixo para matrizes unidimensionais: #include <stdio.h> #include <stdio.h> main() main()
79

Exemplo 3: Observe as duas solues abaixo para matrizes bidimensionais: #include <stdio.h> #include <stdio.h> main() main() {int mat[3][2],l,c; {int mat[3][2],l,c; for(l=0;l<3;l++) for(l=0;l<3;l++) for(c=0;c<2;c++) for(c=0;c<2;c++) { printf("\ndigite elemento %d{ printf("\ndigite elemento %d%d: ", l+1,c+1); %d: ", l+1,c+1); scanf("%d",&mat[l][c]); scanf("%d",*(mat+l)+c); } } printf("\n\n\nMATRIZ\n\n"); printf("\n\n\nMATRIZ\n\n"); for(l=0;l<3;l++) for(l=0;l<3;l++) { for(c=0;c<2;c++) { for(c=0;c<2;c++) printf("%d\t",mat[l][c]); printf("%d\t",*(*(mat+l)+c)); printf("\n"); printf("\n"); } } printf("\n\n"); printf("\n\n"); }

Vamos explicar melhor as expresses em negrito: &mat[l][c], mat[l][c], *(mat+l)+c) e *(*(mat+l)+c), supondo l=1 e c=1: 1. &mat[1][1] endereo do elemento da matriz m que se encontra na linha 1 e coluna 1. 2. mat[1][1] contedo do elemento da matriz m que se encontra na linha 1 e coluna 1. 3. *(mat+1 ) +1) mat[0][0] lixo
60000 ... 6003

mat[0][1] lixo
60004 ... 6007

mat[1][0] lixo 1a linha

mat[1][1] lixo

mat[2][0] lixo

mat[2][1] lixo

60008

...

60011

60012

...

60015

60016

...

60019

60020

...

60023

2a linha

3a linha

Deslocamento entre linhas: a) mat um array de 3 por 2 e convertida para um endereo para a 1a linha60000. b) mat + 1 um endereo para a 2a linha, iniciando em 60008- (equivale: 60000 + 2(colunas) * 1(deslocamento) * 4(bytes)). Deslocamento entre colunas de uma linha:

80

Professora ANITA LOPES


c) *(mat +1) convertida para um endereo para o primeiro inteiro da 2a linha (comea em 60008 e termina em 60011). d) *(mat +1) + 1 um endereo para o segundo inteiro da 2a linha (comea em 60012 e termina em 60015, pois 60008 + 4(bytes) igual 60012). e) *( *(mat +1) + 1 ) - o segundo inteiro da 2a linha. Observao: A aritmtica de ponteiros(uso do * ), na maioria da vezes, mais rpida e eficiente em se tratando de um acesso seqencial do que a indexao de matrizes, porm no devemos achar que nunca mais usaremos a indexao porque a aritmtica de ponteiros pode ser to complexa e confusa que,s vezes, mais fcil codificar usando a indexao, principalmente se for usada randomicamente. Consideraes sobre FUNES 1. Quando usamos funes, nossos programas ficam menores, pois no temos que repetir o cdigo vrias vezes. 2. Os prottipos de funo servem para declarar as funes, isto , indicar para o compilador qual o seu nome, tipo de retorno e o nmero e tipos dos parmetros 3. As variveis declaradas em uma funo s so acessveis na funo 4. Funes podem ser chamadas por outras funes, mas no podem ser definidas dentro de outras funes 5. Uma funo que no retorna nada deve ser declarada como void 6. Os parmetros recebidos por uma funo com passagem por valor armazenam cpias das variveis usadas na chamada da funo 7. Quando desejarmos alterar os contedos das variveis que so passadas como parmetros para uma funo, devemos declar-las como ponteiros na funo 8. Quando utilizamos um vetor como parmetro para uma funo, estamos fornecendo o endero do primeiro elemento do vetor 9. Em um programa C, as funes de um programa podem estar em vrios arquivo.c 10. Variveis globais so conhecidas e podem ser alteradas por todas as funes do programa 11. A funo scanf necessita receber como parmetro o endereo da varivel de entrada, porque ela precisa alterar esta varivel. (Lembre-se de usar o operador & para variveis numricas e char de um caracter. A varivel vetor de char no precisa, pois j um endereo) 12. As bibliotecas contm o prottipo de algumas funes da biblioteca do C 13. Funes no rodam mais rpido 14. Funes modularizam o programa e podem ser testadas em separado Retorno da funo 1. Uma funo pode ter vrios comando return 2. Voc s pode retornar o contedo de uma varivel atravs do comando return 3. Uma funo pode retornar um ponteiro 4. O retorno da funo main feito para o sistema operacional
81

Professora ANITA LOPES

Consideraes sobre PONTEIROS 1. Aps a atribuio pa=&a[0]; pa e a possuem valores idnticos, isto , apontam para o mesmo endereo A atribuio pa=&a[0]; pode ser escrita como pa=a; a[i] pode ser escrito como *(a+i) &a[i] e a+i se equivalem pa++ e' uma operao invalida 2. 3. 4. 5.

12 ARQUIVO BINRIO

uma seqncia de bytes com uma correspondncia de 1 para 1, no existindo traduo. Permite a gravao de grandes dados de blocos, sendo ideal para estruturas e matrizes. Este o tipo mais comum em linguagem C.

1) FILE(escrito em maiscula ) Estrutura pr-definida para declarar o apontador de arquivo.

FILE *nome da varivel ponteiro de arquivo ;

Exemplo: FILE *arq ; Varivel ponteiro de arquivo.Tambm chamado de apontador de arquivo define nome, status , posio do arquivo, se o arquivo est sendo lido ou gravado

2) Abertura do arquivo: fopen() sintaxe:

nome da varivel ponteiro = fopen( "nome do arquivo" , "tipo de abertura");

#include <stdio.h> main() { FILE *arq; arq=fopen("criacao.dat","ab+"); if(arq) { printf("\nArquivo criado com sucesso!\n\n"); fclose(arq); } else printf("\nNAO foi criado o arquivo\n"); }

82

Professora ANITA LOPES

Professora ANITA LOPES

while( feof(nome da varivel ponteiro)==0)

ou

while( !feof(nome da varivel ponteiro))

leia assim: ENQUANTO NO FOR O FIM DO ARQUIVO

6) Escrevendo no arquivo: fwrite() sintaxe: fopen() usa um nome externo e realiza algumas tarefas, inclusive "negociando" com o SO. Retorna um apontador que ser usado em leitura e escrita no arquivo. tipos de abertura para arquivos binrios: rb wb ab rb+ wb+ ab+ abrir um arquivo binrio para leitura. O arquivo precisa existir. abrir um arquivo binrio para gravao. Se o arquivo existir ser destrudo e inicializado. Se no existir, ser criado abrir um arquivo binrio para gravao. Se o arquivo existir, os dados sero adicionados ao final. Se no existir, ser criado. abrir um arquivo binrio para leitura e gravao. O arquivo precisa existir e pode ser atualizado. abrir um arquivo binrio para leitura e gravao. Se o arquivo existir ser destrudo e inicializado. Se no existir, ser criado abrir um arquivo binrio para atualizaes e para adicionar dados ao fim do arquivo existente ou criar um novo arquivo para leitura e gravao.

fwrite( p, t, q, p1 );

p ponteiro que localiza o dado na MP a ser gravado no arquivo t- tamanho do que vai ser gravado, fornecido pela funo sizeof( argumento) q- quantidade a ser gravada p1 ponteiro de arquivo Exemplo:

fwrite(&cad, sizeof(cad), 1, arq );

escreve o contedo armazenado na estrutura de nome cad, cujo tamanho foi fornecido por sizeof, consultando o ponteiro de arquivo.

fwrite(vet, sizeof(vet), 1, arq );

3) Fechamento do arquivo: fclose() sintaxe: fclose(nome da varivel ponteiro);

escreve o contedo armazenado em um vetor de nome vet, cujo tamanho foi fornecido por sizeof, consultando o ponteiro de arquivo. Observe que o operador de endereo no est presente, pois o vetor sempre localizado pela primeira posio, logo j e um endereo.

7) Lendo do arquivo: fread() sintaxe:

4) Constante simblica: NULL (escrita em maiscula ) NULL uma macro definida em stdio.h. Representa um ponteiro nulo. Quando se tenta ler um arquivo e ele no existe ou, por qualquer motivo no pode ser aberto. Exemplo: if( arq==NULL) printf("\nArquivo nao pode ser aberto\n"); 5) Verificando o fim do arquivo: feof() Esta funo retorna 0 se o final do arquivo no foi atingido e retorna 1, se foi. sintaxe:

fread( p, t, q, p1 );

p ponteiro que localiza a posio na MP onde o dado lido arquivo dever ser gravado t- tamanho do que vai ser lido, fornecido pela funo sizeof( argumento) q- quantidade a ser lidoa p1 ponteiro de arquivo

Exemplo:

fread(&cad, sizeof(cad), 1, arq );

l do arquivo o dado e escreve o contedo na estrutura de nome cad, cujo tamanho foi fornecido por sizeof, consultando o ponteiro de arquivo.
83

84

Professora ANITA LOPES

Professora ANITA LOPES

fread(vet, sizeof(vet), 1, arq ); l do arquivo todo os dados de um vetor e escreve o contedo no vetor vet, cujo tamanho foi fornecido por sizeof, consultando o ponteiro de arquivo. Observe que o operador de endereo no est presente, pois o vetor sempre localizado pela primeira posio, logo j e um endereo.

Ler dados do teclado para um vetor inteiro e grava no arquivo, apagando o contedo do banco de dados vet-gravar.c
#include <stdio.h> #define TAM (10) main() {int vet[TAM],l; FILE *arq; for(l=0;l<TAM;l++) {printf("\n%d numero: ",l+1); scanf("%d",&vet[l]); } arq=fopen("vetor","wb"); if(arq==NULL) printf("\nArquivo nao pode ser aberto\n"); else {fwrite(vet,sizeof(vet),1,arq); fclose(arq); } }

Ler dados do teclado para um vetor inteiro(matricula) e um vetor real(mdia) e grava no arquivo, apagando o contedo do banco de dados vet-gravar1.c #include <stdio.h> #define TAM (10) main() {float vet[TAM];int mat[TAM],l; FILE *arq; for(l=0;l<TAM;l++) {printf("\n matricula %d: ",l+1); scanf("%d",&mat[l]); printf("\nnota: "); scanf("%f",&vet[l]); } arq=fopen("vetor","wb"); if(arq==NULL) printf("\nArquivo nao pode ser aberto\n"); else {fwrite(vet,sizeof(vet),1,arq); fwrite(mat,sizeof(mat),1,arq); fclose(arq); } }

Ler dados do arquivo e grava em um vetor na MP vet-ler.c


#include <stdio.h> #define TAM (10) main() {int vet[TAM],l; FILE *arq; arq=fopen("vetor","rb"); if(arq==NULL) printf("\nArquivo nao pode ser aberto\n"); else {fread(vet,sizeof(vet),1,arq); fclose(arq); for(l=0;l<TAM;l++) printf("\n%d %d ",l+1,vet[l]); } printf("\n\n"); }

Ler dados do arquivo e grava em dois vetores na MP vet-ler1.c #include <stdio.h> #define TAM (10) main() {float vet[TAM];int mat[TAM],l; FILE *arq; arq=fopen("vetor","rb"); if(arq==NULL) printf("\nArquivo nao pode ser aberto\n"); else {fread(vet,sizeof(vet),1,arq);fread(mat,sizeof(vet),1,arq); fclose(arq); printf("\n\nMatr.\tMedia\n\n"); for(l=0;l<TAM;l++) printf("\n%3d\t%5.1f ",mat[l],vet[l]); } printf("\n\n"); }

Ler dados do teclado para uma estrutura e grava no arquivo, apagando gravar.c
#include <stdio.h> main() {struct REGISTRO {int mat; float media; }cad; FILE *arq; 85

86

Professora ANITA LOPES


arq=fopen("base1.dat","wb"); if(arq==NULL) printf("\nArquivo nao foi criado\n"); else { printf("\nArquivo criado com sucesso\n"); printf("\nDigite matricula: "); scanf("%d",&cad.mat); printf("\nDigite media: "); scanf("%f",&cad.media); fwrite(&cad,sizeof(cad),1,arq); fclose(arq); } }

Professora ANITA LOPES

Ler dados do arquivo e grava em uma estrutura, imprimindo na tela, vrias vezes ler1.c

Ler dados do arquivo e grava em uma estrutura na MP ler.c


#include <stdio.h> main() {struct REGISTRO {int mat; float media; }cad; FILE *arq; arq=fopen("base1.dat","rb"); if(arq==NULL) printf("\nArquivo nao existe\n"); else { fread(&cad,sizeof(cad),1,arq); printf("\nArquivo lido com sucesso\n"); printf("\nMatricula: %d\tMedia: %.1f",cad.mat,cad.media); fclose(arq); } printf("\n\n"); }

#include <stdio.h> main() {struct REGISTRO {int mat; float media; }cad; FILE *arq; arq=fopen("base1.dat","rb"); if(arq==NULL) printf("\nArquivo nao existe\n"); else { fread(&cad,sizeof(cad),1,arq); printf("\nArquivo lido com sucesso\n"); while( !feof(arq)) { printf("\nMatricula: %d\tMedia: %.1f",cad.mat,cad.media); fread(&cad,sizeof(cad),1,arq); } fclose(arq); } printf("\n\n"); }

Consulta Arquivo consulta.c

Ler dados do teclado para uma estrutura e grava no arquivo anexando gravar1.c
#include <stdio.h> main() {struct REGISTRO {int mat; float media; }cad; FILE *arq; arq=fopen("base1.dat","ab"); if(arq==NULL) printf("\nArquivo nao foi criado\n"); else { printf("\nArquivo criado com sucesso\n"); printf("\nDigite matricula: "); scanf("%d",&cad.mat); printf("\nDigite media: "); scanf("%f",&cad.media); fwrite(&cad,sizeof(cad),1,arq); fclose(arq); } }

#include <stdio.h> main() { struct REGISTRO { int mat; float media; }cad; FILE *arq; int ACHOU=0, mat_proc,tam=sizeof(cad),cr=0; arq=fopen("base1.dat","rb"); if(arq==NULL) printf("\nArquivo nao foi criado\n"); else { printf("\nDigite matricula de procura: ");scanf("%d",&mat_proc); fread(&cad,sizeof(cad),1,arq); while( !feof(arq) && ACHOU==0) { cr++; if(mat_proc==cad.mat) { printf("\nMatricula: %d\tMedia: %.1f",cad.mat,cad.media); ACHOU=1; } else fread(&cad,sizeof(cad),1,arq); } if(ACHOU==0) printf("\nMatricula nao encontrada\n"); else printf("\nRegistro: %d",cr); fclose(arq); } printf("\n\n");

}
87

88

Professora ANITA LOPES


Consulta e altera dados do registro alteracao.c
#include <stdio.h> #include <ctype.h> main() { struct REGISTRO { int mat; float media; }cad; FILE *arq; int ACHOU=0, mat_proc,tam=sizeof(cad),cr=0; char ch; fpos_t pos; arq=fopen("base1.dat","rb"); if(arq==NULL) printf("\nArquivo nao foi criado\n"); else { printf("\nDigite matricula de procura: ");scanf("%d",&mat_proc); fgetpos(arq,&pos); fread(&cad,tam,1,arq); while( !feof(arq) ) { cr++; if(mat_proc==cad.mat) { ACHOU=1;break; } else { fgetpos(arq,&pos); fread(&cad,tam,1,arq); } } fclose(arq); if(ACHOU==0) printf("\nMatricula nao encontrada\n"); else { printf("\nROTINA DE ALTERACAO\n"); arq=fopen("base1.dat","rb+"); printf("\nMatricula: %d\tMedia: %.1f",cad.mat,cad.media); printf("\nAlterar matricula(s/n): "); fgetc(stdin);scanf("%c",&ch); if(toupper(ch)=='S') { printf("\nNova Matricula: "); scanf("%d",&cad.mat);} printf("\nAlterar media(s/n): "); fgetc(stdin);scanf("%c",&ch); if(toupper(ch)=='S') { printf("\nNova Media: "); scanf("%f",&cad.media); } fsetpos(arq,&pos); fwrite(&cad,tam,1,arq); fclose(arq); } } printf("\n\n");

Professora ANITA LOPES


Consulta e exclui registro exclusao.c

#include <stdio.h> #include <ctype.h> main() { struct REGISTRO { int mat; float media; }cad,aux; FILE *arq,*TEMP; int ACHOU=0, mat_proc,tam=sizeof(cad),cr=0,reg; char ch; fpos_t pos; arq=fopen("base1.dat","rb"); if(arq==NULL) printf("\nArquivo nao foi criado\n"); else { printf("\nDigite matricula de procura: "); scanf("%d",&mat_proc); fgetpos(arq,&pos); fread(&cad,tam,1,arq); while( !feof(arq) ) { cr++; if(mat_proc==cad.mat) { ACHOU=1;break; } else { fgetpos(arq,&pos); fread(&cad,tam,1,arq); } } fclose(arq); } if(ACHOU==0) printf("\nMatricula nao encontrada\n"); else { printf("\nROTINA DE EXCLUSAO\n"); arq=fopen("base1.dat","rb"); TEMP=fopen("TEMP","wb"); fsetpos(arq,&pos); fread(&cad,tam,1,arq); printf("\nMatricula: %d\tMedia: %.1f",cad.mat,cad.media); printf("\nExclui este registro(s/n): "); fgetc(stdin);scanf("%c",&ch); if(toupper(ch)=='S') { aux=cad;rewind(arq); fread(&cad,tam,1,arq); while( !feof(arq)) { if(cad.mat !=aux.mat) fwrite(&cad,tam,1,TEMP); fread(&cad,tam,1,arq); } fclose(arq); fclose(TEMP); remove("base1.dat"); rename("TEMP","base1.dat"); } } printf("\n\n");

}
89

90

Professora ANITA LOPES

Professora ANITA LOPES

Entrar com matrcula, nome, pr1 e pr2. Calcular e armazenar a mdia aritmtica, usando struct. Gravar o registro no disco e depois ler o registro do disco.
#include <stdio.h> main() { struct REGISTRO {char nome[30]; int mat; float pr1,pr2,media; } cad; FILE *arq; arq=fopen("registro0.dat","wb+"); printf("\nDigite matricula:"); scanf("%d",&cad.mat); fgetc(stdin); printf("\nDigite nome:"); fgets(cad.nome,30,stdin); printf("\nDigite nota pr1:"); scanf("%f",&cad.pr1); printf("\nDigite nota pr2:"); scanf("%f",&cad.pr2); cad.media=(cad.pr1+cad.pr2)/2; fwrite(&cad,sizeof(cad),1,arq); rewind(arq); fread(&cad,sizeof(cad),1,arq); printf("\n\nmatricula: %d\tnome: %sPR1: %.1f\tPR2: cad.mat, cad.nome, cad.pr1, cad.pr2,cad.media); fclose(arq); printf("\n\n"); %.1f\tMedia: %.1f", }

Concluso: O fato de voc ter usado o tipo de abertura: "wb" apagou todo o contedo do arquivo.

3. Troque o tipo de acesso: onde se l: arq=fopen("registro0.dat","wb+"); leia-se: arq=fopen("registro0.dat","ab+"); 4. Salve, compile e execute:

1. Execute outra vez o arquivo. 2. Observe que s permaneceram os novos dados digitados.

5. No entendeu porque voc digitou novo registro e s apareceu o primeiro? Voc s tem um comando de leitura, logo precisa fazer uso de uma estrutura de repetio para que possa ler todos os registros gravados.

Onde se l: fread(&cad,sizeof(cad),1,arq); printf("\n\nmatricula: %d\tnome: %sPR1: %.1f\tPR2: %.1f\tMedia: %.1f", cad.mat, cad.nome, cad.pr1, cad.pr2,cad.media);

Leia-se: fread(&cad,sizeof(cad),1,arq); while( !feof(arq) ) { printf("\n\nmatricula: %d\tnome:


91

%sPR1:

%.1f\tPR2:

%.1f\tMedia:

92

Professora ANITA LOPES


%.1f",cad.mat,cad.nome,cad.pr1,cad.pr2,cad.media); fread(&cad,sizeof(cad),1,arq); } 6. Salve, compile e execute:

Professora ANITA LOPES

scanf("%f",&cad.pr1); printf("\nDigite nota pr2:"); scanf("%f",&cad.pr2); cad.media=(cad.pr1+cad.pr2)/2; fwrite(&cad,sizeof(cad),1,arq); rewind(arq); fread(&cad,sizeof(cad),1,arq); while( !feof(arq) ) { printf("\n\nmatricula: %d\tnome: %sPR1: %.1f\tPR2: %.1f\tMedia: %.1f", cad.mat,cad.nome,cad.pr1,cad.pr2,cad.media); fread(&cad,sizeof(cad),1,arq); } fclose(arq); printf("\n\n"); }

Percebemos que, embora o arquivo v sendo anexado, temos que ficar executando o programa vrias vezes para entrarmos com novo registro, por esta razo, colocaremos a entrada dos dados dos registros dentro de uma repetio,

7. Execute novamente:

Veja como ficou o programa:


#include <stdio.h> main() { struct REGISTRO {char nome[30]; int mat; float pr1,pr2,media; } cad; FILE *arq; arq=fopen("registro0.dat","ab+"); printf("\nDigite matricula:"); scanf("%d",&cad.mat); fgetc(stdin); printf("\nDigite nome:"); fgets(cad.nome,30,stdin); printf("\nDigite nota pr1:"); 93

#include <stdio.h> main() { struct REGISTRO {char nome[30]; int mat; float pr1,pr2,media; } cad; FILE *arq; arq=fopen("registro1.dat","ab+"); printf("\nDigite matricula ou 0 para terminar:"); scanf("%d",&cad.mat); while(cad.mat!=0) { fgetc(stdin); printf("\nDigite nome:"); fgets(cad.nome,30,stdin); printf("\nDigite nota pr1:"); scanf("%f",&cad.pr1); printf("\nDigite nota pr2:"); scanf("%f",&cad.pr2); cad.media=(cad.pr1+cad.pr2)/2; fwrite(&cad,sizeof(cad),1,arq); printf("\nDigite matricula ou 0 para terminar:"); scanf("%d",&cad.mat); } rewind(arq); fread(&cad,sizeof(cad),1,arq); while( !feof(arq) ) { printf("\n\nmatricula: %d\tnome: %sPR1: %.1f\tPR2: %.1f\tMedia: %.1f", cad.mat,cad.nome,cad.pr1,cad.pr2,cad.media); fread(&cad,sizeof(cad),1,arq); } fclose(arq); printf("\n\n"); }

94

Professora ANITA LOPES

Professora ANITA LOPES

for(;;) { printf("\nDigite nota pr2:"); scanf("%f",&cad.pr2); if(cad.pr2>=0 && cad.pr2<=10)break; printf("\nDigite novamente. Invalida!\n"); }

Veja a verso "quase final" porque sempre temos algo a acrescentar:


#include <stdio.h> #include <string.h> #include <ctype.h> main() { struct REGISTRO {char nome[30]; int mat; float pr1,pr2,media; } cad; char lixo[30]; int c; FILE *arq; arq=fopen("registro.dat","ab+"); printf("\nDigite matricula ou 0 para terminar:"); scanf("%d",&cad.mat); while(cad.mat!=0) { fgetc(stdin); printf("\nDigite nome:"); fgets(cad.nome,30,stdin); /* em italico, as protecoes */ for(c=0;c<strlen(cad.nome);c++) cad.nome[c]=toupper(cad.nome[c]); if(strlen(cad.nome)==29) { if(cad.nome[28]=='\n')cad.nome[28]='\0'; else fgets(lixo,30,stdin); } else { cad.nome[strlen(cad.nome)-1]='\0' ; while(strlen(cad.nome)<29) strcat(cad.nome," "); cad.nome[29]='\0'; } for(;;) { printf("\nDigite nota pr1:"); scanf("%f",&cad.pr1); if(cad.pr1>=0 && cad.pr1<=10)break; printf("\nDigite novamente. Invalida!\n"); } 95

cad.media=(cad.pr1+cad.pr2)/2; fwrite(&cad,sizeof(cad),1,arq); printf("\nDigite matricula ou 0 para terminar:"); fgetc(stdin); scanf("%d",&cad.mat); } rewind(arq); fread(&cad,sizeof(cad),1,arq); while( !feof(arq) ) { printf("\n%d\t%s\t%.1f\t%.1f\t%.1f",cad.mat,cad.nome,cad.pr1,cad.pr2,cad.media); fread(&cad,sizeof(cad),1,arq); } fclose(arq); printf("\n\n"); }

A utilizao de funes passa a ser vantajosa a partir do momento que nossos programas se tornam muito extensos. #include <stdio.h> #include <string.h> #include <ctype.h> struct CADASTRO { char nome[30]; float nota; }aluno[30],x; FILE *arq; int op,a,n=0,b,flag; main() { char c; do {

96

Professora ANITA LOPES


printf("\n\n\nMENU\n\n"); printf("\n1 - Le nomes e notas do arquivo em disco\n"); printf("\n2 - Grava nomes e notas do arquivo em disco\n"); printf("\n3 - Armazena nomes e notas na MP\n"); printf("\n4 - Ordena\n"); printf("\n5 - Lista\n"); printf("\n6 - Sair\n"); printf("\nOpcao: "); scanf("%d",&op); fgetc(stdin); switch(op) { } } case 1:le_disco(); break; case 2:grava_disco(); break; case 3:armazenaMP(); break; case 4: ordena(); break; case 5: lista(); break; case 6: printf("\nprograma feito por Anita\n"); break; default: printf("\nOpcao invalida\n"); } scanf("%c",&c); } while(op!=6); } le_disco() { flag=0;arq=fopen("cadastro.rec","rb"); if( arq==NULL) printf("\nNao existe arquivo\n"); else { while(fread(&aluno[n],sizeof(aluno[n]),1,arq)==1) n++; fclose(arq); flag=1; printf("\nArquivo lido!\n"); } } grava_disco() { if(n<1) printf("\nLista vazia\n"); else { arq=fopen("cadastro.rec","wb"); if(arq==NULL)
97

Professora ANITA LOPES

printf("\nNao existe arquivo\n"); else { fwrite(aluno,sizeof(aluno[0]),n,arq); fclose(arq); printf("\nRegistros gravados: %d!\n",n); }

armazenaMP() {char lixo[30];int a,x; if(n<30) { printf("\nNome %d: ",n+1); fgets(aluno[n].nome,30,stdin); if(strlen(aluno[n].nome)==29) { if(aluno[n].nome[28]=='\n')aluno[n].nome[28]='\0'; else fgets(lixo,30,stdin); } else { aluno[n].nome[strlen(aluno[n].nome)-1]='\0' ; while(strlen(aluno[n].nome)<29) strcat(aluno[n].nome," "); aluno[n].nome[29]='\0'; } for(x=0;x<strlen(aluno[n].nome);x1++); aluno[n].nome[x]=toupper(aluno[n].nome[x]); printf("\nNota: "); scanf("%f",&aluno[n].nota);fgetc(stdin); n++; } else printf("\nArquivo cheio!\n"); flag=1; }

ordena() {if(flag==1) { for(a=0;a<n-1;a++) for(b=a+1;b<n;b++) if(strcmp(aluno[a].nome,aluno[b].nome)>0) {x=aluno[a]; aluno[a]=aluno[b]; aluno[b]=x; } } else printf("\nENTRE PRIMEIRO COM OS DADOS\n"); } lista() {if(flag==1) {

printf("\n\nNOME\t\t\t\tNOTA\n\n"); for(a=0;a<n;a++) printf("\n%s %5.2f",aluno[a].nome,aluno[a].nota);

98

Professora ANITA LOPES


} else printf("\nENTRE PRIMEIRO COM OS DADOS\n"); }

Professora ANITA LOPES

p ponteiro que localiza o dado na MP a ser gravado no arquivo p1 ponteiro de arquivo 6) Lendo do arquivo: fgets( )

13) Arquivos Textos 1) FILE FILE *nome da varivel ponteiro de arquivo ; 2) Abertura do arquivo: fopen() sintaxe: nome da varivel ponteiro = fopen( "nome do arquivo" , "tipo de abertura"); r w a r+ w+ a+ abrir um arquivo texto para leitura. O arquivo precisa existir. abrir um arquivo texto para gravao. Se o arquivo existir ser destrudo e inicializado. Se no existir, ser criado abrir um arquivo texto para gravao. Se o arquivo existir, os dados sero adicionados ao final. Se no existir, ser criado. abrir um arquivo texto para leitura e gravao. O arquivo precisa existir e pode ser atualizado. abrir um arquivo texto para leitura e gravao. Se o arquivo existir ser destrudo e inicializado. Se no existir, ser criado abrir um arquivo texto para atualizaes e para adicionar dados ao fim do arquivo existente ou criar um novo arquivo.

sintaxe:

fgets( p, t, p1 );

p ponteiro que localiza a posio na MP onde o dado lido arquivo dever ser gravado t- tamanho do que vai ser lido, fornecido pela funo sizeof( argumento) p1 ponteiro de arquivo

Digite uma tabela(no bloco de notas) com os dados que voc desejar e salve-o como tabela1.txt. Nome idade Pedro Maria Filipe Joao 20 19 23 15

Para ler esta tabela, execute o programa abaixo: arquivo-Texto-Ler-Tabela.c #include <stdio.h> main() { FILE *fp; char s[100]; fp=fopen("tabela1.txt","r"); while(fgets(s,100,fp) !=NULL) printf("%s",s); fclose(fp);

3) Fechamento do arquivo: fclose() fclose(nome da varivel ponteiro); 4) Constante simblica: NULL (escrita em maiscula ) if( arq==NULL) printf("\nArquivo nao pode ser aberto\n"); 5) Escrevendo no arquivo: fputs() sintaxe: fputs( p, p1 );
99

TRECHO PARA ENTRADA VIA TECLADO E GRAVAO NO ARQUIVO


arquivo-Texto-Gravar.c #include <stdio.h> #include <string.h> main() { FILE *fp;

100

Professora ANITA LOPES


char s[500]; fp=fopen("arq.txt","a"); while(strcmp(fgets(s,500,stdin),"#\n")!=0) fputs(s,fp); fclose(fp); } TRECHO PARA LEITo-Texto-Ler.c #include <stdio.h> main() {FILE *fp; char s[500]; fp=fopen("arq.txt","r"); while(fgets(s,500,fp)!=NULL) printf("%s",s); fclose(fp); }

Professora ANITA LOPES

TRECHO PARA LEITURA DO ARQUIVO E ARMAZENAMENTO NA MP, IMPRIMINDO TOTAL-CARACTERES

arqTexto-ler-CONTA-LETRA.c #include <stdio.h> #include <string.h> main() {FILE *fp; char s[500]; int cont=0; fp=fopen("arq3.txt","r"); fgets(s,500,fp); while( !feof(fp) ) { cont+=strlen(s); fgets(s,500,fp); } fclose(fp); printf("\nCARACTERES: %d\n",cont); }

TRECHO PARA LEITURA DO ARQUIVO E ARMAZENAMENTO NA MP, IMPRIMINDO TOTAL-PALAVRAS arqTexto-ler-CONTA-PALAVRA.c #include <stdio.h> #include <string.h> main() {FILE *fp; char s[500]; int c=0,cont=0; fp=fopen("arq3.txt","r"); fgets(s,500,fp); while( !feof(fp)) { cont++; for(c=0;c<strlen(s);c++) if(s[c] !=' ' )continue; else cont++; fgets(s,500,fp); } fclose(fp); printf("%d Palavras\n",cont);; }

TRECHO PARA ENTRADA VIA TECLADO E GRAVAO NO ARQUIVO, CONVERTENDO LETRAS PARA MINSCULAS

arqTexto-ler-PARA-CONVERTE-MIN.c #include <stdio.h> #include <string.h> main() { FILE *fp; char s[500];int c; fp=fopen("arq14.txt","a"); while( strcmp(fgets(s,500,stdin),"#\n")!=0 ) { for(c=0;c<strlen(s);c++) s[c]=tolower(s[c]); fputs(s,fp); } fclose(fp); }

101

102

Professora ANITA LOPES


2. Funo calloc(num, tamanho) 14 - Alocao Dinmica A alocao dinmica de memria uma caracterstica importante das linguagens de alto nvel, pois permite criar tipos de dados e estruturas de qualquer tamanho que satisfaa as nossas necessidades durante a execuo de um programa. Quando declaramos variveis locais, globais, matrizes e estruturas, sabemos, de antemo, quanto de memria estar sendo usada, mas, muitas vezes isto no ser possvel, pois o tamanho necessrio seria fornecido durante a execuo. Para que isto seja vivel, a linguagem C inclui o sistema de Alocao Dinmica, usando uma rea de memria, chamada heap que se localiza entre a rea usada pelo programa e a pilha conforme podemos observar na figura abaixo:

Professora ANITA LOPES

Conceito: devolve um ponteiro para o primeiro byte de uma regio capaz de armazenar num itens de tamanho definido na funo que foi alocada no heap. Exemplo: . float *val; int n; . Funo free(varivel ponteiro)

val = (float *)malloc(n*sizeof(float)); val = (float *)calloc(n, sizeof(float));

MEMRIA PRINCIPAL
Alta Variveis locais

HEAP
Variveis globais Baixa Programa

Conceito: devolve ao heap a memria apontada pelo ponteiro. . float *val; free(val); int n; .

Testando a validade da alocao

1. Funo malloc(tamanho) - memory allocation Conceito: devolve um ponteiro para o primeiro byte de uma regio de tamanho definido na funo que foi alocada no heap. ptr = (tipo *)malloc(tamanho); onde: ptr o nome do ponteiro que recebe o endereo do espao de memria alocado. tipo o tipo do endereo apontado (tipo do ponteiro). tamanho o tamanho do espao alocado: nmero de bytes. Sendo mais claro: ptr = (tipo*)malloc(n*sizeof(tipo)); onde: n o numero de elementos que queremos poder armazenar no espao alocado. Exemplo: Alocar um espao para um vetor de 10 elementos inteiros. int *ptr; ptr= (int *)malloc(10*sizeof(int));
103

if( !p ) { printf("\nERRO DE ALOCACAO\n"); exit(1); }

Exemplo 1 #include <stdlib.h> #include <stdio.h> main() {

int i,n; char s; float *val, media(float[],int); puts("Calculo da Media de um Conjunto de Valores"); do { puts("\nDigite o numero (n > 1) de valores: ");scanf("%d",&n); } while(n < 1); /* INICIO da Alocacao de memoria*/ val = (float *)malloc(n*sizeof(float)); if(val == NULL) { puts("Desculpe, NAO ha' memoria disponivel!"); fgetc(stdin);scanf("%c",&s); exit(1); } /* FIM da Alocacao de memoria*/ puts("\n Digite os valores:");

104

Professora ANITA LOPES


for(i = 0; i < n; i++) { printf("\n%do valor: ",i+1); scanf("%f",val+i)} printf("\n\n\nValores Digitados\n"); for(i = 0; i < n; i++) printf("\n%.2f",*(val+i)); printf("\nMedia: %.2f",media(val,n)); /* Liberando a memoria*/ free(val); fgetc(stdin); puts("\n\nPressione enter"); scanf("%c",&s); } float media(float vet[],int q) { int i; float soma = 0.0; for(i = 0; i < q; i++) soma += vet[i]; return(soma/q); } Exemplo 2 #include <stdlib.h> #include <stdio.h> main() { int l,c,aux,i,n,num[5]; char s; int *val; for(i = 0; i < 5; i++) { printf("\n%do valor: ",i+1);scanf("%d",&num[i]); /* INICIO da Alocacao de memoria*/ val = (int *)malloc(5*sizeof(int)); if(val == NULL) { puts("Desculpe, NAO ha' memoria disponivel!"); fgetc(stdin); scanf("%c",&s); exit(1); } /* FIM da Alocacao de memoria*/ /* Inicializacao de val*/ for(i = 0; i <5; i++) val[i]=num[i]; /* Ordenacao */ for(l = 0; l <4; l++) for(c = l+1; c <5; c++) if(val[l]>val[c]) {aux=val[l];val[l]=val[c];val[c]=aux;} printf("\n\n\nValores Digitados\n"); for(i = 0; i <5; i++)
105

Professora ANITA LOPES

printf("\n%d",num[i]); printf("\n\n\nValores Ordenados\n"); for(i = 0; i <5; i++) printf("\n%d",val[i]); /* Liberando a memoria*/ free(val);

fgetc(stdin); puts("\n\nPressione enter"); scanf("%c",&s); }

Exemplo 3 ARQUIVO PARA ENTRAR COM DADOS VIA TECLADO E ARMAZENAR EM DISCO #include <stdio.h> #define TAM (5) main() {int vet[TAM],l; FILE *arq; for(l=0;l<TAM;l++) {printf("\n%d numero: ",l+1); scanf("%d",&vet[l]); } arq=fopen("vetor","wb"); if(arq==NULL) printf("\nArquivo nao pode ser aberto\n"); else {fwrite(vet,sizeof(vet),1,arq); fclose(arq); } } ARQUIVO QUE L DADOS DE UM ARQUIVO, ALOCA ESPAO DINAMICAMENTE PARA ORDENAR E IMPRIMIR VETOR #include <stdlib.h> #include <stdio.h> main() { int l,c,aux,i,t,num[5]; char s; int *val; /* LEITURA do vetor*/ FILE *arq; arq=fopen("vetor","rb"); if(arq==NULL) printf("\nArquivo nao pode ser aberto\n"); else {fread(num,sizeof(num),1,arq); fclose(arq); } t=sizeof(num)/4;

/* INICIO da Alocacao de memoria*/ val = (int *)calloc(t,sizeof(int)); if(val == NULL) { puts("Desculpe, NAO ha' memoria disponivel!"); fgetc(stdin);scanf("%c",&s); exit(1); } /* FIM da Alocacao de memoria*/

106

Professora ANITA LOPES


/* Inicializacao de val*/ for(i = 0; i <t; i++) val[i]=num[i]; /* Ordenacao */ for(l = 0; l <t-1; l++) for(c = l+1; c <t; c++) if(val[l]>val[c]) {aux=val[l];val[l]=val[c];val[c]=aux;} printf("\n\n\nValores Lidos do arquivo\n"); for(i = 0; i <t; i++) printf("\n%d",num[i]); printf("\n\n\nValores Ordenados\n"); for(i = 0; i <t; i++) printf("\n%d",val[i]); /* Liberando a memoria*/ free(val); puts("\n\nPressione enter");scanf("%c",&s); } Bibliografia:

Professora ANITA LOPES

for(i = 0; i <= n-1; i++) printf("\n%d",val[i]);

puts("\n\nDigite o numero (n > 0) de valores: "); scanf("%d",&n); } /* Liberando a memoria*/ free(val); fgetc(stdin);puts("\n\nPressione enter");scanf("%c",&s); }

3. Funo realloc(void *bloco, tamanho) Conceito: permite que a quantidade de memria alocada possa crescer de acordo com a necessidade, aumentando a eficincia do programa. #include <stdlib.h> #include <stdio.h> main() { int i,n; char s; int *val; puts("\n\nVarios vetores"); puts("\n\nDigite o numero (n > 0) de valores: ");scanf("%d",&n); while(n>0) { /* INICIO da Realocacao de memoria*/ val = (int *)realloc(val,n*sizeof(int)); if(val == NULL) { puts("Desculpe, NAO ha' memoria disponivel!"); exit(1); } /* FIM da Alocacao de memoria*/

1. LOPES, Anita, GARCIA, Guto. Introudo Programao- 500 Algoritmos. 6 ed.Rio de Janeiro: Campus, 2002. 2. LOPO,Erik de Castro, JONES Bradlely, AIKTEN Peter. C for Linux Programming .SAMS 3. EVARISTO, Jayme. Aprendendo a Programar em C. Rio de Janeiro: Book Express, 2001. 4. MIZRAHI, V.V. Treinamento dem liguagem C Curso completo.Mdulos 1 e 2. So Paulo: Mc Graw Hill, 1990 Kernighan, Brian W. Ritchie, Dennis M. C- A linguagem de Programao padro ANSI . Rio de Janeiro , Campus , 2002
5.

6. SCHILDT, Herbert. C completo e total. Makron Book 7. UFMG. Apostila de C.

8. UNIVERSIDADE DE CAXIAS DO SUL. Apostila de C.

scanf("%c",&s);

puts("\n Digite os valores:"); for(i = 0; i < n; i++) { printf("\n%do valor: ",i+1);scanf("%d",&val[i]); } printf("\n\n\nValores Digitados\n");
107

108