Hola que tal , como les va , espero que bien. Bueno voy a la pregunta .
Tengo el siguiente codigo :
#include <stdio.h>
main()
{
int i,array1[5]={0,1,2,3,4};
int* ptrArray1;
ptrArray1=array1;
for(i=0;i<5;i++)
printf("\nDesplazamiento del puntero por el array %d.Direccion: %p",*(ptrArray1+i),(ptrArray1+i));
}
El resultado es :
Desplazamiento del puntero por el array 0.Direccion: 0028FEF4
Desplazamiento del puntero por el array 1.Direccion: 0028FEF8
Desplazamiento del puntero por el array 2.Direccion: 0028FEFC
Desplazamiento del puntero por el array 3.Direccion: 0028FF00
Desplazamiento del puntero por el array 4.Direccion: 0028FF04
Perfecto el codigo funca bien todo , ahora , la pregunta. ¿Porque cada vez que corro este programa la direccion en memoria del primer elemento del array es la misma? (Al ser siempre la primera la misma , las otras son iguales xq son consecutivas a esta ).
Gracias.
Cuando tú ejecutas un programa el sistema operativo reserva memoria y se la asigna al programa para que pueda trabajar.
La memoria, como norma general, está paginada y/o segmentada. Básicamente esto quiere decir que está dividida en fragmentos.
El sistema operativo dispone de un algoritmo que elige, entre los disponibles, qué segmento de memoria va a asignar al programa... dicho algoritmo suponemos que es LTI ( lineal e invariante en el tiempo ), es decir, que a una misma entrada, en unas mismas condiciones, generará siempre la misma salida.
Por tanto, si tu ejecutas varias veces seguidas tu programa sucederá lo siguiente:
Ejecutas el programa ( 1ª vez )
El sistema operativo reserva un fragmento de memoria y se lo asigna.
El programa te muestra los desplazamientos.
El programa finaliza y el fragmento de memoria es liberado.
Ejecutas el programa ( 2ª vez )
El sistema operativo, te asigna el mismo fragmento de memoria.
El programa te muestra los desplazamientos.
El programa finaliza y el fragmento de memoria es liberado.
...
Si quieres tener resultados diferentes prueba a poner una pausa en el programa, lo ejecutas una vez y, sin cerrarlo, lo vuelves a ejecutar. Verás como entonces sí te cambian las posiciones de memoria.
Aprovecho este post para preguntar una cosa, que diferencia hay entre estas dos declaraciones:
int* ptrArray1;
int *ptrArray1;
son idénticas.
En c y c++ los espacios no son tenidos en cuenta ( salvo en las cadenas de caracteres )
Cita de: eferion en 18 Julio 2013, 15:53 PM
Cuando tú ejecutas un programa el sistema operativo reserva memoria y se la asigna al programa para que pueda trabajar.
La memoria, como norma general, está paginada y/o segmentada. Básicamente esto quiere decir que está dividida en fragmentos.
El sistema operativo dispone de un algoritmo que elige, entre los disponibles, qué segmento de memoria va a asignar al programa... dicho algoritmo suponemos que es LTI ( lineal e invariante en el tiempo ), es decir, que a una misma entrada, en unas mismas condiciones, generará siempre la misma salida.
Por tanto, si tu ejecutas varias veces seguidas tu programa sucederá lo siguiente:
Ejecutas el programa ( 1ª vez )
El sistema operativo reserva un fragmento de memoria y se lo asigna.
El programa te muestra los desplazamientos.
El programa finaliza y el fragmento de memoria es liberado.
Ejecutas el programa ( 2ª vez )
El sistema operativo, te asigna el mismo fragmento de memoria.
El programa te muestra los desplazamientos.
El programa finaliza y el fragmento de memoria es liberado.
...
Si quieres tener resultados diferentes prueba a poner una pausa en el programa, lo ejecutas una vez y, sin cerrarlo, lo vuelves a ejecutar. Verás como entonces sí te cambian las posiciones de memoria.
No es exactamente así. El programa siempre muestra las mismas direcciones de memoria porque las direcciones que estas mostrando son direcciones virtuales (asignadas en tiempo de compilación). Si tu ejecutas 2 veces el programa, no se te asignara 2 veces el mismo bloque (si es muy seguido si, cumpliendo el principio de localidad).
Las direcciones virtuales son traducidas luego por la MMU a direcciones físicas.
Cita de: Caster en 18 Julio 2013, 15:55 PM
Aprovecho este post para preguntar una cosa, que diferencia hay entre estas dos declaraciones:
int* ptrArray1;
int *ptrArray1;
Fijate:
Si hacemos int* ptr1,ptr2,ptr3; entonces ptr1,ptr2 y ptr3 son punteros a un entero.
Si hacemos int *ptr1,ptr2,ptr3; entonces solo ptr1 es un punterom. El resto son variables enteras.
Gracias a los dos por responder.
Saludos
Cita de: Oblivi0n en 18 Julio 2013, 16:04 PM
Si hacemos int* ptr1,ptr2,ptr3; entonces ptr1,ptr2 y ptr3 son punteros a un entero.
Si hacemos int *ptr1,ptr2,ptr3; entonces solo ptr1 es un punterom. El resto son variables enteras.
Ese es un ejemplo claro de cosas que no hay que hacer a la hora de programar :)
Que luego baila algún espacio y podemos sudar tinta hasta dar con el fallo.
Cita de: Oblivi0n en 18 Julio 2013, 16:04 PM
Si hacemos int* ptr1,ptr2,ptr3; entonces ptr1,ptr2 y ptr3 son punteros a un entero.
Si hacemos int *ptr1,ptr2,ptr3; entonces solo ptr1 es un punterom. El resto son variables enteras.
Seriously? Puedes darme una referencia fidedigna en la que se indique esto?
Cita de: 0xDani en 18 Julio 2013, 16:15 PM
Seriously? Puedes darme una referencia fidedigna en la que se indique esto?
Que tiene de malo el ejemplo que me ha puesto Oblivi0n, yo no le veo el fallo, tiene sentido.
Cita de: 0xDani en 18 Julio 2013, 16:15 PM
Seriously? Puedes darme una referencia fidedigna en la que se indique esto?
http://stackoverflow.com/questions/12626929/pointer-c-declaration (http://stackoverflow.com/questions/12626929/pointer-c-declaration)
No me había dado cuenta de ese detalle... también es cierto que evito ese tipo de declaraciones.
bueno ojo OxDani
void main( )
{
int* a, b;
b = 1;
a = &b;
b = a;
}
resultado:
error: C2440: '=' : cannot convert from 'int *' to 'int'
There is no context in which this conversion is possible
#include <stdio.h>
int main()
{
int* px, py;
int *pz, x=1, y=2, z=3;
px = &x;
py = &y;
pz = &z;
printf("%X %X %X", px, py, pz);
printf("\n%d %d %d", x, y, z);
return 0;
}
Según este codigo, lo que dice Oblivi0n es verdad
Para programar en C hace falta un poco mas que conocer el lenguaje ;)
Cita de: Oblivi0n en 18 Julio 2013, 16:27 PM
http://stackoverflow.com/questions/12626929/pointer-c-declaration (http://stackoverflow.com/questions/12626929/pointer-c-declaration)
De ese link:
int* p, p2; // declares a pointer to int and a regular int
int *p, *p2; // declares two pointers to int
De todas formas, por muy bueno que sea el foro Stack Overflow, no es una referencia fidedigna para este tipo de debates.
Cita de: Oblivi0n en 18 Julio 2013, 16:32 PM
Para programar en C hace falta un poco mas que conocer el lenguaje ;)
Yo más bien diría que lo suyo es no optar por código tan peregrino y, visto lo visto, tan propenso a segundas interpretaciones.
A ver que no me entero de una, entonces si hacemos esto:
int* ptr1,ptr2,ptr3;
El unico puntero que hay aqui es ptr1, no?
Si puedes evitar este tipo de líneas mejor. Por lo que he podido ver en este hilo depende del compilador a utilizar...
En un programa la claridad es un factor clave.
Mejor lo dejas así:
int *ptr1, *ptr2, *ptr3;
Que compila y te quitas de problemas.
Vale, muchas gracias
A ver, al compilar este programa con gcc 4.7.2:
#include <stdio.h>
int main()
{
int* a, b;
int c;
b = &c;
printf("0x%x\n", b);
return 0;
}
me salta este aviso:
Cita de: gcc/home/dani/Escritorio/pointers_test.c:8:4: aviso: la asignación crea un entero desde un puntero sin una conversión [activado por defecto]
De lo que se deduce que b es un entero, y no un puntero.
Saludos.
Cita de: 0xDani en 18 Julio 2013, 17:09 PM
A ver, al compilar este programa con gcc 4.7.2:
#include <stdio.h>
int main()
{
int* a, b;
int c;
b = &c;
printf("0x%x\n", b);
return 0;
}
me salta este aviso:
De lo que se deduce que b es un entero, y no un puntero.
Saludos.
Vale, entonces te pasa lo mismo que a mi compilando con msvc
Cita de: eferion en 18 Julio 2013, 17:11 PM
Vale, entonces te pasa lo mismo que a mi compilando con msvc
Eso parece :P
Y a mi me pasaba lo mismo.
Aprovecho el tema q habia iniciado para hacer otra pregunta.
Tengo lo siguiente
#include <stdio.h>
void funcion1(int);
void funcion2(int);
void funcion3(int);
main()
{
int i;
void (*f[3])(int)={funcion1,funcion2,funcion3};
for(i=0;i<3;i++)
{
(*f[i])(i);
printf(".Direccion en memoria de la funcion:%p",f[i]);
}
}
void funcion1(int a)
{
printf("\nEntro a la funcion 1");
}
void funcion2(int a)
{
printf("\nEntro a la funcion 2");
}
void funcion3(int a)
{
printf("\nEntro a la funcion 3");
}
Queria saber si esta bien lo q afirmo. Es decir , si esta bien de que son las direcciones de memoria de las funciones y no del array. (Supuse que estan bien porque no son consecutivas , pero por las dudas pregunto).
Cita de: Caster en 18 Julio 2013, 16:43 PMA ver que no me entero de una, entonces si hacemos esto:
int* ptr1,ptr2,ptr3;
El unico puntero que hay aqui es ptr1, no?
Correcto. El estándar de C define al lenguaje como uno de formato libre donde el espacio blanco (espacio, tabulador, etc.) solo es significativo en tres casos:
1) Directivas del preprocesador.
2) Cadenas literales.
3) Cuando este indica el final de un token (la unidad mínima que reconoce el lenguaje). Por ejemplo el espacio en "int i;" es significativo mientras que en "int * i;" no lo es (esta ultima se puede separar sin ambigüedades en los tokens 'int', '*', 'i' y ';').
En el ejemplo que mencionas si eliminamos el espacio, los separadores (las comas) y el indicador de fin de sentencia (el punto y coma) los tokens se agrupan así:
int
*ptr1
ptr2
ptr3
Resultando en la declaración de tres variables donde solo la primera es un puntero.
----
Cita de: jednak en 18 Julio 2013, 23:47 PMQueria saber si esta bien lo q afirmo. Es decir , si esta bien de que son las direcciones de memoria de las funciones y no del array. (Supuse que estan bien porque no son consecutivas , pero por las dudas pregunto).
Es correcto, solo un comentario: en el bucle no necesitas aplicar indireccion en la llamada a función y, siendo pesados, no es posible imprimir (de forma portable) la dirección de una función.
La mejor forma en el caso del bucle es:
for (i = 0; i < 3; i++){
f[i](i);
printf("La direccion en memoria es %p\n", (void *) f[i]);
}
Un saludo