Páginas

quinta-feira, 3 de dezembro de 2009

nodo_generico.c

 
/*
    Uisleandro CS
    Descobra também uma nova utilidade para o #define !
    Observe que é necessário fazer algumas modificações para
    usá-lo em listas, pilhas e filas, etc.
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// #define POINTER_ALLOC(tp) (tp *)malloc(sizeof(tp))

/*
    Inicializa o 'nodo' com o tipo desejado (aloca o tamanho desejado).
    Aloca memória para o nodo..
    Aloca memória para nodo->value com o tamanho do tipo passado como parâmetro.
    Cita o próximo de nodo como NULL
*/
#define NODO_INICIA(no,tp)\
    no = (nodo *)malloc(sizeof(nodo));\
    if(!no) exit(1);\
    no->value = malloc(sizeof(tp));\
    if(!no->value) exit(1);\
    no->next = (struct nodo *)NULL

/*
    Retorna o valor apontado pelo ponteiro, faz o cast para o tipo desejado
*/
#define NODO_GET_VALUE(no,tp) (*((tp *)no->value))

/*
    Usa um ponteiro para mudar o valor apontado pelo 'nodo';
    Faz a conversão de tipos (cast);
    Passa uma cópia do valor passado como parametro para o espaço alocado anteriremente.
*/
#define NODO_SET_VALUE(no,tp,val) *((tp *)no->value) = val

/*
    Libera espaço na memória ocupado pelo nodo
*/
#define NODO_EXCLUI(no) free(no->value); free(no)

typedef struct nodo
{
    void * value;
    struct nodo * next;
} nodo;

typedef struct
{
    char nome[30];
    int idade;
} pessoa;

int main()
{

    nodo * n;

    pessoa ps;
 
    strcpy(ps.nome,"nome1");
    ps.idade = 10;
 
    printf("pessoa = {\"%s\" %d}; \n\n", ps.nome, ps.idade);

    NODO_INICIA(n, pessoa);
        NODO_SET_VALUE(n, pessoa, ps);
        printf("n->value = {\"%s\", %d};\n\n", NODO_GET_VALUE(n, pessoa).nome, NODO_GET_VALUE(n, pessoa).idade);
        //pessoa q = NODO_GET_VALUE(n, pessoa);
        //printf("q = {\"%s\", %d};\n\n", q.nome, q.idade);
    NODO_EXCLUI(n);
 
    NODO_INICIA(n, int);
        NODO_SET_VALUE(n, int, 100);
        printf("n->value = %d;\n\n", NODO_GET_VALUE(n, int));
    NODO_EXCLUI(n);

    NODO_INICIA(n, double);
        NODO_SET_VALUE(n, double, 100);
        printf("n->value = R$%.2f;\n\n", NODO_GET_VALUE(n, double));
    NODO_EXCLUI(n);
 
    system("pause");
 
    return 0;
}

terça-feira, 1 de dezembro de 2009

c - convertendo numero em string


  1. Fazer isso é muito penoso, ha uma forma mais fácil, vejam: 
    1. http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/
  2. Aqui uma maneira de fazer isso no c++ convertendo int para std::string
    1. http://www.cplusplus.com/forum/general/3319/

 
/*
  Criado por Uisleandro CS; uisleandro@gmail.com
  Util para imprimir valores numéricos em arquivos.
*/

#include <stdlib.h>
#include <stdio.h>

// faz (float % float), recebe double ou float como parametro.
#define FLOAT_MOD(num, div) (num - ( (int)( num / div ) * div ))

// converte um número entre 0 e 9 para char.
#define INT_TOCHAR(num) ('0'+num)

#define FLOAT_GET_DECIMAL(num) (num - ( (int)( num / (int)num ) *

(int)num ) )

void raiserror(int i, char * c, char * d)
{
  printf("erro em %s: %s\n\n", c, d);
  system("pause");
  exit(i);
}

// pega a parte decimal do float
// takes the decimal part of float;
float decimal(float f)
{
  return FLOAT_MOD(f, (int)f);
}


// recebe a parte decimal de um número
// converte a parte decimal para um string
// NAO USAR
char * decimal_toString(float f, int count)
{
  char * c;
  int i = 0;

  if(f > 1) raiserror(1, "decimal_toString","parametro f >

1");

  if(!( c = malloc(count * sizeof(char)) )) raiserror(1,

"decimal_toString", "memoria insuficiente");

  while(count > 0)
  {
      f *= 10;
      c[i++] = INT_TOCHAR((int)f);

      if(f > 1) f = decimal(f);

      count--;
  }
  return c;
}


// retorna a ordem de um número.
// USAR?
int get_ordem(int i)
{
  int o = 1;

  while(i > 9)
  {
      o *= 10;
      i /= 10;
  }

  return o;
}

/*
converte n numeros da parte decimal do float para string
também serve para converter int
*/
char * float_toString(float uf, int decimais)
{
  char * c;
  int i = 0;
  int ui = (int)uf;
  int ordem = 1;
  int acrescimo = 1;

  //ordem = get_ordem(uf);
  while(ui > 9)
  {
      ordem *= 10;
      ui /= 10;
  }

  // take decimal part
  float dec = FLOAT_GET_DECIMAL(uf);

  // se decimais, inclui ponto
  if(decimais > 0) acrescimo += decimais + 1;

  // aloca o espaco para uma quantidade de caracteres
  if(!( c = malloc( (ordem + acrescimo)* sizeof(char)) ))
  raiserror(1, "float_toString", "memoria insuficiente");

  // adiciona cada numero do que tem maior ordem para o de menor ordem
  while(ordem > 0)
  {
      c[i++] = INT_TOCHAR((int)(uf - (int)uf % ordem ) / ordem);
      uf -= (uf - (int)uf % ordem );
      ordem /= 10;
  }

  if(decimais <= 0)
  {
      c[i] = '\0';
      return c;
  }

  c[i++] = '.';

  // adiciona todos os numeros da parte decimal..
  while(decimais > 0)
  {
      dec *= 10;
      c[i++] = INT_TOCHAR((int)dec);
      if(dec > 1) dec = FLOAT_GET_DECIMAL(dec);
      decimais--;
  }

  c[i] = '\0';

  return c;
}

// vou  precisar criar uma função para converter de double para

string.
int main()
{
  // srand(time(NULL));

  float f = 123.03998;

  //float g = FLOAT_MOD(f, 123.03);

  //printf(";%.5f mod 123;", f);
  //printf(";%.5f;", g);
  //printf(";%c;", INT_TOCHAR(2));

  /*
      TODO: Vou usar para salvar os erros da rede em um arquivo
      para que eu possa gerar o gráfico no scilab!
  */
  printf("%s = float_toString(%f)\n\n",float_toString(f, 6), f);

  // printf("%f\n\n..", decimal(f));

  // decimal_toString(decimal(f), 10);


  // printf("%s = decimal_toString(%f)",

decimal_toString(decimal(f), 10), f);


  //printf("%d", get_ordem(f));

  //printf(";%d;", float_toString(f,1));

  system("pause");
}

Programação Multithread em C (windows)

 
/*
Exemplo de programação multithread em C:
dá para saber o que é um thread sincronico e assincronico.. teste
*/

// crt_begthrdex.cpp
// compile with: /MT
#include <windows.h>
#include <stdio.h>
#include <process.h>

unsigned Counter; 
unsigned __stdcall SecondThreadFunc( void* pArguments )
{
    printf( "In second thread...\n" );

    while ( Counter < 1000000 )
        Counter++;
  
 //printf("Counter=%d\n",Counter);
    _endthreadex( 0 );
    return 0;
} 

int main()
{ 
    HANDLE hThread;
    unsigned threadID;

    printf( "Creating second thread...\n" );

    // Create the second thread.
    hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID );

    // Wait until second thread terminates. If you comment out the line
    // below, Counter will not be correct because the thread has not
    // terminated, and Counter most likely has not been incremented to
    // 1000000 yet.
    // Serve para a sincronização do thread ao programa principal.
    WaitForSingleObject( hThread, INFINITE );
    
    
    printf( "Counter should be 1000000; it is-> %d\n", Counter );
    
    // Destroy the thread object.
    CloseHandle( hThread );
    
    system("pause");
}

fonte: Documentação offline do Visual Studio.