2012-10-17 20 views
9

Proszę wiedzieć, że jestem jeszcze bardzo nowe do C i wskaźniki w ogóle ... To dla klasy więc nie pytam o wyraźnej kod, tylko pomóc zrozumienia pojęć .Wskaźniki i pętle w C

Próbuję utworzyć pętlę do przypisywania losowych wartości do int wewnątrz struktury. Problem występuje, gdy przypisuję wartości do bieżącej iteracji wskaźnika lub tablicy.

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; 
} 

Teraz z mojego zrozumienia, co jest najprawdopodobniej nieprawidłowe, powinien mieć możliwość korzystania z students[i] przypisanie wartości do każdej iteracji, ale VS 2010 mówi mi „wyrażenie musi mieć typ wskaźnika.” Czy to już nie wskaźnik? Został przekazany do funkcji jako wskaźnik, prawda?

+1

"Nie proszę o wyraźny kod, a jedynie pomoc w zrozumieniu koncepcji." PLUS nie rzuciłeś zwracanej wartości 'malloc()' - jest to definitve +1. –

+0

* Treść * twojej tablicy nie jest * wskaźnikiem * dla studentów; to * jest * strukturą ucznia. Więc w takim przypadku prześlij "->" i zamień na ".". – WhozCraig

+0

Czy jestem jedynym dręczonym przez brakujący nawias klamrowy? :-) – Massimiliano

Odpowiedz

7

Zmiana:

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

do:

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

Powód: students jest wskaźnikiem do tablicy struct student. students[i] jest rzeczywistą wersją struct student. Zauważ, że students[i] jest faktycznie równoważny z *(students + i).

+0

Nie napisałem nic w C, ale widziałem wiele z nich wokół StackOverflow. Dlaczego '* (studenci + i)' działa? Dlaczego to dodaje cztery do adresu zamiast jednego? – mowwwalker

+0

Kompilator "zna" typ wskaźnika, więc gdy generuje kod dla arytmetyki wskaźnikowej (arytmetyka adresu), dodaje rozmiar jednego elementu. Jest to dokładnie to samo, co indeksowanie tablicy, tylko inna składnia. –

5

studentów jest wskaźnikiem, ale kiedy wskaźnik go wtedy są nawiązujące do rzeczywistej przykład struktury, więc dlatego trzeba używać . zamiast -> dostęp do pola w tej struktury

+4

Innymi słowy, wyrażenie 'studenci' ma typ' struct student * ', natomiast wyrażenie' studends [i] 'ma typ' struct student'. – cdhowie

3

Czy to już nie jest (student [i]) wskaźnik?

No. Po to was dereference (pamiętaj: za pomocą składni subskrypcji tablica ptr[index] na wskaźniki oznacza *(ptr + index)), to będzie zwykły struct, dla których należy użyć składni członkiem dostępowej . pola zamiast -> co jest dla wskaźniki do struktur:

students[i].id = i + 1; 

itd. powinny być w porządku.

1

Odpowiedź Pawła rozwiąże Twój problem. Ale ponieważ chcesz zrozumieć tę koncepcję ...

Zasadniczo chodziło o dynamiczne przydzielenie tablicy danych na stercie. Teraz, gdy uczniowie są w rzeczywistości wskaźnik do tablicy Student na stercie. Jednak, kiedy się do niego jako studenci [indeks], jesteś rzeczywiście robi coś w tym

*(students + index) 

którego się odnosimy do instancji Student w miejscu (studenci + index). Zauważ, że jest już odsyłaczem, więc odwołujesz się bezpośrednio do tej instancji. Stąd, kiedy piszesz studenci [indeks] -> id, jest taka sama jak

*(students + index)->id 

Powinno być jasne, że teraz to po prostu nie jest poprawna składnia. Należy zamiast pisać

students[index].id 

co jest równoważne

(*(students + index)).id 

To naprawdę oznacza: jesteś zwiększając wskaźnik zwani studenci indeksem * sizeof (student) bajtów pamięci, a dostęp do jego pola id .

+2

Wrzuć (studenci + indeks) -> id, aby ukryć jedyną pominiętą opcję. – WhozCraig