{"id":34018,"date":"2024-02-16T19:07:08","date_gmt":"2024-02-16T19:07:08","guid":{"rendered":"https:\/\/blogs.ugto.mx\/rea\/?p=34018"},"modified":"2024-02-16T19:07:08","modified_gmt":"2024-02-16T19:07:08","slug":"clase-digital-14-arreglos-dinamicos-de-variables-y-regreso-de-funciones-por-referencia","status":"publish","type":"post","link":"https:\/\/blogs.ugto.mx\/rea\/clase-digital-14-arreglos-dinamicos-de-variables-y-regreso-de-funciones-por-referencia\/","title":{"rendered":"Clase digital 14. Arreglos din\u00e1micos de variables, y regreso de funciones por referencia"},"content":{"rendered":"\n\n\n<div class=\"wp-block-cover is-light\" style=\"min-height:284px;aspect-ratio:unset;\"><span aria-hidden=\"true\" class=\"wp-block-cover__background has-background-dim-40 has-background-dim\"><\/span><img decoding=\"async\" class=\"wp-block-cover__image-background wp-image-34301\" alt=\"\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.15.25.png\" data-object-fit=\"cover\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"1148\" height=\"596\" class=\"wp-block-cover__image-background wp-image-34301\" alt=\"\" src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.15.25.png\" data-object-fit=\"cover\" srcset=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.15.25.png 1148w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.15.25-300x156.png 300w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.15.25-1024x532.png 1024w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.15.25-768x399.png 768w\" sizes=\"auto, (max-width: 1148px) 100vw, 1148px\" \/><\/noscript><div class=\"wp-block-cover__inner-container is-layout-flow wp-block-cover-is-layout-flow\">\n<p class=\"has-text-align-center has-base-3-color has-text-color has-large-font-size wp-block-paragraph\">Arreglos din\u00e1micos de variables, y regreso de funciones por referencia<\/p>\n<\/div><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"introduccion\">Introducci\u00f3n<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\u00a1Hola de nuevo!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La clase anterior seguramente ha sido algo desconcertante, esto de entender los apuntadores es un tanto confuso, miren que acceder a los datos que se guardan en la memoria a trav\u00e9s de la direcci\u00f3n donde est\u00e1n guardados suena m\u00e1s al trabajo de un cartero que entrega cartas a domicilio que a un programador en C. Pero no desesperen, en esta clase veremos su GRAN utilidad y seguramente coincidir\u00e1n en que los apuntadores son una gran idea.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Seguramente nos hemos hecho la pregunta \u00bfpara qu\u00e9 sirven los apuntadores? En esta clase estudiaremos dos de las grandes aplicaciones pr\u00e1cticas del uso de apuntadores:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Generaci\u00f3n de arreglos din\u00e1micos<\/li>\n\n\n\n<li>Regreso de informaci\u00f3n entre funciones.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Te recomendamos mucho repasar las clases 11 (Arreglos est\u00e1ticos) y 12 (funciones) para comprender a profundidad estas aplicaciones<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pues bueno, \u00a1Manos a la obra!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"desarrollo-del-tema\">Desarrollo del tema <\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Comencemos recordando que es un apuntador: Un apuntador es una variable que tiene como intenci\u00f3n almacenar una direcci\u00f3n en memoria. Como su objetivo fundamental es guardar direcciones, el tama\u00f1o de una variable apuntadora ser\u00e1 determinado por la capacidad de la computadora para almacenar informaci\u00f3n en la memoria din\u00e1mica, hoy en d\u00eda la arquitectura de las computadoras est\u00e1 determinada por 64 bits, esto es 8 bytes, as\u00ed pues, TODA variable apuntadora tendr\u00e1 un tama\u00f1o de 8 bytes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pero tambi\u00e9n recordemos que existen distintos tipos de variables apuntadoras (todas ellas de 8 bytes) las hay apuntadoras a datos double, float, int, etc. Un tipo importante es el apuntador a void, que significa que esa variable apuntar\u00e1 a datos sin un tipo en particular. No olvidemos que el tipo de apuntador para lo que nos sirve es para poder realizar operaciones aritm\u00e9ticas entre apuntadores.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pongamos un ejemplo, supongamos que hemos declarado la variable PtrChar del tipo char:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">char *PtrChar;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PtrChar=0x100;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Y tambi\u00e9n hemos declarado otra variable PtrFloat del tipo float:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&nbsp;float *PtrFloat;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PtrFloat=0x200;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ambas variables tienen un tama\u00f1o de 8 bytes pero como cada apuntadora sabe a qu\u00e9 tipo de dato est\u00e1 apuntando y las hemos hecho apuntar a una direcci\u00f3n en particular, vea lo que pasa con las l\u00edneas de c\u00f3digo :<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PtrChar++;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PtrFloat++;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ahora la variable PtrChar tiene almacenada la direcci\u00f3n 0x101, y la variable PtrFloat almacenar\u00e1 la direcci\u00f3n 0x204, \u00a1ven! El apuntador a char da un salto al siguiente char y PtrFloat tambi\u00e9n da un salto al siguiente float, pero ese float se encuentra 4 posiciones alejado en vez de una posici\u00f3n que se encuentra alejado el dato char. As\u00ed pues, el tipo de apuntador solo es \u00fatil para realizar la aritm\u00e9tica apropiada.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pues bien, con lo anterior en mente estudiemos a la funci\u00f3n malloc, que se encuentra localizada en la biblioteca stdlib, as\u00ed que nunca olviden incluir el encabezado stdlib.h en su c\u00f3digo. Veamos la declaraci\u00f3n de la funci\u00f3n malloc:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">void* malloc ( unsigned numero_de_bytes );<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">La funci\u00f3n malloc tiene como objetivo localizar memoria libre en la memoria RAM de la computadora. El argumento de la funci\u00f3n es el n\u00famero de bytes consecutivos que se solicitan apartar, la funci\u00f3n regresa por la izquierda un apuntador a la direcci\u00f3n del primer byte. Malloc negocia con el sistema operativo el apartado de ese bloque de memoria, una vez asignado, el sistema operativo identifica esa secci\u00f3n de la memoria como \u201cocupada\u201d y no la asignar\u00e1 a ning\u00fan otro usuario o solicitud hasta que se libere, de alguna manera el programa en donde se ejecuta la funci\u00f3n malloc, se vuelve \u201cdue\u00f1o\u201d de esa parte de la memoria y nadie m\u00e1s tiene permiso de leer o escribir en ella. Si otro proceso intenta acceder a esa secci\u00f3n de la memoria, aparecer\u00e1 el famoso error de ejecuci\u00f3n <strong>Segmentation Fault<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Como habr\u00e1n visto malloc nos permite, en el momento de ejecuci\u00f3n apartar memoria, \u00bfpero \u00bfc\u00f3mo se comporta malloc si lo que pido no puede ser apartado? Pues muy sencillo, la funci\u00f3n regresa una direcci\u00f3n inv\u00e1lida etiquetada con la constante NULL (dicha definici\u00f3n se encuentra dentro del encabezado stdlib.h).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As\u00ed pues, cada vez que pedimos memoria es MUY buena idea verificar si nos la dieron, si el apuntador regresado es distinto a NULL querr\u00e1 decir que el sistema operativo si pudo localizar memoria y se nos asign\u00f3, pero si el regreso es NULL querr\u00e1 decir que la petici\u00f3n fall\u00f3.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Si la petici\u00f3n fue aceptada y se nos apart\u00f3 memoria nunca olvidemos que nuestra responsabilidad como programadores es liberar esa memoria al desocuparla, para desocupar memoria usamos la funci\u00f3n free:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">void free (void* ptr);<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">El argumento de entrada de la fusi\u00f3n es el apuntador que apunta al bloque de memoria que se quiere liberar.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.17.13.png\" alt=\"\" class=\"wp-image-34303\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"917\" height=\"688\" src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.17.13.png\" alt=\"\" class=\"wp-image-34303\" srcset=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.17.13.png 917w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.17.13-300x225.png 300w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.17.13-768x576.png 768w\" sizes=\"auto, (max-width: 917px) 100vw, 917px\" \/><\/noscript><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Estudiemos con detenimiento la l\u00ednea 20:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PtrArreglo=(double *)malloc(sizeof(double)*N);<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">En el argumento de entrada de la funci\u00f3n malloc tenemos la funci\u00f3n sizeof que, recordemos, nos regresa el tama\u00f1o en bytes de un tipo de dato o de una variable, este sizeof seguramente regresar\u00e1 un 8 (las variables de tipo double usan 8 bytes), es mucho mejor usar la funci\u00f3n que poner directamente el n\u00famero 8 porque esta funci\u00f3n responde le valor espec\u00edficamente para el tipo de computadora en que se est\u00e1 corriendo el programa. Muy bien, si sabemos que tenemos 8 bytes por datos y pedimos N datos, el n\u00famero de bytes ser\u00e1 el producto.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Hay otra anotaci\u00f3n importante que hacer en esta l\u00ednea, el cast que realiza (double *), recordemos que malloc regresa un apuntador de tipo gen\u00e9rico void, este cast indica que la variable que almacenar\u00e1 la posici\u00f3n de memoria es de tipo double. Este cast es el responsable de poder usar el apuntador tan f\u00e1cilmente como se ve en la l\u00ednea 27, no poner este cast har\u00eda fallar el programa.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tanto en la l\u00ednea 27 como en la l\u00ednea 31, observen que el apuntador PtrArreglo se usa como usamos los arreglos est\u00e1ticos, maravilloso, \u00bfno?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La l\u00ednea 33 es muy importante ejecutarla al terminar de usar la memoria, si no se realiza el proceso terminar\u00e1 y no le avisar\u00e1 al sistema operativo que la memoria ya la puede etiquetar como disponible, de quedar ocupada y muerto el proceso, solo el colector de basura del sistema operativo ser\u00e1 capaz de identificar esta secci\u00f3n de memoria abandonada y recuperarla, algo as\u00ed como que uno tirar\u00e1 basura en la calle y el pobre barrendero tuviera que levantarla y ponerla en su lugar. \u00a1Pues ya aprendimos a usar memoria din\u00e1mica! Bueno, al menos para arreglos de una dimensi\u00f3n, como se usar\u00edan los apuntadores para formar arreglos bidimensionales (un arreglo matricial, por ejemplo).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Existen varias alternativas, estudiaremos la que se nombra apuntador a un apuntador, para consultar distintas formas de construir este arreglo puedes consultar:<\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-fe48e5de wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button is-style-fill\"><a class=\"wp-block-button__link has-base-3-color has-text-color has-background has-link-color wp-element-button\" href=\"https:\/\/www.geeksforgeeks.org\/dynamically-allocate-2d-array-c\/\" style=\"border-radius:100px;background:linear-gradient(135deg,rgb(240,152,0) 0%,rgb(240,152,0) 100%)\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>     ACCEDE<\/strong>       <\/a><\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Comencemos discutiendo un par de temas te\u00f3ricos, \u00bfQu\u00e9 significa una declaraci\u00f3n como la siguiente?:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">double **Array;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">esto quiere decir que declaramos la variable Array como un apuntador que apunta a otro apuntador (usualmente se le llama un doble apuntador), pues bueno, recordando que todo arreglo que no tiene \u00edndice es un apuntador podemos entender a&nbsp; la variable Array como un arreglo de apuntadores, entonces, si queremos medir memoria para una arreglo 2Dimensional de M renglones y N columnas, lo que hacemos es que primero generamos un arreglo&nbsp; de M apuntadores, una vez teniendo este arreglo, para cada valor de este arreglo se asigna la memoria solicitada para un arreglo de N datos, veamos:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.42.13-801x1024.png\" alt=\"\" class=\"wp-image-34304\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"801\" height=\"1024\" src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.42.13-801x1024.png\" alt=\"\" class=\"wp-image-34304\" srcset=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.42.13-801x1024.png 801w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.42.13-235x300.png 235w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.42.13-768x982.png 768w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.42.13.png 873w\" sizes=\"auto, (max-width: 801px) 100vw, 801px\" \/><\/noscript><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Estudiemos con detalle la l\u00ednea 23:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.44.00.png\" alt=\"\" class=\"wp-image-34306\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"929\" height=\"34\" src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.44.00.png\" alt=\"\" class=\"wp-image-34306\" srcset=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.44.00.png 929w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.44.00-300x11.png 300w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.44.00-768x28.png 768w\" sizes=\"auto, (max-width: 929px) 100vw, 929px\" \/><\/noscript><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Contrastemos la l\u00ednea con la equivalente del caso de arreglos de 1D:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.44.37.png\" alt=\"\" class=\"wp-image-34307\" style=\"width:1008px;height:auto\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"932\" height=\"41\" src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.44.37.png\" alt=\"\" class=\"wp-image-34307\" style=\"width:1008px;height:auto\" srcset=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.44.37.png 932w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.44.37-300x13.png 300w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.44.37-768x34.png 768w\" sizes=\"auto, (max-width: 932px) 100vw, 932px\" \/><\/noscript><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Noten que dentro del sizeof ahora est\u00e1 un double * en vez de solo el double, esto se debe a que queremos localizar apuntadores a double, recuerden que su tama\u00f1o es de 8 bytes, casualmente coincide con los 8 bytes necesarios para almacenar un dato double, pero otra cosa ser\u00eda si los datos fueran float, por ejemplo. La segunda diferencia importante est\u00e1 en el cast que cambia el apuntador de tipo void ahora a un doble apuntador de tipo double, antes el cast se realizaba a un apuntador sencillo tipo double.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La l\u00ednea lo que consigue es realizar un arreglo (apuntador) de apuntadores a double.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Las l\u00edneas 30 a la 34 lo que estamos haciendo es estar llenando de arreglos de double (apuntadores) a cada elemento del arreglo de arreglos, podemos imaginar que cada rengl\u00f3n del arreglo matricial es un arreglo vectorial 1D.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La l\u00ednea 39 demuestra que, una vez creado el arreglo, su uso es id\u00e9ntico al de un arreglo est\u00e1tico:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.43.23.png\" alt=\"\" class=\"wp-image-34305\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"916\" height=\"45\" src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.43.23.png\" alt=\"\" class=\"wp-image-34305\" srcset=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.43.23.png 916w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.43.23-300x15.png 300w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.43.23-768x38.png 768w\" sizes=\"auto, (max-width: 916px) 100vw, 916px\" \/><\/noscript><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">En las l\u00edneas de c\u00f3digo 49 y 50 se programa el proceso de limpieza de memoria liber\u00e1ndola en cada rengl\u00f3n y finalmente en la l\u00ednea 52 se libera el segundo apuntador a arreglos, terminando con la liberaci\u00f3n de cada bloque de memoria.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfQu\u00e9 tal? \u00a1Ven que los apuntadores son realmente \u00fatiles! Ahora abordaremos la necesidad de usar apuntadores en el argumento de funciones, pero para entender este tema debemos estar seguros de comprender como se comportan las variables dentro de funciones.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Volvamos a recordar el concepto de alcance de una variable, el alcance de una variable se define como la secci\u00f3n del c\u00f3digo donde una variable es reconocida. La regla de alcance dice que una variable es visible (o alcanzable) a partir de su declaraci\u00f3n y hasta el momento en que se localiza la llave cerrada }.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Con toda la informaci\u00f3n anterior hagamos un peque\u00f1o ejercicio, escribamos un programa que pregunte cuantos datos del tipo double queremos almacenar, los aparte, los manipule y luego los libere. Analicemos nuevamente el programa de la lecci\u00f3n 12 (funciones):<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Ejemplo de funci\u00f3n con argumentos con retorno de valor<\/h4>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.45.40.png\" alt=\"\" class=\"wp-image-34308\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"933\" height=\"728\" src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.45.40.png\" alt=\"\" class=\"wp-image-34308\" srcset=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.45.40.png 933w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.45.40-300x234.png 300w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.45.40-768x599.png 768w\" sizes=\"auto, (max-width: 933px) 100vw, 933px\" \/><\/noscript><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Las variables base, exponente, resultado tienen una vida que nace a partir de la l\u00ednea 8 y son liberadas de memoria hasta la l\u00ednea 16, cuando el flujo del programa entra a la l\u00ednea 14, sucede algo muy interesante, el flujo salta a la l\u00ednea 17 donde se declaran las variables x y y, a partir de esta l\u00ednea y hasta terminar la funci\u00f3n estas dos variables tendr\u00e1n su alcance. Pero concentr\u00e9monos en el brinco de la l\u00ednea 14 a la 17, \u00bfC\u00f3mo le hacemos para que valores de una variable de la funci\u00f3n principal pasen a variables de la funci\u00f3n invocada? Pues C lo que hace es un cruce por valor, esto es, el valor guardado en la variable base se copia a la variable x y el valor guardado en la variable exponente se copia a la variable y, en ese momento la variable exponente y base se esconden (pierden visibilidad) y solo podemos acceder a valores de las variables x y y. En la l\u00ednea 19 se declara la variable restpow que ser\u00e1 visible hasta la l\u00ednea 22 donde termina la funci\u00f3n y desaparecen las variables x, y, restpow perdiendo todo valor guardado en ellas. De la l\u00ednea 22 el flujo del programa regresa a la l\u00ednea 14, la variable resultado recibe el valor enviado en la l\u00ednea 21 a trav\u00e9s de restpow. Finalmente, al llegar a la l\u00ednea 16 las variables base, exponente, resultado se liberan y los datos guardados en ellas se pierden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Noten, el flujo de informaci\u00f3n del programa principal hacia la funci\u00f3n potencia es f\u00e1cil, basta con poner dentro del par\u00e9ntesis del encabezado de la funci\u00f3n una variable que capture valores, pero el flujo de regreso solo puede darse por un lugar, el valor de retorno, la palabra reservada return solo permite regresar el valor de UNA variable, si quisi\u00e9ramos regresar 2 o m\u00e1s variables no podemos hacerlo por el return. Ufff ahora si estamos en problemas.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Bien, con todo esto en mente aparece una pregunta importante \u00bfC\u00f3mo podr\u00edamos dise\u00f1ar una funci\u00f3n que sea capaz de regresar m\u00e1s de un valor?, imaginemos que desarrollamos una funci\u00f3n que encuentra el valor m\u00ednimo y el valor m\u00e1ximo de una lista de n\u00fameros y queremos que la funci\u00f3n regrese ambos valores no solo uno \u00bfQu\u00e9 hacemos?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00a1Usamos apuntadores! Van a ver el truco tan inteligente que podemos realizar, resumamos la situaci\u00f3n, en C todos los intercambios de informaci\u00f3n entre funciones se realizan mediante la copia de valores, podemos llevar a la funci\u00f3n cualquier tipo de valor incluida la direcci\u00f3n donde se localiza una variable que fue declarada en la funci\u00f3n principal. El chiste es que la funci\u00f3n llamada capture el valor de la direcci\u00f3n donde est\u00e1 localizada la variable y luego, con el operador indirecci\u00f3n cambiemos el contenido de esa variable, \u00a1y voila! El truco de magia se ha realizado, hemos copiado el valor calculado dentro de una funci\u00f3n y lo hemos guardado indirectamente en una variable que no ten\u00edamos acceso \u00bfNo les parce brillante la idea? Escribamos el c\u00f3digo.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.48.10.png\" alt=\"\" class=\"wp-image-34309\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"913\" height=\"709\" src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.48.10.png\" alt=\"\" class=\"wp-image-34309\" srcset=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.48.10.png 913w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.48.10-300x233.png 300w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.48.10-768x596.png 768w\" sizes=\"auto, (max-width: 913px) 100vw, 913px\" \/><\/noscript><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img decoding=\"async\" src=\"data:image\/gif;base64,R0lGODlhAQABAIAAAAAAAP\/\/\/yH5BAEAAAAALAAAAAABAAEAAAIBRAA7\" data-src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.49.15.png\" alt=\"\" class=\"wp-image-34310\" \/><noscript><img loading=\"lazy\" decoding=\"async\" width=\"920\" height=\"503\" src=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.49.15.png\" alt=\"\" class=\"wp-image-34310\" srcset=\"https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.49.15.png 920w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.49.15-300x164.png 300w, https:\/\/blogs.ugto.mx\/rea\/wp-content\/uploads\/sites\/71\/2024\/02\/Captura-de-Pantalla-2024-02-14-a-las-11.49.15-768x420.png 768w\" sizes=\"auto, (max-width: 920px) 100vw, 920px\" \/><\/noscript><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Estudiemos el comportamiento del programa anterior, ver\u00e1n c\u00f3mo operan los apuntadores, y espero que queden sorprendidos con la astucia de quienes lo usan.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La l\u00ednea 18, tal como lo vimos en esta clase, solicita memoria din\u00e1mica para generar un arreglo de 1D con N datos del tipo double. La l\u00ednea 20 es una condicional que verifica si la memoria se pudo conseguir, recuerden, si no se puede conseguir el resultado ser\u00e1 un apuntador a Nulo (NULL). El ciclo for de las l\u00edneas 22 a 26 solamente llena con valores aleatorios los N datos del arreglo, aqu\u00ed vale la pena detenerse en la l\u00ednea&nbsp; 24, como ver\u00e1n el apuntador llamado Arreglo se puede usar con los corchetes de la misma manera en que se usan los arreglos est\u00e1ticos; pero lo interesante es el lado derecho del igual, la funci\u00f3n rand() regresa un n\u00famero entero pseudoaleatorio que puede tomar valores entre 0 y RAND_MAX, RAND_MAX es una constante que est\u00e1 definida en stdlib.h, para poder convertir este n\u00famero aleatorio entre 0 y 1 (double) lo que hacemos es un cast del resultado de la funci\u00f3n y luego una divisi\u00f3n por RAND_MAX, como el n\u00famero con rango mayor es el numerador que es double, la divisi\u00f3n se hace entre dobles (hay un cast impl\u00edcito) y el resultado es un n\u00famero del tipo double.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La l\u00ednea 28 tiene una parte MUY interesante, es la llamada a la funci\u00f3n MaxMin, mejor, antes de estudiar la llamada a la funci\u00f3n analicemos la funci\u00f3n misma,&nbsp; en la l\u00ednea 41 tenemos el encabezado, vean que se declaran las variables Arreglo que es un apuntador a double, la variable N que es del tipo int, y las variables Max y Min, que ambas son del tipo apuntador a double; aunque Arreglo, Max y Min son variables del mismo tipo las usaremos con intenciones diferentes; Arreglo lo que recibir\u00e1 es la direcci\u00f3n de memoria donde se localiza el arreglo de datos, aqu\u00ed no hay sorpresa, pero Max recibir\u00e1 la direcci\u00f3n de memoria de la variable donde vamos a guardar el valor m\u00e1s grande que encontremos en el arreglo, y Min tendr\u00e1 la direcci\u00f3n de memoria donde almacenaremos el valor m\u00e1s peque\u00f1o encontrado, \u00bfven la diferencia? Mientras que en Arreglo vamos a consultar datos, en Max y en Min vamos a modificar indirectamente los valores de las variables a las que apuntan. De la l\u00ednea 47 a la 57 tenemos un cl\u00e1sico algoritmo de b\u00fasqueda de m\u00e1ximos y m\u00ednimos, repasemos, Ma es la variable donde se guardar\u00e1 el valor m\u00e1ximo y Mi el m\u00ednimo, asignamos el primer valor del arreglo a Ma y a Mi (esto lo hacemos con el siguiente razonamiento, si el arreglo solo tuviera un valor, ese valor ser\u00eda el m\u00e1ximo y el m\u00ednimo), pero como no solo tenemos un valor sino N, entonces comenzamos la b\u00fasqueda a partir del segundo valor, si Arreglo[i] vemos que es m\u00e1s grande que Ma, hemos encontrado un nuevo m\u00e1ximo y se lo asignamos a Ma, igualmente si Arreglo[i] es m\u00e1s peque\u00f1o que Mi, habremos encontrado un nuevo m\u00ednimo y se lo asignamos a Mi, al llegar al final de la lista de datos podemos asegurar que Ma tendr\u00e1 el m\u00e1ximo y Mi tendr\u00e1 el m\u00ednimo \u00a1Pero atenci\u00f3n en las l\u00edneas 62 y 63! Aqu\u00ed es donde se opera la magia, vean, lo que decimos en la l\u00ednea 62 es que el valor m\u00e1ximo Guardado en Ma lo guardamos indirectamente en el ligar a donde apunta el apuntador Max (esto lo hacemos usando el operador de asignaci\u00f3n indirecta *, revisen la clase 13 de apuntadores si tienen dudas), lo mismo pasa en la l\u00ednea 63 pero para Mi. \u00a1Ven, indirectamente pusimos el valor encontrado en la variable que tiene alcance solo en la funci\u00f3n main, hicimos un poco de trampa, m\u00e1s bien fuimos astutos, no pod\u00edamos tener acceso a las variables M\u00e1ximo y M\u00ednimo de la funci\u00f3n principal porque estamos fuera de su campo de acci\u00f3n, pero a cambio declaramos las variables Max y Min, que son apuntadoras, por lo que pueden guardar una direcci\u00f3n y le pedimos que guarden la direcci\u00f3n de las variables M\u00e1ximo y M\u00ednimo, e indirectamente cambiamos el valor de estas variables guardando lo que quer\u00edamos, \u00a1brillante!, \u00bfno? Finalmente, todas las variables locales a la funci\u00f3n desaparecen, pero el cambio indirecto a M\u00e1ximo y M\u00ednimo de la funci\u00f3n principal ya est\u00e1 hecho y ese no desaparece.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ahora si regresemos a la l\u00ednea 28, veamos, recuerden, cuando en C se invoca a una funci\u00f3n el cruce de informaci\u00f3n se hace mediante la copia de valores, as\u00ed que Arreglo de main copia su valor (direcci\u00f3n donde comienza el arreglo de datos) a la variable Arreglo de la funci\u00f3n, el valor de N de la funci\u00f3n principal se copia a la variable N de la funci\u00f3n, pero aqu\u00ed viene lo bueno, \u00a1atenci\u00f3n! Lo que se copia a la variable Max de la funci\u00f3n no es el valor de M\u00e1ximo sino la direcci\u00f3n de M\u00e1ximo (recuerden que el operador &amp; es el operador de direcci\u00f3n y lo que hace es responder la direcci\u00f3n donde vive la variable) as\u00ed que Max recibe la direcci\u00f3n de M\u00e1ximo (no su valor), lo mismo pasa con Min y M\u00ednimo<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u00bfLo entendieron? Una jugada realmente magistral, resumamos, como en la funci\u00f3n MaxMin NO, repito NO, se puede cambiar los valores de las variables de la funci\u00f3n main, lo que hacemos es pasar la direcci\u00f3n de las variables que queremos modificar, y luego utilizando el operador de indirecci\u00f3n (*) modificamos el valor de esas variables a las que no ten\u00edamos acceso.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">YA solo don comentarios m\u00e1s, no olvidemos lo importante de la l\u00ednea 30, al terminar de usar la memoria din\u00e1mica que solicitamos, la liberamos. El segundo comentario es que vean que en la l\u00ednea 31 y 36 asignamos el valor de 0 o de -1 a la variable estado y en la l\u00ednea 38 regresamos ese valor. Es una convenci\u00f3n que el valor que regresa la funci\u00f3n main es un 0 si la ejecuci\u00f3n del programa se logr\u00f3 sin falla y alg\u00fan valor negativo si hubo alguna falla, vean que la funci\u00f3n main regresar\u00e1 un 0 si se logr\u00f3 asignar memoria din\u00e1mica y regresar\u00e1 un -1 si la asignaci\u00f3n fall\u00f3. En clases anteriores siempre regres\u00e1bamos un 0, ahora decidimos que regresar.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vean, con el truco de los apuntadores pudimos hacer una llamada a una funci\u00f3n que, para fines pr\u00e1cticos, no se intercambi\u00f3 el valor de variables sino la referencia de la direcci\u00f3n donde est\u00e1n localizadas variables A este tipo de llamada se le conoce por llamada por referencia (estrictamente es un cruce por valor, pero el valor intercambiado es la direcci\u00f3n de una variable a la que modificaremos su contenido indirectamente).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Un documento que recomendamos ampliamente consultar es el siguiente:<\/p>\n\n\n\n<div class=\"wp-block-buttons is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-fe48e5de wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button is-style-fill\"><a class=\"wp-block-button__link has-background wp-element-button\" href=\"https:\/\/pdos.csail.mit.edu\/6.828\/2017\/readings\/pointers.pdf\" style=\"border-radius:100px;background:linear-gradient(135deg,rgb(240,152,0) 0%,rgb(240,152,0) 100%)\" target=\"_blank\" rel=\"noreferrer noopener\">     ACCEDE      <\/a><\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">En \u00e9l podr\u00e1n repasar el tema de apuntadores y sus usos en programaci\u00f3n, para aquellos que quieran profundizar en este tema tan interesante, no se la pierdan.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusi\u00f3n<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Esta clase es una de las m\u00e1s retadoras del curso, se analizaron 2 aplicaciones t\u00edpicas de los apuntadores;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Manejo de memoria din\u00e1mica de arreglos en una y en varis dimensiones<\/li>\n\n\n\n<li>El cruce de informaci\u00f3n por referencia entre funciones<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Estos dos ejemplos de uso de apuntadores son los m\u00e1s usados en C, por favor, no desesperes si tienes que repetir varias veces el estudio de esta clase, eso s\u00ed, si logras comprender lo involucrado en esta clase te aseguramos que tu nivel de programaci\u00f3n es bueno.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"fuentes-de-informacion\">Fuentes de informaci\u00f3n<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>C Programming Language, Brian W. Kernighan Dennis M. Ritchie. Prentice Hall; 2 ed.<a href=\"https:\/\/pdos.csail.mit.edu\/6.828\/2017\/readings\/pointers.pdf\" target=\"_blank\" rel=\"noreferrer noopener\"> https:\/\/pdos.csail.mit.edu\/6.828\/2017\/readings\/pointers.pdf<\/a><\/li>\n\n\n\n<li>Programaci\u00f3n C\/punteros <a href=\"https:\/\/en.wikiversity.org\/wiki\/C_Programming\/Pointers\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/en.wikiversity.org\/wiki\/C_Programming\/Pointers<\/a><\/li>\n\n\n\n<li>Programaci\u00f3n C\/Punteros y matrices <a href=\"https:\/\/en.wikibooks.org\/wiki\/C_Programming\/Pointers_and_arrays\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/en.wikibooks.org\/wiki\/C_Programming\/Pointers_and_arrays<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Introducci\u00f3n \u00a1Hola de nuevo! La clase anterior seguramente ha sido algo desconcertante, esto de entender los apuntadores es un tanto confuso, miren que acceder a los datos que se guardan en la memoria a trav\u00e9s de la direcci\u00f3n donde est\u00e1n guardados suena m\u00e1s al trabajo de un cartero que entrega cartas a domicilio que a &#8230; <a title=\"Clase digital 14. Arreglos din\u00e1micos de variables, y regreso de funciones por referencia\" class=\"read-more\" href=\"https:\/\/blogs.ugto.mx\/rea\/clase-digital-14-arreglos-dinamicos-de-variables-y-regreso-de-funciones-por-referencia\/\" aria-label=\"Leer m\u00e1s sobre Clase digital 14. Arreglos din\u00e1micos de variables, y regreso de funciones por referencia\">Leer m\u00e1s<\/a><\/p>\n","protected":false},"author":142,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_crdt_document":"","episode_type":"","audio_file":"","podmotor_file_id":"","podmotor_episode_id":"","cover_image":"","cover_image_id":"","duration":"","filesize":"","filesize_raw":"","date_recorded":"","explicit":"","block":"","itunes_episode_number":"","itunes_title":"","itunes_season_number":"","itunes_episode_type":"","footnotes":""},"categories":[880,881],"tags":[],"class_list":["post-34018","post","type-post","status-publish","format-standard","hentry","category-licenciatura-en-ingenieria-biomedica","category-uda-programacion-basica"],"acf":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blogs.ugto.mx\/rea\/wp-json\/wp\/v2\/posts\/34018","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.ugto.mx\/rea\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.ugto.mx\/rea\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.ugto.mx\/rea\/wp-json\/wp\/v2\/users\/142"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.ugto.mx\/rea\/wp-json\/wp\/v2\/comments?post=34018"}],"version-history":[{"count":4,"href":"https:\/\/blogs.ugto.mx\/rea\/wp-json\/wp\/v2\/posts\/34018\/revisions"}],"predecessor-version":[{"id":34479,"href":"https:\/\/blogs.ugto.mx\/rea\/wp-json\/wp\/v2\/posts\/34018\/revisions\/34479"}],"wp:attachment":[{"href":"https:\/\/blogs.ugto.mx\/rea\/wp-json\/wp\/v2\/media?parent=34018"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.ugto.mx\/rea\/wp-json\/wp\/v2\/categories?post=34018"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.ugto.mx\/rea\/wp-json\/wp\/v2\/tags?post=34018"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}