2010-11-30 20 views
24

¿Este código es correcto? Se ejecuta como se esperaba, pero ¿este código está usando correctamente los punteros y la notación de puntos para la estructura?Pase de estructura por referencia en C

struct someStruct { 
unsigned int total; 
}; 

int test(struct someStruct* state) { 
state->total = 4; 
} 

int main() { 
struct someStruct s; 
s.total = 5; 
test(&s); 
printf("\ns.total = %d\n", s.total); 
} 
+1

¿por qué se supone que el test devuelve un int? en realidad no hay retorno allí. – Muggen

+0

C tiene referencias? Sorprendido ... –

+1

@honk: no en el sentido C++, pero antes de que se inventara C++, los punteros eran una especie de "referencia" (porque tienen una "referencia"). Ahora tienen un "pointee" o algo así sin sentido. Como 'someStruct' tiene semántica de valores," pass-by-reference "(que C no hace en términos de C++) es exactamente lo mismo que" pasar una referencia por valor "(lo que hace, la" referencia "en cuestión siendo un puntero). –

Respuesta

15

Ese es el uso correcto de la estructura. Hay preguntas sobre sus valores de devolución.

Además, como está imprimiendo una int sin firmar, debe usar %u en lugar de %d.

1

Sí. Es correcto. Si no fuera (desde el punto de vista./->), su compilador le gritaría.

3

Sí, así es. Realiza una estructura s, establece su total en 5, le pasa un puntero a una función que usa el puntero para establecer el total en 4 y luego lo imprime. -> es para miembros de punteros a estructuras y . es para miembros de estructuras. Justo como los usaste.

Los valores de retorno son diferentes. test probablemente sea nulo, y main necesita un return 0 en su extremo.

39

Su uso de la notación de puntero y punto es bueno. El compilador debería proporcionarle errores y/o advertencias si hubiera algún problema.

Aquí hay una copia de su código con algunas notas adicionales y cosas para pensar en cuanto al uso de estructuras y punteros y funciones y alcance de las variables.

// Define the new variable type which is a struct. 
// This definition must be visible to any function that is accessing the 
// members of a variable of this type. 
struct someStruct { 
    unsigned int total; 
}; 

/* 
* Modifies the struct that exists in the calling function. 
* Function test() takes a pointer to a struct someStruct variable 
* so that any modifications to the variable made in the function test() 
* will be to the variable pointed to. 
* A pointer contains the address of a variable and is not the variable iteself. 
* This allows the function test() to modify the variable provided by the 
* caller of test() rather than a local copy. 
*/ 
int test(struct someStruct *state) { 
    state->total = 4; 
    return 0; 
} 

/* 
* Modifies the local copy of the struct, the original 
* in the calling function is not modified. 
* The C compiler will make a copy of the variable provided by the 
* caller of function test2() and so any changes that test2() makes 
* to the argument will be discarded since test2() is working with a 
* copy of the caller's variable and not the actual variable. 
*/ 
int test2(struct someStruct state) { 
    state.total = 8; 
    return 0; 
} 

int test3(struct someStruct *state) { 
    struct someStruct stateCopy; 
    stateCopy = *state; // make a local copy of the struct 
    stateCopy.total = 12; // modify the local copy of the struct 
    *state = stateCopy; /* assign the local copy back to the original in the 
           calling function. Assigning by dereferencing pointer. */ 
    return 0; 
} 

int main() { 
    struct someStruct s; 

    /* Set the value then call a function that will change the value. */ 
    s.total = 5; 
    test(&s); 
    printf("after test(): s.total = %d\n", s.total); 

    /* 
    * Set the value then call a function that will change its local copy 
    * but not this one. 
    */ 
    s.total = 5; 
    test2(s); 
    printf("after test2(): s.total = %d\n", s.total); 

    /* 
    * Call a function that will make a copy, change the copy, 
     then put the copy into this one. 
    */ 
    test3(&s); 
    printf("after test3(): s.total = %d\n", s.total); 

    return 0; 
} 
+0

¿Cuál es la importancia de poner el "\ *" antes del nombre de la variable (como se hace en esta publicación) o después del nombre del tipo (como lo hace el OP)? AQUÍ: prueba int (struct someStruct \ * Estado) OP: prueba int (struct someStruct \ * Estado) – ALM

+0

@ALM el asterisco indica la hora de especificar el tipo de una variable indica que se trata de un puntero a ese tipo de variable. Entonces 'someStruct state' es una variable que es de tipo' someStruct' pero 'someStruct * state' es un puntero a una variable de tipo' someStruct'. Ver [Conceptos básicos del puntero] (http://cslibrary.stanford.edu/106/). –

+0

Apreciar su respuesta; sin embargo, mi pregunta no era para qué es *, mi pregunta fue ¿QUÉ ES SIGNIFICATIVO DE TENER EL * (a) después del nombre de tipo de la estructura y (b) tenerlo antes del nombre asignado de struct? Espero que eso aclare mis dudas. – ALM

Cuestiones relacionadas