Muitos mais exercícios!
Nota importante. Alguns destes exemplos são programas escritos
nas aulas teóricas - e testados no computador durante essas aulas.
Não se encontram ordenados nem completos; muitos são exercícios!
/*- Problema:
Programa que escreve as palavras que ocorrem num ficheiro,
uma por linha;
Palavra:
sequência máxima de 1 ou mais letras
Ex: a, batatas, Puro
*/
#include <stdio.h>
#define FORA 0
#define LETRAS 1
int letra(int c){
return(c>='a' && c<='z' || c>='A' && c<='Z');
}
main(){
int c,estado=FORA;
c=getchar();
while(c!=EOF){
if(estado==LETRAS){
if(!letra(c)){putchar('\n');estado=FORA;}
else
putchar(c);
}
else{
if(letra(c)){putchar(c);estado=LETRAS;}
}
c=getchar();
}
}
//-- letras e códigos
main(){
int c;
char b;
while(1){
scanf("%c", &b);
c=b;
printf("%c\n",c);
printf("%d\n",c);
printf("%c\n",c-32);
printf("%d\n",c-32);
}
}
//-- 1. Se usasse só c (sem b)?
//-- 2. Experimentar e explicar
/*- Programa que escreve os inteiros que ocorrem num ficheiro, um
por linha;
Inteiro:
[+|-]<1 ou mais dígitos>
Ex: 22, -5, +999
teste com o próprio programa e com a.out
Admite-se que 2 inteiros estão separados pelo menos por um caracter
que não é sinal nem dígito.
os +33 porquinhos
FFFSNNFFFFFFFFFFF
*/
#include <stdio.h>
#define FORA 0
#define SINAL 1
#define NUMERO 2
int digito(int c){
return(c>='0' && c<='9');
}
int sinal(int c){
return(c=='+' || c=='-');
}
main(){
int c,estado=FORA,sin;
c=getchar();
while(c!=EOF){
switch(estado){
case FORA:
if(sinal(c)){estado=SINAL; sin=c;}
else
if(digito(c)){estado=NUMERO;putchar(c);}
break;
case SINAL:
if(digito(c)){estado=NUMERO;putchar(sin);putchar(c);}
else
estado=FORA;
break;
case NUMERO:
if(digito(c)) putchar(c);
else{
putchar('\n');
estado=FORA;
}
default:
}
c=getchar();
}
}
/*-- Programa de conversão de maiúsculas em minúsculas
A B C D ....
65 66 67 68
a b c d ....
97 98 99 100
diferença = 32
A -> a subtrai-se 32
B -> b subtrai-se 32
*/
Exercício!
/*- ^: Control
Execício: eliminar todos os ^M que tenham a seguir um ^J
Utilidade: converter do modo DOS (texto) para o modo Unix
CTM, CTJ: abreviaturas (define)
cm: 1 se o último caracter for ^M
(está em suspenso a escrita de um ^M)
c: caracter lido
*/
#include <stdio.h>
#define CTM 13
#define CTJ 10
int main(){
int c,cm=0;
c=getchar();
while(c!=EOF){
switch(c){
case CTJ:
putchar(c);
cm=0;
break;
case CTM:
if(cm) putchar(CTM);
cm=1;
break;
default:
if(cm) putchar(CTM);
putchar(c);
cm=0;
}
c=getchar();
}
}
//-- Dado n, escrever quantos divisores n tem.
int ndiv(int n){
int cont=0, //-- contador de divisores
d; //-- testar se e' divisor (1..n)
for(d=1;d<=n;d++)
if(n%d==0)
cont=cont+1;
return cont;
}
int main(){
int n;
for(n=1;n<1000;n++)
if(ndiv(n)==2)
printf("O número %3d é primo\n",n);
}
/*--
Lido n>2, escreve os primeiros n termos de
x(n) = x(n-1)+2x(n-2)
x(1) = 0
x(2) = 2
"%d "
x1: penultimo 0 2 2 6
x2: ultimo 2 2 6 10
n: num. de termos a escrever
i: contar termos
leia n
escreve x1 e x2
para i=3,...n{
calcular novo x1
calcular novo x2
imprime x2
}
Exercício :
Escrever todos os primos da forma 2^n-1 até 1000000
*/
main(){
int x1=0,x2=2,n,i,ant;
scanf("%d",&n);
printf("%d ",x1);
printf("%d ",x2);
for(i=3;i<=n;i++){
ant=x1;
x1 =x2;
x2 =x2+2*ant;
printf("%d ",x2);
}
}
/*-- Dado n, imprimir os seus digitos
por ordem inversa numa base <=10
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 1 2 3 4 5 6 7 8 9 A B C D E F
*/
#define BASE 16
int simbolo(int);
main(){
int n;
scanf("%d",&n);
while(n>0){
printf("%c ",simbolo(n%BASE));
n=n/BASE;
}
printf("\n");
}
//-- d=4 -> '4', d=10 -> 'A'
int simbolo(int d){
if(d>=0 && d<10)
return('0'+d);
else
return('A'+(d-10));
}
Vários modos de calcular combinações.
Comentar o que não interessa.
//-------------------------------------
int comb(int a, int b){
if(b==0)
return(1);
if(a==0)
return(0);
return comb(a-1,b)+comb(a-1,b-1);
}
//-------------------------------------
int fact(int n){
int i,p=1;
for(i=2;i<=n;i++)
p=p*i;
return(p);
}
//-- Combinacoes (a,b)
int comb(int a, int b){
return(fact(a)/(fact(b)*fact(a-b)));
}
//-------------------------------------
int comb(int a,int b){
int i,num=1,den=1;
if(a-b<b) b=a-b;
for(i=a;i>=a-b+1;i--) num*=i;
for(i=2;i<=b;i++) den*=i;
return(num/den);
}
//-------------------------------------
main(){
int m,n;
printf("m? "); scanf("%d",&m);
printf("n? "); scanf("%d",&n);
while(m>=0){
printf("(%d,%d) = %d\n",m,n,comb(m,n));
printf("m? "); scanf("%d",&m);
printf("n? "); scanf("%d",&n);
}
}
/* Decompor um inteiro dado em produto de primos
50 = 2x5^2
Processo: dividir o número dado por 2, enquanto possível.
Seja e o número de vezes
Escreevr 2^e
dividir o número dado por 3, enquanto possível.
Seja e o número de vezes
Escreevr 3^e
Escrita: Se e=0, não escrever
Se e=1, escrever só a base
* Porque é que podemos testar a divisibilidade por
2,3,4,... e não só pelos primos?
Teorema: ...
*/
//-- Escreve um factor. Chamado com exp>=1
void factor(int p, int exp, int primeiro){
if(!primeiro) printf(" x ");
printf("%d",p);
if(exp>1) printf("^%d",exp);
}
main(){
int n,e,prim=1,div=2;
scanf("%d",&n);
while(n>1){
e=0;
while(n%div==0){
n=n/div;
e++;
}
if(e>=1){factor(div,e,prim);prim=0;}
div++;
}
printf("\n");
}
/* Exercício:
a) Quais os erros? Corriga-os
b) O que escreve o programa? Verifique, correndo-o.
c) Qual a visibilidade das variáveis globais?
--------------------------
*/
#define AHAHAH 30
int a=5,b=1;
double c;
double vezes2(int x){
int a=2;
printf("[%d] \n",a);
printf("[%d] \n",b);
return a*x;
}
main(){
int a,v;
scanf("%d",&b);
v=vezes2(b);
printf("b=%d, 2b=%d, AhAhAh=%d\n",b,v,AHAHAH);
}
Exercício!
#define MAX 5
//---------------------------------
main(){
int a[MAX],b[2*MAX],i,min;
// .... ler os 5 valores a[0],...,a[4]
// .... determinar em min o menor dos a[i]
// .... subtrair a todos os a[i] o valor min
// .... fazer b[0]=b[1]=a[0], b[2]=b[3]=a[1],...
// .... escrever a[] e b[]
}
Procurar o valor da solução aproximada de
f(x)=0
sabendo-se que f(a) e f(b) têm sinais contrários.
Usar o método da bissecção sucessiva
(até que b-a < ERRO)
| f(a)>0
| |
|................|.................
a m b f(b)<0
|
|
-----------------------------------------*/
#include <math.h>
#define ERRO 1E-6
double f(double x){
return(cos(x));
}
main(){
double a,b,m;
a=0;
b=3;
while(b-a>ERRO){
.....
}
}
/* Pesquisa sequêncial
------------------------------------------
Exercício: Escrever a função
int procura(int a,int v[],int n)
que retorna
-1 se a não está em v[0..n-1]
i se a=v[i]
---
Se houver vários i com a =v[i]?
Método da "sentinela"
---------------------------------------------*/
//-- Retorna i tal que v[i]=a ou (-1) se não existe
int procura(int a,int v[],int n){
.....
}
#define MAX 8
//---------------------------------------
main(){
int x,p,n=5,v[MAX]={123,5,44,6,10};
printf("Valor? "); scanf("%d",&x);
p=procura(x,v,n);
if(p==-1)
printf("Não está.\n");
else
printf("Está na posição %d\n",p+1);
}
/* --------------------------------------
Pesquisa binária
~~~~~~~~~~~~~~~~
Exercício: Escrever a função
int procura(int a,int v[],int n){
que retorna -1 se a não está em v[0..n-1]
i se a=v[i]
Sabe-se que v[] está ordenado e deve ser efectuada
procura binária.
Complemento: Versão recursiva
se x esta em v[] está em v[a..b]
i: 0 1 2 3 4 5 6 7
----------------------------------
v[i] 5 6 10 44 88 99 100 123
a b
Procurar 10
Procurar 90
-----------------------------------------*/
//-- Retorna um i tal que v[i]=a ou (-1) se não existe
int procura(int x,int v[],int a, int b){
Exercício!!!....
}
#define MAX 8
//---------------------------------------
main(){
int x,p,n=8,v[MAX]={5,6,10,44,88,99,100,123};
do{
printf("Valor? "); scanf("%d",&x);
p=procura(x,v,0,n-1);
if(p==-1)
printf("Não está.\n");
else
printf("Está na posição %d\n",p);
}
while(x>=0);
}
/*-- Ordenação de um vector pela *selecção do mínimo*
para i=0,1,...,n-2
min = índice do mínimo em i,i+1,...,n-1
v[i] <-> v[min]
0 1 2 3 (n=4)
-------
8 3 5 2
i
j......
Implementa e função
void selmin(int a[], int n);
*/
//------------------------------
void selmin(int a[], int n){
int i,j,min,t;
for(i=0;i<=n-2;i++){
min=i;
... exercício!!!...
}
}
//------------------------------
void printv(int a[],int n){
int i;
for(i=0;i<n;i++)
printf("%4d",a[i]);
printf("\n");
}
//------------------------------
int main(){
int v[]={8,2,10,4,1,8}, n=6;
printv(v,n);
selmin(v,n);
printv(v,n);
}
/*-- Ordenação de um vector de caracteres (string) pela selecção do
mínimo
Usar com a.out < ficheiro de nomes
*/
#include <string.h>
#define MAXL 100
#define MAX 500
//---------------------------------
// Ordena o vector de "strings" a[]
void selmin(char *a[], int n){
int i,j,min;
char t[MAX];
for(i=0;i<=n-2;i++){
min=i;
for(j=i+1;j<n;j++)
if(strcmp(a[j],a[min])<0) min=j;
strcpy(t, a[i]);
strcpy(a[i], a[min]);
strcpy(a[min],t);
}
}
//------------------------------
void printv(char *a[],int n){
int i;
for(i=0;i<n;i++)
printf("%s\n",a[i]);
printf("\n\n");
}
//------------------------------
int main(){
char *s[MAX];
int i=0,m,n;
do{
s[i] = (char *)malloc(MAXL+1);
//-- Ler o "man scanf"
m=scanf("%[^\n]",s[i]); getchar();
i++;
}
while(m>0);
n=i-1;
printv(s,n);
selmin(s,n);
printv(s,n);
}
/* -------------------------------------------
Escrever uma função que inverte uma string,
void inverte(char s[]){
Exemplo:
"batatas" ==> "satatab"
0123456
s[0] <-> s[n-1]
s[1] <-> s[n-2] s[i] <-> s[n-1-i]
s[2] <-> s[n-3] i=0,...,n/2-1
b a t a t a
0 1 2 3 4 5
- - -
Nota. Não pode usar as funções de string do
sistema (strlen,...).
--------------------------------------------*/
int compr(char s[]){
int i=0;
while(s[i])
i++;
return i;
}
void inverte(char s[]){
int i,n,t;
n=compr(s);
for(i=0;i<=n/2-1;i++){
t = s[i];
s[i] = s[n-1-i];
s[n-1-i] = t;
}
}
//----------------------------
#define MAX 1000
main(){
char s[MAX];
scanf("%[^\n]",s);
inverte(s);
printf("==> %s\n",s);
}
/* ------------------------------------------
Escrever uma função que "roda" as letras
minusculas de uma string de um dado valor;
void roda(int n,char s[])
Exemplo:
"fez",2 ==> "hgb"
Nota. Não pode usar as funções de string do
sistema (strlen,...).
---------------------------------------------*/
void roda(int n,char s[]){
....
}
//--------------------------------------------
#define MAX 1000
main(){
int a;
char s[MAX];
while(1){
printf("n? "); scanf("%d",&a);
printf("frase? "); scanf("%s",s);
roda(a,s);
printf("==> %s\n",s);
}
}
/* Enunciado:
Escreva a função
void cifra(char s[],char chave[]);
que cujo efeito é codificar s[] de acordo com a chave;
por exemplo
s[] = "as aves voam"
ac aiac aiac
au adeu vwao
chave = "acai"
0208
A chave é sempre uma sequência de letras minúsculas.
*/
//-- Função pedida ---------------------------------
//--------------------------------
int roda(int n,int ch){
n = n+26;
ch = ch-'a';
ch = (ch+n)%26;
ch = ch+'a';
return ch;
}
//-----------------------------------
void cifra(char s[],char chave[]){
int i=0, //-- ind. da mensagem
j=0, //-- ind. da chave
r; //-- valor a rodar
while(s[i]!=0){
if(s[i]>='a' && s[i]<='z'){
r=chave[j]-'a';
s[i]=roda(r,s[i]);
j++;
if(chave[j]==0) j=0;
} i++;
}
}
//-----------------------------------
void decifra(char s[],char chave[]){
int i=0, //-- ind. da mensagem
j=0, //-- ind. da chave
r; //-- valor a rodar
while(s[i]!=0){
if(s[i]>='a' && s[i]<='z'){
r=chave[j]-'a';
s[i]=roda(-r,s[i]);
j++;
if(chave[j]==0) j=0;
}
i++;
}
}
//----- main (para teste) -------------------------
#define MAXF 1000
#define MAXC 100
main(){
char s[MAXF], chave[MAXC];
scanf("%[^\n]",s);
scanf("%s",chave);
printf("Frase = %s\n",s);
cifra(s,chave);
printf("Cifra = %s\n",s);
decifra(s,chave);
printf("Original (espero!) = %s\n",s);
}
/*----------------------------------------
Escreva a função
int merge(int v[],int m,int w[],int n,int z[])
que efectua a fusão (merge) dos vectores v[],m
e w[],n em z[]. O valor retornado é o número de
elementos de z[].
------------------------------------------*/
int merge(int v[],int m,int w[],int n,int z[]){
int pv=0,pw=0,pz=0,i;
...
}
//------------------------------
void printv(int a[],int n){
int i;
for(i=0;i<n;i++)
printf("%4d",a[i]);
printf("\n");
}
//-------------------------------
#define MAX 1000
main(){
int a[]={2,4,4,5,5,8,9,10},na=8,
b[]={1,2,4,5,5,6},nb=6,
x[MAX],nx;
printv(a,na);
printv(b,nb);
nx=merge(a,na,b,nb,x);
printv(x,nx);
}
Explicação do "mergesort"
~~~~~~~~~~~~~~~~~~~~~~~~~
Usar "merge" para ordenar:
Seja
merge(a,b,c,d): merge v[a..b] com v[c..d]
A)----------------------------------
ind: 0 1 2 3 4 5 6 7
- - - - - - - -
Formar grupos de 2 ordenados (c=1)
merge(0,0,1,1) -> [0,1]
merge(2,2,3,3) -> [2,3]
merge(4,4,5,5) -> [4,5]
merge(6,6,7,7) -> [6,7]
B)----------------------------------
ind: 0 1 2 3 4 5 6 7
---- ---- ---- ----
Formar grupos de 4 ordenados (c=2)
merge(0,1,2,3) -> [0,3]
merge(4,5,6,7) -> [4,7]
C)----------------------------------
ind: 0 1 2 3 4 5 6 7
---------- ----------
Formar grupo de 8 ordenados (c=4)
merge(0,3,4,7) -> [0,7]
------------------------------------
Caso geral, ordenar um vector com n=2^p
elementos.
c=1; //-- comprimento de um grupo
for(i=0;i<n;i=i+2*c){
merge(i,i+c-1,i+c,i+2*c-1)
c=c*2;
}
//- Gerando números aleatórios
#include <stdio.h>
#include <stdlib.h>
//--> Ver o manual de "rand".
/*----------------------------------------
inteiro aleatório uniforme em [a...b],
probabilidade = 1/(b-a+1) */
int aleator(int a, int b){
return(a+(rand()%(b-a+1)));
}
/*----------------------------------------
real aleatório uniforme em [a...b] */
double raleator(double a, double b){
double x = (double)rand()/RAND_MAX;
return a+(b-a)*x;
}
#define MAX 20
main(){
int i;
srand(getpid());
/* for(i=0;i<MAX;i++)
printf("%3d",aleator(1,6)+aleator(1,6));
*/
for(i=0;i<MAX;i++)
printf("%6.8lf\n",raleator(1,3));
}
/*- Calcular empiricamente a probabilidade
de, ao lançar um par de dados, sair
2, 3, ..., 12.
prob 1 = ...
prob 2 = ...
- Comparar com as "previsões" teóricas
c[2] : num. de vezes que saiu 2
c[3] : num. de vezes que saiu 3
---
*/
#include <stdio.h>
#include <stdlib.h>
/*----------------------------------------
inteiro aleatório uniforme em [a...b],
probabilidade = 1/(b-a+1) */
int aleator(int a, int b){
return(a+(rand()%(b-a+1)));
}
#define MAX 1000000
main(){
int c[13]={0}, //- c[] todo com 0's
i;
//-- Contar em c[i] quantas vezes saiu i
for(i=0;i<MAX;i++)
c[aleator(1,6)+aleator(1,6)]++;
//-- Escrever as probabilidades c[i]/MAX
for(i=0;i<=12;i++)
printf("Probabilidade de %2d = %5.3lf\n",
i,((double)c[i])/MAX);
}
/*- Área entre o eixo xx e uma função f(x)>=0
Método
w|...........
| -- .
| . * / \.
| / \./ .
|/ * .
--------------------
a b xx
*: "tiro": par (x,y) com
x em [a,b], y em [0,w]
N: número de tiros
Área do rectângulo: (b-a)*y
Área debaixo da função = (aprox) = m/N*((b-a)w)
m: número de tiros (x,y) com y<=x
----------------------------------------
Erro
Valor exacto
*/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
/*----------------------------------------
real aleatório uniforme em [a...b] */
double raleator(double a, double b){
double x = ((double)rand())/RAND_MAX;
return a+(b-a)*x;
}
//----------------------------------------
double f(double x){
return sin(x);
}
#define N 1000000
main(){
int i,m=0;
double a=0.0,b=1.0,c=1.0,x,y,rectang;
srand(getpid());
for(i=0;i<N;i++){
x=raleator(a,b);
y=raleator(0,c);
if(y<f(x)) m++;
}
rectang=(b-a)*c;
printf("Tiros = %8d, área = %6.4lf\n",
N,rectang*((double) m)/N);
}
/*----
Há 3 portas fechadas, uma delas tem um carro
(as outras não têm nada).
O concorrente escolhe uma, seja A.
O apresentador abre outra, seja B, que não
tem nada.
Deve o concorrente mudar para C ou manter A?
Qual a probabilidade de ganhar em cada caso?
Supondo que o concorrente troca de porta:
- Com probabilidade 2/3 (escolha inicial
do concorrente errada) o apresentador
indica a porta correcta!
- Com probabilidade 1/3 a mudança da escolha leva
a perda do carro.
Assim, a probabilidade de ganhar o carro passa de
1/3 a 2/3.
Resultados:
Probabilidade (sem trocar) = 0.3353
Probabilidade (trocando) = 0.6664
------*/
#include <stdio.h>
#include <stdlib.h>
#define MAX 100000
// random integer in [a...b]
int random_int(int a, int b)
{return(a+(rand()%(b-a+1)));}
//-- selects the integer in {0,1,2} !=a, !=b
int select_not(int a,int b){
int i;
for(i=0;i<3;i++)
if(i!=a && i!=b)
return i;
}
main(){
int i,s,c,esc,abre;
srand(getpid());
//-- acertar, sem mudar, quite trivial
s=0;
for(i=0;i<MAX;i++){
esc=random_int(1,3); //- porta escolhida
c =random_int(1,3); //- porta com o carro
s +=(esc==c);
}
printf("Probabilidade (sem trocar) = %6.4lf\n",(double)s/MAX);
//-- acertar, mudando a escolha
s=0;
for(i=0;i<MAX;i++){
esc=random_int(0,2);
c =random_int(0,2);
if(c==esc)
//-- o apres. escolhe uma das 2 portas
abre = (esc+random_int(1,2))%3;
else{
//-- o apresentador só tem 1 hipótese
abre = select_not(c,esc);
esc = select_not(esc,abre);
s +=(esc==c);
}
}
printf("Probabilidade (trocando) = %6.4lf\n",(double)s/MAX);
}
/* Chamada
mais 12 18
30
--------------------------------------
a.out 12 aiai
--------------------------------------
main(int np, char *par[]){
np: 3
par[0]: nome do programa (string)
par[1]: parametro 1, 12 (string)
par[2]: parametro 2, aiai (string)
Conversão de strings para inteiros
Detecção de erros ("mais a 10", "mais 1")
*/
void erro(char *mes){
printf("Erro: %s\n",mes);
exit(1);
}
main(int np, char *par[]){
int a,b,n;
if(np!=3)erro("Num. de pars errado!");
n=sscanf(par[1],"%d",&a);
if(n==0) erro("Par 1 não é numero");
n=sscanf(par[2],"%d",&b);
if(n==0) erro("Par 2 não é numero");
printf("Soma = %d\n",a+b);
}
/*----
Macros com parametros
Vantagens e desvantagens,
comparação com funções
Perigos
A expansão
*/
#define MAIS(A,B) (A+B)
#define MAIOR(A,B) (A>=B?A:B)
main(){
int r;
r = MAIS(2,2)*MAIS(2,2);
printf("r = %d\n",r);
r = MAIOR(4,5);
printf("r = %d\n",r);
}
/*-----------------------------------------
Com o tipo int, não podemos calcular
por exemplo fact(20)
1) Verifique
2) Determine o maior inteiro representável,
2^31-1 = 2147483647
3) Representando um dos inteiros por um
par (v[],m) conforme se indica
---------
12349 => v[] = 9 4 3 2 1
---------
(m=4) 0 1 2 3 4
Escreva uma função
int mult(int x,int v[],int m)
que coloca em v[] o produto v[]*m
dando como resultado o novo m.
*90 8 2 (90*28=2520)
90
-----------
0 2 2 7
90*8+0 =720 => 0 72 ^
90*2+72=252 => 2 25 |
90*0+25=25 => 5 2 |
90*0+2 =2 => 2 0 |
---------------------------------------------
Use a função escrita para imprimir
o factorial de um inteiro x dado
(por exemplo, 1000).
main(){
int i,n=20,p=1;
for(i=2;i<=n;i++)
p*=i;
printf("Factorial de 20 = %d\n",p);
printf("Um int ocupa %d bytes\n",sizeof(int));
}
-------------------------------------------*/
int mult(int x,int v[],int m){
int i=0,tr=0,val;
for(i=0;i<=m || tr>0;i++){
val=v[i]*x+tr;
v[i]=val%10;
tr=val/10;
}
return i-1;
}
//--------------------------------
#define MAX 10000
main(){
int i,x=10,v[MAX]={0},m;
scanf("%d",&x);
v[0]=1; m=0;
for(i=2;i<=x;i++)
m=mult(i,v,m);
for(i=m;i>=0;i--)
printf("%1d",v[i]);
printf("\n");
}
/*---------------------------------------
conta o número de bytes e de palavras
do ficheiro dado,
$ conta fich
$ 100 byte(s), 120 palavra(s)
-----------------------------------------*/
#include <stdio.h>
void erro(char s[]){
printf("** %s\n",s);
exit(1);
}
main(int np, char *par[]){
FILE *f;
int bytes=0,pals=0,c,esp=1;
if(np!=2)
erro("Uso errado");
f=fopen(par[1],"r");
if(f==NULL)
erro("Erro de ficheiro");
c=getc(f);
while(c!=-1){
bytes++;
if(esp && c!=' '){
esp=0;
pals++;
}
else
if(c==' ')
esp=1;
c=getc(f);
}
printf("%d bytes, %d palavras \n",bytes,pals);
}
/*---------------------------------
semelhante a
cat <fich1> ... <fichn>
----------------------------------
Ficheiro f Terminal
----------------------------------
getc(f) getchar()
fscanf(f,"...",...) scanf("...",...)
putc(c,f) putchar(c)
---------------------------------*/
#include <stdio.h>
void lista(char *nome,FILE *f){
int ch;
printf("\n%s:\n",nome);
ch=getc(f);
while(ch!=EOF){
putc(ch,stdout); // = putchar(ch)
ch=getc(f);
}
}
//---------------------------------
void erro(char *mes){
printf("Erro: %s\n",mes);
exit(1);
}
//---------------------------------
main(int np, char *par[]){
int i;
FILE *f;
//-- tem que haver >=2 pars
if(np<2)
erro("Uso: cate <fich>,...");
for(i=1;i<np;i++){
f=fopen(par[i],"r");
if(f==NULL) erro("Erro de ficheiro");
lista(par[i],f);
fclose(f);
}
}
/*----------------------------------------
Efectua a multiplição de matrizes
r = m x v
| 1 2 3 | | 1 |
| 2 3 4 | x | 2 |
| 0 1 0 | | 3 |
Convencionar m[i][j]: linha i, coluna j
-----------------------------------------*/
#define DIM 3
main(){
int i,j,s,v[DIM]={1,2,3},
m[DIM][DIM]={{1,2,3},{2,3,4},{0,1,0}},
r[DIM];
//-- calcular r[i]
for(i=0;i<DIM;i++){
s=0;
for(j=0;j<DIM;j++)
s+=m[i][j]*v[j];
r[i]=s;
}
for(i=0;i<DIM;i++)
printf("%3d\n",r[i]);
}
/*----------------------------------------
Procurar a palavra pal na matriz de caracteres
m[][] a partir da linha lin, coluna col,
com a direcção di, dj
Resultado: SIM (1) ou NAO (0)
Ex:
pal = "piu", i=2, j=1,
| 'f' 'a' 'p' 'i' |
pal = | 'i' 'p' 'o' 'p' |
| 'p' 'p' 'i' 'u' |
| 'g' 'a' 't' 'o' |
retorna SIM
int procura(char *pal, char v[][],
int i, int j,
int di, int dj)
Melhorias: leitura da matriz
outras direcções
procurar várias palavras
-----------------------------------------*/
#define MAX 4
int procura(char pal[], char v[][MAX],
int i0, int j0,
int di, int dj){
int c=0,i=i0,j=j0;
while(i<MAX && j<MAX){
if(pal[c]!=v[i][j])
return 0;
else
if(pal[c+1]==0)
return 1;
i+=di; j+=dj; c++;
}
return 0;
}
//------------------------------------------
main(){
int i,j,dx,dy;
char
v[MAX][MAX] = {{'f','a','p','i'},
{'i','p','o','p'},
{'p','p','i','u'},
{'g','a','t','o'}},
pal[] = "piu";
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++){
if(procura(pal,v,i,j,0,1))
printf("Linha %d, coluna %d, horizontal\n",i+1,j+1);
if(procura(pal,v,i,j,1,0))
printf("Linha %d, coluna %d, vertical\n",i,j);
}
}
/*--------------------------------------------
Pequeno simulador do LIFE
Cada casa tem 8 vizinhos
vivos com 2 ou 3 vizinhos --> sobrevivem
vazios com 3 vizinhos --> nascem
--------------------- ---------------------
| | | | | | | | | | | |
--------------------- ---------------------
| | | X | X | | | | | | | |
--------------------- ---------------------
| | X | X | | | => ? | | | | | |
--------------------- ---------------------
| | | X | | | | | | | | |
--------------------- ---------------------
| | | | | | | | | | | |
--------------------- ---------------------
Um processo:
variáveis: DIM: tamanho
v[][]: tabuleiro
c[][]: contador de vizinhos
inicialização directa
Melhorias:
leitura inicial,
limites do quadro...
----------------------------------------------*/
#define DIM 20
//-- Situação inicial ---------
void inicializa(char v[][DIM]){
int i,j,mi=DIM/2, mj=DIM/2;
for(i=0;i<DIM;i++)
for(j=0;j<DIM;j++)
v[i][j]=' ';
v[mi] [mj] ='X';
v[mi-1][mj] ='X';
v[mi+1][mj] ='X';
v[mi] [mj-1] ='X';
v[mi-1][mj+1] ='X';
}
//-- Mosta o tabuleiro ---------
void mostra(char v[][DIM]){
int i,j;
printf("\n\n\n\n\n");
for(i=DIM-1;i>=0;i--){
printf("\n");
for(j=0;j<DIM;j++)
printf("%2c",v[i][j]);
}
printf("\n");
}
//-- Geração seguinte ----------
void gera(char v[][DIM]){
int i,j,m,n,c[DIM][DIM];
for(i=0;i<DIM;i++)
for(j=0;j<DIM;j++){
c[i][j]=0;
for(m=i-1;m<=i+1;m++)
for(n=j-1;n<=j+1;n++)
if(m>=0 && m<DIM &&
n>=0 && n<DIM &&
(m!=i || n!=j) &&
v[m][n]=='X')
c[i][j]++;
}
for(i=0;i<DIM;i++)
for(j=0;j<DIM;j++)
if(v[i][j]==' ' && c[i][j]==3)
v[i][j]='X';
else
if(v[i][j]=='X' && (c[i][j]<2 || c[i][j]>3))
v[i][j]=' ';
}
//-----------------------------------
#define GERS 20
main(){
char v[DIM][DIM];
int i;
inicializa(v);
mostra(v);
for(i=0;i<GERS;i++){
gera(v);
mostra(v);
system("sleep 1");
}
}
PC/PI - página reservada - versão 2005.02.08