что происходит, когда Вы изменяете элемент станд.:: набор?

Глобальные переменные необходимы в небольшом встроенном приложении, написанном на C. Например, вам нужно использовать глобальную переменную для передачи информации между подпрограммой обработки прерываний и другим модулем. Вот несколько советов, которые помогут вам эффективно использовать глобальные переменные во встроенных приложениях:

  • Различайте статические переменные и глобальные переменные. Статические переменные могут использоваться из всех функций в одном и том же C-файле. Они являются эквивалентом закрытых членов в классе C ++. В Си вы должны выполнять работу компилятора самостоятельно. Используйте ключевое слово static, чтобы избежать случайного использования переменной за пределами модуля и сделать ее видимой. Возможно, вы захотите добавить префикс к имени модуля.

  • Следуйте соглашению об именовании глобальных переменных (используется многими C-файлами). Сделайте ясно, что они глобальны.

  • Если вам нужно много глобальных переменных, рассмотрите возможность их объединения в структуру.

  • Используйте ключевое слово volatile, когда это необходимо. Это необходимо, если глобальная переменная изменена ISR.

12
задан Lightness Races with Monica 1 February 2012 в 14:35
поделиться

3 ответа

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

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

Почему это довольно легко понять. Реализация set не будет знать, что вы изменили значение за ее спиной. Обычная реализация - это красно-черное дерево. После изменения значения позиция в дереве для этого экземпляра будет неправильной. Вы ожидаете увидеть всевозможные неправильные поведения, такие как существует запросов, возвращающих неправильный результат из-за того, что поиск идет по неправильной ветви дерева.

24
ответ дан 2 December 2019 в 04:34
поделиться

Точный ответ зависит от платформы, но, как правило, «ключ» (то, что вы добавляете в набор или первый тип карты), должен быть "неизменный". Проще говоря, это не должно быть изменено, и не существует такой вещи, как автоматическая повторная вставка.

Точнее, переменные-члены , используемые для сравнения ключа, не должны изменяться.

1241] Компилятор Windows vc довольно гибкий (протестирован с VC8), и этот код компилируется:

// creation
std::set<int> toto;
toto.insert(4);
toto.insert(40);
toto.insert(25);

// bad modif
(*toto.begin())=100;

// output
for(std::set<int>::iterator it = toto.begin(); it != toto.end(); ++it)
{
    std::cout<<*it<<" ";
}
std::cout<<std::endl;

Результат: 100 25 40 , Тем не менее, такое поведение полезно, если вы хотите изменить данные, не участвующие в операторе <. Но вам лучше знать, что вы делаете: это цена, которую вы получаете за чрезмерную гибкость.

Некоторые могут предпочесть поведение gcc (проверено с помощью 3.4.4), которое дает ошибку «назначение местоположения только для чтения». Вы можете обойти это с помощью const_cast:

const_cast<int&>(*toto.begin())=100;

Теперь он также компилируется на gcc, тот же результат: 100 25 40 . Но, по крайней мере, это, вероятно, заставит вас задуматься о том, что происходит, затем перейдите к переполнению стека и посмотрите эту ветку: -)

5
ответ дан 2 December 2019 в 04:34
поделиться

Вы не можете этого сделать; они const . Не существует метода, с помощью которого набор set может обнаружить, что вы вносите изменения во внутренний элемент, и, как результат, вы не можете этого сделать. Вместо этого вам нужно удалить и снова вставить элемент. Если вы используете элементы, копирование которых дорого, возможно, вам придется переключиться на использование указателей и настраиваемых компараторов (или переключиться на компилятор C ++ 1x, который поддерживает ссылки rvalue, что сделало бы все намного лучше).

4
ответ дан 2 December 2019 в 04:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: