[C con Clase] Problema conceptual al pasar por referencia array de 2 dimensiones en C

Armando B. VERA rdlmat en gmail.com
Jue Jun 11 23:08:00 CEST 2015


En "Aprenda C como si estuviera en primero", pag 43 está muy bien explicado
que cualquier interpretación que intente hacer está demás.
Si no encuentras el material te paso por correo.

El 11 de junio de 2015, 15:30, Diego <diegogeid en gmail.com> escribió:

> Hola Horacio, muchas gracias por la ayuda.
>
> Esos dos artículos tratan sobre arrayes unidimensionales, se entienden y
> no radica ahí el problema.
>
> Mi problema / duda surge al intentar interpretar la forma correcta en que
> debería pasarle un array bidimensional a una función, ya que el compilador
> lo interpreta como un puntero doble (si en el prototipo declaro que es un
> puntero simple, da Warning) pero si lo utilizo como puntero doble da error,
> ya que no es un puntero a punteros sinó que apunta a direcciones contiguas
> de memoria con el contenido de los datos en forma ordenada, según la
> posición mas el índice. Es decir, a mi entender, el compilador entiende que
> es un puntero doble pero lo trata como uno simple y ahí aparecen mis
> confusiones.
>
> La solución especificando que tipo entradas exige y haciendo casting de
> variables, ya sea antes o después de la función, pero estoy seguro que
> estoy haciendo algo mal y que hay una explicación y una solución mas
> elegante y correcta.
>
> Dado:
> float numeros[5][5];
>
> Con el prototipo:
> Pasar(float **numeros);
>
> Si adentro de la función lo utilizo como un puntero a float, da warning.
> Para subsanarlo utilizo un cast a (float *)
> Si adentro de la función lo utilizo como puntero doble da error (ya que no
> es un puntero a punteros)
>
> Si el prototipo es:
> Pasar(float *numeros);
> Da warning, el compilador entiende que numeros[][] es un puntero a
> puntero, puedo castearlo con (float *).
>
> El problema es que mediante las técnicas que se me ocurren, siempre tengo
> que castearlo para evitar errores y eso me hace pensar que estoy haciendo
> las cosas mal, o que tengo un error conceptual. Es así?
>
> Saludos y gracias
> Diego
>
>
>
> El 11 de junio de 2015, 11:20, Horacio Peñafiel <
> horacio.penafiel en donweb.com> escribió:
>
>>  Diego, buscando en la web, encontré estos dos sitios, por ahí ayude a
>> clarificar el tema:
>>
>> *http://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c
>> <http://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c>*
>> *http://www.le.ac.uk/users/rjm1/cotter/page_59.htm
>> <http://www.le.ac.uk/users/rjm1/cotter/page_59.htm>*
>>
>> Saludos!
>>
>> ing. Horacio Peñafiel
>>
>>
>>
>> El 11/06/2015 a las 11:08 a.m., Diego escribió:
>>
>> Comento y pregunto, mas que nada, por una cuestión académica.
>>
>> Lo que me llevó a pensar que se trataba de un doble puntero es que si
>> no paso como parámetro un float * da warning ya que entiende que
>> referencia[5][5] es un doble puntero y no uno simple (fácilmente se
>> subsana con un cast), a alguien se le ocurre porque asume que el
>> compilador entiende que un float [5][5] debe ser direccionado como
>> puntero doble según los warnings, pero es es tratado como puntero
>> simple?
>>
>> Saludos!
>> Diego
>>
>> El día 10 de junio de 2015, 17:48, Diego <diegogeid en gmail.com> <diegogeid en gmail.com> escribió:
>>
>>  Hola, gracias a ambos. Ambos tienen razón en decir que los arrays
>> bidimensionales no se tratan de igual forma que punteros dobles, no
>> los organiza de esa forma.
>>
>> El error surgió porque, tal como un array se puede direccionar como
>> una variable a puntero debido a su organización de memoria, asumí que
>> un array bidimensional se puede interpretar como un array de punteros
>> a punteros, NO SE ORGANIZA ASÍ EN MEMORIA, en realidad es un array de
>> [MxN], de esa forma, Horacio, la solución que brindas solo sirve para
>> los elementos de la primera fila. El parámetro a pasar, como bien
>> indicas Horacio es un puntero a float, y para utilizar el elemento M,
>> N debería usar referencia[M*5+N], creo que es la solución que indicás
>> Felipe, o definir el pasaje de referencia como referencia[5][5] en el
>> prototipo de la función, o en un tercer caso, definir como puntero a
>> puntero correctamente, inicializar y ahí direccionar como hice adentro
>> de la función. Ese caso sería mas eficiente si voy a utilizar varias
>> veces los índices.
>>
>> Finalmente, Felipe, entiendo que puede haber diferencias en el tamaño
>> de datos, pero no creo que influya el tamaño de datos en el problema,
>> siempre que se asigne correctamente como puntero a float, mas allá de
>> la arquitectura, agradezco si es una aclaración, si es una confusión,
>> no dudes en plantearla.
>>
>> Saludos y gracias a ambos!
>> Diego
>>
>>
>>
>>
>>
>> El día 10 de junio de 2015, 17:03, Felipe Valencia <anfevp en gmail.com> <anfevp en gmail.com> escribió:
>>
>>  Hola,
>>
>> Esencialmente existe una diferencia entre como se organizan los dople
>> punteros y las matrices de dos dimensiones. Las marices de dos dimensiones
>> se organizan consecutivamente y los dobles punteros estan esparcidos en
>> memoria.
>>
>> Mira este enlacehttp://stackoverflow.com/questions/4470950/why-cant-we-use-double-pointer-to-represent-two-dimensional-arrays
>> (Ingles)
>>
>> De hecho en la posicion test[1] esta el valor de la siguiente linea, seria
>> un 6 si continuaras con la inicializacion, y en la posicion referencia[1]
>> sera leida como la direccion de la siguiente linea.
>>
>> Ademads en PC de  64 bits los punteros son de 64 bits y los float son de 32
>> bits. Agrega la linea printf("Size %d %d \n",sizeof(float*),sizeof(float));
>>
>> Yo usualmente en estos casos uso matrices de una dimension en vez de dos
>> dimensiones, y calculo los indices, o solo uso punteros reservando memoria
>> con malloc o new.
>>
>> Ademas uso como IDE eclipse el cual trae un debuggeador donde puedes vez los
>> valores en memoria, supongo que Code::Blocks tambien debe mostrar memoria
>>
>>
>> Chao!!
>>
>>
>>
>>
>> El 10 de junio de 2015, 20:17, Diego <diegogeid en gmail.com> <diegogeid en gmail.com> escribió:
>>
>>  Hola, saludos a todos.
>>
>> Aparentemente estoy teniendo un error conceptual. Copio el código
>> abajo. Alguien podría ayudarme?
>>
>> Al intentar acceder a un elemento del aray desde el main no tengo
>> problemas, pero al intentar acceder desde una función el programa
>> retorna al sistema operativo un código de error (0xC0000005) y
>> porsupuesto que no continúa.
>>
>> Según los printf, los punteros apuntan a la misma posicion de memoria
>> tanto en el main como en la función, que estoy haciendo mal?
>>
>> PD: estoy compilando en Windows mediante Code::Blocks en Windows
>> mediante gcc, el error que da, según google, corresponde a una
>> violación de acceso a memoria.
>>
>> Saludos y gracias!
>>
>> ----------------------------------------------
>>
>> #include <stdio.h>
>> #include <stdlib.h> //No es necesario
>>
>> void probar(float **referencia)
>> {
>>
>>     printf("La posición de memoria donde empieza el array
>> multidimensional es %p\n", referencia);
>>
>> //No imprime el siguiente printf y vuelve al ssitema con un error
>> 0xC0000005
>>
>>     printf("test: %f %f...!\nPuntero: %p\n", referencia[0][0],
>> referencia[0][1], referencia);
>> }
>>
>> int main()
>> {
>>     float test[5][5]={1, 2, 3, 4, 5};
>>
>>     printf("La posición de memoria donde empieza el array
>> multidimensional es %p\n", test);
>>
>>     printf("test: %f %f...!\nPuntero: %p\n", test[0][0], test[0][1],
>> test);
>>
>>     probar(test);
>>
>>     return 0;
>> }
>>
>> _______________________________________________
>> Lista de correo Cconclase Cconclase en listas.conclase.nethttp://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
>> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>>
>>
>>
>> --
>> Andrés Felipe Valencia P
>> MSc student
>> ALaRI - Advanced Learning and Research Institute USI - Università della
>> Svizzera Italiana
>> Via Giuseppe Buffi 13, Lugano CH-6904, Switzerland
>> Mobile: + 41 076 822 27 57
>>
>> _______________________________________________
>> Lista de correo Cconclase Cconclase en listas.conclase.nethttp://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
>> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>>
>>  _______________________________________________
>> Lista de correo Cconclase Cconclase en listas.conclase.nethttp://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
>> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>>
>>
>>
>> --
>>
>>    *Ing. Horacio Peñafiel*
>> *Senior Software Developer*
>> *Departamento Desarrollo*
>>
>> *DonWeb *
>> La Actitud Es Todo
>> www.DonWeb.com
>>
>>
>>     ------------------------------
>>
>> Nota de confidencialidad: Este mensaje y archivos adjuntos al mismo son
>> confidenciales, de uso exclusivo para el destinatario del mismo. La
>> divulgación y/o uso del mismo sin autorización por parte de DonWeb.com
>> queda prohibida.
>> DonWeb.com no se hace responsable del mensaje por la falsificación y/o
>> alteración del mismo.
>> De no ser Ud el destinatario del mismo y lo ha recibido por error, por
>> favor, notifique al remitente y elimínelo de su sistema.
>>
>> Confidentiality Note: This message and any attachments (the message) are
>> confidential and intended solely for the addressees. Any unauthorised use
>> or dissemination is prohibited by DonWeb.com.
>> DonWeb.com shall not be liable  for the message if altered or falsified.
>> If you are not the intended addressee of this message, please cancel it
>> immediately and inform the sender
>>
>> Nota de Confidencialidade: Esta mensagem e seus eventuais anexos podem
>> conter dados confidenciais ou privilegiados.
>> Se você os recebeu por engano ou não é um dos destinatários aos quais ela
>> foi endereçada, por favor destrua-a e a todos os seus eventuais anexos ou
>> copias realizadas, imediatamente.
>> É proibida a retenção, distribuição, divulgação ou utilização de
>> quaisquer informações aqui contidas.
>>
>> Por favor, informenos sobre o recebimento indevido desta mensagem,
>> retornando-a para o autor.
>>
>> _______________________________________________
>> Lista de correo Cconclase Cconclase en listas.conclase.net
>> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
>> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>>
>
>
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20150611/aa73f996/attachment.html>
------------ próxima parte ------------
A non-text attachment was scrubbed...
Name: logo-donweb-2014-1.png
Type: image/png
Size: 6502 bytes
Desc: no disponible
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20150611/aa73f996/attachment.png>


Más información sobre la lista de distribución Cconclase