2012-10-17 19 views
9

sappiate che io sono ancora molto nuovo a C e puntatori in generale ... questo è per una classe, quindi non sto chiedendo per il codice esplicito, solo aiutare la comprensione dei concetti .Puntatori e loop in C

Sto provando a creare un ciclo per assegnare valori casuali a un interno di una struttura. Il problema si verifica quando assegno i valori all'iterazione corrente del mio puntatore o array.

struct student{ 
    int id; 
    int score; 
}; 

struct student* allocate(){ 
    /*Allocate memory for ten students*/ 
    int ROSTER_SIZE = 10; 
    struct student *roster = malloc(ROSTER_SIZE * sizeof(struct student)); 

    /*return the pointer*/ 
    return roster; 
} 

void generate(struct student* students){ 
    /*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/ 
    int i = 0; 

    for (i = 0; i < 10; ++i) { 
     students[i]->id = i + 1; 
     students[i]->score = rand()%101; 
} 

Ora, dalla mia comprensione, che è più probabile corretta, dovrei essere in grado di utilizzare students[i] per assegnare valori a ogni iterazione, ma VS 2010 mi dice "l'espressione deve avere un tipo di puntatore." Non è già un puntatore? È passato alla funzione come un puntatore, giusto?

+1

"Non sto chiedendo il codice esplicito, solo aiuto nella comprensione dei concetti." INOLTRE non hai lanciato il valore di ritorno di 'malloc()' - questo è un +1 definito. –

+0

Il * contenuto * dell'array non è * puntatori * alle strutture dello studente; è * è struttura studentesca. Quindi perdere l'uso '->' in questo caso e sostituirlo con '.'. – WhozCraig

+0

Sono l'unico infastidito dalla parentesi graffa mancante? :-) – Massimiliano

risposta

7

Cambio:

students[i]->id = i + 1; 
students[i]->score = rand()%101; 

a:

students[i].id = i + 1; 
students[i].score = rand()%101; 

Motivo: students è un puntatore a una matrice di struct student. students[i] è un vero e proprio struct student. Notare che students[i] equivale effettivamente a *(students + i).

+0

Non ho scritto nulla in C, ma ne ho visto molte in giro con StackOverflow. Perché '* (studenti + i)' funziona? Perché questo aggiunge quattro all'indirizzo invece di uno? – mowwwalker

+0

Il compilatore "conosce" il tipo di puntatore, quindi quando genera codice per l'aritmetica del puntatore (aritmetica dell'indirizzo), aggiunge la dimensione di un elemento. È molto simile all'indicizzazione degli array, solo una sintassi diversa. –

5

studenti è un puntatore, ma quando si indice allora si sta riferendo a un'istanza effettiva della struttura, in modo quindi è necessario utilizzare . invece di -> per accedere a un campo in quella struttura

+4

In altre parole, l'espressione 'students' ha tipo' struct student * ', mentre l'espressione' studends [i] 'ha tipo' struct student'. – cdhowie

3

Non è (studenti [i]) già un puntatore?

No. Dopo aver dereferenziarlo (ricordate: utilizzando la sintassi di sottoscrizione gamma ptr[index] su puntatori significa *(ptr + index)), sarà una struttura semplice, per il quale si dovrebbe usare la sintassi membro di accesso . campo al posto del -> che è per puntatori a strutture:

students[i].id = i + 1; 

ecc dovrebbe andare bene.

1

La risposta di Paul risolverà il tuo problema. Ma dal momento che stai chiedendo di capire il concetto ...

Fondamentalmente, ciò che hai fatto era di allocare dinamicamente una matrice di dati sull'heap. Ora che gli studenti sono in effetti un puntatore all'array di Studente sull'heap. Tuttavia, quando si fa riferimento ad esso come gli studenti [index], si sta effettivamente facendo qualcosa di simile

*(students + index) 

Si riferisce a un'istanza Studente presso la posizione del (studenti + indice). Nota che è già de-referenziato, quindi ti stai già riferendo direttamente a quell'istanza. Quindi, quando si scrivono gli studenti [index] -> id, è lo stesso che

*(students + index)->id 

Dovrebbe essere chiaro a voi ora che questo non è semplicemente la sintassi corretta. Si dovrebbe invece scrivere

students[index].id 

che equivale a

(*(students + index)).id 

questo significa veramente: si sta incrementando il puntatore chiamato studenti di indice * sizeof (Studente) byte in memoria, e accedere al suo campo di identificazione .

+2

Inserisci (studenti + indice) -> id per coprire l'unica opzione rimasta fuori. – WhozCraig