¿Está mal este código C?

Sé que los punteros contienen las direcciones de las variables, por ejemplo:

int c = 5; int *p; p = &c; printf("%d",*p); // Outputs 5. 

Pero qué pasa si quiero enviar una dirección a una función:

 void function (int *p) { p++; } int c; function (&c); 

Cuando se llama a la función, el valor de &c se asigna a int *p . Supongo que la instrucción exacta es: *p = &c; , pero no entiendo lo que esto significa.

Prefiero escribir int* p = &c; , es decir, a un puntero al tipo int se le asigna la dirección de c.

La notación de puntero puede ser confusa, como lo ha notado, porque estos dos son equivalentes:

 int *p = &c; 

y

 int *p; p = &c; 

¡Espero que esto ayude!

EDITAR: La confusión se produce porque * se usa tanto como operador de desreferencia como para declarar un puntero. Entonces, cuando p contiene la dirección de c , *p referencia al puntero y devuelve el valor de c . Pero cuando dices int *p = &c; , el * está diciendo “p es un puntero a un int”, pero no está haciendo ninguna desreferenciación.

*p = &c; medio:

Obtenga la dirección de c en la memoria que se determina en tiempo de enlace en tiempo de comstackción ( gracias Mikeage ), por ejemplo, 0x1234 como ejemplo. El puntero al tipo int, es decir, *p está asignado a 0x1234, lo que no me suena bien, creo que debería hacerlo de esta manera, p = &c entonces *p tendría el valor apuntado por la dirección de c . Y, por lo tanto, *p tendría el valor de lo que c fue asignado (lo que se denomina desreferenciación : al poner un * antes de la variable del puntero, puede obtener el valor).

En su función, está intentando incrementar el valor apuntado por p.

 función de vacío (int * p)
 {
   * p ++;
 }

 // Se llamaría así
 int c = 5;
 función (& c);  // ¡Ahora c tendría 6!

El punto clave es que desea pasar por referencia, que es lo que hace el parámetro &c . Si omites el paso por referencia como este:

 función de vacío (int p)
 {
   p ++;
 }
 // Y llámalo así
 int c = 5;
 función (c);  // c sigue siendo 5

Ahora c aún sería 5, pero dentro de la función en sí c es 6, pero no se devuelve ninguna copia ya que se incrementa dentro de la stack local para la función en sí.

Realmente no puedo descifrar tu pregunta, pero la function parece un error y lo que quisiste decir es, quizás,

 ++(*p) 

De lo contrario es un no-op.

Si desea que la función aumente c cuando se le llama con &c , escriba esto:

 void function(int *p) { ++(*p); } 

function(int *p) significa que p es el parámetro de función. Entonces, sea cual sea el valor que el llamante dé, ese será asignado a p (no a *p ).

El tipo de p es int * . Es decir, p es un puntero a int.

Si p es un puntero a int, entonces *p es el int al que apunta.

c es un int. Por lo tanto, &c es un puntero a int, y el int al que apunta es c . Por lo tanto, si p es &c , entonces *p es c .

Con mi versión de la función, este código:

 int c = 5; function(&c); 

Hace lo mismo que este código:

 int c = 5; // same as before int *p; // parameter of the function p = &c; // assign the caller's value to the parameter ++(*p); // body of the function, increments *p, which is the same as c. 

Lo que hace lo mismo que este código:

 int c = 5; ++c; 

¿Estás seguro de p++; es lo que quieres hacer en tu función? Eso es incrementar la ubicación apuntada por p , no está incrementando el valor en la ubicación actual. Si desea boost el valor (es decir, hacer que c convierta en 6), entonces lo que desea es (*p)++; .

Otros han respondido a tu pregunta. Simplemente añadiré que una forma útil de leer las declaraciones de punteros es esta. Digamos que tengo la siguiente statement:

 int i; 

Esto es realmente fácil. Aquí, i es un int . Ahora, digamos que tengo esto:

 int *pi; 

Aquí, puede decir que pi es un puntero a un int (que es correcto). Otra forma de verlo sería que *pi es un int , es decir, cuando tiene *pi en su código, ese *pi será de tipo int . Habiendo entendido eso, creo que es fácil ver que ++pi o pi++ no incrementa el int , porque pi es del tipo incorrecto. Quieres (*pi)++ . Los paréntesis son necesarios porque en C, el operador ++ tiene mayor prioridad que el operador único * . Como no utiliza ninguno de los efectos secundarios del incremento, también puede hacerlo: ++*p .

Por supuesto, como con todos los indicadores, pi tiene que apuntar a algo útil para que lo anterior tenga sentido.