2009-06-28 20 views
7

Sto scrivendo un piccolo programma in C per fare un po 'di numeri crunch, e ha bisogno di passare attorno agli array tra le funzioni. Le funzioni dovrebbero accettare e restituire i puntatori, giusto?I puntatori e gli array sono diversi in C?

Ad esempio, questo (lo so che non può essere la cosa più efficiente):

int* reverse(int* l, int len) { 
    int* reversed = malloc(sizeof(*reversed)*len); 
    int i, j; 
    for (i = 0, j = len-1; i < len; i++, j--) { 
     reversed[j] = l[i]; 
    } 
    return reversed; 
} 

Am I utilizzando i puntatori a destra?

+1

tuo esempio sguardi bene. L'argomento più ampio della differenza tra array e puntatori è stato affrontato qui in precedenza, come in http://stackoverflow.com/questions/660752/pointer-vs-array-in-c-non-trivial-difference. –

+0

(Ciò non si qualifica come risposta) L'array e l'algebra del puntatore differiscono solo in quanto sizeof (nome_array) restituisce il conteggio degli elementi nome_array, non la dimensione della matrice in byte. – jpinto3912

risposta

14

codice Lo snippet è corretto. Tuttavia, i puntatori e gli array in C sono effettivamente diversi. Mettere semplicemente "il puntatore a digitare T" non è lo stesso di "l'array di tipo T".

Si prega di dare un'occhiata a C Faq discutendo i puntatori & matrici per ottenere una migliore comprensione di questo.

+2

Upvoted per C Faq - più dettagliato di una risposta andrebbe su così. –

+1

+1 per le domande frequenti su C. –

1

Da una prospettiva di basso livello, una matrice è un blocco continuo di memoria a cui si accede dall'indirizzo dell'inizio di quel blocco e dell'offset, quindi da quel livello di astrazione, è un puntatore. Tuttavia, dal punto di vista del linguaggio C, un tipo di matrice è diverso da un tipo di puntatore. Fondamentalmente una matrice può essere assegnata a un valore puntatore ma non è lo stesso tipo.

Ai fini della funzione, si sta facendo OK.

+3

la tua affermazione in grassetto implora la spiegazione. –

+0

non importa, Crashworks lo ha già spiegato –

0

le matrici in C sono rappresentate e manipolate da un puntatore al primo elemento, ad es.

int arr[50]; 
int * ptr1 = arr; 
int * ptr2 = &arr[0]; 

in questo esempio, ptr1 == ptr2 perché l'indirizzo del primo elemento della matrice e il puntatore base per la matrice sono uguali.

così il vostro esempio di base è corretta, anche se ho il sospetto che il malloc dovrebbe probabilmente essere:

int* reversed = malloc(sizeof(int)*len); 

+0

Questo è solo nel caso in cui voglio cambiarlo in qualcos'altro (un 'long', per esempio) quindi non dovrò cambiare due cose. – Javier

+1

No, il suo malloc va bene (e preferibile al tuo) dal C99. – smcameron

+0

@ [smcameron]: @reyjavikvi]: una tecnica interessante (non ho notato il prefisso * la prima volta, mi dispiace per quello!). Ho imparato C nel 1982 e non l'ho usato molto dal 1994, quindi non ho mai letto le specifiche C99 (deve aver perso il memo su quello! ;-)) –

1

Nella teoria pedante, gli array e i puntatori sono cose diverse, poiché un array specifica una regione di memoria e quindi le dimensioni di un array sono parte del suo tipo. Quindi si dice che il nome di un array declassa in un puntatore quando viene utilizzato in quel contesto. There's a detailed explanation in the C-FAQ.

In pratica sono gli stessi dal momento che formalmente a[i] è la stessa cosa di *(a+i), e quindi il compilatore considera il nome di un array e un puntatore esattamente nello stesso modo. L'unica differenza che vale la pena di preoccuparsi è che

void foo() 
{ 
    int a[5]; // allocates five words of space on the stack 
    int *b; // allocates *one* word of space on the stack (to hold the pointer) 
} 

Lo snippet di codice va bene. Basta fare attenzione a liberare la memoria della funzione malloc() in chiunque la chiami.

2

Un collegamento a C-Domande frequenti: matrici e puntatori è già stato fornito, ma c'è anche una spiegazione approfondita in C for Smarties: Arrays and Pointers. Potresti voler leggere prima la pagina "Analisi delle espressioni".

Un paio di cose su vostro esempio che andrebbe corretto:

  1. Utilizzando int invece del corretto size_t per memorizzare dimensioni oggetto.
  2. Mancata verifica del valore di ritorno di malloc().

Un modo per "risolvere" questo secondo problema è quello di lasciare che il chiamante a decidere in cui è memorizzato l'uscita (forse il chiamante non vuole o ha bisogno di una serie di fresco allocato):

int *reverse(int *out, int *l, size_t len) { 
    size_t i, j; 
    for (i = 0, j = len - 1; i < len; ++i, --j) { 
    out[j] = l[i]; 
    } 
    return out; 
} 
Problemi correlati