{"id":6363,"date":"2024-01-03T09:46:30","date_gmt":"2024-01-03T08:46:30","guid":{"rendered":"https:\/\/msxitalia.org\/?p=6363"},"modified":"2024-01-03T09:46:33","modified_gmt":"2024-01-03T08:46:33","slug":"linguaggio-c-per-msx-lezione-5","status":"publish","type":"post","link":"https:\/\/msxitalia.org\/en\/linguaggio-c-per-msx-lezione-5\/","title":{"rendered":"C language for MSX \u2013 lesson 5"},"content":{"rendered":"\n<h2 class=\"wp-block-heading has-text-align-center\">Linguaggio C per MSX<\/h2>\n\n\n\n<h2 class=\"wp-block-heading has-text-align-center\">Rubrica a cura di Nicola Brogelli (Parte 5)<\/h2>\n\n\n\n<h2 class=\"wp-block-heading has-text-align-center\">Array e Puntatori<\/h2>\n\n\n\n<h2 class=\"wp-block-heading\">Array<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Gli array sono sequenze di variabili dello stesso tipo che vengono memorizzare consecutivamente nella memoria ed alle quali \u00e8 possibile accedere usando uno stesso nome (identificatore) a cui viene aggiunto un indice. L&#8217;uso principale di array \u00e8 archiviare e organizzare un gran numero di elementi simili in una singola \u201cstruttura dati\u201d , rendendone pi\u00f9 facile la gestire e manipolazione.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Un \u201coggetto\u201d di tipo array \u00e8 una <em>n-upla<\/em> di elementi ordinati dello stesso tipo, ai quali \u00e8 possibile accedere mediante il loro indice. Gli elementi di un array di dimensione <em>n<\/em> sono compresi in un intervallo che va da 0 a n \u2013 1.<\/p>\n\n\n\n<p class=\"has-text-align-center wp-block-paragraph\"><em>type<\/em> <em>identifier [constant-expressio]<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">La definizione sopra illustrata, rappresenta la dichiarazione di un array monodimensionale (vedremmo in seguito gli array a pi\u00f9 dimensioni). Possiamo vedere come l\u2019array ha un tipo ben definito il quale descrive gli elementi che l\u2019array pu\u00f2 contenere, un identificatore che \u00e8 il nome dell\u2019array e un valore numerico maggiore di zero che definisce la sua dimensione. Un array pu\u00f2 essere inizializzato contestualmente alla sua dichiarazione elencando all\u2019interno delle parentesi graffe i valori separati da virgole. Oppure pu\u00f2 essere dichiarato e successivamente inizializzato.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nell\u2019esempio successivo non \u00e8 necessario dare una dimensione all\u2019array in quanto \u00e8 inizializzato in modo esplicito (contestualmente alla dichiarazione inizializziamo l\u2019array con i valori riportati tra parentesi graffe).<\/p>\n\n\n\n<p class=\"has-text-align-left wp-block-paragraph\"><code>int numeri[] = {1,2,3,4,5};<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sugli array non sono definite operazioni aritmetiche e di confronto ne possono essere restituiti da una funzione, l\u2019unica operazione definita \u00e8 la selezione con indice (gli array posso essere utilizzati come argomento di una funzione, vedremmo alcuni esempi nella prossima dispensa).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Le istruzioni che seguono dichiarano che <em>numeri<\/em> \u00e8 un array di interi con dimensione 5, e successivamente si assegna il valore 7 all\u2019elemento numero quattro dell\u2019array.<\/p>\n\n\n\n<p class=\"has-text-align-left wp-block-paragraph\"><code>int numeri[5];<br>numeri[3] = 7;<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dobbiamo fare molta attenzione perch\u00e9 il linguaggio non e effettua nessun controllo sui valori degli indici, l\u2019esempio seguente non darebbe nessun errore in fase di compilazione, ma potrebbe generare problemi a tempo di esecuzione. Andremmo infatti a scrivere il valore 7 in una zona di memoria di cui non conosciamo il significato.<\/p>\n\n\n\n<p class=\"has-text-align-left wp-block-paragraph\"><code>int numeri[5];<br>numeri[5] = 7;<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Array e Puntatori<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Questo \u00e8 un argomento un po\u2019 pi\u00f9 complesso, ma cercher\u00f2 di descriverlo nel modo pi\u00f9 semplice possibile. Il nome di un array (nel caso precedente era numeri) \u00e8 anche l\u2019indirizzo di memoria in cui si trova il primo elemento dell\u2019array stesso. Pertanto possiamo dire che se <em>numeri<\/em>[n] \u00e8 un array allora &amp;<em>numeri<\/em>[0] e <em>numeri<\/em> rappresentano in modo analogo il suo indirizzo. Nella porzione di codice qui sotto le due stampe riporteranno lo stesso indirizzo di memoria.<\/p>\n\n\n\n<p class=\"has-text-align-left wp-block-paragraph\"><code>int numeri[] = {1,2,3,5,6};<br>printf(\u201c\\n stampo numeri: %d\u201d, numeri);<br>printf(\u201c\\n stampo &amp;numeri[0]: %d\u201d, &amp;numeri[0]);<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Se al nome dell\u2019array viene sommato un valore intero i, il risultato sar\u00e0 un indirizzo di memoria dato dall\u2019indirizzo di base dell&#8217;array pi\u00f9 un offset dato da i. Nell\u2019esempio seguente entrambe le stampe restituiranno lo stesso indirizzo di memoria (la differenza sostanziale con l\u2019esempio precedente risale nell\u2019offset i).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>int numeri[] = {1,2,3,5,6};<br>int i = 2; \/\/ i deve essere un numero compreso tra 0 e 4<br>printf(\u201c\\n stampo numeri: %d\u201d, numeri + i);<br>printf(\u201c\\n stampo &amp;numeri[i]: %d\u201d, &amp;numeri[i]);<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mentre *<em>numeri<\/em> e <em>numeri<\/em>[0] rappresentano allo stesso modo il primo elemento dell\u2019array (valore). Quindi entrambe le stampe mostrate nella porzione di codice daranno lo stesso risultato.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>int numeri[] = {1,2,3,5,6};<br>printf(\u201c\\n stampo *numeri: %d\u201d, *numeri); \/\/ stamper\u00e0 1<br>printf(\u201c\\n stampo numeri[0]: %d\u201d, numeri[]); \/\/ stamper\u00e0 1<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Come per gli indirizzi, anche in nell\u2019esempio di codice riportato qui sotto, per ottenere il valore di un i-esimo elemento dell\u2019array, abbiamo sommato a numeri l\u2019offset i. Entrambe le stampe restituiranno lo stesso risultato.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>int numeri[] = {1,2,3,5,6};<br>int i = 2; \/\/ i deve essere un numero compreso tra 0 e 4<br>printf(\u201c\\n stampo *(numeri + i): %d\u201d, *(numeri + i)); \/\/ stamper\u00e0 3<br>printf(\u201c\\n stampo numeri[i]: %d\u201d, numeri[i]); \/\/ stamper\u00e0 3<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Quindi riassumendo, il primo elemento di un array <em>numeri<\/em>[n] si riferisce mediante l\u2019espressione *<em>numeri<\/em>, l\u2019<em>i<\/em>-esimo elemento dell\u2019array si riferisce con l\u2019espressione *(<em>numeri<\/em> + i). Ma pi\u00f9 in generale se ind \u00e8 un indirizzo e ogni riferimento a ind[i] pu\u00f2 essere espresso nella forma *(ind + i).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Aritmetica e Puntatori<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Vediamo di dare un ulteriore approfondimento all\u2019aritmetica dei puntatori che abbiamo accennato negli esempi precedenti. Utilizzando l\u2019aritmetica dei puntatori potremmo accedere come visto in precedenza ai vari elementi dell\u2019array. Incrementando un puntatore si incrementa l\u2019indirizzo di memoria contenuto nel puntatore facendo si che punti all\u2019elemento successivo. Per far ci\u00f2 il C conosce il tipo di dato puntato e incrementa l\u2019indirizzo in base alla sua dimensione. Quindi supponiamo che <em>pi<\/em> sia un puntatore ad un array di interi con l\u2019istruzione<em> pi++<\/em> il valore di <em>pi <\/em>viene incrementato della dimensione del tipo int (generalmente 2 byte). Allo stesso modo se <em>pf<\/em> punta a un array di float, <em>pf++<\/em> incrementer\u00e0 il suo valore della dimensione di tipo float (generalmente 4 byte). Questo vale anche per incrementi superiori all\u2019unit\u00e0. Se ad esempio aggiungiamo un valore n a un puntatore, il C incrementa di del numero di byte necessari per raggiungere il nuovo indirizzo di memoria. Quindi:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code><em>pi<\/em> +=4<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">incrementer\u00e0 il contenuto di <em>pi<\/em> di 8 byte (assumendo sempre che un int sia 2 byte).<br>Tutto il ragionamento fatto fino a qui vale allo stesso modo per il decremento che viene effettuato tramite gli operatori &#8212; o -= .<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">L\u2019ultima operazione prevista a la differenziazione tra due puntatori che puntano a due differenti elementi dello stesso array, questo permette di sapere quanto distino l\u2019uno dall\u2019altro.<br>Quindi se <em>pi1<\/em> e <em>pi2<\/em> sono due puntatori ad un medesimo array di interi , l\u2019espressione <em>pi1 \u2013 pi2<\/em> fornisce la distanza tra loro due.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Sono validi anche tutti gli operatori relazionali come ==, !=, &gt;, &lt; ecc.. purch\u00e9 entrambi i puntatori puntino allo stesso array.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Linguaggio C per MSX Rubrica a cura di Nicola Brogelli (Parte 5) Array e Puntatori Array Gli array sono sequenze di variabili dello stesso tipo che vengono memorizzare consecutivamente nella memoria ed alle quali \u00e8 possibile accedere usando uno stesso nome (identificatore) a cui viene aggiunto un indice. L&#8217;uso principale di array \u00e8 archiviare e [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":6286,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[4],"tags":[],"dipi_cpt_category":[],"class_list":["post-6363","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linguaggio-c"],"_links":{"self":[{"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/posts\/6363","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/comments?post=6363"}],"version-history":[{"count":9,"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/posts\/6363\/revisions"}],"predecessor-version":[{"id":6444,"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/posts\/6363\/revisions\/6444"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/media\/6286"}],"wp:attachment":[{"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/media?parent=6363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/categories?post=6363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/tags?post=6363"},{"taxonomy":"dipi_cpt_category","embeddable":true,"href":"https:\/\/msxitalia.org\/en\/wp-json\/wp\/v2\/dipi_cpt_category?post=6363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}