Buenas noches, tengo una duda para entender este simple codigo
#include <iostream>
void modificar( int *, int);
int main( int argc, char* args[] )
{
const int fil = 2;
const int col = 6;
int a[fil][col] = {};
int *b;
b = *a;
modificar(*a,fil*col);
for(int i = 0; i < fil*col; i++)
cout << *(b+i) << " ";;
cin.get();
cin.get();
return 0;
}
void modificar( int *a, int tamanio)
{
int j;
for(j = 0; j < tamanio; j++)
*(a+j) = j;
}
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
A ver es un poco lioso, de hecho a mi también me cuestan bastante los punteros dichosos.
En la línea:
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.
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.)
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!
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/ (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%201/)
http://minidosis.org/C++/Subprogramas/Acciones%202/ (http://minidosis.org/C++/Subprogramas/Acciones%202/)
http://minidosis.org/C++/Subprogramas/Devolver%20M%C3%A1s%20de%20un%20Resultado/ (http://minidosis.org/C++/Subprogramas/Devolver%20M%C3%A1s%20de%20un%20Resultado/)
http://minidosis.org/C++/Subprogramas/Definici%C3%B3n%20de%20Acci%C3%B3n/ (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/ (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++/ (http://minidosis.org/C++/)
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
int a[2];
int *b;
b = a;
En cambio en este ejemplo
int a[2][6];
int *b;
b = *a;
Se supone "b" debe contener la direccion de memoria de "a" y pareciese que le estoy es asignando su valor :-\
int a[2][6];
int *b;
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.
Cita de: erest0r en 7 Noviembre 2013, 12:25 PMlo 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
int a[2];
int *b;
b = a;
En cambio en este ejemplo
int a[2][6];
int *b;
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
¿Entonces aquí se esta pasando a dereferenciado y fil multiplicado por col?
modificar(*a,fil*col);
Cita de: vangodp en 7 Noviembre 2013, 14:47 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
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"
int **a0;
int *a1;
int a2;
a1 = &a2;
a0 = &a1;
// *a0 obtiene la direccion de memoria que contiene a1
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.
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