direttive strlen nel preprocessore C?




direttive preprocessore c (4)

È possibile implementare strlen() nel preprocessore C ?

Dato:

#define MYSTRING "bob"

C'è una macro preprocessore, X , che mi consente di dire:

#define MYSTRING_LEN X(MYSTRING)

Tu puoi fare:

#define MYSTRING sizeof("bob")

Quello dice 4 sulla mia macchina, a causa del nulla aggiunto alla fine.

Ovviamente questo funziona solo per una costante di stringa.

Utilizzando MSVC 16 ( cl.exe -Wall /TC file.c ) questo:

#include "stdio.h"
#define LEN_CONST(x) sizeof(x)

int main(void)
{
    printf("Size: %d\n", LEN_CONST("Hej mannen"));

    return 0;
}

uscite:

Size: 11

La dimensione della stringa più il carattere NUL.


Non usa il preprocessore, ma sizeof è risolto in fase di compilazione. Se la tua stringa è in una matrice, puoi usarla per determinarne la lunghezza al momento della compilazione:

static const char string[] = "bob";
#define STRLEN(s) (sizeof(s)/sizeof(s[0]))

Tieni presente che STRLEN sopra includerà il terminatore null, diversamente da strlen() .


Generalmente il pre-processore C non trasforma effettivamente alcun dato, lo sostituisce solo. Ciò significa che potresti essere in grado di eseguire tale operazione a patto di inquinare lo spazio dei nomi del pre-processore C con i dati che implementano strutture di dati persistenti (funzionali).

Detto questo, non vuoi davvero farlo perché l'intera funzionalità "aggiunta" fallirà in modo spettacolare una volta passato qualcosa di diverso da una stringa. Il pre-processore C non ha alcun concetto di tipo di dati, né ha il concetto di de-referenziazione della memoria (utile se si desidera la lunghezza di una stringa memorizzata in una variabile). Fondamentalmente, sarebbe un divertente "vedere quanto lontano potresti farcela", ma alla fine avresti un MYSTRING_LEN che ti porterebbe solo a breve distanza dall'obiettivo.

Inoltre, la mancanza di spazi dei nomi del pre-processore C significa che un tale sistema di espansione macro non sarebbe contenibile. Si dovrebbe fare attenzione a mantenere i nomi generati da interferire con altre macro utili. Alla fine, probabilmente si esaurirà la memoria nel pre-processore per qualsiasi uso significativo, in quanto il pre-processore non è realmente costruito per contenere un nome per ogni personaggio convertito nel token "unità" e un nome per ogni token "unità" viene compresso nella sua notazione decimale finale.


Sì: #define MYSTRING_LEN(s) strlen(s)

Nella maggior parte dei compilatori, questo produrrà una costante in fase di compilazione per un argomento costante ... e non puoi fare di meglio.

In altre parole: non hai bisogno di una macro, usa solo strlen; il compilatore è abbastanza intelligente da fare il lavoro per te.





strlen