++i
увеличит значение i
, и затем возвратит увеличенное значение.
i = 1;
j = ++i;
(i is 2, j is 2)
i++
увеличит значение i
, но возвратит исходное значение, которое i
содержало прежде чем быть увеличенным.
i = 1;
j = i++;
(i is 2, j is 1)
Для for
цикл, любой работы. ++i
кажется более распространенным, возможно, потому что, именно это используется в [1 114] K& R.
В любом случае, следуйте, инструкция "предпочитают ++i
[более чем 1 110]", и Вы не пойдете не так, как надо.
существует несколько комментариев относительно эффективности [1 111] и i++
. В любом non-student-project компиляторе не будет никакого различия в производительности. Можно проверить это путем рассмотрения сгенерированного кода, который будет идентичен.
вопрос об эффективности интересен..., вот моя попытка ответа: там различие в производительности между мной ++ и ++ я в C?
Как [1 116] На нотах Freund, это отличается для объекта C++, так как operator++()
функция, и компилятор не может знать для оптимизации далеко создания временного объекта для содержания промежуточного значения.
LoadLibrary и GetProcAddress будут вашими друзьями.
Также ознакомьтесь с в этом руководстве .
Да, вы всегда можете проверить на наличие функции в библиотеке во время выполнения и предпринять соответствующие действия. Проверьте API LoadLibrary и GetProcAddress. http://msdn.microsoft.com/en-us/library/ms683212 (VS.85) .aspx
Я считаю, что MSDN - ваш лучший выбор для этого. Каждая страница MSDN для документации по функциям содержит в конце раздел, в котором указано, какая версия Windows поддерживает эту функцию.
В качестве примера, проверьте документацию GetModuleHandle . Он содержит раздел с названием Требования , в котором есть поле Минимальный поддерживаемый клиент и Минимальный поддерживаемый сервер .
Однако, если вы хотите проверить наличие существование функций динамически, то вы можете сделать это с помощью LoadLibrary и GetProcAddress .
вы должны использовать LoadLibrary и GetProcAddress для динамической загрузки и вызова новых функций.
Если вы хотите узнать во время компиляции, чтобы получить прерывание сборки, если функция недоступна в целевой ОС (например, Win 95), вы можете определить некоторые макросы , задокументировано здесь : NTDDI_VERSION, _WIN32_WINNT, WINVER.
Если вы хотите, чтобы ваше приложение работало нормально, когда функциональность недоступна (например, списки переходов в ОС старше Win7), вам следует использовать комбинацию LoadLibrary / GetProcAddress, чтобы выяснить, доступна ли функция, которую вы ищете.
Это зависит от типов функций.
Для простых (не COM) функций единственный способ - использовать LoadLibrary
и GetProcAddress
. Если один из них не работает, вы знаете, что в ОС отсутствует эта функция. Написание этих объявлений типа указателя функции для указателей функций, дублирующих существующие сигнатуры функций, может быть утомительным, хотя в VC ++ 2010 вы можете использовать для этого decltype
. Например:
HMODULE user32 = LoadLibraryW(L"user32");
if (user32 != NULL)
{
auto messageBoxW = reinterpret_cast<decltype(MessageBoxW)*>(GetProcAddress(user32, "MessageBoxW"));
if (messageBoxW != NULL)
{
messageBoxW(HWND_DESKTOP, L"Hello!", NULL, MB_OK);
}
}
Однако многие API-интерфейсы Shell доступны через COM-компоненты и интерфейсы. Это разные случаи. Иногда вам нужно иметь дело с совершенно новыми компонентами; например, IApplicationDestinations
- это новый интерфейс в Win7, и компонентный класс, который его реализует, также является новым. В таких случаях можно просто выполнить CoCreateInstance
, и проверьте возвращаемое значение для REGDB_E_CLASSNOTREG
- это означает, что такой компонентный класс не зарегистрирован в системе (и, по сути, не поддерживается).
Иногда, однако, новые версии ОС вводят новые интерфейсы на существующих коклассах. Примером является ITaskbarList3
, новый в Win7, но предоставленный в существующем компонентном классе, который реализует ITaskbarList
и восходит к Win95. В таких случаях вам следует сначала создать экземпляр компонентного класса для самого простого интерфейса, а затем использовать QueryInterface
для получения новых версий интерфейса и определить, что они не поддерживаются, проверив возвращаемое значение для E_NOINTERFACE
.
ITaskbarList3
, новый в Win7, но предоставленный в существующем компонентном классе, который реализует ITaskbarList
и восходит к Win95. В таких случаях вы должны сначала создать экземпляр компонентного класса для самого простого интерфейса, а затем использовать QueryInterface
для получения новых версий интерфейса и обнаружить, что они не поддерживаются, проверив возвращаемое значение для E_NOINTERFACE
. однако в новых версиях ОС вводятся новые интерфейсы для существующих компонентных классов. Примером является ITaskbarList3
, новый в Win7, но предоставленный в существующем компонентном классе, который реализует ITaskbarList
и восходит к Win95. В таких случаях вам следует сначала создать экземпляр компонентного класса для самого простого интерфейса, а затем использовать QueryInterface
для получения новых версий интерфейса и определить, что они не поддерживаются, проверив возвращаемое значение для E_NOINTERFACE
. Используйте LoadLibarary
, чтобы получить дескриптор библиотеки и GerProcAddress
для получения указателя на функцию. Для тех функций, которые не поддерживаются текущей ОС, вы получите ошибку ERROR_CALL_NOT_IMPLEMENTED
из GetLastError
.
Я не согласен с текущими решениями. В результате вы получите довольно много нечитаемого кода.
Более хорошая альтернатива - обернуть функциональность в пользовательскую DLL только для Windows 7. Для других систем предоставьте другую версию DLL, реализующую те же функции. Это часто может быть неработоспособным. Например, функция установки расширений панели задач не работает в старых версиях Windows.
Динамическое переключение между этими библиотеками DLL осуществляется с помощью функции отложенной загрузки MSVC. Вы можете использовать специальный перехватчик в вашем EXE-файле, чтобы выбрать правильную версию DLL при вызове первой функции в вашей DLL, и в этот момент вы знаете, работаете ли вы в Windows 7.