Глобальные переменные необходимы в небольшом встроенном приложении, написанном на C. Например, вам нужно использовать глобальную переменную для передачи информации между подпрограммой обработки прерываний и другим модулем. Вот несколько советов, которые помогут вам эффективно использовать глобальные переменные во встроенных приложениях:
Различайте статические переменные и глобальные переменные. Статические переменные могут использоваться из всех функций в одном и том же C-файле. Они являются эквивалентом закрытых членов в классе C ++. В Си вы должны выполнять работу компилятора самостоятельно. Используйте ключевое слово static, чтобы избежать случайного использования переменной за пределами модуля и сделать ее видимой. Возможно, вы захотите добавить префикс к имени модуля.
Следуйте соглашению об именовании глобальных переменных (используется многими C-файлами). Сделайте ясно, что они глобальны.
Если вам нужно много глобальных переменных, рассмотрите возможность их объединения в структуру.
Используйте ключевое слово volatile, когда это необходимо. Это необходимо, если глобальная переменная изменена ISR.
Вы не должны редактировать значения, хранящиеся в наборе напрямую. Я скопировал это из документации MSDN, которая в некоторой степени авторитетна:
Используется набор классов контейнера STL. для хранения и поиска данных из коллекции, в которой значения из содержащихся элементов уникальны и служат ключевыми ценностями согласно к которому данные автоматически приказал. Значение элемента в набор не может быть изменен напрямую. Вместо этого вы должны удалить старые значения и вставлять элементы с новыми значениями.
Почему это довольно легко понять. Реализация set
не будет знать, что вы изменили значение за ее спиной. Обычная реализация - это красно-черное дерево. После изменения значения позиция в дереве для этого экземпляра будет неправильной. Вы ожидаете увидеть всевозможные неправильные поведения, такие как существует
запросов, возвращающих неправильный результат из-за того, что поиск идет по неправильной ветви дерева.
Точный ответ зависит от платформы, но, как правило, «ключ» (то, что вы добавляете в набор или первый тип карты), должен быть "неизменный". Проще говоря, это не должно быть изменено, и не существует такой вещи, как автоматическая повторная вставка.
Точнее, переменные-члены , используемые для сравнения ключа, не должны изменяться.
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 . Но, по крайней мере, это, вероятно, заставит вас задуматься о том, что происходит, затем перейдите к переполнению стека и посмотрите эту ветку: -)
Вы не можете этого сделать; они const
. Не существует метода, с помощью которого набор set
может обнаружить, что вы вносите изменения во внутренний элемент, и, как результат, вы не можете этого сделать. Вместо этого вам нужно удалить и снова вставить элемент. Если вы используете элементы, копирование которых дорого, возможно, вам придется переключиться на использование указателей и настраиваемых компараторов (или переключиться на компилятор C ++ 1x, который поддерживает ссылки rvalue, что сделало бы все намного лучше).