Dynamiczna tablica struktur

0

Napisałem taki krótki program, jest on już po poprawkach:

#include <iostream>

int main () {
	
	int database_size;
	struct people {
	char name[20];
	char surname[20];
	int mark;
	int age;
	};
	
	std::cout << "How many people in database: ";
	std::cin >> database_size;
	std::cin.sync();
	
	people *person = new people [database_size];
	
	for (int i=0; i<database_size; i++) {
		std::cout << "What is your name: ";
		std::cin.getline(person[i].name,20);
		
		std::cout << "What is your surname: ";
		std::cin.getline(person[i].surname,20);
		
		std::cout << "What mark deserve you: ";
		std::cin >> person[i].mark;
		
		std::cout << "How old are you: ";
		std::cin >> person[i].age;
		 
	}
	
	
	for (int j=0; j<database_size; j++) {
		std::cout << "Surname: " << (person[j]).surname;
		std::cout << ", " << (person[j]).name;
		std::cout << "\nMark: " << (person[j]).mark;
		std::cout << "\nAge: " << (person[j]).age;
		
	}
}
 

Problem polega na tym, że nie rozumiem dlaczego działa. Stworzyłem dynamiczną tablicę struktur. W ksiażce "Język C++. Szkoła Programowania" Stephena Prata jest takie zdanie: "Jeśli tworzymy strukturę dynamiczną, nie możemy użyć operatora "kropka" z nazwą struktury, gdyż struktura nie ma nazwy, a jedynie adres"
W związku z powyższym początkowo napisałem powyższy program tak:

std::cout << "What is your name: ";
std::cin.getline(person[i]->name,20);

to spowodowało błąd:

[Error] base operand of '->' has non-pointer type 'main()::people'

Ponadto chciałem jeszcze w inny sposób się odwołać do pól struktur, mianowicie:

 std::cout << "\nMark: " << *(person[j]).mark;

to z kolei wygenerowało błąd

[Error] invalid type argument of unary '*' (have 'int')

Rozumiem, że tablica struktur nie jest strukturą, aczkolwiek tak na chłopski rozum, jest to zbór struktur, więc starałem się robić analogicznie jak dla pojedynczej struktury.

0

W C (i w dużej mierze w C++) zapis a[b] jest równoznaczny z *(a+b) (co implikuje również b[a]). Ponieważ dokonujesz dereferencji, nie możesz czynić tego ponownie.

Btw: zamiast uczyć się new i delete, zacznij od użycia std::vector

2

Musisz zrozumieć jaki typ mają poszczególne zapisy.
person to wskaźnik do tablicy obiektów
person[i] to konkretny element w tej tablicy obiektów, czyli jeden obiekt, dlatego używasz kropki

Gdybyś miał wskaźnik do tablicy wskaźników

people** person = new people*[database_size];
person[0] = new people;

no to wtedy będziesz mógł używać zapisu person[0]->name.

1
mlp99 napisał(a):

W ksiażce "Język C++. Szkoła Programowania" Stephena Prata jest takie zdanie: "Jeśli tworzymy strukturę dynamiczną, nie możemy użyć operatora "kropka" z nazwą struktury, gdyż struktura nie ma nazwy, a jedynie adres"

Tak na chłopski rozum. W tym zdaniu mowa o dynamicznej strukturze czyli people *foo = new people; Ty zaś tworzysz dynamiczną tablicę, która przechowuje konkretne obiekty a nie wskaźniki. Najłatwiej to zrozumieć używają wektora

std::vector<people> foo = {...};
foo[0].name;
 
std::vector<people*> bar = {new ...};
bar[0]->name;

edit
@twonek wyjaśnił to bardziej poprawnie niż ja.

edit2&3 literówki

2

Oczywiście każdy używa takich nazw jakie mu się podobąją, ale struct people sugeruje, że struktura zawiera dane wielu osób, a wskaźnik people* person to już w ogóle niezła zagadka ;)

Powinno być odwrotnie.

0

Poza tym co napisano wyżej - podstawowa zasada, jak "ręcznie" bierzesz pamięć, to i ręcznie musisz ją zwolnić...

1 użytkowników online, w tym zalogowanych: 0, gości: 1