El uso de tipos de datos en lenguaje C
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)) p>
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) p>
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} p>
<…
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 { p>
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