punteros parametros funciones ejemplos dobles declaracion como cadenas arreglos c pointers literals

parametros - Las direcciones de dos punteros son iguales



punteros en c ejemplos (10)

#include<stdio.h> #include<string.h> int main() { char * p = "abc"; char * p1 = "abc"; printf("%d %d", p, p1); }

Cuando imprimo los valores de los dos punteros, está imprimiendo la misma dirección. ¿Por qué?


Como han dicho otros, el compilador se da cuenta de que tienen el mismo valor, por lo que decide compartirlos en el ejecutable final. Pero se vuelve más elegante: cuando compilo lo siguiente con gcc -O

#include<stdio.h> #include<string.h> int main() { char * p = "abcdef"; char * p1 = "def"; printf("%d %d", p, p1); }

imprime 4195780 4195783 para mí. Es decir, p1 comienza 3 bytes después de p , por lo que GCC ha visto el sufijo común de def (incluido el terminador /0 ) y ha realizado una optimización similar a la que ha mostrado.

(Esta es una respuesta porque es demasiado tiempo para ser un comentario).


Cuando crea un literal de cadena ("abc"), se guarda en una memoria, que contiene literales de cadena, y luego se reutiliza si se refiere al mismo literal de cadena, por lo tanto, ambos punteros apuntan a la misma ubicación, donde " abc "cadena literal se almacena.

Lo aprendí hace un tiempo, así que tal vez no lo haya explicado claramente, lo siento.


Es la optimización del compilador pero se olvida la optimización para la portabilidad. Los códigos compilados en algún momento son más legibles que los códigos reales.


Esto realmente depende de qué compilador estás usando .

En mi sistema con TC ++ 3.5 , imprime dos valores diferentes para los dos punteros, es decir, dos direcciones diferentes .

Su compilador está diseñado para verificar la existencia de cualquier valor en la memoria y, dependiendo de su existencia , reasignará o usará la misma referencia del valor previamente almacenado si se hace referencia al mismo valor.

Así que no lo piense demasiado, ya que depende de la forma en que el compilador analiza el código.

ESO ES TODO...


Los literales de cadena en el código se almacenan en un segmento de datos de solo lectura del código. Cuando escribes un literal de cadena como "abc", en realidad devuelve un "const char *" y si tienes todas las advertencias del compilador, te diría que estás lanzando en ese punto. No está permitido alterar esas cadenas por la misma razón que ha señalado en esta pregunta.


Si dos literales de cadena diferentes con el mismo contenido se coloca en la misma ubicación de memoria o en diferentes ubicaciones de memoria depende de la implementación.

Siempre debe considerar p y p1 como dos punteros diferentes (aunque tengan el mismo contenido) ya que pueden o no apuntar a la misma dirección. No deberías confiar en las optimizaciones del compilador.

C11 estándar, 6.4.5, literales de cadenas, semántica

No se especifica si estas matrices son distintas siempre que sus elementos tengan los valores adecuados. Si el programa intenta modificar dicha matriz, el comportamiento no está definido.

El formato para imprimir debe ser %p :

printf("%p %p", (void*)p, (void*)p1);

Vea esta respuesta por qué.


Su compilador ha hecho algo llamado "agrupamiento de cadenas". Usted especificó que quería dos punteros, ambos apuntando al mismo literal de cadena, por lo que solo hizo una copia del literal.

Técnicamente: debería haberse quejado de ti por no hacer los punteros "const"

const char* p = "abc";

Esto es probablemente porque está usando Visual Studio o está usando GCC sin -Wall.

Si desea expresamente que se almacenen dos veces en la memoria, intente:

char s1[] = "abc"; char s2[] = "abc";

Aquí declara explícitamente que desea dos matrices de caracteres de cadena c en lugar de dos punteros a caracteres.

Advertencia: La agrupación de cadenas es una función de compilador / optimizador y no una faceta del lenguaje. Como tal, los diferentes compiladores en diferentes entornos producirán un comportamiento diferente dependiendo de factores como el nivel de optimización, los indicadores del compilador y si las cadenas están en diferentes unidades de compilación.


Tu compilador parece ser bastante inteligente, detectando que ambos literales son los mismos. Y como los literales son constantes, el compilador decidió no almacenarlos dos veces.

Parece que vale la pena mencionar que esto no necesariamente tiene que ser el caso. Por favor, mira la respuesta de Blue Moon sobre esto .

Por cierto: la declaración printf() debería verse así

printf("%p %p", (void *) p, (void *) p1);

como "%p" se usará para imprimir valores de puntero, y se define para el puntero de tipo void * solamente. * 1

También diría que el código omite una declaración de return , pero el estándar C parece estar en proceso de cambio. Otros podrían aclarar amablemente esto.

* 1: Casting to void * aquí no es necesario para los punteros char * , sino para los punteros a todos los demás tipos.


eres uso literal de cadena,

cuando el compilador atrapa dos literales de la misma cadena,

da la misma ubicación de memoria, por lo tanto, muestra la misma ubicación del puntero./


porque cadena "abc" sí mismo una dirección en la memoria. cuando escribes "abc" otra vez almacena la misma dirección