tipos - Sintaxis y uso de muestra de_Generic en C11
poblacion muestra y muestreo ejemplos (3)
Uso clion 1.2.4, y clion no es compatible con c11 ahora, entonces uso el siguiente código en c99 en vez de _Generic
#include <stdio.h>
int main(int argc, char **argv) {
char *s;
if (__builtin_types_compatible_p(__typeof__(s), long)) {
puts("long");
} else if (__builtin_types_compatible_p(__typeof__(s), char*)) {
puts("str");
}
return (0);
};
Escuché que C11 agregó genéricos. Busqué en Google un poco, miré algunos artículos, entendí que había una nueva palabra clave ( _Generic
) y todo. Pero parece que no puedo entenderlo todo.
¿Es algo así como los genéricos en C # o plantillas en C ++? ¿Alguien puede darme una breve explicación de la definición C11 de genéricos, su sintaxis y un ejemplo simple de uso de muestras?
This es una muy buena introducción. Aquí está la descripción general:
La selección genérica se implementa con una nueva palabra clave: _Generic. La sintaxis es similar a una simple declaración de cambio para los tipos:
_Generic( ''a'', char: 1, int: 2, long: 3, default: 0)
evalúa a 2 (las constantes de los caracteres son entradas en C).
Básicamente funciona como un tipo de switch
, donde las etiquetas son nombres de tipos que se prueban contra el tipo de la primera expresión (la ''a''
anterior). El resultado se convierte en el resultado de evaluar el _Generic()
.
This inspiró el siguiente ejemplo (ejecutable), que desbloquea todo tipo de posibilidades extrañas para la introspección agrietada ...
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#define typename(x) _Generic((x), /* Get the name of a type */ /
/
_Bool: "_Bool", unsigned char: "unsigned char", /
char: "char", signed char: "signed char", /
short int: "short int", unsigned short int: "unsigned short int", /
int: "int", unsigned int: "unsigned int", /
long int: "long int", unsigned long int: "unsigned long int", /
long long int: "long long int", unsigned long long int: "unsigned long long int", /
float: "float", double: "double", /
long double: "long double", char *: "pointer to char", /
void *: "pointer to void", int *: "pointer to int", /
default: "other")
#define fmt "%20s is ''%s''/n"
int main() {
size_t s; ptrdiff_t p; intmax_t i; int ai[3] = {0}; return printf( fmt fmt fmt fmt fmt fmt fmt fmt,
"size_t", typename(s), "ptrdiff_t", typename(p),
"intmax_t", typename(i), "character constant", typename(''0''),
"0x7FFFFFFF", typename(0x7FFFFFFF), "0xFFFFFFFF", typename(0xFFFFFFFF),
"0x7FFFFFFFU", typename(0x7FFFFFFFU), "array of int", typename(ai));
}
╔═══════════════╗ ═════════════════╣ Amazeballs... ╠═════════════════════════════════════ ╚═══════════════╝ size_t is ''unsigned long int'' ptrdiff_t is ''long int'' intmax_t is ''long int'' character constant is ''int'' 0x7FFFFFFF is ''int'' 0xFFFFFFFF is ''unsigned int'' 0x7FFFFFFFU is ''unsigned int'' array of int is ''other''