Найти конец массива, объявленного как тип структуры C ++ - PullRequest
0 голосов
/ 18 января 2020

Я недавно учился использовать тип данных struct в c ++. Я знаю, как работают основы struct типа данных и как манипулировать его переменными. Но мне было интересно, как мне определить конец массива struct datatype. Например, рассмотрим код ниже:

struct PersonDetails
{
    string name, address;
    int age, number;
}

Теперь в программе на C ++ я создаю массив типа структуры следующим образом:

PersonDetails Data[500];

Теперь рассмотрим, что у меня есть 30 записей в массиве данных и Я должен отобразить эти записи, просматривая индекс массива данных. Итак, как мне определить, что я должен l oop только через первые 30 индексов, поскольку данные хранятся только в этих индексах. Как и в массиве char, мы сравниваем все индексы с '\0', чтобы определить конец массива. Тогда какой метод мы будем использовать для Data[] массива?

Редактирование, о котором я понятия не имею, о векторах и проекте, над которым я работаю, требует от меня использования основ языка c ++ (функций, структур управления, циклов и т. Д.). c.).

Ответы [ 4 ]

3 голосов
/ 18 января 2020

Это невозможно.

Для char[], во времена стандартизации C, разработчики согласились использовать \0 (целочисленное значение 0) в качестве специального символа, обозначающего end -of-строка . Все работает, пока все следуют этому соглашению (т.е. и стандартные библиотечные функции, и разработчики, использующие эти функции).

Если вы хотите иметь такое соглашение для вашего типа, вы можете просто записать " Data объект с обеими пустыми строками и обоими целыми числами, равными 0, является терминатором массива", но вы должны будете следовать этому соглашению . Вам нужно написать функции, которые остановят обработку массива при обнаружении такого объекта. Вы должны убедиться, что в каждом массиве есть хотя бы один такой объект.

Вместо

Вы должны использовать std::vector<Data>, который может автоматически размещаться для любого количества Data объектов. и теперь будет точно, сколько из них хранится в данный момент (используя метод size())

или

использовать std::array<Data, 30>, который может хранить точно 30 объектов, и вы можете предположить, что все они являются действительными объектами.

0 голосов
/ 18 января 2020

Самое простое решение состоит в том, чтобы просто иметь отдельную переменную, указывающую, сколько элементов массива заполнено.

PersonDetails Data[500];
int numPersons = 0;

Data[0].name = ... ;
Data[0].address = ...;
Data[0].age = ...;
Data[0].number = ...;
numPersons = 1;

Data[1].name = ... ;
Data[1].address = ...;
Data[1].age = ...;
Data[1].number = ...;
numPersons = 2;

...

Затем вы используете эту переменную при циклическом просмотре массива.

for (int i = 0; i < numPersons; ++i)
{
    // use Data[i] as needed...
}
0 голосов
/ 18 января 2020

Я не совсем согласен, использование std::array не имеет никакого значения.

Проблема, с которой вы сейчас сталкиваетесь, не возникает в , есть ли у нас такой элемент в контейнере , но полезен ли проверяемый нами элемент.

Рассмотрим приведенный вами пример для массива char с. Мы просто проверяем, является ли один из элементов \0, чтобы решить, или нет, мы должны остановить итерацию.

Как это работает? Элементы ramaining, конечно, по умолчанию инициализируются как \0, они существуют , но бесполезны .

Аналогично, вы можете проверить, в этом примере

name.empty()

Или, чтобы избежать возможных исключений, как указано в разделе комментариев, сделайте следующее:

добавьте пользовательский конструктор в класс (или структуру, они на самом деле одинаковы.), которые инициализируют возраст до -1, а затем проверяют, если age == -1.

, потому что это невозможно для людей, не имеющих никакого имени, то есть вы не присваиваете ни одному из оставшихся элементов , Таким образом, остановите итерацию.

В качестве дополнения, использование std::vector имеет смысл, но если это пока не вариант для вас, вам не нужно это учитывать.

0 голосов
/ 18 января 2020

ИМХО правильный способ решить эту проблему состоит в том, чтобы не использовать массив C в стиле, а вместо этого использовать std::array или std::vector, который знает это .size().

Повторение std::vector или std::array тривиально:

for (const auto& element : Data_array) {
    // Do something with the array element
}

См. Также:

https://en.cppreference.com/w/cpp/container/array

https://en.cppreference.com/w/cpp/container/vector

https://en.cppreference.com/w/cpp/language/for

https://en.cppreference.com/w/cpp/language/range-for

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...