Beruflich Dokumente
Kultur Dokumente
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
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
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.
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:
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
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
%<n.f>f
%%
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); }
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.
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() {
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)));
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
cdecl default enum float inline new register sizeof this volatile
char delete _es for int operator return _ss typedef while
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
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
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=# /*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:
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
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
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.
/* l para uma varivel inteira*/ /* l para duas variveis inteiras separadas por
13
14
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
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); }
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
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
As expresses lgicas usadas nas estruturas de teste so formadas pelos operadores relacionais e lgicos.
Operadores relacionais verificam a relao de magnitude e igualdade entre dois valores. So seis os operadores relacionais em C:
19
20
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
SADA 0 0 0 1
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
SADA 0 1 1 1
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.
SADA 0 1
22
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 & | ^ ~ >> <<
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.
}
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
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.
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
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
26
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.
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");
#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
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"); }
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
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)); } }
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);
31
32
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
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) {
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> #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
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
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
bom voc j ir se acostumando com este conceito de apontamento, pois para se programar bem em C, precisaremos dominar o conceito de ponteiros.
/* 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
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
#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
#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
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:
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:
#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
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.
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
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
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",×[c].vitorias); printf("\nTotal de derrotas: "); scanf("%d",×[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");
}
A principal diferena que quando se declara, no se aloca espao na MP e quando se define, sim.
49
50
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:
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;
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, ;
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
52
#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");
#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
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
: 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
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(...) {... }
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
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
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
#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);
} 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
#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
);
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); }
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
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.
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.
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
Quando declaramos uma varivel ponteiro, precisamos informar o tipo de varivel que ser apontada pelo ponteiro.
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.
68
(*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); }
*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
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
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
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 *.
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
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;
76
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.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?
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
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][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
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.
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
#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
ou
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:
escreve o contedo armazenado na estrutura de nome cad, cujo tamanho foi fornecido por sizeof, consultando o ponteiro de arquivo.
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.
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:
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
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 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
Ler dados do arquivo e grava em uma estrutura, imprimindo na tela, vrias vezes ler1.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"); while( !feof(arq)) { printf("\nMatricula: %d\tMedia: %.1f",cad.mat,cad.media); fread(&cad,sizeof(cad),1,arq); } fclose(arq); } printf("\n\n"); }
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
#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
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);
%sPR1:
%.1f\tPR2:
%.1f\tMedia:
92
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:
#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
for(;;) { printf("\nDigite nota pr2:"); scanf("%f",&cad.pr2); if(cad.pr2>=0 && cad.pr2<=10)break; printf("\nDigite novamente. Invalida!\n"); }
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
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) {
98
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
100
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
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)
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; .
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
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
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);
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
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.
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