alla enum non avevo pensato e potrebbe essere una cosa buona, grazie.

per rispondere al tuo PS:
no la funzione deve leggere la matrice, vedere che cosa c'è e, se per esempio mi serve sapere dove sono le x, creare un qualche tipo di variabile che mi rappresenti tramite degli 1 le caselle in cui ci sono le X; poi devo confrontare questa variabile con una fatta in precedenza, dello stesso tipo ovviamente, che rappresenti 3 caselle consecutive riempite con lo stesso tipo di pedina (o tutte e tre X o tutte e tre O) in modo da fare dei controlli bitwise e stabilire se inserendo una pedina nella casella attigua (a quella della matrice) posso fare "forza 4".

Io avevo pensato a semplici variabili unsigned long long (o qualcosa di più lungo da definire) con cui poter fare i controlli in bitwise, ma la dimensione della tabella deve essere decisa in runtime quindi non è possibile ciò.
avevo pensato anche alle stringhe, penso che potrei utilizzare le funzioni getchar e putchar per leggere la matrice e inserire l'1 se la condizione da me voluta è verificata, ma secondo me si allunga un po' il brodo e la fuzione diventa un po lenta. Un'altra cosa che avevo pensato era una lista con un campo e un puntatore al successivo, semplice semplice ma anche indipendenta dal numero di elementi che si inseriscono.

Poi un'altra cosa: sapete spiegarmi bene che cosa sono le union?????

P.S. Ma cosa è più veloce, shiftare una variabile di n posti o una chiamata di un puntatore a puntare una certa cella di memoria?

Grazie ancora in anticipo