Как работать с элементами динамического массива из функции?
И Тааак
Начнём...
(Если лень читать описание или Вы сеньор прогер - сразу см внизу: "САМ ВОПРОС" и "ДОП ВОПРОС")
Есть структура:
struct People {
char name;
int score;
};
В мейне инициализируется массив n таких структур (указатель на такой массив):
People *EsFP = new People[n];
Далее он заполняется значениями из файла:
for (unsigned int i = 0; i < n; i++) {
fscanf_s(fp, "%s %d", EsFP[i].name, 32, &EsFP[i].score))
}
Далее необходимо отредачить (в данном случае - перемешать) элементы массива через функцию и я это реализовал так:
void Fisher_Yates_shuffle(int n, People* EsFP[]) {
People* a;
People* b;
for (int i = n - 1; i >= 1; i--) //(начинаем с последнего элемента, заканчиваем первым)
{
a = EsFP[0] + i; //теперь а указывает на EsFP[i]
int j = rand()%(n+1); //выбираем рандомный индекс элемента, с которым поменяем EsFP[i]
b = EsFP[0] + j; //теперь b указывает на EsFP[i]
People_swap(a, b); //функция свапа двух элементов массива структур People
}
}
САМ ВОПРОС: строчки
a = EsFP[0] + i; и b = EsFP[0] + j;
вообще адекватны? Всм. нельзя ли чего-то более простого? Типа неработающего EsFP[i] и EsFP[j]?
Функция People_swap() (на всякий пожарный):
void People_swap(People* a, People* b){
People temp = *a;
strcpy_s(a->name,b->name);
a->score = b->score;
strcpy_s(b->name, temp.name);
b->score = temp.score;
}
ДОП ВОПРОС: сама идея реализации такой функции тоже смущает) было бы неплохо обойтись и без неё. Но можно ли?
Во-первых, исправьте, пожалуйста, объявление struct People: первое поле (name) имеет тип char, а это всего один символ. А ниже Вы считываете из файла строку именно в это поле.
Во-вторых, лучше объявить тип «указатель на People» и сделать переменную EsFP массивом из таких указателей, тогда перемешивание затронет только адреса данных, но сами данные не придётся тягать из одного места в памяти в другое место в той же памяти.
А если Вы сомневаетесь насчёт функции People_swap, то можете вписать перед заголовком этой функции ключевое слово «inline» и не придавать значения. Пускай компилятор решает, нужна функция или не нужна.
Обратите внимание: хотя переменная EsFP объявлена как указатель на People, но применение к ней квадратных скобок фактически разыменовывает этот указатель. Таким образом, EsFP[0] — это уже не адрес, а значение. a = EsFP[0] + i и b = EsFP[0] + j будут работать, но не так, как Вы задумали. Возможно, Вы имели ввиду: a = EsFP + i и b = EsFP + j.
1.Работа с динамическими массивами в С++ ничем не отличается от работы с обычными. Синтаксис - тот же самый. Потому что и статический, и динамический массив - это по сути адрес начального элемента. Поэтому в фунцию надо передать просто People*EsFP
2.Переставлять элементы массива копированием - это ламерство. За это в любой серьезной конторе надают по рукам. Правильное решение - переставлять индексы элементов.