Constellation Knowledge Network - Preguntas y respuestas sobre Bagua - El uso de tipos de datos en lenguaje C

El uso de tipos de datos en lenguaje C

El propósito de la definición de macro

Zijin Hongfei Sending Station (viernes 2 de noviembre de 2007 211925)

1 es evitar que los archivos de encabezado se incluyan repetidamente.

#ifndef COMDEF_H

#Definir COMDEF_H

Contenido del archivo de encabezado

#endif

2. Los tipos evitan que diferentes plataformas y compiladores provoquen la cantidad de bytes de tipo.

Diferencia, fácil de trasplantar.

typedef carácter sin signo Valor booleano; tipo de valor booleano.

typedef unsigned long uint32 valor de 32 bits sin signo

typedef unsigned short uint 16; valor de 16 bits sin signo

typedef unsigned char uint8 valor de 8 bits sin signo

typedef firmado valor int largo int32 de 32 bits con signo

typedef firmado valor corto de 16 bits

typedef carácter firmado int8 valor de 8 bits con signo

No se recomienda lo siguiente.

typedef byte de carácter sin signo; tipo de valor de 8 bits sin signo.

typedef palabra corta sin signo; tipo de valor de 16 bits sin signo.

typedef unsigned long dword unsigned tipo de valor de 32 bits.

typedef carácter sin signo uint 1; tipo de valor de 8 bits sin signo.

typedef unsigned short uint2 tipo de valor de 16 bits sin signo.

typedef unsigned long uint4 tipo de valor de 32 bits sin signo.

typedef carácter con signo int 1; tipo de valor de 8 bits con signo.

typedef firmado corto 2; tipo de valor firmado de 16 bits.

typedef long int int4 tipo de valor de 32 bits con signo.

typedef con signo largo Sint 31; valor con signo de 32 bits

typedef con signo corto Sint 15; valor con signo de 16 bits

typedef Carácter con signo sint7 con signo 8- valor de bit

3. Obtenga un byte o palabra en la dirección especificada.

#Definir MEM_B( x)(((byte)(x)))

#Definir MEM_W( x ) ( ( (palabra ) (x)))

4. Encuentre los valores máximo y mínimo.

#Definir MAX(x,y) ( ((x) (y)) (x) (y))

#Definir MIN(x,y) ( ((x ) (y)) (x) (y))

5. Obtener el desplazamiento de un campo en la estructura.

#Definir FPOS (tipo, campo)

lint -e545 ((type)0)-field)lint +e545

Obtener una estructura. Número de bytes ocupados por el campo.

#define FSIZ(type, field)sizeof((type)0)-field)

7. Convierte dos bytes en una palabra según el formato LSB.

# define FLIPW(ray)((((word)(ray)[0])256)+(ray)[1])

8. en dos bytes.

#Definir FLOPW(rayo, val)

(rayo)[0]=((val)256);

(rayo)[1]= ((val)&0xFF)

9. Obtener la dirección (ancho de palabra) de una variable.

# define B _ PTR(var)((byte)(void)&(var))

# define W _ PTR(var)((palabra)(void ) &(var))

10, obtiene los bytes altos y bajos de una palabra.

#define WORD_LO(xxx)((byte)((palabra)(XXX)&255))

#define WORD_HI(xxx)((byte)( (palabra) (xxx) 8))

11, devuelve el múltiplo de 8 más cercano que sea mayor que x.

#Definición RND8( x ) ((((x) + 7) 8 ) 8)

12, convierte una letra a mayúscula.

#Definición up case(c)(((c)= " a " & & amp(c)= " z ")((c)-0x 20)(c))

13, determina si el carácter es un número con un valor de 10.

# define DECCHK(c)((c)= " 0 " & & amp(c)= "9")

14, determina si el carácter es un valor numérico El número 16.

# define hex chk(c)(((c)= " 0 " && amp(c)= "9")

((c)= " A " & amp ;& amp(c)= "F")

((c)= " a " & amp;& amp(c)= " f "))

15. A método para evitar el desbordamiento

# define INC _ SAT(val)(val =((val)+1(val))(val)+1(val))

16, devuelve el número de elementos de la matriz.

# define ARR _ TAMAÑO(a)(tamañode((a))tamañode((a[0]))

17, valor de retorno mod _ por _ potencia _ de _ two (x, n) = x% (2 n) con cola sin firmar

#define MOD_BY_POWER_OF_TWO( val, MOD_BY)

((dword)(val). amp;(dword )((mod_by)-1))

18, Procesamiento de E/S de la estructura de mapeo del espacio IO en el espacio de almacenamiento

#Definir inp (puerto) ( ((volatile). byte)(puerto)))

#define inpw(puerto)(((palabra volátil)(puerto)))

#define inpdw(puerto)( ((dword volátil) (puerto)))

#define salida(puerto, val)(((byte volátil)(puerto))=((byte)(val)))

#define salida (puerto, val)(((palabra volátil)(puerto))=((palabra)(val)))

#define outpdw(puerto, val)(((dword volátil)(puerto)) =((dword)(val)))

[Agregado el 9 de septiembre de 2005]

19, use alguna depuración de seguimiento de macros

El estándar describe cinco nombres de macro predefinidos:

_ L I N E _

_ F I L E _

_ D A T E _

_ T I M E _

_ S T D C _

Si la compilación no es estándar, es posible que solo se admitan los nombres de macro anteriores, o no se admitan

Traductores

También lo son. Es posible proporcionar otros nombres de macro predefinidos

Las macros _L I N E _ y _ F I L E _ se han analizado en la sección sobre # línea y también se analizan aquí

Sobre otros nombres de macro.

La _D en la directiva macro E_ contiene una cadena en forma de mes, día y año, que indica la fecha en la que el archivo fuente se traduce al código.

Período.

La hora en que el código fuente se traduce al código de destino está contenida como una cadena en el formato horas:minutos:

Segundos

Si la implementación. es estándar, la macro _ S T D C _ contiene la constante decimal 1. Si contiene otros

números, la implementación no es estándar. Puede definir macros, por ejemplo

Al definir _DEBUG, genere información de datos y la línea donde se encuentra el archivo.

#ifdef _DEBUG

#define DEBUGMSG(mensaje, fecha)

printf(msg); printf("%d%d%d ", fecha, _LINE_, _FILE_)

#De lo contrario

#define DEBUGMSG(mensaje, fecha)

#endif

20. Ser uso es incorrecto.

Enciérrelo entre paréntesis.

Por ejemplo: #define ADD(a, b) (a+b)

Utilice la instrucción do{} while(0) para incluir varias declaraciones para evitar errores.

Por ejemplo: #difne DO(a,b)a+b;

a++;

Cuando se aplica: si (...)

DO(a, b); un error

Otro

Solución #difne DO(a, b)DO { a+b;

a++;} while(0)

Uso de # y ## en macros

1. Uso general

Usamos # para convertir el parámetro de macro en un. cadena de caracteres, utilice ## para pegar los dos parámetros de macro juntos.

Usar

#includecstdio

# incluir restricciones

Usar espacio de nombres std

#Definir cadena# s

#Definir CONS(a,b) int(a##e##b)

int main()

{

printf( STR(vck)); Cadena de salida vck

printf(%dn, CONS(2, 3)); 2e3 salida 2000

Devuelve 0;

}

En segundo lugar, cuando el parámetro de la macro es otra macro.

Cabe señalar que cuando se utiliza ' # ' o ' # # ' en una definición de macro, los parámetros de la macro no se expandirán.

1, en lugar de "#" y "# #"

#Definir TOW (2)

#Definir MUL(a, b) (ab)

printf(%d%d=%dn,TOW,TOW,MUL(TOW,TOW));

La macro en esta línea se expandirá a:

printf(%d%d=%dn, (2), (2), (2)(2));

El parámetro TOW en MUL se expandirá a (2).

2. Cuando hay "#" o "# #"

#Definir uno (2)

#Definir cadena #s

#Definir CONS(a, b) int(a##e##b)

printf(int max %sn, STR(INT _ MAX));

Esta línea se expandirá a:

printf(int max %sn, INT_MAX);

printf(%sn, CONS(A,A)); Error de compilación

p>

Esta línea es:

printf(%sn, int(AeA));

Ni INT_MAX ni a se expandirán, pero este problema La solución es simple. Agrega otra capa.

Convierte macros entre.

El propósito de agregar esta macro es expandir todos los parámetros de todas las macros en esta capa, de modo que una de las macros se pueda convertir

Una macro (_STR) para obtener la macro correcta parámetros macro.

#Definir uno (2)

# definir _STR # s

#Definir macro de conversión string_string

# definir _CONS(a , b) int(a##e##b)

#Definir CONS(a, b) _CONS(a, b) macro de transformación

printf(int max % sn, STR ( INT _ MAX)); Int _ max, el valor máximo del tipo Int, es

Variable #includeclimates

La salida es int max 0x7ffffff.

Str (int _ max)-_ str (0x7ffffff) y luego se convierte en una cadena

printf (%dn, CONS (A, A));

La salida es: 200

CONS(A,A) - _CONS((2),(2)) - int((2)e(2))

Tres. Algunas aplicaciones especiales de "#" y "# #"

1. Combinar nombres de variables anónimas

# define _ _ _ anónimo 1 (tipo, var, línea) tipo var## línea

#define __ANONYMOUS0(tipo, línea)_ANONYMOUS 1(tipo, _ anónimo,

línea)

# define ANONYMOUS(tipo)_ _ ANÓNIMO 0 (tipo, __LINE__)

Por ejemplo: ANONYMOUS (static int); es decir, static int _ unlimited7070 representa esta línea.

Número;

Primer nivel: anónimo (int estático); __ANONYMOUS0 (int estático,

_ _ LINE _ _

<); p>Segundo piso:-__anonymous 1 (static int,_anonymous,70);

Tercer piso:-static int_anonymous 70;

Es decir, solo uno Desbloquea la macro del actual capa, por lo que __LINE__ se puede desbloquear en la segunda capa;

2 Estructura de relleno

#Definir relleno (a) {a, #a}

Enumeración. IDD{ABRIR,CERRAR}.

mensaje de estructura typedef {

IDD id

const char mensaje;

} MSG

MSG _msg[ ] = {FILL(OPEN), FILL(CLOSE)};

Equivalente a:

MSG_MSG[]= {{Abrir, abrir},

{ CLOSE, CLOSE}}

3. Grabar nombre de archivo

#define _GET_FILE_NAME(f) #f

#defineGet file name(f)_ Obtener el archivo nombre (f)

Nombre de archivo de caracteres estáticos [] = Obtener el nombre del archivo (__file_ _);

4. Obtener el tamaño del búfer de cadena correspondiente al tipo numérico.

# define _ TIPO _ BUF _ TAMAÑO(TIPO)TAMAÑO de # TIPO

# define TIPO _ BUF _ TAMAÑO (TIPO)_ TIPO _ BUF _ TAMAÑO (TIPO)

char BUF[TIPO _ BUF _ TAMAÑO(INT _ MAX)];

-char BUF[_ TIPO _ BUF _ TAMAÑO(0x 7 fffffff)]; >-char buf[sizeof 0x 7 fffffff];

Esto es equivalente a:

char buf[11];

Cómo usar C (y C++ ), pertenecen a la categoría de preprocesamiento del compilador.

Pertenece al concepto de tiempo de compilación (no de tiempo de ejecución). La siguiente es una breve descripción de los problemas comunes de uso de macros.

Para resumir.

Acerca de # y # #

En las macros en lenguaje C, la función de # es encadenar los parámetros de macro que le siguen.

(Stringfication), simplemente significa que la macro variable a la que hace referencia está a la izquierda y a la derecha después de ser reemplazada.

Encierre cada uno entre comillas dobles. Por ejemplo, la macro en el siguiente código:

#define WARN_IF(EXP)

do{ if (EXP)

fprintf(stderr, Advertencia # expn ); }

while(0)

Entonces se producirá el siguiente proceso de reemplazo en el uso real:

WARN _ IF(divider = = 0);

p>

reemplazado con

do{

if(divisor == 0)

fprintf(stderr, advertencia divisor= = 0n);

} while(0);

Esto generará un mensaje rápido en el flujo de error estándar siempre que el divisor sea 0.

Y # # se llama conector y se utiliza para conectar dos tokens en uno solo.

Tenga en cuenta que el objeto conectado aquí es un token, no necesariamente una macro variable. Por ejemplo, quieres preparar un plato.

Una matriz de estructuras que consta de un único nombre de comando y un puntero de función donde desea que se nombre el nombre de la función y el elemento del menú.

Existe una relación intuitiva entre los nombres. Entonces el siguiente código es muy práctico:

Comando de estructura

{

Nombre del personaje;

void (función) (void);

};

#define command(name){name,name# #_command}

Entonces puedes usar algunos comandos predefinidos. Inicializa uno fácilmente.

Un conjunto de estructuras de comando:

Comando de estructura comando[] = {

Comando (salir),

Comando (ayuda) ,

...

}

La macro de comando actúa aquí como un generador de código y se puede reducir hasta cierto punto.

La densidad del código también puede reducir indirectamente los errores causados ​​por descuidos. También podemos conectar n símbolos.

Token N+1, esta función tampoco está disponible en el símbolo #. Por ejemplo:

#Define LINK_MULTIPLE(a, b, c, d) a##_##b##_##c##_##d

typedef estructura_tipo_registro

LINK_MULTIPLE(nombre, empresa, puesto, salario);

Aquí, esta declaración se ampliará a:

typedef estructura_record_type

p>

Name_Company_Position_Salary;

Acerca del uso de...

... se llama macro Variadic en macro C, lo que significa macros Variadic. Por ejemplo:

#Define myprintf(templt,...)

fprintf(stderr, templt, __VA_ARGS__)

o

# define myprintf(templt, args...)

fprintf(stderr, temporal, arguments)

Dado que la primera macro no tiene nombres de parámetros, usamos la macro predeterminada __VA_ARGS__ para reemplazar él. Orden

En ambas macros, nombramos explícitamente los parámetros args, por lo que podemos usar args en la definición de la macro.

Cambié de opinión. Al igual que stdcall en lenguaje C, los parámetros variables deben figurar como el elemento más importante en la lista de parámetros.

Ahora. Cuando solo podemos proporcionar la primera plantilla de parámetro en la macro anterior, el estándar C requiere que escribamos.

Cheng:

myprintf(templt,);

Formulario. El proceso de reemplazo en este momento es:

myprintf(error!n,);

reemplazo con:

fprintf(stderr, error!n,);

Esto es un error de sintaxis y no se puede compilar normalmente. Generalmente existen dos soluciones a este problema. Primero, la solución proporcionada por GNU

CPP permite que la llamada de macro anterior se escriba como:

myprintf(templt);

Será reemplazada por:

fprintf(stderr, error!n,);

Obviamente, todavía habrá errores de compilación aquí (excepto en este ejemplo, no habrá errores de compilación en algunos casos)< /p >

Incorrecto). Además de este método, tanto c99 como GNU CPP admiten los siguientes métodos de definición de macros:

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

## __VAR_ARGS__)

En este momento # # sirve como símbolo de conexión antes de la eliminación cuando __VAR_ARGS__ está vacío.

Una coma en la superficie. Entonces, el proceso de traducción en este momento es el siguiente:

myprintf(templt);

convertido en:

fprintf(stderr, templt);

De esta forma, si la plantilla es legal, no habrá errores de compilación. A continuación se muestran algunas macros fáciles de usar.

Qué salió mal y cómo usarlo correctamente.

Anidamiento de errores - Anidamiento de errores

La definición de una macro no necesariamente tiene que tener corchetes completos y emparejados, pero para evitar errores y mejorar la legibilidad,

Es mejor evitar dicho uso.

Problemas causados ​​por la precedencia del operador - problemas de precedencia del operador

Debido a que la macro es solo un reemplazo simple, si el parámetro de la macro es una estructura compuesta, es posible después del reemplazo.

Debido a que la precedencia de operadores entre cada parámetro es mayor que la interacción entre partes dentro de un solo parámetro

Precedencia de operadores, si no protegemos cada parámetro macro con paréntesis, pueden ocurrir resultados no deseados .

Situación. Por ejemplo:

# define celda _ div(x, y) (x + y - 1) y

Por lo tanto

a = ceil _ div(b & amp;c,sizeof(int));

se convertirá a:

a =(b & amp;c+sizeof(int)-1)sizeof(int) ;

Debido a que +- tiene prioridad sobre &, las fórmulas anteriores son equivalentes.

Yu:

a =(b & amp; (c+sizeof(int)-1))sizeof(int

Esto obviamente no lo es; una pelea La intención original del hombre del teléfono.

Para evitar esto, debes escribir más corchetes:

#define ceil_div(x,y) (((x) + (y) - 1) (y))

Eliminar redundancia punto y coma - tragar punto y coma

Normalmente, para hacer que las macros similares a funciones parezcan superficialmente llamadas ordinarias del lenguaje C.

De manera similar, generalmente agregamos un punto y coma después de la macro, como la siguiente macro con parámetros:

MY _ MACRO(x);

Pero si The El siguiente es el caso:

#Definir mi macro (x) {

Línea 1

Línea 2

Línea 3}

<…

if(condición())

MI _ MACRO(a);

Otros

{. ..}

Esto provocará un error de compilación debido al punto y coma adicional. Para evitar esta situación

MY _ MACRO(x); esta forma de escribir, necesitamos definir la macro de esta forma:

#define MY_MACRO(x) do {

Línea 1

Línea 2

Línea 3} while(0)

Así que siempre y cuando te asegures de usar siempre punto y coma, no ¿Cuál será el problema?

Copia de efectos secundarios

Los efectos secundarios aquí significan que la macro puede evaluar sus argumentos varias veces a medida que se expande.

(Es decir, el valor), pero si este parámetro macro es una función, se puede llamar muchas veces.

Esto da como resultado resultados inconsistentes y errores aún más graves. Por ejemplo:

#Definir min(X,Y) ((X) (Y) (Y) (X))

...

c = min(a, foo(b));

En este momento, la función foo() se llama dos veces. Para resolver este posible problema, debemos escribir la macro min(X, Y) así:

#Definir el valor mínimo (X, Y) ({

tipo de (X)X _ =(X);

tipo de(Y)Y _ =(Y);

(x _ y _)x _ y })

({...}) devuelve el último valor de varias declaraciones internas y también permite declaraciones internas.

Variable (porque forma el alcance local mediante llaves).

-

51e pequeño 2 es, 513 pequeño 28 es.

En Linux me gustan los hombres, pero en realidad no lo soy.

El GNU recursivo más fuerte no es Unix.

He vuelto del infierno

Las lágrimas siguen en el cielo.

,siiiiiiiiiiiiiiiiiiiiiisssiis 2x 9 gaaaaaaaa &gggh 3x 22552252555222555555555552 r

上篇: ¿Qué significa para una mujer embarazada soñar con tener un bebé? 下篇: El dedo del pie de Zhou Gong resultó herido_Sueño con una lesión en el dedo del pie.
Artículos populares