#include <stdio.h>
#include <stdlib.h>

void
getstr(char *&retstr)
{
 char *tmp = (char *)malloc(25);
 strcpy(tmp, "hello,world");
 retstr = tmp;
}

int
main(void)
{
 char *retstr;

 getstr(retstr);
 printf("%s\n", retstr);

 return 0;
}

gcc no compilar este archivo, pero después de la adición #include <cstring> podía usar el g++ para compilar este archivo de origen.

El problema es: ¿el lenguaje de programación C compatible con pasar el puntero argumento por referencia? Si no, ¿por qué?

Gracias.

  • No relacionado con tu pregunta, pero por curiosidad, ¿cuál es el caso de uso para pasar un puntero como referencia?
  • si desea que la función de ser capaz de modificar el puntero, y tener la modificación se propaguen más allá del alcance de la función.
  • Si desea realizar malloc de cadenas en una función que no se puede liberar esa memoria, entonces usted podría considerar el uso de valgrind o herramienta equivalente para la prueba de fugas de memoria.
  • Una referencia es una manera de confundir a los programadores como a lo que realmente está sucediendo. Si la disciplina de su enfoque para punteros usted encontrará que las referencias no son necesarias. Cuando se trata de una referencia a un compilador toma acciones sobre un objeto y la gestión del direccionamiento indirecto para usted.
  • PP: simplificación excesiva de referencias; cualquier característica puede ser objeto de abuso.
InformationsquelleAutor Jichao | 2009-12-01

6 Comentarios

  1. 29

    No, el C no admite referencias. Es por diseño. En lugar de referencias que usted podría usar puntero a puntero en C. Referencias están disponibles sólo en lenguaje C++.

  2. 20

    Referencias son una característica de C++, mientras que C es compatible sólo los punteros. Para que la función de modificar el valor del puntero, pase el puntero a puntero:

    void getstr(char ** retstr)
    {
        char *tmp = (char *)malloc(25);
        strcpy(tmp, "hello,world");
        *retstr = tmp;
    }
    
    int main(void)
    {
        char *retstr;
    
        getstr(&retstr);
        printf("%s\n", retstr);
    
        //Don't forget to free the malloc'd memory
        free(retstr);
    
        return 0;
    }
    • No lanzas lo malloc() devuelve. Si has incluido stdlib.h, que no hace absolutamente nada. Si no, se esconde el hecho.
    • Como malloc devuelve void* me parece una buena práctica de fundición explícitamente a la clase en lugar de depender de las conversiones implícitas. Si stdlib.h no está incluido, de fundición no ocultar ese hecho – el compilador le advertirá de que malloc no ha sido declarada.
  3. 5

    Intente esto:

    
    void
    getstr(char **retstr)
    {
     char *tmp = (char *)malloc(25);
     strcpy(tmp, "hello,world");
     *retstr = tmp;
    }
    
    int
    main(void)
    {
     char *retstr;
    
     getstr(&retstr);
     printf("%s\n", retstr);
    
     return 0;
    }
    • No lanzas el valor de retorno de malloc. Se puede ocultar un fracaso para #include <stdlib.h> (que usted se olvidó en el código anterior). Consulte c-faq.com/malloc/mallocnocast.html También, no se olvide de comprobar el valor de retorno de malloc.
    • Wow, que algunas personas luchan para ver la diferencia entre una prueba de concepto de la rutina de prueba y el código de producción! Era obvio que se trataba de un áspero y listo prueba de rutina, porque no había correspondiente free pero supongo que algunas personas pierden el obvio!
  4. 2

    Este debe ser un comentario, pero es demasiado largo para un cuadro de comentarios, así que lo estoy haciendo CW.

    El código proporcionado puede ser mejor escrito como:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void
    getstr(char **retstr)
    {
        *retstr = malloc(25);
        if ( *retstr ) {
            strcpy(*retstr, "hello,world");
        }
        return;
    }
    
    int
    main(void)
    {
        char *retstr;
    
        getstr(&retstr);
        if ( retstr ) {
            printf("%s\n", retstr);
        }
        return 0;
    }
  5. 1

    Hay un interesante truco en libgmp, ya que emula referencias:
    typedef mpz_t __mpz_struct[1];

    y, a continuación, puede escribir así:

    mpz_t n;
    mpz_init(n);
    ...
    mpz_clear(n);

    Yo no recomendaría el uso de este método, ya que puede ser incomprensible para los demás, todavía no protege de ser un NULL: mpz_init((void *)NULL), y es tan detallado como puntero a puntero de la contraparte.

  6. 0

    C lang no tiene variables de referencia, pero su parte de C++ lang.

    La razón de la introducción de la referencia es para evitar que cuelgan de los punteros
    y pre-comprobación de punteros de nulidad.

    Puede considerar como referencia puntero constante decir puntero const sólo puede apuntar a los datos que haya sido inicializado a punto.

    • La otra diferencia (además de la sintáctica) parte de que las referencias no pueden ser nulos.

Dejar respuesta

Please enter your comment!
Please enter your name here