Pregunta

tengo una función como

void printMe (void *i)
{
    printf("%d", i);
}

donde quiero pasar un puntero vacío e imprimirlo en la pantalla. El ejemplo anterior está bien si el i es entero, flotante o doble, pero se bloquea si i es un char. No hay sobrecarga en C como suelo usar en C ++. Entonces, la pregunta es esta: ¿podemos crear una función en C que imprima el elemento que es su parámetro y, en caso afirmativo, cómo es esto posible porque me elude por completo en este momento?

¿Fue útil?

Solución

P1: Entonces la pregunta es esta, ¿podemos crear una función en C que imprima el elemento que es su parámetro

A: No de la manera que quieres. Tendrá que pasar información a la función, diciéndole el tipo de datos que está pasando.

P2: y si es así, ¿cómo es esto posible porque me elude por completo en este momento?

A: Te está eludiendo porque no se puede hacer. No hay metadatos asociados con un vacío * que el compilador o el tiempo de ejecución puedan usar para descubrir a qué tipo apuntan. Necesitas cualquiera

  1. pasa una estructura que contiene un
    puntero e información sobre qué
    el puntero apunta a (por ejemplo, un enum).
  2. pasar un parámetro adicional con información sobre lo que el puntero apunta a

Como está el código, lo único que puede imprimir aquí es la dirección a la que apunto.

Un puntero vacío apunta a datos sin procesar, printf asume que sabes qué tipo de datos estás imprimiendo, no tiene inteligencia y no puede & "; descifrar &"; para ti.

Es así de simple.

Lo que puede hacer es pasar información de tipo a la función, pero luego termina con algo muy parecido a printf it self, donde pasa una cadena de formato que contiene información de tipo sobre los datos en los siguientes argumentos.

Espero que esto ayude.

También. . . " No hay sobrecarga en C como suelo usar en C ++ "

Incluso en c ++, la sobrecarga ocurre en el momento de la compilación, y aquí no hay forma de que el compilador sepa qué datos se pasarán a esa función, por lo que, aunque esté acostumbrado a sobrecargar, nunca funcionaría de esta manera (p. ej. intente lo mismo con printf, pero compílelo con un compilador de C ++, obtendrá exactamente los mismos resultados). Realmente intente

cout << i;

en la función anterior, y le dará la dirección a la que apunto, no el " valor " de i. Necesitaría lanzar i y derivarlo antes de poder obtener su valor

cout << *(int*)i;

Entonces, para que lo anterior funcione en C ++, necesitaría tener muchas funciones sobrecargadas (o una función de plantilla, que es realmente lo mismo, excepto que el compilador ejecuta las funciones por usted), p. funciones sobrecargadas

printMe(int i){...}
printMe(double d){...}
printMe(char c){...}
printMe(char* string){...}

En c solo necesita asignar nombres específicos a esas funciones

printInt(int i){...}
printDouble(double d){...}
printChar(char c){...}
printString(char* string){...}

Otros consejos

Para empezar, está imprimiendo el puntero, no lo que apunta. Para imprimir el contenido real, debe pasar *i a printf, no i.

Si realmente quieres hacer esto, una solución es:

void printMe (void *p, int typ) {
    switch(typ) {
        case TYP_INT: printf("%d", *((int*)p)); break;
        case TYP_CHR: printf("%c", *((char*)p)); break;
        /* and so on ... */
    }
}
  

Entonces la pregunta es esta, ¿podemos crear una función en C que imprima el elemento que es su parámetro?

Sí, podemos. Dicha función ya forma parte de la biblioteca estándar: se llama printf;)

Como no hay sobrecarga de funciones en tiempo de compilación en C, de alguna manera debe proporcionar el tipo de argumentos en tiempo de ejecución. La cadena de formato <=> se puede usar para hacer esto, por lo que realmente no hay razón para construir su propia función de contenedor cuando ya hay una solución que funcione.

Si está intentando imprimir el valor del puntero, el uso correcto es printf("%p", i);. El especificador 'd' es para enteros, y la 'p' es para punteros. Es su responsabilidad hacer esto correctamente, y pueden suceder cosas malas si los mezcla.

No sé por qué esto fallaría para un char * y no para un int *, y es posible que tenga otros problemas causando esto. Si todavía falla con% p, algo más se estropeó. Vea si puede instalar algún tipo de software de monitor de memoria para verificar si hay punteros colgantes o doble free (), porque en ese momento el dinero inteligente es que ha dañado la memoria en alguna parte.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top