# 和 ## Resumen de uso

Cómo usar macros en lenguaje C Las macros (Macro) en C (y C ++) pertenecen a la categoría de preprocesamiento del compilador y generalmente se usan y reemplazan durante la compilación. La siguiente es una explicación del uso de # y ## en las definiciones de macros .

1. Acerca de # y ##

# Uso
En la definición de macro del lenguaje C, la función de # es convertir los parámetros de macro que le siguen en una cadena. En pocas palabras, después de reemplazar la variable de macro a la que se refiere, agregue una comilla doble en los lados izquierdo y derecho de eso. Por ejemplo, la definición de macro en el siguiente código:

#define ADDSTR(str)    do{ fprintf(stderr, "add strings: " #str "/n"); }   while(0)
ADDSTR(hello);

De esta manera, el ADDSTR anterior (hola); significa que se ejecuta el siguiente código,

do{ 
	fprintf(stderr, "add strings: " "hello" "/n");
	}  while(0);

## 的 用
## se llama concatenador, que se utiliza para conectar dos Tokens en un Token. Tenga en cuenta que el objeto conectado aquí es solo un Token, no necesariamente una variable macro. Por ejemplo, desea crear una matriz de estructura compuesta por nombres de comando de elemento de menú y punteros de función, y espera que haya una relación intuitiva y de nombre entre el nombre de la función y el nombre de comando del elemento de menú. Entonces el siguiente código es muy práctico:

#define USER_DATA_DEFINE(type,name)                                     \
                                                                        \
type name __attribute__((section("NO_INIT_WITH_SAVE"), zero_init));     \
                                                                        \
typedef struct                                                          \
{                                                                       \
    char      name[NAME_LEN];                                           \
    type      *address;                                                 \
    uint32_t  length;                                                   \
}Var##name##_t;                                                         \

USER_DATA_DEFINE(USER_DATA_CTRL_WORD_T,        user_data_ctrl_word);

La declaración anterior USER_DATA_DEFINE (USER_DATA_CTRL_WORD_T, user_data_ctrl_word); puede ser equivalente al siguiente código:

USER_DATA_CTRL_WORD_T  user_data_ctrl_word __attribute__((section("NO_INIT_WITH_SAVE"), zero_init));
typedef struct  {
	char      name[NAME_LEN]; 
	type      *address; 
	uint32_t  length;
}Varuser_data_ctrl_word_t;

Por lo tanto, el símbolo ## puede usarse para hacer que el código parezca más simple y claro;

## Uso especial

Al explicar este uso especial, primero explique la función de ...; ... se llama macro de parámetro variable en la macro de C. tal como:

#define myprintf(templt,...) fprintf(stderr,templt,__VA_ARGS__)

// o

#define myprintf(templt,...) fprintf(stderr,templt,args)

Dado que el parámetro de la variable no se nombró en la primera macro, lo reemplazamos con la macro predeterminada __VA_ARGS__. En la segunda macro, nombramos explícitamente el parámetro variable args, por lo que podemos usar args para referirnos al parámetro variable en la definición de la macro. Como stdcall en lenguaje C, los parámetros variables deben aparecer como último elemento en la lista de parámetros. Cuando solo podemos proporcionar el primer parámetro templt en la macro anterior, el estándar C requiere que escribamos:
myprintf (templt,);
El proceso de reemplazo en este momento es:
myprintf ("Error! / N",);
Reemplazar con:
fprintf (stderr, "Error! / N",);

Este es un error de sintaxis y no se puede compilar normalmente.
Pero si lo definimos como el siguiente formulario, no se reportará ningún error:

#define myprintf(templt, ...) fprintf(stderr,templt, ##__VAR_ARGS__)

En este momento, la función del símbolo de enlace ## es eliminar la coma al frente cuando __VAR_ARGS__ está vacío. Entonces, el proceso de traducción en este momento es el siguiente:
myprintf (templt);
se transforma en:
fprintf (stderr, templt);

Supongo que te gusta

Origin blog.csdn.net/weixin_43704402/article/details/113881795
Recomendado
Clasificación