elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Trabajando con las ramas de git (tercera parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Problema de puntero
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Problema de puntero  (Leído 3,855 veces)
erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Problema de puntero
« en: 7 Noviembre 2013, 02:03 am »

Buenas noches, tengo una duda para entender este simple codigo

Código
  1. #include <iostream>
  2.  
  3. void modificar( int *, int);
  4.  
  5. int main( int argc, char* args[] )
  6. {
  7.    const int fil = 2;
  8.    const int col = 6;
  9.    int a[fil][col] = {};
  10.    int *b;
  11.    b = *a;
  12.  
  13.    modificar(*a,fil*col);
  14.  
  15.    for(int i = 0; i < fil*col; i++)
  16.        cout << *(b+i) << " ";;
  17.  
  18.  
  19.    cin.get();
  20.    cin.get();
  21.    return 0;
  22. }
  23.  
  24. void modificar( int *a, int tamanio)
  25. {
  26.    int j;
  27.    for(j = 0; j < tamanio; j++)
  28.        *(a+j) = j;
  29. }
  30.  
  31.  

1) ¿Que esta sucediendo cuando b = *a?

2) Los arreglos unidimensionales que he practicado se le pasan a la funcion solamente con su nombre, y ¿Por que aqui paso el arreglo con puntero? modificar( *a, fil*col );

En realidad pregunto esto, porque estaba probando y me funciono eso, pero no entiendo esas 2 lineas :S

Gracias


« Última modificación: 7 Noviembre 2013, 02:05 am por erest0r » En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
Almapa

Desconectado Desconectado

Mensajes: 111


Ver Perfil
Re: Problema de puntero
« Respuesta #1 en: 7 Noviembre 2013, 09:17 am »

A ver es un poco lioso, de hecho a mi también me cuestan bastante los punteros dichosos.
En la línea:
Código:
b = *a;

lo que se hace es guardar en la variables b el valor de la memoria donde se empieza a guardar la variable "a" que es una matriz 2x6.  Vamos a suponer que el valor de "b" es 4000.
(a==[2]x[6];     *a==4000;   b=4000)

Bien, a la función "modificar" se le pasan dos datos:  *a == 4000  y  fil*col==2*6==12.
Código:
void modificar( int *a, int tamanio)
{
    int j;
    for(j = 0; j < tamanio; j++)
        *(a+j) = j;
}

En la función se definen las posiciones de memoria que apuntarán al valor  (a+j) es decir, se define *(a+j), y se define igualándolo a j.
(Si j=0  ->   *(a+j)==*(4000+0)=0;   Si j=1  ->   *(a+j)==*(4000+1)=1;   etc.)


Código:
for(int i = 0; i < fil*col; i++)
        cout << *(b+i) << " ";
Al volver de la función hay otro bucle que en el que se mostrarán los valores de  *(b+i) dónde como sabemos b=4000 y "i" irá desde 0 a 12 por lo que mostrará:
(Si i=0  ->   *(b+i)==*(4000+0)  --> 0;   Si j=1  ->   *(b+i)==*(4000+1)  --> 1;   etc.   tal y como se había definido en la función modificar).


Espero haberte ayudado y si me he equivocado corrijanme así aprenderé yo también.

Un saludo!


En línea

vangodp


Desconectado Desconectado

Mensajes: 455



Ver Perfil
Re: Problema de puntero
« Respuesta #2 en: 7 Noviembre 2013, 09:52 am »

b = *a; En esta linea lo que quiere decir es que a b le asignamos el "valor" de a, con el operador * usamos el valor, y el operador & usamos su dirección.
 Si fuera: b = &a entonces a la b se le asignaba el numero de la dirección de memoria.
 Esos operadores se utilizan mucho para punteros, los punteros son algo que lían un poco al programadores nuevos pero son de mucha utilidad para trabajar con la memoria del ordenador.
 Con los punteros o trabajas con la dirección o trabajas con el valor de una variable, entonces * es valor y & es su dirección.(Esta claro que no es así de simple pero tampoco mucho mas complicado no es)
 Si una funcion es asi: takeA(int *A) Esta función esta esperando el valor entonces deberíamos pasar la dirección de esta manera takeA(&A), al saber que la función va  trabajar con el valor de lo que le vamos pasar pues simplemente le pasamos la dirección.
 Si la función es así: take(&B); La función  espera la dirección ahora, sabemos que va modificar la variable directo a la dirección memoria, o sea que le tenemos que pasar normalmente el valor take(B);
 Esto se usa para cambiar desde una función a una variable que esta dentro de otra función como en este ejemplo.
 En tu pregunta nº 2 creo que le pasas 2 parámetros enteros, el 1º es el valor de a, y el segundo es fil multiplicado por col
 Busca leer sobre paso por referencia.
 O mira este vídeo, es sobre el tema este.
 http://minidosis.org/C++/Subprogramas/Valor%20vs%20Referencia/

 Aquí dejo algunos vídeos mas relacionados con este tema tan delicado :D
http://minidosis.org/C++/Subprogramas/Acciones%201/
http://minidosis.org/C++/Subprogramas/Acciones%202/
http://minidosis.org/C++/Subprogramas/Devolver%20M%C3%A1s%20de%20un%20Resultado/
http://minidosis.org/C++/Subprogramas/Definici%C3%B3n%20de%20Acci%C3%B3n/
Te recomiendo que veas todos estos videos de aqui:
http://minidosis.org/C++/Punteros%20y%20Referencias/
Si tienes ganas de aprender los verias todos que Paueky es la caña  ;-)
http://minidosis.org/C++/
« Última modificación: 7 Noviembre 2013, 10:06 am por vangodp » En línea

erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: Problema de puntero
« Respuesta #3 en: 7 Noviembre 2013, 12:25 pm »

Si, yo conozco eso, lo que no entiendo es por qué si es un arreglo unidimensional se le pasa a la funcion

funcion( arreglo );

En cambio para arreglo de 2 dimensiones se le pasa

funcion( *arreglo );

Y cuando se asigna la direccion de memoria de un arreglo unidimensional se suele hacer

Código
  1. int a[2];
  2. int *b;
  3. b = a;
  4.  

En cambio en este ejemplo

Código
  1. int a[2][6];
  2. int *b;
  3. b = *a;
  4.  

Se supone "b" debe contener la direccion de memoria de "a" y pareciese que le estoy es asignando su valor  :-\
« Última modificación: 7 Noviembre 2013, 12:30 pm por erest0r » En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
xiruko


Desconectado Desconectado

Mensajes: 438


Ver Perfil
Re: Problema de puntero
« Respuesta #4 en: 7 Noviembre 2013, 13:19 pm »

Código
  1. int a[2][6];
  2. int *b;
  3. b = *a;

a es un array de punteros a entero, o lo que es lo mismo es una matriz bidimensional de enteros (int**).

b es un puntero a entero, o lo que es lo mismo es un array de enteros (int*).

Así pues, cuando haces b=*a es porque estas desreferenciando el puntero a un nivel, por lo que le estas pasando a b la dirección de la primera fila de la matriz a. Es lo mismo que si hicieras b=a[0] o b=&a[0][0].

En la función modificar, le pasas como parámetro *a, y como a es del tipo int**, lo que le pasas a la función es del tipo int* (porque desreferencias una vez con el asterisco), por lo que a la función solo le llega un vector de enteros que en este caso sería la primera fila de la matriz a.

Saludos.
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Problema de puntero
« Respuesta #5 en: 7 Noviembre 2013, 14:37 pm »

lo que no entiendo es por qué si es un arreglo unidimensional se le pasa a la funcion

funcion( arreglo );

En cambio para arreglo de 2 dimensiones se le pasa

funcion( *arreglo );

Y cuando se asigna la direccion de memoria de un arreglo unidimensional se suele hacer
Código
  1. int a[2];
  2. int *b;
  3. b = a;

En cambio en este ejemplo
Código
  1. int a[2][6];
  2. int *b;
  3. b = *a;

Se supone "b" debe contener la direccion de memoria de "a" y pareciese que le estoy es asignando su valor
La regla que aplica en este escenario es: en C y C++ cuando se nombra a un array de tipo "T [N]" mediante su identificador o una expresion ello resulta (salvo excepciones, por ejemplo sizeof) en la direccion en memoria del primer elemento del array y este puntero es de tipo "T *".

Los pasos al evaluar la expresion "b = *a" son:

1) "a" es una array de tipo "int [2][6]" y resulta en la direccion en memoria del elemento "a[0]" y es de tipo "int (*)[6]", un puntero a array.

2) Al aplicar indireccion con "*a" ya no tratamos con el puntero a array sino con el array. Este es de tipo "int [6]" y aplica lo mismo: la expresion denotando un array resulta en la direccion en memoria de su primer elemento (de a[0][0]) y el tipo del puntero es "int *".

3) La direccion en memoria de a[0][0] y de tipo "int *" se almacena en la variable "b", como los tipos coinciden no hay problema.

Por ultimo hay que tener mucho cuidado y no confundir arrays con punteros, tienen una relación estrecha pero son distintos. Una buena analogía aquí es el trabajo del cartero: nunca confunde la dirección de una casa (de nuestro lado un puntero) con la casa en si (para nosotros el objeto apuntado).

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
vangodp


Desconectado Desconectado

Mensajes: 455



Ver Perfil
Re: Problema de puntero
« Respuesta #6 en: 7 Noviembre 2013, 14:47 pm »

¿Entonces aquí  se esta pasando a dereferenciado y fil multiplicado por col? 
modificar(*a,fil*col);
En línea

rir3760


Desconectado Desconectado

Mensajes: 1.639


Ver Perfil
Re: Problema de puntero
« Respuesta #7 en: 7 Noviembre 2013, 16:55 pm »

¿Entonces aquí  se esta pasando a dereferenciado
Casi. La indirección no se aplica a "a", se aplica al puntero resultante de evaluar "a" (ya se que raya en la pedantería pero mejor ser tan precisos como sea posible).

Un saludo
En línea

C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language
erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: Problema de puntero
« Respuesta #8 en: 7 Noviembre 2013, 17:35 pm »

Entonces  como "a" es del tipo (int **) [Debi haberle colocado otro nombre a ese arreglo], contiene la direccion de memoria de por decirlo asi "*a", y este a su vez tiene la diereccion de memoria de "a"

Código
  1. int **a0;
  2. int *a1;
  3. int a2;
  4.  
  5. a1 = &a2;
  6. a0 = &a1;
  7.  
  8. // *a0 obtiene la direccion de memoria que contiene a1
  9.  
  10.  

Y cuando pase por parametro "*a0" que en este caso es "*a", estoy es pasando la direccion de memoria de la primera posicion de "a2" que es del arreglo.

No se si me explique bien y si fue la mejor forma de explicarlo, pero lo veo asi.

« Última modificación: 7 Noviembre 2013, 17:43 pm por erest0r » En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
erest0r

Desconectado Desconectado

Mensajes: 147



Ver Perfil
Re: Problema de puntero
« Respuesta #9 en: 7 Noviembre 2013, 17:52 pm »

Bueno por lo que lo probe sí es así, entonces se pasa el puntero todo como un arreglo unidimensional a la función, gracias por la explicación.  :D
En línea

Cruzar la calle junto a mucha gente cuando el semáforo sigue en rojo da seguridad y espíritu de equipo... o cruzamos todos o morimos juntos.
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Problema: Tamaño de Puntero char
Programación C/C++
yovaninu 8 6,688 Último mensaje 16 Agosto 2011, 14:56 pm
por Gallu
Problema con puntero láser azul
Electrónica
danielpower 0 3,096 Último mensaje 9 Febrero 2012, 07:33 am
por danielpower
Problema con puntero a una memoria reservada
Programación C/C++
fafafa01 3 2,167 Último mensaje 26 Junio 2016, 14:04 pm
por AlbertoBSD
Problema en C puntero a punteros.
Programación C/C++
Sicherer 7 4,846 Último mensaje 29 Septiembre 2017, 00:37 am
por AlbertoBSD
Problema con archivos: Reposicionamiento del puntero de registro activo.
Programación C/C++
FranAI 2 3,426 Último mensaje 23 Octubre 2020, 23:02 pm
por FranAI
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines