Итак, я программировал для своего Arduino, который является вариантом C ++. Я написал программу, чтобы отмечать каждое число на 4-значном семисегментном дисплее. У меня возникли проблемы с установкой контактов [] на разные массивы разной длины.

Например, отображение одного означает, что 2 контакта будут включены, что выражается в массиве int one[] = {1,2};, а отображение четырех занимает четыре контакта int four[] = {1,2,3,4};.

Я пробовал:

int pins[] = null;
int one[] = {1,2};
int four[] = {1,2,3,4};
switch(num) {
    case 1: pins = one; break;
    case 4: pins = four; break;
}

Однако это вызывает проблемы и не позволяет мне загружать его, потому что везде просто ломается.

У меня ограниченные знания о C ++, только то, что он похож на Java, о которой я знаю довольно много.

Я чувствую, что кормлю акул с недостаточной защитой, и этот бит в моем коде меня беспокоит.

У меня вопрос: как инициализировать массив, а потом изменить его?

1
TheBrenny 3 Авг 2014 в 06:02
Проблема с использованием массива заданного размера заключается в том, что если вам нужно изменить его текущий размер, вам придется скопировать все элементы из предыдущего массива в новый массив. Чтобы избежать копирования массива, вы должны использовать достаточно большой массив, скажем, размером 1000, если это не проблема. Однако у вас может возникнуть проблема с эффективностью при попытке обойти весь массив, часть которого пуста. Однако вы можете использовать векторы. С векторами или списком вам не нужно знать их размер при создании. Вы просто создаете вектор, а затем добавляете к нему элементы по ходу дела.
 – 
Juniar
3 Авг 2014 в 07:03
Проблема в том, что даже с массивом размера 7 (количество сегментов и максимальное количество контактов одновременно (цифровые часы 8)) я все еще не могу переназначить, потому что размер 2 несовместим с размером 7. И из-за по моему ограниченному знанию варианта-c, я не знаю, как составлять списки, и я чувствую, что они будут потреблять больше энергии от чипа arduino по сравнению с ранее упомянутым указателем. Но спасибо за ответ. Мои знания варианта-c растут!
 – 
TheBrenny
3 Авг 2014 в 07:13
1
Существует несколько структур данных, таких как: векторы, список, связанный список и карты. Все эти структуры данных были созданы с одной и той же проблемой, которую вы имеете в виду. Использовать вектор очень просто, просто создайте вектор, а затем добавьте к нему элементы. Хорошая часть заключается в том, что он поставляется с функциями, которые позволяют вам получать доступ к элементам или просматривать все данные, и вам не нужно беспокоиться об изменении их размера.
 – 
Juniar
3 Авг 2014 в 07:31
Часть «не нужно беспокоиться» не соответствует действительности на платформе с ограниченными ресурсами, такой как Arduino. Ближе к истине то, что использование любой из коллекций с автоматическим изменением размера — это план на автоматический сбой. Может ли голосующий прокомментировать, насколько, по их мнению, этот комментарий был полезным советом?
 – 
jdr5ca
5 Авг 2014 в 07:18
Хотя этот вопрос был создан специально для Arduino, информация, представленная в комментарии, была мне полезна, так как я очень хочу изучить вариант-c в ближайшее время, когда у меня будет время. Я нашел, что комментарий был полезен.
 – 
TheBrenny
5 Авг 2014 в 09:32

2 ответа

Лучший ответ

Как написано, это не скомпилируется, потому что pins не имеет определенного размера и присвоение массива другому массиву другого размера не допускается. Однако вы можете использовать указатель на массив, чтобы добиться того, что вы пытаетесь сделать:

int one[] = {1,2};
int four[] = {1,2,3,4};
int* pins = nullptr; // use NULL if your compiler doesn't support C++11.
size_t pinslen = 0;

switch (num) {
case 1:
    pins = one;
    pinslen = sizeof one;
    break;
case 4:
    pins = four;
    pinslen = sizeof four;
    break;
}
5
user3553031 3 Авг 2014 в 08:46
pins — это не указатель на массив, а просто указатель на int. Он указывает на адрес первого элемента одного из этих двух массивов.
 – 
David G
3 Авг 2014 в 06:19
Да, в C/C++ указатель на int такой же, как указатель на массив int. Код правильный. С помощью указателя доступ к элементам массива осуществляется с помощью синтаксиса массива, например: y = pins[3]; Этот пример демонстрирует опасность: если pins = четыре, то pins[3] в порядке, если pins = one, то pins[3 ] делает что-то не так.
 – 
jdr5ca
3 Авг 2014 в 06:34
1
@ jdr5ca, но pinslen решает эту проблему? for(int i = 0; i < pinslen; i++); правильно?
 – 
TheBrenny
3 Авг 2014 в 07:18
Итак, немного погуглив и поработав, я обнаружил, что int* pins = nullptr; не работает. Однако int *pins = 0; сделал... Это странно. Я набирал последний много раз, но он работает только сейчас. Что ж, это работает, возможно, обновите свой ответ, и я снова отмечу его.
 – 
TheBrenny
3 Авг 2014 в 08:44
Возможно, ваш компилятор еще не поддерживает C++11. nullptr — это новое дополнение к C++.
 – 
user3553031
3 Авг 2014 в 08:45

int one[] = {1,2};, int four[] = {1,2,3,4}; не одного типа, у нас есть int one[2] и int four[4]. Они оба могут распасться до int*, но вы теряете информацию о размере и должны оставить размер самостоятельно.

Есть возможность использовать std::vector следующим образом:

std::vector<int> one = {1, 2};
std::vector<int> four = {1, 2, 3, 4};
std::vector<int>* pins = nullptr;
switch (num) {
    case 1: pins = &one; break;
    case 4: pins = &four; break;
}

А для C ++ 03:

const int c_one[] = {1, 2};
const int c_four[] = {1, 2, 3, 4};
std::vector<int> one(c_one, c_one + 2);
std::vector<int> four(c_four, c_four + 4);
std::vector<int>* pins = 0;// or NULL
switch (num) {
    case 1: pins = &one; break;
    case 4: pins = &four; break;
}

В качестве альтернативы вы можете скопировать контакты и не использовать указатель, например:

const int one[] = {1, 2};
const int four[] = {1, 2, 3, 4};
std::vector<int> pins;
switch (num) {
    case 1: pins.assign(one, one + 2); break;
    case 4: pins.assign(four, four + 4); break;
}
1
Jarod42 3 Авг 2014 в 12:07
Как я уже упоминал ранее в комментарии, я не на 100% уверен в варианте-c, даже близко не на 20%. Я хотел ответить на основные вопросы, и предыдущий ответ оказался самым полезным. Однако ваш ответ по-прежнему является подспорьем, на котором другие могут учиться.
 – 
TheBrenny
3 Авг 2014 в 11:57