{"id":6829,"date":"2011-05-04T18:24:12","date_gmt":"2011-05-04T16:24:12","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=6829"},"modified":"2011-10-05T12:24:37","modified_gmt":"2011-10-05T10:24:37","slug":"12-i-puntatori-parte-1","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/12-i-puntatori-parte-1\/","title":{"rendered":"12. I Puntatori &#8211; parte 1"},"content":{"rendered":"<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/04\/corso-completo-c-i-puntatori-parte-1-00.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/04\/corso-completo-c-i-puntatori-parte-1-00.jpg\" alt=\"corso-completo-c-i-puntatori-parte-1-00\" title=\"corso-completo-c-i-puntatori-parte-1-00\" width=\"200\" height=\"100\" class=\"alignleft size-full wp-image-6831\" \/><\/a> Ed eccoci arrivati all&#8217;argomento che per tanti utenti rappresenta la &#8220;bestia nera&#8221; della programmazione in C, i puntatori. Purtroppo devo darvi una brutta notizia, tutta la programmazione moderna si basa in maniera pi\u00f9 o meno velata sull&#8217;uso dei puntatori, quindi non fatevi venire in mente di saltare questa lezione e mettiamoci subito al lavoro.<!--more--><\/p>\n<h4>Cos&#8217;\u00e8 un puntatore?<\/h4>\n<p>Un puntatore non \u00e8 nient&#8217;altro che un tipo di variabile cos\u00ec come lo sono int, long, char etc, il suo scopo, per\u00f2, non \u00e8 quello di memorizzare l&#8217;informazione in s\u00e8, come accade per le classiche variabili, ma quello di memorizzare l&#8217;indirizzo di memoria dove di fatto l&#8217;informazione \u00e8 memorizzata.<\/p>\n<p><strong>Nota: <\/strong>Per chi non lo sapesse la memoria dei nostri computer \u00e8 organizzata in blocchi, ciascun blocco ha un proprio indirizzo (che non \u00e8 altro che un numero, spesso espresso in esadecimale come ad esempio 0x345F2A).<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/05\/corso-completo-c-i-puntatori-parte-1-01.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/05\/corso-completo-c-i-puntatori-parte-1-01.jpg\" alt=\"corso-completo-c-i-puntatori-parte-1-01\" title=\"corso-completo-c-i-puntatori-parte-1-01\" width=\"550\" height=\"306\" class=\"aligncenter size-full wp-image-6866\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/05\/corso-completo-c-i-puntatori-parte-1-01.jpg 550w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/05\/corso-completo-c-i-puntatori-parte-1-01-300x166.jpg 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/05\/corso-completo-c-i-puntatori-parte-1-01-150x83.jpg 150w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Va precisato che anche il puntatore, in quanto variabile, \u00e8 archiviato in memoria, quindi ha un suo proprio indirizzo, ma questo non ci deve confondere le idee.<\/p>\n<p>Nell&#8217;immagine vediamo 4 variabili, l&#8217;ultima memorizzata all&#8217;indirizzo di memoria 0x803FA4 \u00e8 una variabile di tipo puntatore ed il suo contenuto \u00e8 0x803FA2, quando dal programma accederemo a questa variabile (vedremo a breve come) verremo &#8220;dirottati&#8221; all&#8217;allocazione di memoria 0x803FA2 che ha come contenuto il numero 42.<\/p>\n<p>Utilizzare una variabile che contenga l&#8217;indirizzo dove recuperare il dato \u00e8 utile per realizzare quello che viene chiamato indirizzamento indiretto, ovvero piuttosto che utilizzare direttamente la variabile x utilizzo la variabile presente all&#8217;indirizzo di memoria puntato da x.<\/p>\n<p>Anche se pu\u00f2 sembrare piuttosto esoterico, l&#8217;indirizzamento indiretto \u00e8 indispensabile per il funzionamento interno della CPU (<a href=\"http:\/\/it.wikipedia.org\/wiki\/Architettura_di_un_processore_basato_su_registri_generali\" target=\"_blank\">link<\/a>) mentre i linguaggi di pi\u00f9 alto livello lo utilizzano per fornire maggiore flessibilit\u00e0 ai programmi e per velocizzare le operazioni con variabili molto grandi in memoria.<\/p>\n<p>Facciamo un piccolo esempio, supponiamo di avere una variabile che occupi veramente molto spazio, e che questa variabile debba essere usata in due punti molto diversi del nostro programma. Piuttosto che effettuare una copia del dato, che comporterebbe uno spreco di tempo e memoria, possiamo creare un puntatore all&#8217;allocazione e utilizzare il puntatore all&#8217;interno del nostro codice cos\u00ec che quando ci servir\u00e0 una copia del dato baster\u00e0 effettuare una copia del solo puntatore, risparmiando un mucchio di tempo.<\/p>\n<p>Suppongo che nessuno si stia ponendo in questo momento una domanda cruciale, cio\u00e8: &#8220;Se il puntatore contiene solo l&#8217;informazione sull&#8217;indirizzo dove reperire il dato, dov&#8217;\u00e8 l&#8217;informazione sul <strong>tipo<\/strong> di dato?&#8221; ovvero &#8220;Come fa il nostro programma a sapere quanti byte leggere a partire dall&#8217;indirizzo di memoria puntato dal puntatore? Per un char dovrebbe leggere solo un byte, per un int 4 byte etc etc..&#8221; Bene, ottima domanda! Proprio per questo tutti i puntatori hanno un tipo, dichiareremo infatti un puntatore ad intero, oppure un puntatore a char e cos\u00ec via, in questo modo il nostro programma sapr\u00e0 quanti byte leggere.<\/p>\n<p>Una piccola eccezione \u00e8 data dal tipo &#8220;puntatore a void&#8221;, il termine &#8220;void&#8221; l&#8217;abbiamo gi\u00e0 incontrato quando abbiamo parlato delle funzioni, dicendo che una funzione che non restituisce alcun valore si dichiara come<\/p>\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\nvoid nomefunzione {\r\n\r\n        \/\/codice della funzione.\r\n\r\n}\r\n<\/pre>\n<p>In questo caso il termine &#8220;void&#8221; indica che si tratta di un puntatore generico, che non ha specificato nessun tipo di dato, quindi punta in modo generico ad un intero blocco della memoria. Per utilizzarlo \u00e8 sempre possibile utilizzare l&#8217;operazione di cast (<a href=\"http:\/\/www.devapp.it\/wordpress\/7-operazioni-matematiche-e-logiche.html\" target=\"_blank\">lezione 7<\/a>).<\/p>\n<h4>Dichiarazione di un puntatore<\/h4>\n<p>Per dichiarare una variabile di tipo puntatore si usa una sintassi molto simile alla dichiarazione di una variabile normale, l&#8217;unica differenza \u00e8 che bisogna inserire un &#8221; * &#8221; prima del nome della variabile. Per esempio per dichiarare due variabili di tipo rispettivamente puntatore ad intero e puntatore a carattere la sintassi da utilizzare \u00e8 la seguente<\/p>\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\nint *a;\r\nchar *b;\r\n<\/pre>\n<p>Una piccola nota sul carattere &#8221; * &#8220;: non \u00e8 necessario scriverlo attaccato al nome della variabile, questa \u00e8 la convenzione che utilizzo io, ma in altri casi potreste trovare qualcosa come<\/p>\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\nint* a;\r\nchar* b;\r\n<\/pre>\n<p>La questione \u00e8 puramente simbolica, ma anche qui ci sono parecchie scuole di pensiero, se avete voglia potete leggere il parere di B. Stroustrup, l&#8217;inventore del C++ (<a href=\"http:\/\/www2.research.att.com\/~bs\/bs_faq2.html#whitespace\" target=\"_blank\">link<\/a>). L&#8217; unica cosa certa \u00e8 che se vi capita di parlare con un programmatore non dovete dire &#8220;int asterisco a&#8221; ma &#8220;int star a&#8221; se volete essere sicuri di essere capiti.<\/p>\n<p>L&#8217;operatore (perch\u00e9 si tratta di un operatore, non di un orpello grafico) &#8221; * &#8221; si chiama operatore di deferenziazione e quando \u00e8 anteposto al nome di una variabile fa si che al suo posto venga utilizzato il valore dell&#8217;allocazione di memoria all&#8217;indirizzo contenuto nella variabile.<\/p>\n<p>Vediamo se tutto \u00e8 chiaro con una domanda difficile.<\/p>\n<p>Supponiamo di aver scritto questo codice, in cui dichiariamo una variabile di tipo puntatore ad intero e poi assegnamo tramite l&#8217;operatore di deferenziazione il valore 42.<\/p>\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\n#include <stdio.h>\r\n\r\nint main(int argc, char **argv) {\r\n\r\nint i,j;  \/\/variabili dichiarate ma non inizializzate. serviranno dopo.\r\n\r\nint *a;\r\n\r\n        *a = 42;\r\n\r\n        printf(\"Il puntatore punta ad una variabile che vale %d \", *a);\r\n\r\n}\r\n<\/pre>\n<p>Tutto sembra corretto, anche se compiliamo non ci sono errori particolari, eppure quando eseguiamo il programma appare un drammatico &#8220;segmentation fault&#8221;, come mai?<\/p>\n<p>Esaminiamo il codice, in particolare la riga:<\/p>\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\n*a = 42;\r\n<\/pre>\n<p>Questa istruzione dovrebbe assegnare 42 alla variabile contenuta all&#8217;indirizzo di memoria contenuto nella variabile a, ma purtroppo la variabile a non \u00e8 stata inizializzata, quindi il suo valore, di solito \u00e8 zero oppure un valore non prevedibile, quindi quello che accade \u00e8 che il programma tenta di scrivere &#8220;42&#8221; in zone di memoria che non gli appartengono, quindi il sistema operativo per sicurezza lo blocca e genera l&#8217;errore &#8220;segmentation fault&#8221; facendo crashare il programma.<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/05\/corso-completo-c-i-puntatori-parte-1-02.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/05\/corso-completo-c-i-puntatori-parte-1-02.jpg\" alt=\"corso-completo-c-i-puntatori-parte-1-02\" title=\"corso-completo-c-i-puntatori-parte-1-02\" width=\"550\" height=\"277\" class=\"aligncenter size-full wp-image-6865\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/05\/corso-completo-c-i-puntatori-parte-1-02.jpg 550w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/05\/corso-completo-c-i-puntatori-parte-1-02-300x151.jpg 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/05\/corso-completo-c-i-puntatori-parte-1-02-150x75.jpg 150w\" sizes=\"auto, (max-width: 550px) 100vw, 550px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Quindi abbiamo scoperto che quando si usano i puntatori in realt\u00e0 le variabili da inizializzare sono due e non pi\u00f9 una sola, dobbiamo inizializzare il contenuto della variabile puntatore e inizializzare il contenuto della variabile puntata. Ma come si inizializza una variabile di tipo puntatore? Ci sono due metodi: il primo, che vedremo in una prossima lezione, \u00e8 quello di chiedere direttamente al sistema operativo un indirizzo di memoria libero da poter utilizzare, mentre il secondo consiste nell&#8217;assegnare ad un puntatore l&#8217;indirizzo di una variabile gi\u00e0 dichiarata. Ad esempio potremmo assegnare al puntatore &#8220;a&#8221; il valore 0x803FA3 che \u00e8 l&#8217;indirizzo dove \u00e8 memorizzata la variabile j.<\/p>\n<p>In questo modo con queste due inizializzazioni:<\/p>\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\na = 0x803FA3;\r\n\r\n*a = 42;\r\n<\/pre>\n<p>non si genererebbe errore, perch\u00e9 0x803FA3 \u00e8 un indirizzo appartenente al nostro programma ed il sistema operativo non ci impedisce di accedervi.<\/p>\n<p><strong>Attenzione:<\/strong> Nella riga a = 0x803FA3; non ho dimenticato l&#8217;asterisco e non \u00e8 un refuso di stampa, in questo caso vogliamo modificare il valore contenuto all&#8217;interno del puntatore, e non della variabile puntata dal puntatore, quindi il simbolo &#8221; * &#8221; non va messo.<\/p>\n<p>Ma come facciamo a conoscere l&#8217;indirizzo di memoria che il sistema operativo ha assegnato alle nostre variabili? 0x803FA3 \u00e8 solo un esempio inventato e non c&#8217;\u00e8 modo di sapere durante la scrittura di un codice qual&#8217;\u00e8 l&#8217;indirizzo che verr\u00e0 assegnato alle nostre variabili durante l&#8217;esecuzione del programma. Quindi come fare? Possiamo utilizzare un operatore che \u00e8 il duale dell&#8217;operatore di deferenziazione ed \u00e8 l&#8217;operatore &#8221; &#038; &#8220;.<\/p>\n<p>Anteposto al nome della variabile fa si che al suo posto venga utilizzato l&#8217;indirizzo della variabile.<\/p>\n<p>Quindi potremmo riscrivere il codice precedente in questo modo:<\/p>\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\n#include <stdio.h>\r\n\r\nint main(int argc, char **argv) {\r\n\r\nint i,j;  \/\/variabili dichiarate ma non inizializzate. serviranno dopo.\r\n\r\nint *a;\r\n\r\n        a = &j; \/\/assegno al puntatore a l'indirizzo della variabile j\r\n\r\n*a = 42; \/\/assegno all'indirizzo puntato da a il valore 42\r\n\r\n        printf(\"Il puntatore punta ad una variabile che vale %d \", *a);\r\n\r\n}\r\n<\/pre>\n<p>Quello che abbiamo fatto in questo esempio \u00e8 quello di far puntare il puntatore <em>a<\/em> all&#8217;indirizzo dov&#8217;\u00e8 memorizzata la variabile <em>j<\/em>, quindi possiamo modificare il valore di <em>j<\/em> sia modificando <em>j<\/em> stessa sia modificando <em>*a<\/em>.<\/p>\n<p>Vediamo in questo esempio qualche esempio di utilizzo dell&#8217;operatore <em>*<\/em> ed <em>&#038;<\/em>:<\/p>\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\n#include <stdio.h>\r\n\r\nint main(int argc, char **argv) {\r\n\r\n int valore_a;\r\n\r\n int *ptr1;\r\n\r\n ptr1 = &valore_a;\r\n\r\n *ptr1        = 42;\r\n\r\n printf(\"valore_a vale: %d \\n\", valore_a);\r\n\r\n printf(\"*ptr1 vale: %d\\n \", *ptr1);\r\n\r\n\/\/praticamente *ptr1 e valore_a sono sinonimi.\r\n\r\n printf(\"La variabile valore_a e' memorizzata in %#x \\n\", &valore_a);\r\n\r\n printf(\"La variabile ptr1 vale (punta a) %#x \\n\", ptr1);\r\n\r\n printf(\"La variabile ptr1 e' memorizzata in %#x \\n\", &ptr1);\r\n\r\n\/\/ non confondiamo l'indirizzo al quale \u00e8 memorizzato il puntatore con    \/\/l'indirizzo al quale punta, queste righe evidenziano la differenza.\r\n\r\n}\r\n<\/pre>\n<p>Copiate e compilate questo codice, studiate i commenti e parliamone sul forum.<\/p>\n<p>Concludo questa importante lezione proponendo qualche esercizio:<\/p>\n<ol>\n<li>Scrivere un programma C che dopo aver dichiarato 3 interi e tre puntatori ad intero gli assegni dei valori arbitrari agli interi e poi calcoli il massimo utilizzando i puntatori e non le variabili intere.<\/li>\n<li>Che cosa succede se scrivo:\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\nint *ptr1;\r\n\r\nptr1 = &ptr1;\r\n<\/pre>\n<\/li>\n<li>Dati queste dichiarazioni:\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\nint *p;\r\nint i;\r\nint k;\r\ni = 42;\r\nk = i;\r\np = &i;\r\n<\/pre>\n<p>se volessi portare il valore di i a 75 quale operazione dovrei eseguire?<\/p>\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\n    k = 75;\r\n    *k = 75;\r\n    p = 75;\r\n    *p = 75;\r\n    due o pi\u00f9 delle precedenti risposte.\r\n<\/pre>\n<\/li>\n<li>Le seguenti dichiarazioni sono corrette? Fornire spiegazioni adeguate:\n<pre lang=\"c\" line=\"1\" escaped=\"true\">\r\nchar c = 'A';\r\ndouble *p = &c;\r\n<\/pre>\n<\/li>\n<\/ol>\n<p>Credo che per questa lezione sia abbastanza \ud83d\ude42<br \/>\nAlla prossima!<\/p>\n<h4>Letture consigliate:<\/h4>\n<p><a href=\"http:\/\/www.amazon.it\/gp\/search\/ref=as_li_qf_sp_sr_il_tl?ie=UTF8&#038;keywords=887192200X&#038;tag=de0d-21&#038;index=aps&#038;linkCode=as2&#038;camp=3370&#038;creative=23322\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/03\/C-Corso-Completo-di-Programmazione-kernighan-ritchie-devAPP.jpg\" alt=\"C-Corso-Completo-di-Programmazione-kernighan-ritchie-devAPP\" title=\"C-Corso-Completo-di-Programmazione-kernighan-ritchie-devAPP\" width=\"54\" height=\"75\" class=\"alignleft size-full wp-image-7803\" \/><\/a> <a href=\"http:\/\/www.amazon.it\/gp\/search\/ref=as_li_qf_sp_sr_il_tl?ie=UTF8&#038;keywords=887192200X&#038;tag=de0d-21&#038;index=aps&#038;linkCode=as2&#038;camp=3370&#038;creative=23322\" target=\"_blank\"><strong>Il linguaggio C. Principi di programmazione e manuale di riferimento (Accademica) <\/strong><\/a><br \/>\n<em>Brian W. Kernighan &#8211; Dennis M. Ritchie<\/em><br \/>\n<strong>Editore:<\/strong> Pearson | <strong>Lingua:<\/strong> Italiano | <strong>Brossura:<\/strong> 313 pagine<br \/>\n<strong>Prezzo Listino:<\/strong> <del datetime=\"2011-09-03T10:00:08+00:00\">EUR 27,00<\/del><br \/>\n<strong>Prezzo Promozione:<\/strong> EUR 22,95 con Spedizione gratuita<\/p>\n<p><a href=\"http:\/\/www.amazon.it\/gp\/product\/8850329547\/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&#038;tag=de0d-21&#038;linkCode=as2&#038;camp=3370&#038;creative=23322&#038;creativeASIN=8850329547\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2011\/09\/C-Corso-Completo-di-Programmazione-Deitel-Deitel-devAPP.jpg\" alt=\"C-Corso-Completo-di-Programmazione-Deitel-Deitel-devAPP\" title=\"C-Corso-Completo-di-Programmazione-Deitel-Deitel-devAPP\" width=\"54\" height=\"75\" class=\"alignleft size-full wp-image-7550\" \/><\/a> <a href=\"http:\/\/www.amazon.it\/gp\/product\/8850329547\/ref=as_li_qf_sp_asin_il_tl?ie=UTF8&#038;tag=de0d-21&#038;linkCode=as2&#038;camp=3370&#038;creative=23322&#038;creativeASIN=8850329547\" target=\"_blank\"><strong>C. Corso completo di programmazione<\/strong><\/a><br \/>\n<em>Paul J. Deitel &#8211; Harvey M. Deitel<\/em><br \/>\n<strong>Editore:<\/strong> Apogeo | <strong>Lingua:<\/strong> Italiano | <strong>Brossura:<\/strong> 640 pagine<br \/>\n<strong>Prezzo Listino:<\/strong> <del datetime=\"2011-09-03T10:00:08+00:00\">EUR 39,00<\/del><br \/>\n<strong>Prezzo Promozione:<\/strong> EUR 33,15 con Spedizione gratuita<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/supporto-applicazioni\/le-applicazioni-dei-nostri-autori\/parole-vietate-di-ignazio-calo\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/02\/bannerIgnazioc.png\" alt=\"\" width=\"480\" height=\"100\" \/><\/a><br \/>\n<\/center><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ed eccoci arrivati all&#8217;argomento che per tanti utenti rappresenta la &#8220;bestia nera&#8221; della programmazione in C, i&#8230;<\/p>\n","protected":false},"author":53,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[569],"tags":[593,588,724,723,737,241],"class_list":["post-6829","post","type-post","status-publish","format-standard","hentry","category-corso-completo-di-c","tag-corso-completo-di-c-2","tag-corso-di-c","tag-esempi-codice-programmazione-c","tag-esercizi-programmazione-c","tag-i-puntatori-in-c","tag-ignazio-calo"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/6829","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=6829"}],"version-history":[{"count":7,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/6829\/revisions"}],"predecessor-version":[{"id":7816,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/6829\/revisions\/7816"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=6829"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=6829"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=6829"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}