Anda di halaman 1dari 59

Linguagem C

Departamento de Cnca da Computao


IME/USP
Comando de repetio while
Sintaxe
while (condio) comando
onde comando pode corresponder a uma nstruo smpes ou a uma
seqnca de nstrues entre chaves separados por " ; " e condo uma
expresso gca, cu|o resutado pode ser verdadero ou faso.
Descrio
Enquanto a condo for verdadera, o comando repetdo. O comando pode
ser apenas uma nstruo do C ou um boco de nstrues entre chaves.
Por exempo, se|a x uma varve ntera. O segmento de programa abaxo
smpesmente subtra 1 de x, 5 vezes (note que o comando 'x = x-1;' repetdo
5 vezes).
x=5;
while (x > 0)
{
x = x -1;
}
printf("valor de x = %d\n",x);
A gura abaxo mostra gracamente o uxo de execuo desses comandos.
Para entender esse dagrama, cada retnguo representa um boco de
nstrues, que so executadas seqencamente, um boco de cada vez, de
cma para baxo. O prmero comando, a atrbuo x = 5 (a varve x recebe o
vaor 5), executado antes do whe.
Nessa representao grca, bocos retanguares podem ser encaxados, como
pode ser vsto no boco correspondente ao whe. Esse comando testa a
condo (x>0) e se ea for verdadera, executa os comandos do sub-boco
assocado, que nesse caso contem apenas a atrbuo x = x - 1. Observe a
seta na couna esquerda do boco do whe. Ea ndca que ao termnar o sub-
boco, a condo do whe precsa ser testada novamente. Assm, o sub-boco
repetdo enquanto a condo do whe for verdadera, e s quando a condo
for fasa, o whe termna, e a nstruo segunte executada (no caso, o
prntf).
NOTA: para que o seu programa termne, voc precsa garantr que a condo
do whe se|a aterada de aguma forma. Caso contrro, o programa entra em
"oopng nnto".
Exemplos comentados:
Exemplo 1:
Dada uma seqnca de nmeros nteros, cacuar os seus quadrados.
Soluo:
Uma souo possve pode ser descrta de modo nforma como:
0 - mprma uma mensagem para o usuro saber o que fazer
1 - ea o prmero nmero da seqnca na varve num
2 - enquanto num for dferente de zero faa:
2.1 cacue quadrado = num * num
2.2 mprma o vaor de quadrado
2.3 ea o prxmo nmero da seqnca na varve num
3. m
O funconamento do programa pode ser entenddo tambm peo dagrama
abaxo:
Em gera, mas smpes desenhar o dagrama e, quando voc estver certo de
que ee funcona, sua "traduo" para a nguagem C smpes, basta copar o
esqueeto de um programa em C vsto anterormente, e preencher as acunas.
O programa em C cara:
#include <stdio.h>
#include <stdlib.h>
int main () {
/* declaracoes */
int num; /* variavel utilizada para leitura da sequencia */
int quad; /* variavel que armazena o quadrado de um numero */
/* programa */
printf("Digite uma sequencia terminada por zero\n");
scanf("%d", &num);
while (num != 0) /* os simbolos '!=' significam diferente */
{
quad = num * num ;
printf ("O quadrado de %d = %d\n", num, quad);
scanf("%d", &num);
}
/* fim do programa */
system ("pause");
return 0;
}
NOTA: programao exge muta ateno a detahes. Porm, como o nmero de
comados bastante mtado, no to dfc assm aprender uma nguagem
de programao. Programar porm pode ser consderado dfc por aguns, pos
o probema precsa ser decomposto e descrto de modo forma. Vamos resover
vros exerccos para que voc desenvova o racocno para decompor os
probemas.
Exemplo 2:
Dada uma seqnca de nmeros nteros termnada por zero, cacuar a
somatra dos nmeros da seqnca.
Soluo
Para mehor entender o probema, vamos ver um exempo concreto de entrada
e sada. Para a entrada
2 3 -4 5 0
a sada deve ser 6 (2 + 3 - 4 + 5).
Uma forma possve para resover esse probema magnar uma varve que
armazena as somas parcas. Essa varve deve ncar com o vaor zero, e para
cada nmero da seqnca, ser somada com mas esse nmero, at o na da
seqnca. Assm, para o exempo acma, o vaor de soma torna-se 2 aps
processar o prmero eemento da seqenca (soma-se o 2), 5 aps o segundo
(soma-se o 3), 1 aps o tercero (soma-se o 4), e assm at o na.
O dagrama abaxo ustra um rascunho usando nossa pseudo nguagem de
bocos:
Traduzndo esse esboo para C temos:
#include <stdio.h>
#include <stdlib.h>
int main () {
/* declaracoes */
int num; /* variavel utilizada para leitura da sequencia */
int soma; /* variavel que armazena a soma da sequencia */
/* programa */
printf("Digite uma sequencia terminada por zero\n");
scanf("%d", &num);
while (num != 0) /* os simbolos '!=' significam diferente */
{
soma = soma * num ;
scanf("%d", &num);
}
printf("Soma da sequencia = %d \n", soma);
/* fim do programa */
system ("pause");
return 0;
}
Exemplo 3:
Vamos aterar um pouco o enuncado do exempo anteror, para:
Dado um nmero ntero postvo, cacuar a soma de seus dgtos.
Por exempo, para o nmero 1234, a sada deve ser 1+2+3+4 = 10.
Soluo
A prmera pergunta sera: como a gente pode separar um dgto do nmero,
para podermos cacuar a soma? A resposta o operador resto, que utzamos
tambm na aua drgda do compador Dev-C++ para determnar nmeros
pares e mpares. Lembre-se que o resutado de 7%3 1, pos 7 = 2 * 3 + resto,
onde resto = 1; e o resutado de 7 / 3 2.
A da gera , separar o dgto mas a dreta, atuazar a soma, e tratar o
prxmo dgto, at que todos os dgtos se|am somados. O rascunho abaxo
ustra essa da:
Observe que a varve dgto recebe o vaor do dgto mas a dreta de num
(dgto = num % 10) dentro do comando enquanto (whe), e a segur o nmero
modcado para que ee perca o dgto processado (num = num / 10). A
tabea abaxo ustra a execuo desse programa, mostrando o que acontece
com as varves para o nmero 123:
Comentro num dgto soma
antes do
enquanto
123 0
dentro de
enquanto: dgto
= num % 10
3
num = num / 10 12
soma = soma +
dgto
3
condo do
enquanto
verdadera
dgto = num / 10 2
num = num / 10 1
soma = soma + 5
dgto
condo
verdadera
dgto = num / 10 1
num = num / 10 0
soma = soma +
dgto
6
condo do
enquanto fasa,
m do oop
Traduzndo o pseudo cdgo para C:
#include <stdio.h>
#include <stdlib.h>
int main ( )
{
/* Declaracoes */
int num, soma, digito;
printf ("Entre com um numero: ");
scanf ("%d", &num);
soma = 0;
while (num != 0) /* enquanto houver digitos para processar */
{
digito = num % 10; /* pega o digito mais a direita */
num = num / 10; /* atualiza o numero, mantedo apenas os
digitos no processados */
soma = soma + digito; /* atualiza a soma dos digitos */
}
printf ("Soma dos digitos: %d.\n", soma);
system("pause");
return 0;
}
Eoza Sonoda
Comando de deciso - i then else
Sintaxe:
h duas varaes do comando f:
1 - i (condo) comando-f else comando-ese
2 - i (condo) comando-f
Descrio:
Os comandos f e f-ese so nstrues que permtem a execuo condcona
de outros comandos.
Na forma competa, f-ese, o comando-f executado quando a condo
verdadera, caso contrro, o comando-ese executado. A gura abaxo ustra
um boco em pseudo-nguagem grca que corresponde ao comando f-ese:
H ocases em que o ese desnecessro, e por sso a nguagem C permte a
outra construo f (sem o ese) desse comando. No dagrama, o boco
comando-ese (quando a condo fasa), se torna vazo, ou se|a, no exstem
comandos para serem executados.
Exemplos
Exemplo 1:
escreva um programa que ea 2 nmeros nteros e mprma o maor.
Soluo
A smpcdade desse programa permte observar o uso do comando f-ese.
Para sso, vamos utzar 2 varves para armazenar os vaores de entrada, e
outra para armazenar o maor vaor. Um rascunho pode ser observado no
dagrama da gura abaxo:
Traduzndo o dagrama para C temos:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int num1, num2, maior;
printf("Entre com 2 numeros inteiros");
scanf("%d %d", &num1, &num2);
i (num1 > num2)
maior = num1;
else
maior = num2;
printf("O maior numero e: %d", maior);
system("pause");
return 0;
}
Observe que basta comparar num1 com num2 para sabermos qua o maor.
Exemplo 2:
escreva um programa que ea 3 nmeros nteros dstntos e os mprma em
ordem crescente.
Soluo:
a da bsca comparar os nmeros, porm, h vras formas de faz-o.
Como h apenas 3 nmeros, podemos testar todas as possbdades da
segunte forma (apenas um trecho do programa):
/* assuma que as variveis num1, num2 e num3 j estejam carregadas
*/
i (num1 <= num2 && num2 <= num3)
printf("a ordem %d %d %d\n", num1, num2, num3);
i (num1 <= num3 && num3 <= num2)
printf("a ordem %d %d %d\n", num1, num3, num2);
i (num2 <= num3 && num3 <= num1)
printf("a ordem %d %d %d\n", num2, num3, num1);
i (num2 <= num1 && num1 <= num3)
printf("a ordem %d %d %d\n", num2, num1, num3);
i (num3 <= num1 && num1 <= num2)
printf("a ordem %d %d %d\n", num3, num1, num2);
i (num3 <= num2 && num2 <= num1)
printf("a ordem %d %d %d\n", num3, num2, num1);
Note que, como os nmeros so dstntos, s pode haver uma combnao
vda, e portanto apenas uma das respostas mpressa, e a comparao <=
podera ser smpestemente <. No entanto, caso os nmeros pudessem ser
repetdos, mas de uma resposta sera mpressa com a comparao <=
(nenhuma resposta com a comparao <). O comando f-ese tambm podera
ser utzado da segunte forma:
/* assuma que as variveis num1, num2 e num3 j estejam
carregadas */
i (num1 <= num2 && num2 <= num3)
printf("a ordem %d %d %d\n", num1, num2, num3);
else i (num1 <= num3 && num3 <= num2)
printf("a ordem %d %d %d\n", num1, num3, num2);
else i (num2 <= num3 && num3 <= num1)
printf("a ordem %d %d %d\n", num2, num3, num1);
/* etc */
Essa souo com f-ese mprmra apenas uma resposta mesmo se
houvessem nmeros repetdos entre os 3 da entrada.
Podemos tambm procurar peo menor nmero prmero (ou peo maor), e
depos comparar os demas, da segunte forma:
if ((num1 <= num2) && (num1 <= num3))
{
/* num1 o menor, basta comparar num2 e num3 */
if (num2 <= num3)
printf("a ordem %d %d %d\n", num1, num2, num3);
else
printf("a ordem %d %d %d\n", num1, num3, num2);
}
else if (num2 <= num1 && num2 <= num3)
{
/* num2 o menor, basta comparar num1 e num3 */
if (num1 <= num3)
printf("a ordem %d %d %d\n", num2, num1, num3);
else
printf("a ordem %d %d %d\n", num2, num3, num1);
}
else /* complete este trecho de programa */
Exerc!cios recomendados da lista
1) Dados um nmero ntero n>0 e uma seqenca com n nmeros nteros,
determnar a soma dos nteros postvos da seqnca. Por exempo, para a
seqnca
6 2 7 0 -5 8 4
o seu programa deve escrever o nmero 19.
2) Dados um nmero ntero n>0 e uma seqenca com n nmeros nteros,
determnar a soma dos nteros postvos e a soma dos nteros negatvos da
seqnca. Por exempo, para a seqnca
6 2 7 0 -5 8 4
o seu programa deve escrever os nmeros 19 e -7.
3) Dzemos que um nmero ntero tranguar se ee o produto de 3
nmeros nteros consecutvos. Por exempo, 120 tranguar pos 4 * 5 * 6
gua a 120. Dado um nmero ntero postvo n, vercar se n tranguar.

Eoza Sonoda
Comando de repetio or
Sintaxe
for (<inicializao>; <condio>; <incremento>) <comandos>
Descrio
Assm como no comando whe o for repete o boco <comandos> enquanto a
<condo> se manter verdadera.
A parte de <ncazao> reazada apenas 1 vez, no nco da execuo do
comando. A segur, a <condo> testada, e caso verdadera, os
<comandos> so executados. Aps a execuo dos <comandos> mas antes
de testar a <condo>, a parte <ncremento> do comando for executada.
O for bascamente uma forma compacta de escrever um loop tpco usando
whe. Por exempo, para que possamos repetr ago n vezes, comum
utzarmos a segunte construo usando o whe:
cont = 0;
while (cont < n)
{
<comandos>
cont++;
}
onde n e cont so varves nteras, e cont++ uma abrevao permtda em C
de cont = cont + 1. Usando o comando for, esse trecho de programa sera
reduzdo para o segunte:
for (cont = 0; cont < n; cont++) <comandos>
Vamos ver aguns exempos competos. Por exempo, consdere o programa
abaxo, para cacuar o fatora de um nmero natura n.
#include <stdio.h>
#int main()
{
int n, cont, fat;
printf("Entre com um numero para calculo do fatorial: ");
scanf("%d", &n);
fat = 1;
cont = 1;
while (cont <= n) {
fat = fat * cont;
cont=cont+1;
}
return 0;
}
Observe que a varve cont utzada para controar o nmero de produtos
que so reazados para obter o fatora. Ea ncazada com o vaor 1, e ao
na do boco de comandos do whe, o contador ncrementado. O comando
encerra quando a condo cont <= n se torna fasa. Esse programa pode ser
facmente reescrto usando o comando for da segunte forma:
#include <stdio.h>
#int main ()
{
int n, cont, fat;
printf("Entre com um numero para calculo do fatorial: ");
scanf("%d", &n);
fat = 1;
for (cont = 1; cont <= n; cont=cont+1)
fat = fat * cont;
return 0;
}
D"C#:
Como ncrementar e decrementar varves so operaes muto comuns, a
nguagem C oferece os operadores ++ e --, de forma que o comando
cont = cont + 1;
pode ser substtudo por
cont++;
Um erro comum cometdo por programadores nexperentes (e portanto
procure evt-o) escrever
cont = cont++;
Exerc!cio 1$11 do caderno de exerc!cios:
Dzemos que um nmero tranguar se ee produto de trs nmeros naturas
consecutvos (e.g.: 120 tranguar pos 120 = 4.5.6). Dado um natura n,
determnar se n tranguar.
Soluo comentada:
Mutos dos probemas em computao podem ser reduzdos a uma forma de
"busca", onde o computador gera todas as combnaes possves at se
encontrar a souo dese|ada.
Para esse probema, como podemos gerar todas as soues?
Bascamente, precsamos denr 3 cosas:
Inco: qua o prmero canddado a souo a ser testado?
Fm: a partr de que vaor no mas necessro procurar a souo?
Incremento: como gerar a prxma souo a ser testada.
Nesse caso, como os nmeros so postvos, a prmera souo a ser testada
sera 1*2*3. A segunda sera 2*3*4, e assm por dante. Caso o produto for
gua ao nmero que dese|amos testar, ento encontramos a souo, e a
resposta sera postva. Ouando o produto se torna maor que o nmero
dese|ado, sabemos que o nmero no pode ser perfeto, e podemos encerrar a
busca. Ve|amos um programa que faz sso:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
int cont, num;
printf("Entre com um nmero: ");
scanf("%d", &num);
for (cont=1; num < cont*(cont+1)*(cont+2); cont++);
/* veja que o for executa um comando vazio */
if (cont*(cont+1)*(cont+2) == num)
printf("O numero %d e perfeito\n");
else
printf("O numero %d nao e perfeito\n");
system("pause");
return 0;
}
Exerc!cios recomendados
Dados um nmero ntero n, n>0, e uma seqnca com n nmeros nteros,
vercar se a seqnca est em ordem crescente.
Dado um nmero ntero n>0, vercar se este nmero contm dos dgtos
ad|acentes guas.
Eoza Sonoda
"ndicadores de passagem
Indcadores de passagem so varves utzadas para determnar se uma
condo partcuar fo satsfeta ou no durante a execuo de um programa
(ou trecho do programa). A caracterstca prncpa desses ndcadores que
ees sempre comeam com um determnado vaor (vaor nca), e se a
condo partcuar for encontrada, o vaor dessa varve muda de vaor, e por
vezes, essa mudana pode at ser utzada para nterromper ou termnar a
execuo do programa.
Consdere o probema de er uma seqnca de nmeros nteros postvos
termnada por um zero, e determnar se a sequnca se encontra em ordem
estrtamente crescente ou no. Por exempo, a seqnca {1,4,5,7,0} se
encontra em ordem estrtamente crescente pos cada um dos eementos
maor que o eemento anteror. O tmo eemento, o nmero 0, apenas ndca o
trmno da seqnca. | a seqnca {4,5,5,7,0} no satsfaz esse crtro
devdo ao '5' segudo de outro '5', que gua e no maor que o eemento
anteror.
%m exemplo:
Usando apenas os comandos ntroduzdos at aqu, escreva um programa que
determna se uma seqnca estrtamente crescente ou no.
Soluo:
uma souo possve comparar todos os pares consecutvos da seqnca. Se
a ordem de agum dos pares no for crescente, sabemos que a seqnca no
crescente.
Uma pergunta mportante : se encontrarmos um par no crescente,
precsamos contnuar processando o resto da seqnca? A resposta no, no
precsamos. Porm, estamos preocupados no momento em aprender a
estruturar probemas, e a nterrupo do processamento pode torn-o
desestruturado (como a ncuso de um comando goto. Se voc no sabe o que
um goto, tmo, pos esse comando probdo nesse curso). Ou se|a, no
vamos nos preocupar anda se o computador faz ccuos desnecessros,
apenas em resover o probema de forma correta e estruturada, da forma mas
smpes que voc consegur. Vamos votar souo do probema, que segue
abaxo:
#include <stdio.h>
int main ()
{
int crescente = 1; /* 1 => e' crescente, 0 => no crescente */
int num; /* armazena o nmero corrente */
int anterior; /* armazena o nmero anterior */
printf("Entre com um numero");
scanf("%d", &num);
anterior = num - 1; /* coloca um valor inicial apropriado para
anterior */
while (num != 0) {
if (num <= anterior)
crescente = 0; /* se num <= anterior a sequencia nao
crescente */
anterior = num; /* armazena o numero corrente em anterior */
printf("Entre com um numero");
scanf("%d", &num);
}
/* fim da sequencia. vamos ver se ela crescente ou nao */
if (crescente == 1)
printf("A sequencia e crescente\n");
else
printf("A sequencia nao e crescente\n");
return 0;
}
Nesse programa, usamos 1 para ndcar que a seqnca crescente e 0 para
ndcar que ea descrescente. Para factar o entendmento do programa, a
nguagem C permte a deno de constantes utzando macros. Macros so
denes passadas ao compador que so transformadas antes da gerao do
cdgo. Ve|a o mesmo probema com a utzao das constantes VERDADEIRO
e FALSO:
#include <stdio.h>
/*
Macros definidas atravs de #define
para facilitar a identificacao de macros no programa,
vamos adotar que seus nomes tenham apenas letras maisculas
*/
#define FALSO 0
#define VERDADEIRO 1
int main () { int crescente = VERDADEIRO; int num, anterior;
printf("Entre com um numero"); scanf("%d", &num); anterior = num
- 1; while (num != 0) { if (num <= anterior) crescente =
FALSO; /* a seq nao crescente */ anterior = num;
printf("Entre com um numero"); scanf("%d", &num); } if
(crescente VERDADEIRO) printf("A sequencia e crescente\n");
else printf("A sequencia nao e crescente\n"); return 0;}
Exerc!cios recomendados
1) Dado um nmero ntero x (por exempo, o nmero de um carto de crdto),
e uma seqnca de nteros termnada por zero (por exempo, uma sta de
cartes extravados), escreva um programa em C que verque se x se
encontra na seqnca.
Obs: uma varao desse programa contar quantas vezes x ocorre na
seqnca. Se esse nmero zero, x no ocorre na seqnca. Mas para esse
exercco, procure utzar um ndcador de passagem.
2) Exercco 9 da sta de exerccos sobre nteros:
Dados nmeros nteros n, i e j, todos maores do que zero, mprmr em
ordem crescente os n prmeros naturas que so mtpos de i ou de j
e ou de ambos. Por exempo, para n=6, i=2 e j=3 a sada dever ser:
0 2 3 4 6 8
3) Exercco 11 da sta de exerccos sobre nteros. Dado um nmero ntero n,
n>0, vercar se n prmo.
Eoza Sonoda
&un'es: introduo
(esumo:
O uso de funes facilita a construo de programas pois possibilita a sua modularizao e
reutilizao de partes de cdigo. Nessa aula veremos como declarar funes usando prottipos,
como definir o corpo da funo e como utilizar funes em seus programas (chamada de funo
e passagem de parmetros!.
Descrio:
Um programa na nguagem C organzado na forma de funes, onde cada funo
responsve peo ccuo/processamento de uma parte do programa. Todo programa
em C precsa de uma funo chamada main, que ndca a prmera funo a ser
executada. Outras funes podem ser chamadas de dentro da funo main, at o m
do programa.
Como declarar uma uno: )rot*tipos
Uma funo decarada atravs de um prottpo como abaxo:
tipo nome (lista de parmetros);
onde:
tipo: dene o tpo do vaor devovdo pea funo (sada);
nome: nome da funo, utzado na chamada;
lista de parmetros: parmetros de entrada da funo.
Por exempo, consdere uma funo que cacue ( eevado a ), onde um nmero
rea e um nmero ntero. Podemos chamar essa funo de pot, e como o resutado
da funo precsa ser rea, seu prottpo sera:
float pot (float base, int exp);
Como de+nir uma uno: Corpo da uno
Uma funo denda por um boco de comandos dendos entre chaves que devem
segur o prottpo. Esses comandos so executados quando a funo chamada. Por
exempo, no caso da funo pot, sua deno podera ser:
/*
* a funo pot calcula a potncia de uma base real
* elevada a um inteiro nao negativo (exp >= 0)
*/
float pot (float base, int exp)
{
/* declarao das variveis locais da funo */
int i; /* conta iteraes */
float res = 1.0; /* armazena resultado */
for (i = 0; i < exp; i++)
res = base * res;
return res;
}
Dentro de cada funo, voc deve prmeramente decarar as varves que sero
utzadas DENTRO da funo (ou se|a entre as chaves que denem o corpo da
funo). Dentro da funo, os parmetros de entrada equvaem a varves, porm, o
vaor nca dessas "varves" so dendas na chamada da funo (ve|a prxma
seo).
Os comandos que denem a funo so dendos a segur e, ao na, o resutado da
funo devovdo ao oca da chamada atravs do comando return.
Como usar un'es em seus programas
Para ustrar o uso de funes, vamos consderar o segunte probema: "Escreva um
programa em C que ea o vaor de dos nteros no negatvos ( e ) e 3 reas ( , e ), e
cacue o vaor do ponmo: ".
Um possve programa sem o uso de funes sera:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
/* Declaraes */
float a, b;
int x, y;
float res = 0.0;
float pot;
int i;
/* leitura */
printf("Este programa calcula (a^{x} + b^{y} + (a+b)^{x+y})\n\n");
printf("Entre com os valores (reais) de a e b: ");
scanf("%f %f", &a, &b);
printf("Entre com os valores (naturais) de x e y: ");
scanf("%d %d", &x, &y);
/* calculo de a^{x} */
pot = 1.0;
i = 0;
while (i < x) {
pot = pot * a;
i++;
}
res = res + pot;
/* calculo de b^{y} */
pot = 1.0;
i = 0;
while (i < y) {
pot = pot * b;
i++;
}
res = res + pot;
/* calculo de (a+b)^{x+y} */
pot = 1.0;
i = 0;
while (i < (x+y)) {
pot = pot * (a+b);
i++;
}
res = res + pot;
printf ("Resultado de (%f ^{%d} + %f ^{%d} + %f^{%d}) = %f\n",
a, x, b, y, a+b, x+y, res);
/* FIM */
system ( "pause" );
return 0;
}
Observe que o ccuo das potncas reazado vras vezes. Vamos aterar
geramente o programa para evdencar que a forma que cacuar as potncas o
mesmo:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
/* Declaraes */
float a, b;
int x, y;
float res = 0.0;
float pot, base;
int i, exp;

/* leitura */
printf("Este programa calcula (a^{x} + b^{y} + (a+b)^{x+y})\n\n");
printf("Entre com os valores (reais) de a e b: ");
scanf("%f %f", &a, &b);
printf("Entre com os valores (naturais) de x e y: ");
scanf("%d %d", &x, &y);
/* calculo de a^{x} */
base = a;
exp = x;
/* bloco calculo de potencia base ^ exp */
pot = 1.0;
i = 0;
while (i < exp) {
pot = pot * base;
i++;
}
res = res + pot;
/* calculo de b^{y} */
base = b;
exp = y;
/* bloco calculo de potencia base ^ exp */
pot = 1.0;
i = 0;
while (i < exp) {
pot = pot * base;
i++;
}
res = res + pot;
/* calculo de (a+b)^{x+y} */
base = a+b;
exp = x+y;
/* bloco calculo de potencia base ^ exp */
pot = 1.0;
i = 0;
while (i < exp) {
pot = pot * base;
i++;
}
res = res + pot;
printf ("Resultado de (%f ^{%d} + %f ^{%d} + %f^{%d}) = %f\n",
a, x, b, y, a+b, x+y, res);
/* FIM */
system ( "pause" );
return 0;
}
Esse programa em partcuar pode ser bastante smpcado com a utzao de
funes. A estrutura de um programa com funes deve segur a segunte estrutura:
",CL%DES
)(-./.")-S
&%,01ES
Essa estrutura deve ser seguda para que um nome (ou dentcador) de uma funo
se|a sempre decarado (ou dendo) antes de ser utzado em uma chamada. Nosso
programa com funes sera:
/* INCLUDES */
#include <stdio.h>
#include <stdlib.h>
/* PROTTIPOS */
float pot (float base, int exp);
/* DEFINIO DAS FUNES */
/*
* Funo pot
* a funo pot calcula a potncia de uma base real
* elevada a um inteiro nao negativo (exp >= 0)
*/
float pot (float base, int exp) {
/* declarao de variveis */
int i = 0;
float pot = 1.0;
while (i < exp) {
pot = pot * base;
i++;
}
return pot;
}
/*
* Funo MAIN
*/
int main ()
{
/* Declaraes */
float a, b;
int x, y;
float res = 0.0;
/* leitura */
printf("Este programa calcula (a^{x} + b^{y} + (a+b)^{x+y})\n\n");
printf("Entre com os valores (reais) de a e b: ");
scanf("%f %f", &a, &b);
printf("Entre com os valores (naturais) de x e y: ");
scanf("%d %d", &x, &y);
/* calculo de a^{x} */
/* observe que na chamada da funo pot, os valores das variveis
a e x so passadas e associadas aos parmetros base e expoente */
res = res + pot(a, x);
/* calculo de b^{y} */
res = res + pot(b, y);
/* calculo de (a+b)^{x+y} */
/* observe que nessa chamada da funo pot, os valores das EXPRESSOES
(a+b) e (x+y) so passadas e associadas aos parmetros base e
expoente */
res = res + pot(a+b, x+y);
printf ("Resultado de (%f ^{%d} + %f ^{%d} + %f^{%d}) = %f\n",
a, x, b, y, a+b, x+y, res);
/* FIM */
system ( "pause" );
return 0;
}
Observe "ue a funo pot pode ser chamada dentro de uma e#presso, e o programa poderia ser
ainda mais simplificado se o resultado fosse calculado diretamente como
res = pot(a, x) + pot (b, y) + pot (a+b, x+y);
$ declarao e#plicita dos prottipos % uma boa pr&tica da computao pois permite "ue voc'
defina as funes em "ual"uer ordem. (aso os prottipos no se)am declarados, as funes
precisam ser definidas antes de serem utilizadas por outras funes. *or e#emplo, caso a funo
$ precise da funo +, + precisa ser definida antes de $. ,#istem por%m funes recursivas, onde
no % poss-vel estabelecer uma preced'ncia na definio. *or e#emplo, se a funo $ precisa de
+, mas a funo + precisa de $, ento o uso dos prottipos obrigatrio.
Eoza Sonoda
&un'es: passagem de par2metros
(esumo:
A nguagem de programao C permte que os parmetros se|am passados para as
funes de duas maneras, por vaor e por refernca. Na passagem por 3alor, como
o prpro nome dz, uma expresso pode ser utzada na chamada. O vaor da
expresso cacuada, e o vaor resutante passado para a execuo da funo. Na
passagem por reer4ncia, o endereo de uma varve deve ser passado na
chamada da funo. Dessa forma, a funo pode modcar a varve dretamente, o
que em gera no recomendve, mas h stuaes onde esse recurso necessro,
por exempo, para a crao de funes que devovem mas de um vaor.
Descrio:
At o momento, vmos apenas uma forma de passagem de parmetros, conhecda
como passagem por vaor. Essa forma permte que as varves de uma funo se|am
protegdas, ou se|a, apenas a funo onde as varves foram decaradas pode
modcar seu contedo. Permtr que uma funo modque o contedo de outra pode
ser muto pergoso, mas h stuaes onde sso necessro. Vamos prmero embrar
como funcona a passagem por vaor e depos ntroduzr o conceto de passagem por
refnca.
)assagem por 5alor
a forma mas comum utzada para passagem de parmetros. Por exempo,
consdere a fama de funes trgonomtrcas, como seno, cosseno, etc. A funo
seno, por exempo, recebe o vaor de um nguo (um nmero rea) e devove o seno
desse nguo. Se tvermos as funes seno e cosseno, podemos facmente denr
uma funo tangente. Em pro|etos grandes de desenvovmento de software, grupos
de programadores podem trabahar no desenvovmento de funes dstntas e |untar
os seus trabahos uma vez que tenham suas funes prontas. Para sso, basta que
cada grupo conhea o prottpo das funes que precsa utzar, e ao na, um
programa chamodo "nker" responsve por |untar os pedaos e construr um
programa executve. Por exempo, consdere que ns temos dsponves os seguntes
prottpos para as funes seno e cosseno:
float seno (float angulo);
float cosseno (float angulo);
Conhecendo esses prottpos, podemos escrever a funo tangente da segunte
forma:
float tangente (float angulo)
{
float s, c;
s = seno(angulo);
c = cosseno(angulo);
return s/c;
}
Essa funo caramente cacua o seno antes de cacuar o cosseno. Imagne se a
funo seno pudesse modcar o vaor do parmetro angulo. Nesse caso, o vaor
passado para a funo cosseno sera dferente do vaor orgna usado para o seno, e o
resutado da funo tangente estara ncorreto. A passagem por vaor consegue evtar
esse tpo de "efeto coatera" atravs da crao de varves ocas para os
parmetros. Ouando uma funo chamada, essas varves so carregadas, como
em atrbues, antes do nco da execuo do corpo da funo. Vamos faar um pouco
mas do escopo de varves a segur.
Escopo de 3ari63eis
O escopo de uma varve dendo peas reges (bocos) onde a varve pode ser
utzada. Por exempo, as varves decaradas no nco do corpo da funo main
podem ser utzadas em quaquer ugar dentro da funo main, porm apenas
DENTRO da main, ou se|a, no podem ser utzadas em outra funo. Varves
decaradas no mesmo escopo precsam ter nomes dferentes, mas nomes podem ser
"reaprovetados" em outros escopos. Ve|amos o exempo abaxo:
#include <stdio.h>
#include <stdlib.h>
int fat (int n)
{
int res = 1;
while (n > 1) {
res = res * n;
n--;
}
return res;
}
int main ()
{
int n, res;
printf("Entre com o valor de n: ");
scanf("%d", &n);
res = fat(n+1) / (n+1);
printf("Fatorial de %d = %d\n", n, res );
system("pause");
return 0;
}
Observe que a funo main e fat possuem ambas varves com o nome res, e que
main possu uma varve chamada n, que o nome do parmetro da funo fat.
Procure no se confundr, pos apesar do mesmo nome, eas so varves dferentes.
Para a funo fat, o parmetro n funcona como uma varve oca (ou se|a, vda
dentro da funo apenas), |untamente com a varve res. A dferena que o
parmetro n recebe seu vaor no nstante da chamada. Vamos smuar esse programa
para a entrada 2.
O programa sempre nca sua execuo pea funo main, que socta a entrada de
um vaor para n. A nha res = fat(n+1)/(n+1); chama a funo fat. Como n=2
(entrada do programa), ento o vaor 3 ( passado para a funo, ou se|a, esse vaor
atrbudo ao parmetro n e a funo fat comea a executar seu corpo. O fatora de
3 cacuado e o vaor 6 atrbudo varve res. Observe que o parmetro n
utzado como varve, o que permtdo pea nguagem C. Esse parmetro
decrementado at 1, porm, como so varves dferentes, o vaor de n dentro de
main contnua sendo 2. Ao termnar o chamado, a funo fat devove o vaor 6 ao
ugar onde fo chamado dentro da funo main, e o programa contnua para cacuar o
vaor da expresso fat(n+1)/(n+1). Como o vaor de n contnua 2, o resutado da
dvso . Esse vaor atrbudo varve res. O tmo printf mprme o vaor de n
e res, que correspondem aos vaores 2 e 2, respectvamente.
)assagem por (eer4ncia
Sempre que possve recomendve utzar a forma de passagem por vaor, para
evtar "efetos coateras", mas h stuaes onde esses efetos so dese|ves, por
exempo, quando dese|amos crar uma funo que retorne mas de um vaor. As
funes que vmos at agora, seno, cosseno, potenca, fatora, etc, s devovem um
vaor, mas que outras funes, que trabahem com nmeros magnros por exempo,
precsam retornar 2 vaores. Por exempo, tente escrever uma funo que retorne o
quadrado de um nmero magnro.
Sabemos que um nmero magnro (ou compexo) possu uma parte rea e outra
compexa , e podemos escrever esse nmero como , onde , e o quadrado de como .
Assm, a varve compexa tem parte rea e parte compexa .
Poderamos fazer uma funo para retornar apenas a parte rea, e outra para retornar
apenas a parte magnra. Mas o C permte crar uma funo que retorne os dos
vaores smutaneamente. Observe a segunte funo:
void complexo2 (float *r, float *t)
{
float real;
real = (*r * *r) - (*t * *t);
*t = 2 * *r * *t;
*r = real;
}
Funes do tpo void como dendas acma correspondem a funes que no
retornam um vaor. No entanto, o smboo '*' na deno dos parmetros rea e
magnro da funo complexo2 ndcam que esses parmetros PODEM ser
modcados dentro da funo, ou se|a, ateraes que esses parmetros sofrerem
sero sentdas FORA da funo, que correspondem aos efetos coateras que NOO
OCORREM quando os parmetros so passados por vaor (sem o uso do caractere '*').
Note anda que essa notao pode ser confusa, pos como o parmetro de entrada
*r e *t, dentro da funo voc precsa utzar esses mesmos "nomes", e sso pode
car confuso quando utzamos esses parmetros para reazar mutpcaes.
Vamos agora ver um programa que utza essa funo:
#include <stdio.h>
#include <stdlib.h>
/* definicao do prototipo */
void complexo2 (float *r, float *t);
int main ()
{
float a, b;
printf ("Entre com um numero complexo (2 numeros inteiros): ");
scanf("%f %f", &a, &b);
complexo2 ( &a, &b);
printf("O quadrado do nmero complexo %f + i %f\n", a, b);
system("pause");
return 0;
}
Observe que no man so decaradas apenas duas varves reas a e b. Observe
tambm que tanto na chamada da funo scanf quanto na chamada da funo
complexo2, as varves a e b so preceddas peo caractere '&'. Nesse caso, esse
caractere ndca que queremos que esses parmetros se|am modcados pea funo,
e retornem os vaores aproprados. No caso da funo scanf, esses vaores
correspondem aos vaores dgtados peo usuro, mas no caso da funo complexo2,
esses vaores so computados pea funo. Fnamente, observe tambm que os
prpros vaores armazenados nas varves a e b so utzados como entrada da
funo complexo2, ou se|a, esses vaores so utzados como parte rea e magnra
para cacuar o vaor do quadrado do nmero compexo, e ao mesmo tempo so
utzados para devover o resutado. Assm, no caso da scanf, os parmetros a e b so
utzados apenas para sada, e no caso da complexo2, os parmetros a e b so
utzados como entrada E sada da funo.
| na funo prntf, as varves a e b no so preceddas peo caractere '&', e portanto
NO SO modcadas pea funo printf.
RESUMINDO, quando dese|amos crar uma funo que devova mas de um vaor,
precsamos denr esses parmetros com um caractere '*' no prottpo da funo, e ao
chamar a funo, os parmetros utzados na chamada correspondentes sada
precsam ser preceddos peo caractere '&' para ndcar que ees podem ser
modcados pea funo chamada.
)onteiros ou #pontadores
Se voc entendeu como crar funes que modcam os parmetros (usando '*') e
como chamar essas funes em seus programas (usando '&'), voc no precsa saber
o que so ponteros ou apontadores por enquanto, mas se voc quser saber como
sso mpementado na nguagem C, ento contnue com a sua etura.
Um apontador ou pontero um tpo de varve que no contm um vaor, mas um
endereo. Lembre-se que a memra do computador organzada na forma de uma
tabea. Cada nha da tabea possu um endereo, e em cada endereo podemos
armazenar um vaor. Cada varve, ao ser crada, assocada a um endereo. Ouando
uma varve utzada em uma expresso do ado dreto de uma atrbuo, seu
endereo utzado para buscar seu vaor, e esse vaor utzado para cacuar o
resutado da expresso. Ouando uma varve utzada do ado esquerdo, seu
endereo utzado para armazenar o resutado da expresso correspondente na
memra. Assm, cada varve possu um endereo dferente e nco, e os
apontadores so varves capazes de manpuar endereos.
Para decarar uma varve do tpo pontero utzamos a segunte estrutura:
tipo *nome;
O astersco ('*') a ndcao que a varve nome um apontador, e o endereo
apontado nterpretado como um vaor do tpo tipo. Portanto, os parmetros de
entrada da funo complexo2 so na verdade apontadores. O uso de varves de tpo
apontador bastante smpes:
int x,y; /* duas variveis inteiras */
int *px,*py; /* dois apontadores para inteiros */
x = 1; /* atribui varivel x o valor 1. */
y = 2; /* atribui varivel y o valor 2. */
px= &x; /* atribui ao apontador px o endereco da variavel x. */
py= &y; /* atribui ao apontador py o endereco da variavel y. */
O sgncado das atrbues acma o segunte. O operador '&' um operador unro
(de derefernca) que retorna o endereo de seu operando. Assm, podemos manpuar
o endereo apontado por uma varve de tpo pontero.
Um outro operador mportante o operador '*' (operador unro de refernca) que
devove o vaor contdo em uma poso de memra apontada por uma varve de
tpo pontero.
Por exempo:
int x,y;
int *px,*py;
x = 1; /* atribui varivel x o valor 1. */
y = 2; /* atribui varivel y o valor 2. */
px= &x; /* atribui ao ponteiro px o endereco da variavel x. */
py= &y; /* atribui ao ponteiro py o endereco da variavel y. */
printf("O endereco de x eh %d e o valor de x eh %d",px,*px);
onde o *px sgnca, teramente, o vaor da poso de memra apontado por px.
Vamos examnar um outro exempo de funes utzando apontadores:
void Troca(int *px, int *py); /* Prototipo. */
int main() {
int x=4,y=7;
/** Ao chamar a funcao passamos o endereco
* das variaveis x e y como parametro.
*/
Troca(&x,&y);
printf("Troca: x vale %d e y vale %d",x,y);
Troca(&x,&y);
printf("Destroca: x vale %d e y vale %d",x,y);
system("pause");
return 0;
}
void Troca(int *px, int *py)
/* Troca os valores das variaveis apontadas por px e py. */
{
int n;
n= *py;
*py= *px;
*px= n;
}
Ao examnarmos a funo Troca, vercamos que houve manpuao nos vaores das
poses cu|os endereos foram passados como parmetro. Deste modo que
consegumos mpementar funes cu|a ao estendda a mas de uma varve (ou
se|a, retorna mas de um vaor).
Vamos ver mas um exempo, usando agora a funo Troca em um programa para
ordenar 3 nteros em ordem crescente, como abaxo:
#include <stdio.h>
#include <stdlib.h>
/* prototipo */
void Troca(int *px, int *py);
int main ()
{
int a, b, c;
printf ("Digite 3 numeros inteiros: ");
scanf("%d %d %d", &a, &b, &c);
if (a > b) Troca (&a, &b);
if (b > c) Troca (&b, &c);
if (a > b) Troca (&a, &b);
printf("Em ordem crescente: %d %d %d\n", a, b, c);
system("pause");
return 0;
}
Por exempo, para a seqnca 3 2 1, teramos:
a b c
nco: 3 2 1
1o f : 2 3 1
2o f : 2 1 3
3o f : 1 2 3
e portanto a sada sera Em ordem crescente: 1 2 3
Erros comuns com un'es
A segur stamos aguns erros comuns cometdos quando se comea a aprender
funes. Procure evta-os:
usar scan dentro de un'es para ler os par2metros Lembre-se que os
parmetros so passados para a funo, por vaor ou refernca, na hora da sua
chamada. Esses vaores no devem ser dos novamente atravs da scanf.
es7uecer o 898 na passagem de par2metros por reer4ncia Nesse caso, o vaor
da varve nterpretado como um endereo, e a funo va tentar modcar
uma rea da memra que pode estar sendo usada por outro programa. Nos
sstemas modernos h protees que mpedem que esses erros aconteam.
es7uecer o 8:8 no uso de um par2metro passado por reer4ncia Nesse caso, o
vaor da varve um endereo e no um vaor, e os ccuos sero portanto
nvdos.
usar um apontador sem iniciali;ar usar varves sem ncazao | causam
probemas, mas usar um apontadores sem ncazao pode causar probemas
anda mas sros, pos voc pode aterar endereos da memra que no foram
reservados ao seu programa, mas | esto sendo utzados por outros
programas.
conundir o escopo de 3ari63eis com mesmo nome mpressonante que no
tenhamos pacnca para escrever nomes de varves que correspondam a sua
funo, e ao nvs utzemos etras como , |, k, etc. Assm no dfc confundr
varves com mesmo nome mas em escopos dferentes.
Eoza Sonoda
Caracteres <Char=
(esumo
O tpo char utzado para representar caracteres. Um caractere representado
atravs de um byte na memra. Lembre-se que um byte tem 8 bts, ou se|a,
possve representar 256 nmeros (ou no caso, codcar at 256 caracteres dstntos).
A nguagem C utza esse nmero como um ndce na tabea ASCII.
Para er e mprmr caracteres, utze '%c' no scanf e no prntf. Ouando uma teca
dgtada (da peo scanf) o cdgo correspondente teca traduzdo para o nmero
bnro correspondente, e armazenado na varve utzada no scanf. Ouando uma
varve caractere utzada no prntf, esse nmero utzado para mprmr o
caractere correspondente na tabea ASCII.
Descrio
At agora vmos como o computador pode ser utzado para processar nformao que
pode ser quantcada de aguma forma numrca, se|a ea ntera ou rea. Por exempo,
o nmero mxmo em uma seqnca de nmeros nteros ou o vaor rea de uma sre
de Tayor para a aproxmao da funo seno.
H muta nformao porm que no nmerca, como por exempo o seu nome,
endereo, uma fotograa sua ou o som de sua voz. Para que possam ser processadas
peo computador, precsamos de uma forma para representar essas nformaes
utzando apenas 0's e 1's, que o que consegumos armazenar em computadores
dgtas.
Textos so compostos por caracteres do afabeto, numrcos, de pontuao,
acentuao, etc. Am desses caracteres, para processar textos e permtr sua edo,
o computador tambm consdera como "caracteres especas" aguns eventos que, em
um edtor de texto no computador, servem para movmentar o cursor, apagar
caracteres, etc.
Caracteres so representados na nguagem C atravs da tabea ASCII (American
Standard Code for Information Interchange). Apenas a poso do caractere
correspondente nessa tabea armazenada em uma varve do tpo char. A tabea
ASCII orgna composta por 128 caracteres, e portanto 7 bts seram sucentes para
representar uma poso da tabea. Como a memra organzada em bytes, o bt
restante fo depos utzado para crar uma tabea com mas caracteres, entre ees
vros caracteres acentuados nexstentes na ngua ngesa (que fo utzada para
crar a tabea ASCII orgna).
Para saber mas sobre a tabea ASCII, vste http://en.wkpeda.org/wk/ASCII.
Entrada e sa!da
Para er e mprmr caracteres, utze '%c' no scanf e no prntf. Ouando uma teca
dgtada (da peo scanf) o cdgo correspondente teca traduzdo para o nmero
bnro correspondente, e armazenado na varve utzada no scanf. Ouando uma
varve caractere utzada no prntf, esse nmero utzado para mprmr o
caractere correspondente na tabea ASCII.
Exemplos com char
Exemplo 1:
As prmeras 32 poses (de 0 a 31) da tabea ASCII so utzadas para caracteres
especas de controe. Faa um programa em C que mprma todos os caracteres da
poso 32 a 126.
Soluo:
#include <stdio.h>
#include <stdlib.h>
int main () {
/* Declaraes */
char c;
int i;
printf("Usando char\n");
for (c = 32; c < 127; c++)
printf("Pos %d: char %c \t", c, c);
printf("\n\nUsando int\n");
for (i = 32; i < 127; i++)
printf("Pos %d: char %c \t", i, i);
system ("pause");
return 0;
}
Observe que, como o tpo char na verdade armazena um nmero correspondente
poso do caractere na tabea, esse nmero pode ser mpresso como um nmero
ntero. No prntf dentro do prmero for, a varve c utzada tanto como ntero
(usando '%d' na mpresso), como caractere (usando '%c' para mpresso).
Observe que dentro do segundo for, uma varve ntera fo utzada tambm como
char (%c) e nt (%d), obtendo exatamente o mesmo resutado.
Voc pode utzar varves do tpo char dentro de expresses numrcas como se
fossem varves nteras, porm, embre-se de que, como uma varve char utza
apenas um byte, os vaores que ea pode representar varam de -128 a +127.
Exemplo 2:
Escreva um programa que ea um caractere mnscuo e transforme-o em mascuo.
Soluo:
para escrever esse programa, no precsamos utzar a tabea ASCII dretamente,
apenas precsamos saber como ea fo denda.
De uma forma gera, bom saber que os dgtos de '0' a '9' ocupam poses na
tabea antes das etras mascuas 'A' a 'Z', que por sua vez ocupam poses na
tabea antes das etras mnscuas de 'a' a 'z'. Assm possve comparar dos
caracteres, de forma que a segunte reao vda:
'0' < '1' < ... < '9' < 'A' < 'B' < ... < 'Z' < 'a' < ... < 'z'.
Essa reao t, por exempo, para reazar uma ordenao afabtca, ou para
resover esse exercco. Ve|a a souo abaxo:
#include <stdio.h>
#include <stdlib.h>
int main () {
char letra, dif;
printf("Digite um letra minuscula: ");
scanf("%c", &letra);
if (letra >= 'a' && letra <= 'z') {
/* sabemos que uma letra minscula */
dif = letra - 'a'; /* distancia at a letra a */
letra = 'A' + dif; /* a mesma distacia de 'A' */
printf("Maiuscula: %d \n", letra );
}
else
printf("\n %c nao e uma letra minuscula\n", letra);
system ("pause");
return 0;
}
Para converter uma etra mnscua para mascuo, como sabemos que a tabea est
em ordem afabtca, a "dstnca" (dferena) do caractere mnscuo do em etra
at a prmera etra ('a') a mesma de 'A' (prmera etra mascua) at o
correspondente mascuo.
Observao:
Suponha que o exerccio tivesse pedido que se mostrasse a letra maiscula e sua
respectiva posio em ASCII.
Temse a certe!a de que voc"# inteligente estudante da $olit%cnica# sa&eria adaptar o
pro&lema de imediato.
Como de costume# est' a&aixo a to esperada soluo:
#include <stdio.h>
#include <stdlib.h>
int main ()
{
char letra, dif;
printf("Digite um letra minuscula: ");
scanf("%c", &letra);
if (letra >= 'a' && letra <= 'z')
{ /* Para o caso de o usurio ter digitado uma letra minscula
*/
dif = letra - 'a'; /* distancia at a letra a */
letra = 'A' + dif; /* a mesma distancia de 'A' */
/* Note que aqui utilizamos a mesma ttica do Exemplo 1, ao
especificarmos a posio *
* que o caractere ocupa na tabela ASCII */
printf("Maiuscula: %c, que ocupa a posicao %d na tabela ASCII
\n", letra,letra );
}
else
/* Para o caso de o usurio ter desrespeitado a observao feita
no programa *
* e ter, por acidente, digitado uma letra maiscula */
printf("\n %c nao e uma letra minuscula\n", letra);
system ("pause");
return 0;
}
Eoza Sonoda
5etores
Vetores so estruturas ndexadas utzadas para armazenar dados de um mesmo tpo.
Para decarar um vetor use a construo:
tipo_do_vetor nome_do_vetor[tamanho];
Para acessar um eemento do vetor, basta utzar o nome_do_vetor segudo do
nmero que corresponde poso do eemento dese|ado (o ndce do eemento) entre
cochetes. O nome com esse ndce pode ser utzado em seu programa como se fosse
uma varve quaquer.
Descrio:
Um vetor (array) uma estrutura ndexada por um ndce que armazena dados de um
mesmo tpo bsco (por enquanto, nteros e reas). Ouando um vetor de tamanho
decarado, uma rea da memra, sucente para armazenar todos os eementos do
vetor, reservada. Essa rea recebe o nome do vetor, e seus eementos podem ser
acessados atravs de um ndce entre cochetes (||). O prmero eemento do vetor
acessado peo ndce 0 (zero), e o tmo peo ndce . O C no verca se esses ndces
so vdos e probemas muto sros podem acontecer caso voc tente acessar uma
poso nvda do vetor (ou se|a, fora do ntervao de 0 a ).
Como declarar um 3etor
Um vetor deve ser decarado da segunte forma:
tipo_do_vetor nome_do_vetor[tamanho];
Exempos:
int vetorInt[6]; /* vetor de 6 inteiros, chamado vetorInt */
float vetorFloat[9]; /* vetor de 9 reais, chamado vetorFloat */
Observe que os vetores so decarados como se fossem varves, exceto que ee
recebe um nmero entre cochetes que dene o tamanho do vetor. Nesse caso, o
vetor vetorInt possu 6 nteros, e o vetor vetorFloat possu 9 reas.
Uma vez decarado, reservada uma rego na memra sucente para armazenar
todo o vetor. A gura abaxo mostra essa estrutura para o vetor vetorInt:
)osio Conte>do Coment6rio
0 ? vaor nca
desconhecdo
1 ? vaor nca
desconhecdo
2 ? vaor nca
desconhecdo
3 ? vaor nca
desconhecdo
4 ? vaor nca
desconhecdo
5 ? vaor nca
desconhecdo
&igura 1: rea da memra reservada para o vetor nome1. Observe que so
reservadas 6 poses, nmeradas de 0 a 5.
Como usar 3etores em seus programas
Cada poso do vetor pode ser consderada uma varve, que pode ser acessada
atravs do nome do vetor e mas um ndce entre cochetes para ndcar a poso
dese|ada. Por exempo, o trecho de programa abaxo cooca o vaor zero em cada uma
das poses do vetor vetorInt:
for (i = 0; i < 6; i++)
vetorInt[i] = 0;
O ndce na verdade pode ser uma expresso, como abaxo:
for (i = 10; i < 16; i++)
vetorInt[i-10] = 0;
mas tenha absouta certeza, porm, de sempre fornecer um ndce vdo.
Exemplos comentados
)ro?lema 1:
Dados nmeros nteros, mprm-os em ordem nversa a da etura.
Exempo: entrada: 5 11 12 3 41 321 sada: 321 41 3 12 11
Para resover esse probema, precsamos armazenar todos os eementos da seqnca
em um vetor, e depos mprmr esses eementos em ordem nversa. Sem essa
estrutura, usando apenas varves, sera muto dfc resover esse probema para um
vaor arbtrro de .
Um programa possve, usando vetores, sera:
define MAX 100
include <stdio.h>
include <stdlib.h>
int main () {
int i, n;
int vet[MAX];
printf("Digite o valor de n: ");
scanf("%d", &n);
/* leitura do vetor */
for (i=0; i<n; i!++)
scanf("%d", &vet[i]);
/* impresso do vetor */
printf("Vetor em ordem inversa: ");
for (i=n-1; i>=0; i--)
printf(" %d", vet[i]);
system("pause");
return 0;
}
Observe que o tamanho do vetor xo, e deve ser dendo antes do programa ser
executado. um erro muto comum entre programadores nexperentes er um nmero
e utz-o para denr o tamanho do vetor. Nesse programa, o vaor mte fo dendo
como MAX e possu vaor 100. Esse programa no pode ser executado para seqncas
maores que 100. Esse programa no testa se vdo, como voc fara esse teste?
Aps a etura (carregamento) do vetor, a estrutura correspondente na memra pode
ser representada pea tabea abaxo:
Poso Contedo Comentro
0 11 vaor do peo 1o scanf
1 12 vaor do peo 2o scanf
2 3 vaor do peo 3o scanf
3 41 vaor do peo 4o scanf
4 321 vaor do peo 5o scanf
5 ? vaor nca
desconhecdo
&igura 2: Observe que apenas as 5 prmeras poses (pos ) receberam vaores
Observe com cudado a nha do programa utzada para carregar o vetor:
scanf("%d", &vet[i]);
A poso do vetor vet, ou se|a, vet[i], utzada da mesma forma que utzamos
quaquer varve at o momento. Essa "varve" passada para a funo scanf
precedda peo caractere '&'.
Agora observe a parte do programa para mprmr o vetor nvertdo. Como o vetor fo
carregado como mostra a gura acma, devemos comear na tma poso
carregada e decrementar at a prmera. A tma poso carregada nesse caso fo a
poso 4, e a prmera fo 0.
)ro?lema 2:
Dados anamentos de uma roeta (nmeros entre 0 e 36), cacuar a freqnca de
cada nmero.
Como a gente cacua a freqnca de um nmero? Basta contar quantas vezes ee
aparece na seqnca, e dvdr peo tota de nmeros da seqnca. Precsamos
portanto crar um contador para cada resutado possve, ou se|a, 37 contadores. Cada
contador comea com zero, e toda vez que anamos a roeta, a gente ncrementa
apenas o contador correspondente. Ao na, basta cacuar as freqncas. A souo
competa dada abaxo:
include <stdio.h>
include <stdlib.h>

int main () {
int resultado; /* resultado de uma jogada */
int n; /* total de jogadas */
int vet[37];
/* inicializacao do vetor */
for (resultado = 0; resultado < 37; resultado++)
vet[resultado] = 0;

printf("Digite o valor de n: ");
scanf("%d", &n);
/* contagem dos resultados */
for (i=1; i<=n; i++) {
printf("Digite o resultado da jogada %d :", i);
scanf("%d", &resultado);
vet[resultado] = vet[resultado] + 1;
}
/* impresso do resultado */
for (resultado = 0; resultado < 37; resultado++)
printf("Frequencia do resultado %d = %f \n",
resultado, (float)vet[resultado]/n);

system("pause");
return 0;
)ro?lema 3
Dada uma seqnca de nmeros reas termnando com zero, mprm-os emnando
as repetes e ndcando quantas vezes cada um aparece na seqnca.
Exempo:
entrada: 1.51 3.14 2.78 3.14 8.2 2.78 0
sada:
1.51 2
3.14 1
2.78 2
8.2 1
(ES-L%0@-:
Para er e mprmr os nmeros sem repeto, podemos utzar um vetor para
armazenar os nmeros dos. Caso o nmero | este|a no vetor, ento ee pode ser
gnorado, e quando o nmero no est no vetor, ento ee deve ser ntroduzdo no
vetor. Como precsamos tambm contar quantas vezes cada nmero aparece na
seqnca, assm como no probema da roeta, precsamos crar tambm um vetor de
contadores. Se o nmero | pertence ao vetor, ento basta ncrementar o contador
correpondente, caso contrro, o nmero ntroduzdo no vetor de dados e o contador
correspondente ncazado (com 1).
Por exempo, ve|a a seqnca de transformaes abaxo. Tanto o vetor dados quanto
o vetor contador comeam sem ncazao.
poso vetor dados vetor contador
0 ? ?
1 ? ?
2 ? ?
3 ? ?
4 ? ?
5 ? ?
... ? 0
Ouando o prmero nmero do, a tabea deve ser atuazada para:
poso vetor dados vetor contador
0 1.51 1
1 ? 0
2 ? 0
3 ? 0
4 ? 0
5 ? 0
... ? 0
O segundo e tercero nmeros (3.14 e 2.78) tambm so novos, ento os coocamos
tambm no vetor de dados, com os respectvos contadores guas a 1:
poso vetor dados vetor contador
0 1.51 1
1 3.14 1
2 2.78 1
3 ? 0
4 ? 0
5 ? 0
... ? 0
O quarto nmero da seqnca 3.14. Ee | aparece na seqnca, e portanto
devemos apenas ncrementar o contador correspondente:
poso vetor dados vetor contador
0 1.51 1
1 3.14 2
2 2.78 1
3 ? 0
4 ? 0
5 ? 0
... ? 0
e o programa contnua at encontrar um zero na entrada. O segunte programa uma
souo possve para o procedmento descrto acma:

include <stdio.h>
include <stdlib.h>
define MAX 100
define TRUE 1
define FALSE 0
int main () {
float dados[MAX];
int contador[MAX];
float num; /* numero lido da sequencia */
int final = 0; /* numero de indices sendo utilizados */
int achei; /* TRUE se num esta no vetor */
int i;
printf("Digite um numero da sequencia: ");
scanf( "%f", &num );
while (num != 0)
{
/* sera que num esta no vetor dados?
A variavel achei um indicador de passagem, comeca com FALSE,
e recebe TRUE se o valor de num estiver no vetor dados
*/
achei = FALSE;
for (i=0; i<final; i++) {
if (dados[i] num ) {
achei = TRUE;
contador[i] = contador[i] + 1;
}
}
if (achei FALSE) {
/* colocar num no vetor de dados e inicializar contador */
dados[final] = num;
contador[final] = 1;
final++;
}
printf("Digite um numero da sequencia: ");
scanf( "%f", &num );
}
/* imprima o resultado */
for (i=0; i<final; i++)
printf("Num: %.2f x %d\n", dados[i], contador[i]);
system("pause");
return 0;
}
Erros comuns
Ao desenvover seus programas com vetores, preste ateno com reao aos
seguntes detahes:
ndces nvdos: tome muto cudado, especamente dentro de um whe ou for, de
no utzar ndces negatvos ou maores que o tamanho mxmo do vetor.
Deno do tamanho do vetor: se faz na decarao do vetor. O tamanho dee
constante, s mudando a sua decarao que podemos aterar o seu tamanho.
Isso sgnca que podemos estar "desperdando" agum espao que ca no
na do vetor. No cometa o erro de er , onde sera o tamanho do vetor, e
tentar "decarar" o vetor em seguda.

5etores e ponteiros
O nome_do_vetor utzado na decarao do vetor pode ser utzado tambm como
um pontero que aponta para o endereo da prmera poso do vetor.
O ndce dos cochetes podem ser nterpretados como uma expresso artmtca com
ponteros, da segunte forma: Se vet o nome de um vetor e tambm um pontero,
ento *vet o vaor armazenado na poso zero do vetor (sua 1a poso), ou se|a,
vet[0]. Da mesma forma, o eemento vet[i] equvaente a *(vet+i), ou se|a, o
vaor apontado peo apontador vet desocado de poses.
Esse conceto ser fundamenta para entender como a nguagem C mpementa
funes que acetam vetores como parmetros.
Exerc!cios (ecomendados
Escreva um programa que ea um ntero postvo m, os coecentes de um
ponmo rea p0 de grau n, trs reas x0, x1 e x2 e cacue p0(x0), p1(x1) e
p2(x2), onde p1 e p2 so respectvamente a prmera e a segunda dervada do
ponmo p0.
Dada uma seqnca de n nmeros nteros, determnar um segmento de soma
mxma. Exempo: Na seqnca 5, 2, -2, -7, 3A 1BA 1CA -3A D, -6, 4, 1 a soma do
segmento 33.
Dada uma seqnca de nmeros nteros, verque se exstem dos segmentos
consecutvos guas nesta seqnca, sto , se exstem e tas que:
Imprma, caso exstam, os vaores de e . Exempo: Na seqnca 7, 9, 5, 4, 5, 4, 8, 6
exstem e .
Eoza Sonoda
Eatri;es
(esumo:
Matrzes so estruturas b-dmensonas utzadas para armazenar dados de um
mesmo tpo. Para decarar uma matrz use a segunte construo:
tipo_da_matriz nome_da_matriz [num_linhas][num_colunas];
Para acessar os eementos da matrz, basta denr cada coordenada dese|ada
entre cochetes, ou se|a, use A||||| para acessar o eemento (,|) da matrz A.
Uma matrz pode ser consderada como um vetor de vetores, assm, o nome da
matrz, por exempo A, utzado para referencar toda a estrutura
bdmensona de A, mas cada nha da matrz pode ser utzada para
referencar uma couna (correspondente aos eementos da nha A||). Ouando
os dos ndces so fornecdos, ento acessamos um eemento da matrz. Ve|a
que dessa forma, no possve referencar uma couna dretamente.
Descrio:
Uma matrz uma estrutura bdmensona capaz de armazenar dados de um
mesmo tpo. Podemos consderar o conceto de matrz como uma extenso do
conceto de vetores, onde vetores correspondera a uma estrutura
undmensona. As matrzes (e vetores) s podem ser acessados atravs de
ndces nteros, ou se|a, a dmenso de uma matrz denda atravs de 2
nmeros, o nmero de nhas e o de counas. Na nguagem C, o prmero ndce
(escrto mas perto do nome da matrz) sempre corresponde nha, e o
segundo ndce, couna a ser acessada.
Como declarar uma matri;
Uma matrz deve ser decarada da segunte forma:
tipo_da_matriz nome_da_matriz [num_linhas][num_colunas];
Exempos:
int matInt [6][2]; /* matriz com 6 linhas e 2 colunas de
inteiros */
float matReal [5][7]; /* matriz com 5 linhas e 7 colunas de
floats */
char matChar [3][4]; /* matriz com 3 linhas e 4 colunas de
chars */
Observe que a decarao de matrzes semehante decarao de vetores,
porm necessro denr o tamanho da segunda dmenso. Na prmera
decarao, todos os eementos da matrz matInt so nteros. O prmero
nmero dene o nmero de nhas e o segundo o nmero de counas a serem
reservados na memra do computador para armazenar essa matrz. A segunda
decarao reserva uma matrz de oats, com 5 nhas e 7 counas.
Uma vez decarada, por exempo a matrz matChar com 3 nhas e 4 counas,
reservada uma rego na memra sucente para armazenar toda a matrz. A
gura abaxo mostra essa estrutura:
Lnha Couna Contedo Comentro
0 0 ? vaor nca
desconhecdo
0 1 ? vaor nca
desconhecdo
0 2 ? vaor nca
desconhecdo
0 3 ? vaor nca
desconhecdo
1 0 ? vaor nca
desconhecdo
1 1 ? vaor nca
desconhecdo
1 2 ? vaor nca
desconhecdo
1 3 ? vaor nca
desconhecdo
2 0 ? vaor nca
desconhecdo
2 1 ? vaor nca
desconhecdo
2 2 ? vaor nca
desconhecdo
2 3 ? vaor nca
desconhecdo
&igura 1: rea da memra reservada para a matrz matChar. Observe que so
reservadas 12 poses, cada uma das 3 nhas tem 4 counas.
Observe que a matrz pode ser consderada como um vetor de vetores, ou se|a,
a matrz um vetor de nhas, e cada nha um vetor de counas. Essa da
ser exporada nos exempos a segur.
Como usar matri;es em seus programas
Assm como vetores, cada poso da matrz funcona como uma varve, que
pode ser acessada atravs do nome da matrz e os ndces entre cochetes que
ndcam a coordenada dese|ada. Por exempo, o trecho de programa abaxo
cooca o caractere '*' em cada uma das poses do vetor matChar:
for (lin = 0; lin < 3; lin++)
for (col = 0; col < 4; col++)
/* lembre-se que um char deve vir entre apostrofes */
matChar[lin][col] = '*';
O ndce na verdade pode ser uma expresso, mas assm como vetores, tenha
sempre cudado de fornecer um ndce vdo.
Exemplos comentados
)(-FLEE# 1
Faa um programa que ea , e os eementos de uma matrz rea quadrada e
mprma quas nhas, counas e dagonas (prncpa e secundra) da matrz
so compostas apenas por zeros.
Souo (ve|a os comentros no prpro programa):
#include <stdio.h>
#define MAX 100
#define SIM 1
#define NAO 0
#define EPS 0.001
/*
funo saoIguais: compara se 2 numeros reais so iguais
devido a preciso numrica, dois reais NO devem ser comparados
diretamente para determinar igualdade
*/
int saoIguais(float f1, float f2) {
int res = NAO;
float dif = f1 - f2;
if (dif < EPS && dif > -EPS)
res = SIM;
return res;
}
int main () {
float A [MAX][MAX]; /* reservando espao para uma matriz MAX x
MAX */
int m, lin, col, soZero;

/* leitura dos dados */
printf("Entre com o tamanho da matriz quadrada: ");
scanf("%d", &m);
printf("Entre com os elementos da matriz\n");
for (lin=0; lin<m; lin++)
for (col=0; col<m; col++)
scanf("%f", &A[lin][col]);

/* verifica se existe alguma linha s com zeros */
for (lin = 0; lin < m; lin++) { /* para cada linha ... */
soZero = SIM; /* soZero um indicador de
passagem que */
for (col = 0; col < m; col++) /* muda de valor se a linha
conter algum */
if (saoIguais(A[lin][col], 0.0) NAO)
soZero = NAO; /* elemento diferente de zero */
if (soZero SIM) /* imprime a resposta parcial */
printf("A linha %d tem so zeros\n", lin);
}

/* verifica se existe alguma coluna s com zeros */
for (col = 0; col < m; col++) {
soZero = SIM;
for (lin = 0; lin < m; lin++)
if (saoIguais(A[lin][col], 0.0) NAO)
soZero = NAO; /* elemento diferente de zero */
if (soZero SIM)
printf("A coluna %d tem so zeros\n", col);
}
/* verifica diagonal principal */
soZero = SIM;
for (lin = 0; lin < m; lin++)
/* na diagonal, lin igual a col */
if (saoIguais(A[lin][lin], 0.0) NAO)
soZero = NAO;
if (soZero SIM)
printf("A diagonal principal tem so zeros\n");
/* verifica diagonal secundria */
soZero = SIM;
for (lin = 0; lin < m; lin++)
if (saoIguais(A[lin][m-1- lin], 0.0) NAO)
soZero = NAO;
if (soZero SIM)
printf("A diagonal secundaria tem so zeros\n");

return 0;
}
)(-FLEE# 2 - &%,01ES C-E E#.("GES:
O uso de matrzes em funes bem semehante ao uso de vetores, ou se|a,
sempre por refernca. Como exempo, vamos escrever um programa que
duas matrzes e cacua o seu produto, mas dessa vez, usando funes para er
e mprmr as matrzes.
Vamos prmero escrever uma funo que carrega uma matrz rea .
void leMatriz(float M[MAX][MAX], int m, int n) {
int lin, col;
for (lin=0; lin<m; lin++)
for (col=0; col<n; col++)
scanf("%f", &M[lin][col]);
}
Observe a deno da matrz como parmetro da funo leMatriz e que na
chamada da funo scanf, o endereo de cada eemento passado atravs de
&M[lin][col]). A dmenso das nhas na verdade facutatva, ou se|a, o
prottpo:
void leMatriz(float M![][MAX], int m, int n);
tambm vdo. Porm, a deno da segunda dmenso obrgatra, pos
caso contrro o compador no sera capaz de cacuar as poses corretas
dos eementos da matrz na memra (no sabera quantas counas puar para
chegar na prxma nha). Acredtamos que essa notao possa ser confusa no
nco, e portanto manteremos a notao que dene as duas dmenses.
Vamos agora escrever uma funo para mprmr uma matrz rea :
void imprimeMatriz(float M[MAX][MAX], int m, int n) {
int lin, col;
for (lin=0; lin<m; lin++) {
for (col=0; col<n; col++)
printf("%.2f \t", M[lin][col]);
printf("\n"); /* muda de linha */
}
}
Fnamente, vamos escrever o programa que mutpca duas matrzes:
#include <stdio.h>
#define MAX 100
void leMatriz(float M[MAX][MAX], int m, int n);
void imprimeMatriz(float M[MAX][MAX], int m, int n);
/* Seja A uma matriz de dimenso r x s e B uma matriz de
dimenso s x t. Esse programa calcula o produto de A x B,
resultando em uma matriz C de dimenso r x t
*/
int main () {
float A[MAX][MAX], B[MAX][MAX], C[MAX][MAX];
int r,s,t;
int lin, col, k;
float soma;
printf("Este programa calcula o produto de 2 matrizes\n");
printf("Digite as dimenses das matrizes: ");
scanf("%d %d %d", &r, &s, &t);
printf("Entre com os valores da matriz A\n");
leMatriz(A, r, s);
printf("Entre com os valores da matriz B\n");
leMatriz(B, s, t);
/* a matriz C tem r linhas e t colunas */
for (lin = 0; lin < r; lin++) {
for (col = 0; col < t; col++) {
/* calculo do produto da linha lin pela coluna col */
soma = 0;
for (k = 0; k<s; k++)
soma = soma + A[lin][k]*B[k][col];
C[lin][col] = soma;
}
}
/* vamos imprimir o resultado */
imprimeMatriz(C, r, t);
return 0;
}
Sabemos que um eemento da sada pode ser cacuado atravs da frmua:
Observe que h 3 comandos for encaxados. Dos dees so utzados para
vstar todos os eementos da sada (a matrz tem dmenso , e o tercero
utzado para cacuar o vaor da matrz em cada poso, varando .
Eatri;es e 5etores
Uma matrz pode ser consderada como um vetor de vetores, assm, o nome da
matrz (por exempo A) utzado para referencar toda a estrutura
bdmensona de A (ve|a, em partcuar, como a matrz A fo passada para as
funes leMatriz e imprimeMatriz dentro do programa anteror).
Mas com A um vetor de vetores, cada nha da matrz pode ser utzada para
referencar um vetor couna (a nha A|| um apontador para o nco do vetor
couna correspondente nha A||). Ouando os dos ndces so fornecdos,
ento acessamos um eemento da matrz. Ve|a que no possve referencar
uma couna dretamente como um vetor devdo a manera utzada para
armazenar uma matrz (ve|a a tabea 1), ou se|a, a matrz mantm a ordem
near dos eementos em uma nha, mas no mantm essa ordem para os
eementos de uma couna.
Vamos ver um exempo, usando o mesmo programa de produto de matrzes, e
a funo produtoEscalar vsto na aua sobre funes com vetores. Para sua
convennca, a funo produtoEscalar copada abaxo:
float produtoEscalar (float V1[MAX], float V2[MAX], int N) {
int i;
float res = 0;
for (i=0; i<N; i++)
res = res + V1[i] * V2[i];
return res;
}
Observe que o procedmento para mutpcar uma nha da matrz A por uma
couna da matrz B o mesmo procedmento do produto escaar. Sabendo que
cada nha da matrz pode ser consderado um vetor (mas no as counas), o
segunte programa cacua o produto de duas matrzes:
#include <stdio.h>
#define MAX 100
void leMatriz(float M[MAX][MAX], int m, int n);
void imprimeMatriz(float M[MAX][MAX], int m, int n);
float produtoEscalar (float V1[MAX], float V2[MAX], int N);
/* Seja A uma matriz de dimenso r x s e B uma matriz de
dimenso s x t. Esse programa calcula o produto de A x B,
resultando em uma matriz C de dimenso r x t
*/
int main () {
float A[MAX][MAX], B[MAX][MAX], C[MAX][MAX], vet[MAX];
int r,s,t;
int lin, col, k;
printf("Este programa calcula o produto de 2 matrizes\n");
printf("atraves do usa da funcao produtoEscalar \n");
printf("Digite as dimensoes das matrizes: ");
scanf("%d %d %d", &r, &s, &t);
printf("Entre com os valores da matriz A\n");
leMatriz(A, r, s);
printf("Entre com os valores da matriz B\n");
leMatriz(B, s, t);
/* a matriz C tem r linhas e t colunas */
for (lin = 0; lin < r; lin++) {
for (col = 0; col < t; col++) {
/* calculo do produto escalar da linha lin pela coluna col
*/
/* a linha pode ser passada diretamente, pois um vetor
*/
/* a coluna precisa ser carregada em um vetor auxiliar */
for (k = 0; k<s; k++) vet[k] = B[k][col];
/* repare agora como podemos chamar a funcao
produtoEscalar */
C[lin][col] = produtoEscalar(A[lin], vet, s);
}
}
/* vamos imprimir o resultado */
imprimeMatriz(C, r, t);
return 0;
}
Exerc!cios (ecomendados
Dzemos que uma matrz um quadrado atno de ordem se em cada nha e
em cada couna aparecem todos os nteros (ou se|a, cada nha e couna
permutao dos nteros ).
a) Escreva uma funo que recebe como parmetros um ntero n, um vetor V
com n nteros e verca se em V ocorrem todos os nteros de 1 a
n.
b) Usando a funo acma, verque se uma dada matrz ntera um
quadrado atno de ordem n.
a) Escreva uma funo que recebe como parmetros uma matrz rea , e uma
poso da matrz, e cacua a mda artmtca dos vznhos de ,
ou se|a, a mda entre , , e . Desconsdere os vznhos nas
dagonas e que no pertencem a matrz (por exempo, os vznhos
de (0, 0) so somente (0,1) e (1,0)).
b) Escreva uma funo que recebe como parmetro uma matrz rea e devove
uma matrz , onde a mda artmtca dos vznhos de (,|). Para
sto, utze a funo do tem anteror.
c) Escreva um programa que uma matrz rea , e um nmero ntero ;
utzando a funo do tem anteror, o programa deve transformar
a matrz vezes, mprmndo a matrz nca e depos de cada
transformao.
Eoza Sonoda
Cadeias de caracteres <strings=
Na nguagem C, uma ou string (ou cadeia de caracteres) um vetor de
caracteres em que o caractere nuo ('\0') nterpretado como m da parte
reevante do vetor. Exempo:
char *s;
s = malloc( 10 * sizeof (char));
s[0] = 'A';
s[1] = 'B';
s[2] = 'C';
s[3] = '\0';
s[4] = 'D';
Depos da execuo desse fragmento de cdgo, o vetor s[0..3] contm a
cadea de caracteres ABC. O caractere nuo marca o m dessa cadea. A poro
s[4..9] do vetor gnorada.
Comprimento e endereo
O comprimento (= length) de uma strng o seu nmero de caracteres, sem
contar o caractere nuo na.
O endereo de uma strng o endereo do seu prmero caractere, da mesma
forma que o endereo de um vetor o endereo de seu prmero eemento. Em
dscusses nformas, usua confundr uma strng com o seu endereo. Assm,
a expresso "consdere a strng s" deve ser entendda como "consdere a strng
cu|o endereo s".
Strings constantes
Para especcar uma strng constante, basta embruhar uma sequnca de
caracteres num par de aspas dupas. O caractere nuo na ca subentenddo.
Por exempo, "ABC" uma strng constante e o fragmento de cdgo
char *s;
s = "ABC";
equvaente ao que aparece na ntroduo desta pgna (exceto peo fato de
que a strng "ABC" ocupa apenas 4 bytes na memra). O prmero argumento
das funes printf e scanf, quase sempre uma strng constante. Por
exempo,
scanf( HIdH, &n);
printf( H- 3alor de n J IdH, n);
Exemplo: contagem de 3ogais
A funo abaxo conta o nmero de vogas em uma strng. A funo conta
apenas as vogas no acentuadas, mas muto fc modcar o cdgo para
que todas as vogas se|am contadas.
int contaVogais( char s[]) {
int numVogais, i;
char *vogais;
3ogais K Haeiou#E"-%HL
numVogais = 0;
for (i = 0; s[i] != '\0'; ++i) {
char ch;
int j;
ch = s[i];
for (j = 0; vogais[j] != '\0'; ++j) {
if (vogais[j] == ch) {
numVogais += 1;
break;
}
}
}
return numVogais;
}
Exerc!cios
Oua a dferena entre "A" e 'A'?
Oua a dferena entre "mno" e "m\no"? Oua a dferena entre "MNOP" e
"MN0P"? Oua a dferena entre "MN\0P" e "MN0P"?
Escreva uma funo que receba um caractere c e devova uma strng cu|o
nco caractere c.
Escreva uma funo que receba uma strng e mprma uma tabea com o
nmero de ocorrncas de cada caractere na strng. Escreva um
programa para testar a funo.
Escreva uma funo que decda se uma strng ou no um pandromo (ou
se|a, se o nverso da strng gua a ea). Escreva um programa para
testar a funo.
Escreva uma funo que receba strngs s e t e decda se s segmento de t
(ou se|a, se s pode ser obtda apagando um nmero arbtrro de
eementos do nco de t e um nmero arbtrro de eementos no m
de t). Escreva um programa que use a funo para contar o nmero de
ocorrncas de uma strng s em uma strng t.
|Sedg 3.60| Escreva uma funo que receba uma strng e substtua cada
segmento de dos ou mas espaos por um s caractere ' '.
Escreva uma funo que receba uma strng de 0s e 1s, nterprete essa strng
como um nmero em notao bnra e devova o vaor desse nmero.
# ?i?lioteca string
A bboteca padro string da nguagem C contm vras funes de
manpuao de strngs. Para usar essas funes, o seu programa deve ncur o
arquvo-nterface string.h:
#include <string.h>
No que segue, as strngs sero tratadas como um novo tpo-de-dados:
typedef char *string;
1$ A funo strlen (abrevatura de string length) recebe uma strng e devove
o seu comprmento. O cdgo dessa funo podera ser escrto assm:
unsigned int strlen( string s) {
int i;
for (i = 0; s[i] != '\0'; ++i) ;
return i;
}
2$ A funo strcpy (abrevatura de string cop() recebe duas strngs e copia a
segunda (ncusve o caractere nuo na) para o espao ocupado para a
prmera. O contedo orgna da prmera strng perddo. Antes de chamar a
funo, o programador deve certcar-se de que o espao aocado para
prmera strng sucente para acomodar a cpa da segunda. |Buher
overow uma das mas comuns orgens de bugs de segurana!| O cdgo
dessa funo podera ser escrto assm:
void strcpM( string s, string t) {
int i;
for (i = 0; t[i] != '\0'; ++i)
s[i] = t[i];
s[i] = '\0';
}
(Na verdade, o cdgo acma est geramente ncorreto, pos a funo strcpy
da bboteca string devove o endereo da prmera strng. Mas os usuros da
funo usuamente s esto nteressados no efeto da funo e no n'o que ea
devove.)
A funo strcpy pode ser usada para obter um efeto semehante ao do
exempo que abru esta pgna:
char s[10];
strcpy( s, "ABC");
3$ A funo strcmp (abrevatura de string compare) recebe duas strngs e
compara as duas excogracamente. Ea devove um nmero negatvo se a
prmera strng for excogracamente menor que a segunda, devove 0 se as
duas strngs so guas e devove um nmero postvo se a prmera strng for
excogracamente maor que a segunda.
Embora os parmetros da funo se|am do tpo char *, a funo se comporta
como se ees fossem do tpo unsigned char *. Assm, por exempo, "bb"
consderada excogracamente menor que "bb" e "ba" consderada
excogracamente menor que "b". O cdgo da funo podera ser escrto
assm:
int strcmp( string s, string t) {
int i;
unsigned char usi, uti;
for (i = 0; s[i] == t[i]; ++i)
if (s[i] == '\0') return 0;
usi = s[i]; uti = t[i];
return usi - uti;
}
Convm embrar que o vaor da expresso usi - uti cacuado em
artmtca int (e no mduo 256).
A ordem lexicogr6+ca entre strngs anoga ordem das paavras em um
dconro. Ea se basea na ordenao dos caracteres estabeecda na tabea
ISO8859-1, da mesma forma que a ordem das paavras em um dconro se
basea na ordenao das etras no afabeto. Para comparar duas strngs s e t,
procura-se a prmera poso, dgamos k, em que as duas strngs dferem. Se
s[k] vem antes de t[k] na tabea ISO ento s lexicogra)camente menor
que t. Se k no est dendo ento s e t so dntcas ou uma prexo
prpro da outra; nesse caso, a strng mas curta excogracamente menor
que a mas onga.
Exerc!cios
Dscuta as dferenas entre os trs fragmentos de cdgo a segur: char a[8],
b[8];
strcpy( a, "abacate");
strcpy( b, "banana");
char *a, *b;
a = malloc( 8); strcpy( a, "abacate");
b = malloc( 8); strcpy( b, "banana");
char *a, *b;
a = "abacate";
b = "banana";
O que h de errado com o segunte trecho de cdgo? char b[8], a[8];
strcpy( a, "abacate");
strcpy( b, "banana");
if (a < b)
printf( "%s vem antes de %s no dicionrio", a, b);
else
printf( "%s vem depois de %s no dicionrio", a, b);
O que h de errado com o segunte trecho de cdgo? char *b, *a;
a = "abacate";
b = "banana";
if (a < b)
printf( "%s vem antes de %s no dicionrio", a, b);
else
printf( "%s vem depois de %s no dicionrio", a, b);
O que h de errado com o segunte trecho de cdgo? char *a, *b;
a = "abacate";
b = "amora";if (*a < *b)
printf( "%s vem antes de %s no dicionrio", a, b);
else
printf( "%s vem depois de %s no dicionrio", a, b);
Escreva uma funo que receba uma strng s e um ntero no negatvo i e
devova o i-1-smo caractere de s, ou se|a, o caractere s[i].
Eloiza Sonoda
Object1
Manipulao de Arquivos
At agora, todos os programas feitos nesta disciplina lem dados do teclado (entrada
padro) e escrevem na tela do monitor (sada padro). Aqui mostrado como um
programa em C l dados de um arquivo que est no disco (HD ou DISQUETE) e
como grava um arquivo no disco. Um tratamento profundo do assunto, discutido
brevemente aqui, pode ser encontrado no livro:
The C programming language
Brian W. Kernigham e Dennis M. Ritchie
Prentice-Hall
Abertura de um arquivo (fopen)
Neste ponto tratamos a seguinte questo:
Como fazer que um arquivo em disco, que tem o seu nome externo ao programa, seja
associado a algum objeto ou varivel que interna ou conhecida do nosso programa?
A regra clara (como diria o Armando Marques ) Antes que possa ser lido ou
gravado um arquivo deve ser aberto pela funo de biblioteca fopen. A
funo fopen associa o nome de uma arquivo externo ao programa,
como entrada.txt, a uma varivel do programa. Isto feito da seguinte maneira
FILE *arq_entrada;
. . .
arq_entrada = fopen("entrada.txt","r");
. . .
O primeiro parmetro da funo fopen uma cadeia de caracteres (string, seja l o
que for isto) contendo o nome do arquivo externo. J o segundo parmetro, que
tambm uma cadeia de caracteres, indica o modo como se pretende usar o arquivo:
leitura ("r"), gravao ("w"), anexao ("a"). Por exemplo o comando
FILE *arq_entrada;
. . .
arq_entrada = fopen("entrada.txt","r");
if (arq_imagem == NULL)
{
printf("Um erro oorre! ao tentar a"rir o arq!i#o $mam!te.pgm%.&n");
'
. . .
associa a varivel arq_entrada do nosso programa o arquivo em disco de
nome entrada.txt. O arquivo entrada.txt deve estar na mesma pasta (diretrio,
folder) que o nosso programa, digamos, o ep(.exe. O arquivo aberto
para leitura ("r" de read). Se ocorrer um erro, como tentar associararq_entrada a
um arquivo que no existe, fopen retorna o valor representado pela constante NULL.
Se um arquivo que no existe no disco for aberto para escrita, ele criado. Por
exemplo, o seguinte trecho de cdigo cria um arquivo de nome
)aida.txt:
FILE *arq_)aida;
. . .
arq_)aida = fopen(")aida.txt","*");
if (arq_)aida == NULL)
{
printf("Um erro oorre! ao tentar riar o arq!i#o $)aida.txt%&n");
'
. . .
O arquivo )aida.txt criado na mesma pasta/diretrio que o arquivo que contm o
nosso programa, suponha que seja o ep(.exe. Se o arquivo j existe ele destrudo e
um novo arquivo com o mesmo nome criado. O arquivo aberto para escrita ("w"
de write).
Sempre que um erro ocorre durante a abertura de um arquivo o valor devolvido pela
funo fopen NULL.
Leitura de um arquivo (fscanf)
O prximo passo saber como ler os dados de uma arquivo. Considere o
arquivo entrada.txt que foi associado varivel arq_entrada do nosso programa. O
comando
FILE *arq_entrada;
. . .
arq_entrada = fopen("entrada.txt","r");
. . .
f)anf(arq_entrada,"+d", ,n!m);
. . .
l um nmero inteiro do arquivo entrada.txt da mesma maneira que
. . .
)anf("+d", ,n!m);
. . .
l um nmero digitado atravs do teclado. Na verdade, o comando
)anf("+d",,n!m);
uma abreviatura do comando
f)anf()tdin,"+d", ,n!m);
onde )tdin a entrada padro, que no nosso caso, o teclado.
Escrita em arquivo (fprintf)
Para escrever-se em um arquivo de nome saida.txt pode-se usar os seguintes
comandos
FILE *arq_)aida;
. . .
arq_)aida = fopen(")aida.txt","*");
. . .
fprintf(arq_)aida,"-opia&n");
fprintf(arq_)aida,"+d +d&n", n, m);
. . .
O primeiro fprintf escreve o texto "-opia&n" no arquivo )aida.txt e o
segundo fprintf escreve o contedo da varivel n, um espaco (" "), o contedo da
varivel m e um barra-n ("\n") para mudar de linha.
Veja um exemplo um pouco mais elaborado:
FILE *arq_)aida;
int n;
int m;
. . .
arq_)aida = fopen(")aida.txt","*");
if (arq_)aida == NULL)
{
printf("Um erro oorre! ao tentar riar o arq!i#o $)aida.txt%.&n");
'
. . .
fprintf(arq_)aida,"-opia&n");
fprintf(arq_)aida,"+d +d&n", n, m);
fprintf(arq_)aida,"n*m=+d&n", n*m);
. . .
De maneira semelhante ao que ocorre com o scanf, o comando
printf("+d&n", #a.max);
uma abreviatura do comando
fprintf()tdo!t,"+d&n", #a.max);
onde )tdo!t a sada padro, que no nosso caso, a tela do monitor.
Fechamento de um arquivo (fclose)
A funo fclose encerra a associao estabelecida pelo programa entre uma varivel e
o nome externo do arquivo. O f.o)e tambm libera os recursos do sistema que
controlam a manipulao do arquivo em disco. A chamada abaixo fecha o arquivo
associado varivel arq_)aida.
f.o)e(arq_)aida);
Exemplo
A seguir est um exemplo de programa que copia nmeros de um arquivo de
nome origina..dat para um arquivo de nome opia.dat. O primeiro nmero do
arquivo origina..dat indica o nmero n de nmeros no arquivo.
/*
* 0rograma q!e q!e fa1 !ma opia de !m arq!i#o
* de nome origina..dat para !m arq!i#o de nome opia.dat. 2
* arq!i#o opia.dat fiara no me)mo diretorio do arq!i#o
* origina..dat.
*
*/
3in.!de 4)tdio.56
int main()
{
FILE *arq_o; /* a))oiado ao arq!i#o origina. */
FILE *arq_; /* a))oiado ao arq!i#o opia */
int n; /* n!mero de e.emento) do arq!i#o origina. */
f.oat x;
int i;
/* 7. a"ra arq!i#o origina..dat para .eit!ra */
arq_o = fopen("origina..dat","r");
if (arq_o == NULL)
{
printf("Erro na a"ert!ra do arq!i#o origina..dat.&n");
)8)tem("pa!)e"); /* para 9IN:29N; */
exit(<7); /* a"andona a exe!ao do programa */
'
/* =. a"ra arq!i#o opia.dat para e)rita */
arq_ = fopen("opia.dat","*");
if (arq_ == NULL)
{
printf("Erro na a"ert!ra do arq!i#o opia.dat.&n");
)8)tem("pa!)e"); /* para 9IN:29N; */
exit(<7); /* a"andona a exe!ao do programa */
'
/* (. .eia o taman5o da )eq!enia no arq!i#o origina..dat */
f)anf(arq_o,"+d", ,n);
/* >. e)re#a o n!mero de e.emento) no arq!i#o opia.dat */
fprintf(arq_,"+d&n", n);
/* ?. .eia o) n!mero) do arq!i#o origina..dat e e)re#a em opia.dat*/
for (i = @; i 4 n; iAA)
{
f)anf(arq_o,"+f", ,x);
fprintf(arq_,"+f ", x);
if (i == ?)
{ /* apena) ino n!mero) por .in5a de arq_ */
fprintf(arq_,"&n");
'
'

/* B. fe5e o arq!i#o origina..dat */
f.o)e(arq_o);
/* C. fe5e o arq!i#o opia.dat */
f.o)e(arq_);
ret!rn @;
'
Eloiza Sonoda
Object2

Anda mungkin juga menyukai