Dilemma tra puntatori e array monodimensionali e matrici

di il
7 risposte

Dilemma tra puntatori e array monodimensionali e matrici

Leggo sul mio testo di studi C++:

int mat[5][10];
int* p;
p = mat[0];	//assegnamento lecito - equivale a p=&mat[0][0];
p = mat;		//assegnamento non lecito - equivale a p=&mat[0];
p= &mat;		//assegnamento non lecito
Si afferma: gli indirizzi &mat[0][0], &mat[0], &mat hanno lo stesso valore ma appartengono a tipi diversi.
Quest'ultima affermazione trovo difficile comprenderla.

Si dice poi che il nome di un array corrisponde all'indirizzo del primo elemento.

Sono concetti che detti così non riesco ad afferrare, potete darmi qualche aiuto o riferimento?

7 Risposte

  • Re: Dilemma tra puntatori e array monodimensionali e matrici

    Per prima cosa DEVI sapere che cosa e' una variabile, in vettore, un puntatore, e come questi vengono rappresentati in C.
    Inoltre devi avere chiaro che cosa e' un TIPO DI DATO, come viene rappresentato, quanti byte sono necessari per rappresentarlo, ecc.

    Tutto questo lo trovi, con dovizia di dettagli, in ogni libro sul C/C++.

    Su quale libro stai studiando?
  • Re: Dilemma tra puntatori e array monodimensionali e matrici

    migliorabile ha scritto:


    Per prima cosa DEVI sapere che cosa e' una variabile, in vettore, un puntatore, e come questi vengono rappresentati in C.
    Inoltre devi avere chiaro che cosa e' un TIPO DI DATO, come viene rappresentato, quanti byte sono necessari per rappresentarlo, ecc.

    Tutto questo lo trovi, con dovizia di dettagli, in ogni libro sul C/C++.

    Su quale libro stai studiando?
    Su questo:

    Non vorrei peccare di presunzione ma il concetto di variabile, vettore e puntatore mi è piuttosto chiaro così come i byte necessari a rappresentare il tipo di dato. Facciamo un esempio e prendiamo il caso pratico:
    p=mat;
    p è un puntatore ad un intero, cioè un identificatore contenente un indirizzo di una locazione di memoria dedicata ad ospitare un intero, corretto?
    mat si riferisce al primo elemento della matrice e contiene un valore costante, non capisco il motivo per cui p essendo un puntatore non possa accogliere come valore quello contenuto in mat; probabilmente il mio errore è perchè guardo solo il contenuto che è un indirizzo di memoria mentre in questo caso è diverso il tipo ... ma quì faccio come le balene e mi trovo "spiaggiato" .
  • Re: Dilemma tra puntatori e array monodimensionali e matrici

    zio_mangrovia ha scritto:


    probabilmente il mio errore è perché guardo solo il contenuto che è un indirizzo di memoria mentre in questo caso è diverso il tipo ...
    Ecco bravo, un puntatore ad un intero ed un puntatore ad un puntatore non possono essere la stessa cosa, e guai se il linguaggio accettasse una simile confusione.
  • Re: Dilemma tra puntatori e array monodimensionali e matrici

    Unqualunque ha scritto:


    zio_mangrovia ha scritto:


    probabilmente il mio errore è perché guardo solo il contenuto che è un indirizzo di memoria mentre in questo caso è diverso il tipo ...
    Ecco bravo, un puntatore ad un intero ed un puntatore ad un puntatore non possono essere la stessa cosa, e guai se il linguaggio accettasse una simile confusione.
    Diciamo che mat è di tipo int**, mentre mat[1] è un int* , giusto?
  • Re: Dilemma tra puntatori e array monodimensionali e matrici

    Unqualunque ha scritto:


    zio_mangrovia ha scritto:


    probabilmente il mio errore è perché guardo solo il contenuto che è un indirizzo di memoria mentre in questo caso è diverso il tipo ...
    Ecco bravo, un puntatore ad un intero ed un puntatore ad un puntatore non possono essere la stessa cosa, e guai se il linguaggio accettasse una simile confusione.
    non è proprio così.

    bisogna partire dall'A, non dall'ABC.

    una volta, tanto tempo fa, non esistevano i linguaggi di programmazione ad alto livello, esisteva solo l'assembler (poi chiamato assembly), nel quale non esistono tipi, esistono essenzialmente numeri interi (tralascio la questione ftp).
    questi numeri interi, tipicamente a 8, 16, 32 e oggi 64 bit, possono rappresentare qualsiasi cosa, da un contatore, al numero del voto preso all'esame, fino ad una locazione di memoria (cuttone sul cervellotico sistema segmentato tipico di intel, facciamo finta di avere un singolo segmentone e quindi una memoria flat, anche se flat in realtà non è).

    bene, nel mondo della CPU non c'è distinzione tra dato, indirizzo e addirittura tra dato e programma (cuttone sui meccanismi introdotti per ridurre il rischio di modifica dei programmi e quindi del codice da parte di injection virale etc. la faccio facile).

    benissimo, sta quindi al PROGRAMMA stabilire se il numero 27 è il mio voto in fisica, oppure l'indirizzo della 27-esima cella di memoria.
    ---
    In C, nel vecchio C, questo è stato mantenuto, cioè i puntatori sono puntatori a qualcosa, senza sapere bene cosa.
    un puntatore a un intero è identico a un puntatore a un float, oppure a una stringa.
    è materialmente un numero intero (tipicamente a 32bit).
    Questo però mantiene sul programmatore il "peso" di dover scrivere bene il programma, e in particolare evitare il "mischione" tra tipi diversi.

    Se dichiari un puntatore a un intero, teoricamente, quello deve essere e quello deve rimanere, cioè deve puntare a un "qualcosa" che è un intero.

    Se dichiari un puntatore a una stringa, allo stesso modo, dall'altra parte dovrebbe starci una stringa.

    Non c'è però la minima garanzia, in C, che ciò avvenga.

    Quindi, per mitigare questo problema, hanno introdotto (progressivamente) controlli sui tipi dei puntatori, al fine di intercettare, addirittura in fase di compilazione, operazioni "mischiate" in cui un puntatore al tipo X viene usato per il tipo Y.

    Ci sono meccanismi per "evadere" (casting implicito ed esplicito) a questo limite così rigido.
    ---
    In altri linguaggi la questione è ancora più "irrigidita", cioè il compilatore fa verifiche stringenti e assai "intrusive" sui puntatori.
    Al fine, si auspica, di individuare i bug prima che il programma venga compilato
    ---
    Riassumendo: tutti i puntatori sono uguali, in realtà.
    La CPU se ne frega dei tipi, basta che in un registro di indirizzamento ci sia un intero (cuttone sulle varie piattaforme, su quelle in cui ci sono registri diversi tipo D0, A0, quelle in cui ci sono EAX, quelle in cui i registri sono tutti uguali tra di loro etc.etc)

    Spero che lo spiegone, mentre sto guardando la mia gatta stecchita dal caldo, sia utile
  • Re: Dilemma tra puntatori e array monodimensionali e matrici

    Certo che tutti i puntatori sono uguali, il processore non fa differenza visto che un indirizzo di memoria è un semplice valore. Infatti quando si dice che il linguaggio fa distinzione è sempre compito del compilatore segnalare possibili confusioni. Ma volendo combinare guai come in assembly si è sempre in tempo, forzando il tipo void*.
  • Re: Dilemma tra puntatori e array monodimensionali e matrici

    zio_mangrovia ha scritto:


    Diciamo che mat è di tipo int**, mentre mat[1] è un int* , giusto?
    Si, giusto.
    Infatti mat è un array di array, ossia un array di puntatori a valore (o puntatore doppio), dereferenziandolo con mat ottieni lo specifico array di valori ossia un puntatore a valore, dereferenziandolo due volte con ma[j] ottieni il valore specifico.

    la differenza tra un int **pp; e un mat[m][n]; sta nel fatto che la prima è la dichiarazione di un semplice puntatore doppio, mentre il secondo fornisce una allocazione di memoria di m x n elementi.
Devi accedere o registrarti per scrivere nel forum
7 risposte