Q:

Puntero a struct en ansi C

Tengo definido lo siguien globalmente. 
char   buffer[32+1];
TOKEN  tokenActual;
int    flagToken = 0;

typedef enum{
  INICIO, FIN, LEER, ESCRIBIR, ID, CONSTANTE, PARENIZQUIERDO, PARENDERECHO,
  PUNTOYCOMA, COMA, ASIGNACION, SUMA, RESTA, FDT, ERRORLEXICO
}TOKEN;

typedef struct{
  TOKEN clase;
  char  nombre[32+1];
  int   valor;
}T_REG;

T_REG TS[1000] = {{INICIO,   "inicio",   99},
                  {FIN,      "fin",      99},
                  {LEER,     "leer",     99},
                  {ESCRIBIR, "escribir", 99},
                  {99,       "$",        99}};

y dentro del main tengo esta función:
TOKEN ProximoToken(){
  T_REG *reg;
  tokenActual = scanner(); /*scanner analiza un flujo, devuelve un TOKEN y en buffer almacena lo analizado*/
  if(tokenActual == ID) Buscar(buffer, TS, reg);
  printf("*** Encontre nombre[%s] clase[%d]\n", reg->nombre, reg->clase);
  return tokenActual;
}

y Buscar:
int Buscar(char *id, T_REG *TS, T_REG *reg){
  int i = 0;
  while(strcmp("$", TS[i].nombre)){
    if(!strcmp(id, TS[i].nombre)){
      reg = &TS[i];
      printf("*** Buscar: nombre[%s] clase[%d]\n", reg->nombre, reg->clase);
      return 1;
    }
    i++;
  }
  return 0;
}

Mi problema es que cuando llamo a "Buscar" le paso buffer="inicio", lo busca en TS y cuando lo encuentra me imprime en pantalla:
*** Buscar: nombre[inicio] clase[0]

El tema es que cuando termina Buscar y vuelvo a ProximoToken, yo entiendo que "reg" apunta a una posición en TS.  Y cuando pretendo imprimir en pantalla los valores de ese struct apuntado, imprime basura. 
Que estoy haciendo mal? 
Aclaro que esto es parte de un "seudo compilador" que analiza un archivo con codigo y lo evalua.  Por ejemplo:
inicio
  leer (a,b);
  cc := a + (b-2);
  escribir (cc, a+4);
fin

tengo una funcion que devuelve un punto a puntero:
T_REG** Colocar(char *id, T_REG *TS){
  T_REG **reg;
  int i = 4;
  while(strcmp("$", TS[i].nombre)) i++;
  if(i < 999){
    strcpy(TS[i].nombre, id);
    TS[i].clase = ID;
    TS[i].valor = 0;
    *reg = &TS[i];
    strcpy(TS[++i].nombre, "$");
    return reg;
  }
}

Esta funcion pretende agregar un identificador a la lista TS y devolver un puntero a ese elemento agregado. 
en *reg = &TS[i]; revienta.  porque?  los punteros a punteros se tiene que inicializar?  si pregunto if(*reg == NULL) tmb revienta

A:

Tu problema básicamente es que pasas solo el puntero, si el puntero es NULL, la asignación se completa, pero nunca se devuelve a ProximoToken. 
Te recomiendo cambiar la firma de la función Buscar por la siguiente:
int Buscar(char *id, T_REG *TS, T_REG **reg);

Haces la asignación dentro de la función de la siguiente forma:
*reg = &TS[i];

Y al llamar la función, recuerda pasar la dirección del puntero que necesitas:
Buscar(id, TS, &reg);

Arreglado tu código luciría de la siguiente forma:
int Buscar(char *id, T_REG *TS, T_REG **reg){
  int i = 0;
  while(strcmp("$", TS[i].nombre)){
    if(!strcmp(id, TS[i].nombre)){
      *reg = &TS[i];
      printf("*** Buscar: nombre[%s] clase[%d]\n", reg->nombre, reg->clase);
      return 1;
    }
    i++;
  }
  return 0;
}

De esta forma pasas la dirección del puntero en reg y haces que la dirección cambie cuando sea necesaio si se encuentra el token. 
Edit: En respuesta a tu nuevo problema
En esta linea:
T_REG **reg;

Colocas un puntero a puntero, pero nunca colocas memoria para utilizar dicho puntero, puedes utilizar dos formas:
T_REG *reg;

Y realizar una asignacion normal de puntero para luego retornarlo:
reg = &TS[i];

O bien puedes colocar memoria dinámica (En heap) para utilizar el puntero:
T_REG **reg = malloc(sizeof(T_REG *));

Y utilizar la misma asignación:
*reg = &TS[i];

Tu programa "crashea" porque el puntero a puntero reg no está apuntando hacia una dirección de memoria válida (NULL) y necesitas, o colocar memoria para usarlo, o cambiarlo a un puntero simple.