Exercícios práticos (muitos...)TopAlguns exercícios...Muitos mais exercícios!

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

Exercícios práticos (muitos...)TopAlguns exercícios...Muitos mais exercícios!