sirven que punteros puntero parametros para los funciones ejemplos declaracion como cadenas aritmetica c const-correctness std

que - punteros como parametros de funciones en c



¿Por qué el parámetro endptr para strtof y strtod es un puntero a un puntero de carácter no constante? (2)

La razón es simplemente la usabilidad. char * puede convertir automáticamente a const char * , pero char ** no se puede convertir automáticamente a const char ** , y el tipo real del puntero (cuya dirección se pasa) utilizada por la función de llamada es mucho más probable que sea char * que const char * . La razón por la que esta conversión automática no es posible es que existe una forma no obvia de que se pueda usar para eliminar la calificación de const través de varios pasos, donde cada paso parece perfectamente válido y correcto en sí mismo. Steve Jessop ha proporcionado un ejemplo en los comentarios:

Si pudieras convertir automáticamente char** en const char** , entonces podrías hacer

char *p; char **pp = &p; const char** cp = pp; *cp = (const char*) "hello"; *p = ''j'';.

Para seguridad constante, una de esas líneas debe ser ilegal, y como las demás son operaciones perfectamente normales, tiene que ser cp = pp;

Un enfoque mucho mejor hubiera sido definir estas funciones para void * en lugar de char ** . Tanto char ** como const char ** pueden convertir automáticamente a void * . (El texto afectado era en realidad una muy mala idea; no solo impide la verificación de tipos, sino que C en realidad prohíbe los objetos de tipo char * y const char * al alias). Alternativamente, estas funciones podrían haber tomado un ptrdiff_t * o size_t * argumento en el que se almacena el desplazamiento del final, en lugar de un puntero a él. Esto es a menudo más útil de todos modos.

Si le gusta este último enfoque, siéntase libre de escribir una envoltura de este tipo alrededor de las funciones de la biblioteca estándar y llame a su envoltura, para mantener el resto de su código siempre limpio y limpio.

Las funciones estándar de la biblioteca de C, strtof y strtod tienen las siguientes firmas:

float strtof(const char *str, char **endptr); double strtod(const char *str, char **endptr);

Cada uno de ellos descompone la cadena de entrada, str , en tres partes:

  1. Una secuencia inicial, posiblemente vacía, de espacios en blanco.
  2. Una "secuencia de sujetos" de caracteres que representan un valor de punto flotante
  3. Una "secuencia final" de caracteres que no se reconocen (y que no afectan a la conversión).

Si endptr no es NULL , entonces *endptr se establece en un puntero al carácter que sigue inmediatamente al último carácter que formó parte de la conversión (en otras palabras, el inicio de la secuencia final).

Me pregunto: ¿por qué es endptr , entonces, un puntero a un puntero de carácter no const ? ¿No es *endptr un puntero en una cadena de caracteres const (la cadena de entrada str )?


Usabilidad El argumento str se marca como const porque el argumento de entrada no se modificará. Si endptr fuera const , eso endptr al interlocutor que no debe cambiar los datos a los que se hace referencia desde endptr en la salida, pero a menudo el interlocutor desea hacer eso. Por ejemplo, es posible que desee anular de forma nula una cadena después de sacar el flotante de la misma:

float StrToFAndTerminate(char *Text) { float Num; Num = strtof(Text, &Text); *Text = ''/0''; return Num; }

Una cosa perfectamente razonable para querer hacer, en algunas circunstancias. No funciona si endptr es de tipo const char ** .

Idealmente, endptr debería ser de endptr que endptr de entrada real de str , pero C no proporciona ninguna forma de indicar esto a través de su sintaxis. ( Anders Hejlsberg habla de esto cuando describe por qué se dejó a C # de const ).