В чем разница между tmain() и main() в C?

Если я запускаю свое приложение C++ со следующим методом main (), все в порядке:

Я получаю то, что ожидаю, и мои аргументы распечатываются.

однако, если я использую имя _tmain:

Он просто отображает первый символ каждого аргумента.

какая разница причина?

5 ответов

_tmain не существует в C++. main делает.

_tmain является расширением Microsoft.

main является, согласно стандарту C++, точкой входа программы. Он имеет одну из этих двух подписей:

Microsoft добавила wmain, который заменяет вторую подпись следующим:

и затем, чтобы упростить переключение между Unicode (UTF-16) и их многобайтовым набором символов, они определили _tmain который, если Unicode включен, компилируется как wmain , и иначе как main .

что касается второй части вашего вопроса, первая часть головоломки заключается в том, что ваша главная функция-это неправильно. wmain стоит взять wchar_t аргумент, а не char . Поскольку компилятор не применяет это для main функция, вы получаете программу, где массив wchar_t строки передают main функция, которая интерпретирует их как char строки.

сейчас, в UTF-16, набор символов, используемый Windows, когда Unicode включен, все символы ASCII представлены в виде пары байтов с последующим значением ASCII.

и так как процессор x86 мало-endian, порядок этих байтов меняются местами, так что значение ASCII приходит первым, а затем следует нулевой байт.

и в строке char, как обычно заканчивается строка? Да, нулевым байтом. Таким образом, ваша программа видит кучу строк, каждый байт длинный.

в общем, у вас есть три варианта при программировании Windows:

  • явно используйте Unicode (вызов wmain, и для каждой функции Windows API, которая принимает аргументы, связанные с char, вызовите -W версия функции. Вместо CreateWindow вызовите CreateWindowW). И вместо использования char использовать wchar_t и так далее
  • явно отключить Unicode. Вызовите main и CreateWindowA и используйте char для веревка.
  • разрешить. (вызовите _tmain и CreateWindow, которые разрешают main/_tmain и CreateWindowA / CreateWindowW) и используйте TCHAR вместо char / wchar_t.

то же самое относится к строковым типам, определенным windows.ч: Lpctstr разрешается в LPCSTR или LPCWSTR, и для каждого другого типа, который включает char или wchar_t, всегда существует A-T — версия, которую можно использовать вместо этого.

обратите внимание, что все это специфично для Microsoft. TCHAR не является стандартный тип C++, это макрос, определенный в Windows.h. wmain и _tmain также определяются только Microsoft.

_tmain-это макрос, который переопределяется в зависимости от того, компилируете ли вы Unicode или ASCII. Это расширение Microsoft и не гарантируется для работы с любыми другими компиляторами.

если макрос UNICODE определен, это расширяется до

в противном случае он расширяется до

ваше определение идет для Немного каждого, и (если вы определили UNICODE) будет расширяться до

это просто неправильно.

std:: cout работает с символами ASCII. Вам нужен std:: wcout, если вы используете широкие символы.

попробуйте что-то вроде этого

или вы можете просто заранее решить, использовать ли широкие или узкие символы. 🙂

Обновлено 12 Ноября 2013:

изменен традиционный » TCHAR «на» _TCHAR», который, кажется, является последней модой. Обе работы штраф.

Обновления

соглашение _T используется для указания, что программа должна использовать набор символов, определенный для приложения (Unicode, ASCII,MBCS и т. д.). Вы можете окружить свои строки _T (), чтобы они хранились в правильном формате.

Ok, на вопрос, похоже, ответили довольно хорошо, перегрузка UNICODE должна принимать широкий массив символов в качестве второго параметра. Поэтому, если параметр командной строки «Hello» Это, вероятно, закончится как «H e l l o » и ваша программа будет печатать только в ‘H’ прежде чем он увидит, что он думает, является нулевым Терминатором.

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

Ну, он компилируется, потому что вам разрешено определять перегрузку функции.

связывание-немного более сложная проблема. В C нет информации о украшенном символе, поэтому он просто находит функцию main. Argc и argv, вероятно, всегда существуют как параметры стека вызовов на всякий случай, даже если ваша функция определена с этой сигнатурой, даже если ваша функция игнорирует их.

хотя C++ имеет украшенные символы, он почти наверняка использует C-linkage для main, а не умный компоновщик, который ищет каждый по очереди. Таким образом, он нашел ваш wmain и поместил параметры в стек вызовов, если это int wmain(int, wchar_t*[]) версия.

Создание своего Windows Service

Я решил провести один эксперимент, суть его пока не могу разглашать, но по результатам обязательно опишу его))) Для этого эксперимента, мне нужно написать приложение которое работает как сервис в Windows.

Думаю описывать как создавать обычный Win32 Console Application проект в Visual Studio нет надобности )))

С чего начинается сервис?

int _tmain( int argc, _TCHAR* argv[]) <
SERVICE_TABLE_ENTRY ServiceTable[1];
ServiceTable[0].lpServiceName = serviceName;
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

SERVICE_TABLE_ENTRY это структура, которая описывает точку входа для сервис менеджера, в данном случаи вход будет происходить через ф-цию ServiceMain. Функция StartServiceCtrlDispatcher собственно связывает наш сервис с SCM (Service Control Manager)

Точка входа сервиса

SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;

void ServiceMain( int argc, char ** argv) <
int error;
int i = 0;

serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwCurrentState = SERVICE_START_PENDING;
serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwServiceSpecificExitCode = 0;
serviceStatus.dwCheckPoint = 0;
serviceStatus.dwWaitHint = 0;

serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, (LPHANDLER_FUNCTION)ControlHandler);
if (serviceStatusHandle == (SERVICE_STATUS_HANDLE)0) <
return ;
>

error = InitService();
if (error) <
serviceStatus.dwCurrentState = SERVICE_STOPPED;
serviceStatus.dwWin32ExitCode = -1;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
return ;
>

serviceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (serviceStatusHandle, &serviceStatus);

while (serviceStatus.dwCurrentState == SERVICE_RUNNING)
<
char buffer[255];
sprintf_s(buffer, «%u» , i);
int result = addLogMessage(buffer);
if (result) <
serviceStatus.dwCurrentState = SERVICE_STOPPED;
serviceStatus.dwWin32ExitCode = -1;
SetServiceStatus(serviceStatusHandle, &serviceStatus);
return ;
>
i++;
>

void ControlHandler(DWORD request) <
switch (request)
<
case SERVICE_CONTROL_STOP:
addLogMessage( «Stopped.» );

serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (serviceStatusHandle, &serviceStatus);
return ;

case SERVICE_CONTROL_SHUTDOWN:
addLogMessage( «Shutdown.» );

serviceStatus.dwWin32ExitCode = 0;
serviceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (serviceStatusHandle, &serviceStatus);
return ;

ControlHandler вызывается каждый раз, как SCM шлет запросы на изменения состояния сервиса. В основном ее используют для описания корректной завершении работа сервиса.

Установка сервиса

sc create SampleService binpath= c:SampleService.exe

if (argc — 1 == 0) <
SERVICE_TABLE_ENTRY ServiceTable[1];
ServiceTable[0].lpServiceName = serviceName;
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

if (!StartServiceCtrlDispatcher(ServiceTable)) <
addLogMessage( «Error: StartServiceCtrlDispatcher» );
>
> else if ( wcscmp(argv[argc-1], _T( «install» )) == 0) <
InstallService();
> else if ( wcscmp(argv[argc-1], _T( «remove» )) == 0) <
RemoveService();
> else if ( wcscmp(argv[argc-1], _T( «start» )) == 0 ) <
StartService();
>
>

int InstallService() <
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (!hSCManager) <
addLogMessage( «Error: Can’t open Service Control Manager» );
return -1;
>

SC_HANDLE hService = CreateService(
hSCManager,
serviceName,
serviceName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
servicePath,
NULL, NULL, NULL, NULL, NULL
);

if (!hService) <
int err = GetLastError();
switch (err) <
case ERROR_ACCESS_DENIED:
addLogMessage( «Error: ERROR_ACCESS_DENIED» );
break ;
case ERROR_CIRCULAR_DEPENDENCY:
addLogMessage( «Error: ERROR_CIRCULAR_DEPENDENCY» );
break ;
case ERROR_DUPLICATE_SERVICE_NAME:
addLogMessage( «Error: ERROR_DUPLICATE_SERVICE_NAME» );
break ;
case ERROR_INVALID_HANDLE:
addLogMessage( «Error: ERROR_INVALID_HANDLE» );
break ;
case ERROR_INVALID_NAME:
addLogMessage( «Error: ERROR_INVALID_NAME» );
break ;
case ERROR_INVALID_PARAMETER:
addLogMessage( «Error: ERROR_INVALID_PARAMETER» );
break ;
case ERROR_INVALID_SERVICE_ACCOUNT:
addLogMessage( «Error: ERROR_INVALID_SERVICE_ACCOUNT» );
break ;
case ERROR_SERVICE_EXISTS:
addLogMessage( «Error: ERROR_SERVICE_EXISTS» );
break ;
default :
addLogMessage( «Error: Undefined» );
>
CloseServiceHandle(hSCManager);
return -1;
>
CloseServiceHandle(hService);

CloseServiceHandle(hSCManager);
addLogMessage( «Success install service!» );
return 0;
>

int RemoveService() <
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (!hSCManager) <
addLogMessage( «Error: Can’t open Service Control Manager» );
return -1;
>
SC_HANDLE hService = OpenService(hSCManager, serviceName, SERVICE_STOP | DELETE);
if (!hService) <
addLogMessage( «Error: Can’t remove service» );
CloseServiceHandle(hSCManager);
return -1;
>

DeleteService(hService);
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
addLogMessage( «Success remove service!» );
return 0;
>

int StartService() <
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
SC_HANDLE hService = OpenService(hSCManager, serviceName, SERVICE_START);
if (!StartService(hService, 0, NULL)) <
CloseServiceHandle(hSCManager);
addLogMessage( «Error: Can’t start service» );
return -1;
>

CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return 0;
>

SampleService.exe install
SampleService.exe remove
SampleService.exe start

Продолжение следует, если все не забракуют 🙂

BestProg

Классы и массивы. Указатель на статический член данных класса. Массивы статических членов данных. Массивы указателей на статические члены данных, которые объявлены в классах. Примеры

Содержание

  • 1. Как объявить указатель на статический член данных класса? Пример
  • 2. Пример использования массива, элементами которого есть статические члены данных класса
  • 3. Пример использования массива, элементами которого есть указатели на статические члены данных класса
  • 4. Чему равно значение статического члена, если его не инициализировать?
  • Связанные темы

Поиск на других ресурсах:

1. Как объявить указатель на статический член данных класса? Пример

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

Последовательность шагов следующая:

  • объявить класс со статическим членом;
  • описать статический член данных класса за пределами класса и инициализировать его при необходимости;
  • в некотором методе или за пределами всех методов (глобальный указатель) описать указатель на тип, который имеет статический член данных класса;
  • описать объект класса со статическим членом класса;
  • присвоить указателю адрес статического члена данных объекта класса.

Пример. В примере объявляется класс CPi со статическим членом данных Pi . Также объявляется несколько статических членов, которые не являются членами класса.
В функции _tmain() демонстрируется использование указателей на объявленные статические члены данных.

2. Пример использования массива, элементами которого есть статические члены данных класса

Заданы 3 класса с именами CCounter1 , CCounter2 , CCounter3 . В каждом классе реализован один статический член данных соответственно с именем counter1 , counter2 , counter3 .

Поскольку, в классах есть статические члены данных, то их соответствующим образом можно инициализировать. Также в примере объявляется глобальный массив с именем arCount1[] , который инициализирован статическими членами данных классов CCounter1 , CCounter2 , CCounter3 .

Листинг объявления классов и инициализации статических членов следующий:

Ниже продемонстрировано использование глобального массива arCount1[] и локального массива arCount2[] , объявленного непосредственно в функции _tmain() для консольных приложений:

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

В данном примере по образцу предшествующего примера (п.2) объявляется 3 класса с именами CCounter1 , CCounter2 , CCounter3 . В этих классах объявляется по одному статическому члену данных соответственно с именами counter1 , counter2 , counter3 , которые по отдельности инициализируются начальными значениями.
Пример демонстрирует объявление и использование массивов указателей arPCount1 и arPCount2 на статические члены данных, которые являются членами данных некоторого класса.

Листинг объявления классов, статических членов данных и массива указателей имеет следующий вид:

Демонстрация использования массива указателей в функции _tmain()

4. Чему равно значение статического члена, если его не инициализировать?

Если статический член не инициализирован, то устанавливается значение по умолчанию:

  • для числовых типов ( int , float , double …) значение неинициализированного статического члена равно 0;
  • для типа char значение неинициализированного статического члена равно символу с кодом 0.
  • для типа bool значение равное false , что также соответствует значению 0.

Программирование на C, C# и Java

Уроки программирования, алгоритмы, статьи, исходники, примеры программ и полезные советы

ОСТОРОЖНО МОШЕННИКИ! В последнее время в социальных сетях участились случаи предложения помощи в написании программ от лиц, прикрывающихся сайтом vscode.ru. Мы никогда не пишем первыми и не размещаем никакие материалы в посторонних группах ВК. Для связи с нами используйте исключительно эти контакты: vscoderu@yandex.ru, https://vk.com/vscode

Как включить русский язык в Си

На начальных этапах программирования многие новички сталкиваются с такой проблемой: они в коде пишут какое-либо сообщение на русском языке для консоли (например, используя printf), но при запуске программы вместо русских слов появляются какие-то непонятные знаки. Покажем, как избавиться от этой проблемы.

Например, при запуске вот этой программы:

В консоли будет отображено следующее:

Всё дело в том, что мы не подключили русскую локализацию.

Исправить эту ошибку очень легко!

Для начала надо добавить следующую библиотеку:

Она отвечает за локализацию.

А затем нам надо просто написать в начале тела кода вот эту строку:

Функция setlocale задаёт локализацию программы. По умолчанию это только английский язык.
LC_ALL указывает программе, что локализированы будут все функции.

“Rus”, как легко догадаться говорит о том, что локализация произойдёт на русский язык.

Вот и всё! Мы включили русский язык в Си. Наша программа модернизирована и обогащена на две строки. Теперь она будет выглядеть вот так:

А консоль вот так:

Поделиться в соц. сетях:

  • ← Если не работает карта сайта на WordPress
  • Дата и время в C# →

15 комментария(ев) к статье “ Как включить русский язык в Си ”

  1. Элиша 31.10.2016 в 20:03
  1. admin31.10.2016 в 23:27

Что именно? Какая ошибка?

Можете попробовать такой код:

#include
#include
#include

int main()
<
setlocale(LC_ALL, “Rus”);
printf(“Всем привет! Как дела?”);
getch(); //В Visual Studio _getch();
return 0;
>

  1. Имя 10.01.2017 в 07:59

Этот вариант работает, но он не включает русский язык в стандартном потоке ошибок.

Вместо одних каракулей появились другие. Но никаких ошибок не выдает.

  1. admin08.11.2016 в 16:28

Здравствуйте, Евгений. Существует ещё один способ включения русского языка в Си. Попробуйте использовать следующий код:

#include
#include
#include

int main()
<
SetConsoleCP(1251); //установка кодовой страницы win-cp 1251 в поток ввода
SetConsoleOutputCP(1251); //установка кодовой страницы win-cp 1251 в поток вывода
printf(“Всем привет! Как дела?”);
_getch();
return 0;
>

Здравствуйте, использовала такой метод как в статье.
Все работает при выводе текста функцией printf.
Но, когда я считываю слово функцией scanf, а потом вывожу его функцией printf появляются снова непонятные символы.
Подскажите пожалуйста как это можно исправить.

  1. admin06.01.2017 в 00:58

Здравствуйте! Чуть выше в комментариях приводятся ещё два способа, как включить русский язык в Си. Попробуйте их, должно сработать.

  1. Анастасия 14.06.2018 в 15:06

У меня та же проблема, с printf всё работает, но вот если ввести при scanf, то в выводе printf будут кракозябры

  1. admin14.06.2018 в 21:41

Попробуйте способы, указанные в комментариях выше. Один из них точно сработает.

Спасибо за инфу! Все работает.

Всё работает! Спасибо большое!

Правильно “Ru”, а не “Rus”.
setlocale(LC_ALL, “Ru”);

у меня получилось так:

#include
#include
#include

void main()
<
setlocale(LC_ALL, “Rus”);
wprintf(L”Спасибо”);
>

Если кто-то пишет в NotePad++ или чём-то подобном, не забудьте поменять кодировку самого файла с UTF-8 на, например, Windows-1251.
Спасибо за статью.

STL: стандартная библиотека шаблонов С++

    Статьи , 25 декабря 2014 в 18:04

Механизм шаблонов встроен в компилятор C++, чтобы дать возможность программистам делать свой код короче за счет обобщенного программирования. Естественно, существуют и стандартные библиотеки, реализующие этот механизм. STL является самой эффективной библиотекой C++ на сегодняшний день.

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

Первое знакомство

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

Коллекции

Для использования коллекции в своем коде используйте следующую директиву:

#include ,
где T — название коллекции

Итак, наиболее часто используются:

  • vector — коллекция элементов, сохраненных в массиве, изменяющегося по мере необходимости размера (обычно, увеличивающегося);
  • list — коллекция, хранящая элементы в виде двунаправленного связанного списка;
  • map — коллекция, сохраняющая пары вида , т.е. каждый элемент — это пара вида , при этом однозначная (каждому ключу соответствует единственное значение), где ключ — некоторая характеризующая значение величина, для которой применима операция сравнения; пары хранятся в отсортированном виде, что позволяет осуществлять быстрый поиск по ключу, но за это, естественно, придется заплатить: придется так реализовывать вставку, чтобы условие отсортированности не нарушилось;
  • set — это отсортированная коллекция одних только ключей, т.е. значений, для которых применима операция сравнения, при этом уникальных — каждый ключ может встретиться во множестве (от англ. set — множество) только один раз;
  • multimap — map , в котором отсутствует условие уникальности ключа, т.е. если вы произведете поиск по ключу, то получите не единственное значение, а набор элементов с одинаковым значением ключа; для использования в коде используется #include ;
  • multiset — коллекция с тем же отличием от set’а, что и multimap от map’а, т.е. с отсутствием условия уникальности ключа; для подключения: #include .

Строки

Любая серьезная библиотека имеет свои классы для представления строк. В STL строки представляются как в формате ASCII, так и Unicode:
string — коллекция однобайтных символов в формате ASCII;
wstring — коллекция двухбайтных символов в формате Unicode; включается командой #include .

Строковые потоки

strstream — используются для организации STL-строкового сохранения простых типов данных.
Разбор примеров начнем именно с этого класса.

Строковый поток — это буфер с нуль-терминатором в конце, поэтому при первой распечатке в конце строки оказывается мусор, т.е. получить реальный конец можно не посредством нуль-терминатора, а получив счетчик: pcount() . Затем “реальная часть” потока копируется в новую строку, и мы получаем распечатку уже без мусора.

Итераторы

Очень важное понятие в реализации динамических структур данных — итератор. Неформально итератор можно определить как абстракцию, которая ведет себя как указатель, возможно, с какими-то ограничениями. Строго говоря, итератор — более общее понятие, и является объектной оберткой для указателя, поэтому указатель является итератором. Примерно его устройство может выглядеть так:

Вот несколько формализованных определений итератора:

  • Итераторы обеспечивают доступ к элементам коллекции
  • Для каждого конкретного класса STL итераторы определяются отдельно внутри класса этой коллекции.

Существуют три типа итераторов:

  • (forward) iterator — для обхода коллекции от меньшего индекса к большему;
  • reverse iterator — для обхода коллекции от большего индекс к меньшему;
  • random access iterator — для обхода коллекции в любом направлении.

Вот пример использования итераторов для удаления половин элементов коллекции:

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

Итерация вперед и аналогично назад происходит так:
for (iterator element = begin (); element

При использовании random access iterator, например, так:
for (iterator element = begin (); element

Методы коллекций

Основными методами, присутствующими почти во всех коллекциях являются следующие:

  • empty — определяет, пуста ли коллекция;
  • size — возвращает размер коллекции;
  • begin — возвращает прямой итератор, указывающий на начало коллекции;
  • end — возвращает прямой итератор, указывающий на конец коллекции, т.е. на несуществующий элемент, идущий после последнего;
  • rbegin — возвращает обратный итератор на начало коллекции;
  • rend — возвращает обратный итератор на конец коллекции;
  • clear — очищает коллекцию, т.е. удаляет все ее элементы;
  • erase — удаляет определенные элементы из коллекции;
  • capacity — возвращает вместимость коллекции, т.е. количество элементов, которое может вместить эта коллекция (фактически, сколько памяти под коллекцию выделено);

Вместимость коллекции, как было сказано в начале, меняется по мере надобности, т.е. если вся выделенная под коллекцию память уже заполнена, то при добавлении нового элемента вместимость коллекции будет увеличена, а все значения, бывшие в ней до увеличения, будут скопированы в новую область памяти — это довольно “дорогая” операция. Убедиться в том, что размер и вместимость — разные вещи, можно на следующем примере:

Vector

Самая часто используемая коллекция — это вектор. Очень удобно, что у этой коллекции есть такой же оператор operator [] , что и у обычного массива. Такой же оператор есть и у коллекций map , deque , string и wstring .

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

Алгоритмы

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

  • Методы перебора всех элементов коллекции и их обработки: count , count_if , find , find_if , adjacent_find , for_each , mismatch , equal , search copy , copy_backward , swap , iter_swap , swap_ranges , fill , fill_n , generate , generate_n , replace , replace_if , transform , remove , remove_if , remove_copy , remove_copy_if , unique , unique_copy , reverse , reverse_copy , rotate , rotate_copy , random_shuffle , partition , stable_partition
  • Методы сортировки коллекции: sort , stable_sort , partial_sort , partial_sort_copy , nth_element , binary_search , lower_bound , upper_bound , equal_range , merge , inplace_merge , includes , set_union , set_intersection , set_difference , set_symmetric_difference , make_heap , push_heap , pop_heap , sort_heap , min , max , min_element , max_element , lexographical_compare , next_permutation , prev_permutation
  • Методы выполнения определенных арифметических операций над членами коллекций: Accumulate , inner_product , partial_sum , adjacent_difference

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

Предикаты

Для многих алгоритмов STL можно задать условие, посредством которого алгоритм определит, что ему делать с тем или иным членом коллекции. Предикат — это функция, которая принимает несколько параметров и возвращает логическое значение (истина/ложь). Существует и набор стандартных предикатов.

Потокобезопасность

Важно понимать, что STL — не потокобезопасная библиотека. Но решить эту проблему очень просто: если два потока используют одну коллекцию, просто реализуйте критическую секцию и Mutex .

Заключение

STL — кросс-платформенная библиотека. Конечно, не существует абсолютной гарантии, что эта библиотека есть в любой версии компилятора. Например, она редко реализуется на мобильных устройствах, потому что большая часть реализованных структур данных делает выбор в пользу быстродействия, совершенно не экономя память, а ведь именно память является самым ценным ресурсом на мобильных платформах, в то время как на PC ее сейчас в избытке. Поэтому, нередко вам придется создавать свои реализации STL, например, для переноса вашего приложения на мобильную платформу.

Оцените статью
Fobosworld.ru
Добавить комментарий

Adblock
detector