Convertire variabile in nome

Visto che una buona soluzione è stata pubblicata mi permetto di mostrare cosa avevo pensato io

per prima cosa uso di una funzione, certamente,
funzione che deve restituire una stringa (ovvero char *)
ecco il suo prototipo

char * direzione(int bussola);

poi ho pensato di renderla parametrica e di usare una tabella (array) locale
e quindi un array di stringhe (puntatore a carattere)

char * nomi[]={};

e naturalmente tra le parentesi graffe ci va l'elencazione dei punti cardinali, compresi tra virgolette (essendo singole stringhe) e separati da virgole (essendo un'elencazione di elementi di un array)

poi ho pensati di renderla parametrica, calcolando il "passo di cambio" dei punti cardinali passando per due "sizeof"

e serve comunque di tenere in conto che il Nord comincia "prima" dell'angolo "zero", quindi serve di calcolare un offset da aggiungere, offset che sarà, banalmente, pari a mezzo passo

il tutto deve essere calcolato in aritmetica a virgola mobile, per tenere conto che se si volessero più dei classici e canonici 4 punti cardinali serve tenere conto di angoli minori o uguali a 22 gradi e mezzo

ecco quindi che servirà:
un giochino con un operatore modulo 360
un calcolo del passo
un calcolo dell'offset
una ulteriore operazione di modulo, ma stavolta eseguita in aritmetica float

e usare il valore così ottenuto come indice che indica il corretto elemento nell'array dei puntatori a carattere
puntatore a carattere che sarà oggetto del return della funzione
naturalmente i valori che non cambiano da una esecuzione e la successiva devono essere "static" per non dover ricalcolare tutte le volte

ecco quindi la funzione fatta e finita

char * direzione(int bussola)
{
#ifndef CARDINALI
#define CARDINALI "N","NE","E","SE","S","SW","W","NW"
#endif
   static char * nomi[] = {CARDINALI};
   bussola = bussola % 360;
   static int n = sizeof nomi / sizeof nomi[0];
   static float passo = 360 / n;
   static float offset = passo / 2;
   float grezzo = (bussola + offset);

   if (grezzo > 360)
   {
      grezzo = grezzo - 360;
   }

   return nomi[(int)(grezzo / passo)];
}

e un suo programma di prova minimale

void setup(void)
{
   Serial.begin(9600);

   for (int i = 0; i < 360; i += 10)
   {
      Serial.print(i);
      Serial.print("  ");
      Serial.println(direzione(i));
   }
}

void loop(void)
{
   // nulla da fare
}

provare per credere

e già che ci siete, dato che la funzione è parametrica basta aggiungere in testa al programma questa riga:

#define CARDINALI "Settentrione","Oriente","Mezzogiorno","Occidente"

per avere una deliziosa sorpresa

naturalmente si possono usare tutte le direzioni che si desidera, anche non multiple di quattro

1 Like