1. Краткая справка по языку Си и разработке консольных приложений в среде Visual C++ 2008
Система программирования Visual C++ предоставляет возможность разработки и отладки различных программных продуктов, в том числе приложений, работающих как с использованием графического интерфейса пользователя, так и в консольном режиме. Последние имеют интерфейс пользователя в виде текстового окна, называемого окном программы , в котором последовательно, строка за строкой отображаются данные, вводимые пользователем с клавиатуры, и данные, выводимые программой. Позицию начала ввода или вывода в окне программы указывает курсор — мигающий символ, имеющий вид подчеркивания в режиме вставки или прямоугольника – в режиме замены. По умолчанию длина строки равна 80, а количество строк – 50. Изменить эти и другие параметры окна программы позволяет диалог, открывающийся при вводе команды Свойства в системном меню окна программы при ожидании ввода данных.
При вводе пользователь имеет возможность редактировать последние вводимые данные, используя клавиши с печатными символами, а также клавиши BackSpace (удаление последнего введённого символа), Delete (удаление символа справа от курсора), Insert (переключение режимов вставки и замены), Стрелка вверх (удаление всех введённых символов), Стрелка влево (перемещение курсора в предыдущую позицию), Стрелка вправо (перемещение курсора в следующую позицию). Если в окне диалога, открывающегося при вводе команды Свойства системного меню окна программы, установить на вкладке Общие флажок Выделение мышью , то становится возможным выделять части текста буксировкой мыши, копировать выделенное в буфер обмена щелчком её правой клавиши и затем вставлять в позицию курсора щелчком правой клавиши. Завершается ввод нажатием клавиши Enter, при этом курсор перемещается в начало новой строки.
Вывод данных из программы выполняется в виде текста, символ за символом при автоматическом перемещении курсора в очередную позицию строки, а при достижении её конца – в начало новой строки.
Консольный режим обычно используется в тех случаях, когда основными требованиями к программе являются минимизация времени счёта и расхода оперативной памяти. На подготовку таких программ требуется меньше времени, поэтому консольный режим удобно использовать для быстрой проверки и отладки отдельных алгоритмов. Именно поэтому, имея в виду, что данный сборник задач ориентирован на развитие на-
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
чальных навыков алгоритмизации и отладки небольших программ, предполагается использование консольного режима.
Для создания программы, работающей в консольном режиме, следует после за-
пуска Visual C++ ввести команду File/New/Project. В открывшемся окне New Project
(см. рис. 1.1) выбрать в левом списке строку Win32, в правом списке – Win32 Console Application, ввести в поле Location: (или выбрать в диалоге, нажав кнопку Browse…) папку для размещения проекта, ввести в поле Name: имя проекта и нажать кнопку OK, а затем — кнопку Finish во вновь появившемся окне Win32 Application Wizard. При этом изменится набор окон, как показано на рис. 1.2.
В окне редактирования программы (см. рис. 1.2) будет представлен подготовленный системой исходный текст простейшей программы — шаблон консольной программы
(или просто шаблон программы ).
Элементами шаблона программы являются
//Программа 1.cpp : Defines the entry point for the console application –
комментарий (начинается с пары символов //) указывающий, в каком файле проекта находится описание исходного текста программы и что это приложение консольное.
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
Строка меню граммы
директива #include «stdafx.h» , подключающая к шаблону заголовочный файл stdafx.h , необходимый для использования минимального набора стандартных (библиотечных) функций, обеспечивающих работу проекта,
главная функция ( primary function ), включающая
int _tmain( int argc, _TCHAR* argv[])
тело функции – блок из пары фигурных скобок, содержащих лишь один оператор return 0;
выхода из программы с кодом завершения 0.
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
Для создания файла исполняемой программы шаблона (как и создаваемых на его основе консольных программ), который будет размещён в подпапке Debug папки приложения, следует ввести команду Build/Build Solution. Работающая программа шаблона будет представлять только окно консольного приложения (окно программы) . Для её за-
пуска в среде Visual C++ необходимо ввести команду Debug/Start Without Debugging ( старт без отладки ), или щелкнуть кнопку
, или нажать клавиши Ctrl+F5. В результате откроется окно программы (см. рис 1.3) с предложением нажать любую клавишу, будет выполнен единстаенный оператор шаблона return 0; , завершающий работу программы, а нажатие любой клавиши приведёт к закрытию её окна.
При запуске программы шаблона командой Debug/Start Debugging ( старт в режиме отладки ), или щелчком на кнопке
, или нажатием клавиши F5, или при запуске из папки окно программы также откроется, но сразу же закроется, и работа программы будет завершена. Чтобы задержать окно программы до нажатия клавиши, в программу следует добавить перед оператором return 0; оператор getch(); и директиву
#include «conio.h» как показано ниже #include «stdafx.h» #include «conio.h»
int _tmain( int argc, _TCHAR* argv[])
Впрочем, закрыть окно и завершить работу программы можно и любым другим способом закрытия окна Windows.
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
В дальнейшем при разработке программы в шаблон потребуется добавлять операторы, объявления переменных и именованных констант, комментарии, директивы, создаваемые пользователем функции, а также, при необходимости, директивы #include , подключающих к проекту иные наборы библиотечных и пользовательских функций.
Комментарии никак не влияют на создание исполняемой программы и просто пропускаются компилятором. Назначение же комментариев состоит в том, чтобы облегчить понимание алгоритма программы при чтении её исходного текста. Оформить текст
в виде комментария можно одним из следующих способов:
//оператор getch(); заставит программу
getch(); //ждать нажатия клавиши
заключив текст в скобки вида
текст, занимающий несколько строк,
вводимой с клавиатуры */
или поясняющий текст внутри конструкции языка, если комментарий не искажает их смысл и правила построения
int _tmain( int argc, _TCHAR* argv[ /*массив аргументов*/ ])
int _tmain( int argc /*количество аргументов*/ , _TCHAR* argv[])
Нельзя использовать этот комментарий, например, после знака / , внутри задаваемых пользователем имён, внутри строковых констант (текстов, начинающихся и заканчивающихся символом » , например, «conio.h» ) и других таких же комментариев.
Операторы программы служат для описания её алгоритма. Конструкция оператора определяет, какие действия должны быть выполнены по обработке данных и\или передаче управления от оператора к оператору. В соответствии с правилами построения различают составные операторы или блоки , структурные операторы и простые операторы .
В этом разделе ограничимся рассмотрением некоторых простых операторов и блоков.
Простые операторы могут выражать некоторое законченное действие и завершаться знаком ; (точка с запятой), например, getch(); или return 0; или q++; (увеличить
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
значение переменной q на 1), а также быть частью выражений, например, s=s+q++ (увеличить значение переменной s на значение переменной q, а затем увеличить значение переменной q на 1) или частью списков с разделителем «запятая» внутри структурных операторов (см. один из примеров организации цикла for в разделе 4.1) .
Блоки (составные операторы) начинаются с открывающей фигурной скобки (<) и заканчиваются парной закрывающей фигурной скобкой (>). Они используются в качестве тел функций (например, тело функции _tmain, см. выше), могут быть частями структурных операторов или иметь самостоятельное значение. Их особенностью является то, что они могут содержать, помимо вложенных в них других операторов, в том числе и составных, объявления локальных переменных, используемых («видимых») только внутри этих блоков. Операторы, входящие в составной, могут описывать сложный алгоритм, выполнение которого начинается при входе в составной оператор. Завершение алгоритма происходит либо при выполнении оператора, меняющего естественный порядок их выполнения (в порядке их следования в тексте программы), например, оператором return выхода из функции, либо при достижении парной закрывающей фигурной скобки.
Обрабатываемые данные хранятся в ячейках оперативной памяти, а переменные и константы представляют их в исходном тексте программы. Отличие переменной от константы состоит в том, что переменным можно присваивать новые значения, а значения констант задают только в исходном тексте программы и нельзя изменять их при её выполнении. В простейшем случае для объявления переменной используется конструкция <Имя типа> < > <Имя переменной>;
<Имя типа> — один из предописанных типов: int (целый), float (вещественный), double (вещественный удвоенной точности), char (символьный),
< > — пробел, <Имя переменной> — последовательность латинских букв, цифр, знаков $ и _
(подчерк), начинающаяся с буквы, знака $ или _.
Вместо одной можно описать несколько переменных, записав их имена через за-
При описании переменных им можно задавать начальные значения , которые будут иметь переменные в момент начала выполнения программы. Начальное значение
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
переменной должно записываться вслед за знаком = после её имени (знак «равно» имеет в Си смысл присваивания переменной значения).
Помимо обычных констант, значения и типы которых определяются по их форме записи, можно использовать и именованные константы (иногда их называют перемен- ными-константами), которые представляют значения своими именами. Именованные константы объявляются подобно переменным с начальными значениями, но перед их именами необходимо ставить слово const .
int x, y=-5; /* Объявление двух переменных типа int. Переменная y будет иметь начальное значение -5*/
int const n = 10; /* Объявление именованной константы типа int */
Именованные константы в ряде случаев позволяют облегчить понимание алгоритма программы и избежать ошибок при необходимости изменения значения. Например, если число 10 используется для объявления размеров нескольких массивов и в операторах обработки этих массивов, то желательно использовать именованную константу со значением 10. Тогда, при необходимости замены числа 10 другим, достаточно будет сделать эту замену только в объявлении именованной константы (см. пример программы в разделе 4.6).
Рассмотрим следующий пример программы, вычисляющей время движения тела с ускорением 9,8 м/с 2 на пути заданной длины, вводимой с клавиатуры.
#include «conio.h» /*подключение библиотечных подпрограмм консольного ввода-вывода, в частности getch(); */
#include «math.h» /* подключение библиотечных подпрограмм вычисления математических функций
//главная функция программы
int _tmain( int argc, _TCHAR* argv [])
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
float const g=9.8; /*Именованная константа, представляющая ускорение. */
float T;/*Переменная вещественного типа, которая будет представлять искомое время. */
int S; //Переменная целого типа, представляющая длину пути. // ОПЕРАТОРЫ
//Вывод приглашения к вводу значения переменной S printf( «Enter S: » );
//Ввод значения переменной S scanf( «%d» ,&S);
//Вычисление времени движения тела на заданном пути
//Вывод результата с пояснениями printf( «T=%f\n» , T);
//Задержка закрытия окна программы до нажатия клавиши getch();
В блоке главной функции _tmain программы используется объявление именованной константы (константа g), объявления переменных T и S, а также операторы, представляющие алгоритм решения задачи. Протокол ввода-вывода программы представлен в окне программы на следующем рисунке.
Результат выводится с поясняющим кратким текстом, набранным в латинском алфавите.
Цвет фона (чёрный) и символов (белый) в окне программы можно изменить следующим образом: раскрыть системное меню окна щелчком на кнопке
, выбрать пункт Свойства, в появившемся окне диалога на вкладке Цвета из представленной палитры выбрать для фона и символов желаемые цвета, нажать кнопку OK. Например, при выборе белого цвета для фона и чёрного для символов окно программы примет вид
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
Используемая в Visual C++ кодировка символов не обеспечивает правильный вывод букв кириллицы, что представляет неудобство для русскоязычных пользователей. Наиболее простым способом обеспечения вывода текстов на русском языке является включение в программу объявления функции Ruc перекодирования символов как показано ниже.
#include «stdafx.h» #include «conio.h»
// Подключение библиотечных подпрограмм
// вычисления математических функций.
//заголовок функции Ruc, описание см. ниже. char * Ruc( char s[]);
int _tmain( int argc, _TCHAR* argv[])
float const g=9.8; /*Именованная константа, представляющая ускорение. */
float T;/*Переменная вещественного типа, которая будет представлять искомое время. */
int S; //Переменная целого типа, представляющая длину пути. // ОПЕРАТОРЫ
//Вывод приглашения к вводу значения переменной S .
//Знак \ в конце строки первой строки оператора обозначает //перенос текста константы на начало новой строки. printf(Ruc( «Программа вычисляет время, за которое тело \ при ускорении %f\n пройдёт заданный путь.\n» ), g); printf(Ruc( » Введите длину пути в метрах: » ));
//Ввод значения переменной S. scanf( «%d» ,&S);
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
//Вычисление времени движения тела на заданном пути. //Математическая функция sqrt извлекает квадратный корень. T=sqrt(S*2/g);
//Вывод результата с пояснениями.
printf( «%s T=%f» , Ruc( «Путь будет пройден за » ), T); printf( «%s\n» , Ruc( » секунд.» ));
//Задержка закрытия окна программы до нажатия клавиши. getch();
char * Ruc( char s[])
static char ss[257];
else if (s[i] == -72) ss[i]=( char )(-15); //ё
else if (s[i] == -88) ss[i]=( char )(-16); //Ё
Протокол ввода-вывода программы будет иметь вид
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
В исходном тексте программы использована, помимо главной функции _tmain , дополнительная функция Ruc . Дополнительные функции можно размещать как перед главной функцией, так и после неё. Но если функция размещена после главной или любой другой, из которой она вызывается, то необходимо давать опережающее объявление её заголовка (как и сделано в приведённом примере, так как функция Ruc размещена после главной).
Используемые в программе дополнительные, помимо главной, функции можно также размещать в одном или нескольких отдельных файлах. Чтобы разместить дополнительные функции при их создании в среде Visual C++ в отдельном файле следует ввести команду Project/Add New Item…, в открывшемся окне выделить элемент списка Header File.h, ввести имя, которое хотите дать файлу (например, Перекодировщик ), и щелкнуть на кнопке Add. В результате в папке проекта появится новый файл, в списке
Solution Explorer (открываемом командой View/Solution Explorer) будет размещен соот-
ветствующий ему элемент, а также в окне Visual C++ появится новая вкладка для ввода описаний функций, озаглавленная именем созданного файла ( Перекодировщик.h ). Затем перед заголовком главной функции следует записать директиву #include с именем файла ( #include » Перекодировщик.h » ). Пример представляют следующие рисунки.
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
Если файл с добавляемыми функциями был создан ранее (уже существует), то в файл главной функции нужно просто добавить директиву #include со ссылкой на него
(например, #include «D:\temp\Перекодировщик.h» ).
Одним из важных этапов разработки программ является их отладка – локализация и устранение ошибок, препятствующих созданию исполняемого файла (синтаксических ошибок), и ошибок, вносящих несоответствие программы заданию на её разработку (смысловых ошибок).
Синтаксические ошибки выявляет система программирования при выполнении команды Build/Build Solution или Build/Rebuild Solution. Сообщения об ошибках выво-
дятся в окно Output построчно. Они содержат краткие пояснения о причинах ошибок, номера строк исходного текста программы, в которых ошибки обнаружены, а двойным щелчком на строке сообщения курсор устанавливается на соответствующей строке программы.
В Visual C++ многие библиотечные функции языка C имеют усовершенствованный аналог, который предлагается использовать в сообщениях об ошибках типа warning . Однако такие ошибки не препятствуют созданию исполняемого файла. Другой тип ошибок отмечен в сообщениях словом error . В большинстве случаев эти ошибки связаны с нарушением правил языка C (например, не дано опережающее объявление заголовка функции, размещенной после главной, не поставлена знак «точка с запятой» после объявления переменной, нет соответствия между открывающими и закрывающими скобками) и вызовом не существующих функций. Такие ошибки препятствуют созданию исполняемого файла и их необходимо устранять.
Поиск и устранение смысловых ошибок более сложен. Существующие методики в большинстве случае не могут дать гарантий на отсутствие таких ошибок, однако без их применения разработку программы нельзя считать законченной. К числу таких методик относится тестирование всей программы и её частей. Тестирование всей программы состоит в подборе тестовых исходных данных для работы программы, для которых известны, в соответствии с заданием, требуемые результаты работы программы, и сравнение с ними реальных результатов работы программы. Если реальные результаты не совпадают с требуемыми, значит программа не соответствует заданию и необходимо выявить и устранить причину этого несоответствия. С этой целью может использоваться как отладочная печать, так и имеющиеся в Visual C++ средства отладки.
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
Обычно программу можно разделить на имеющие законченный смысл алгоритмы (подзадачи), выполняемые последовательно или являющиеся частями более сложных алгоритмов (подзадач). В простейшем случае, как в представленной ранее программе вычисления времени прохождения тела в вакууме заданного пути при заданном ускорении, в программе можно выделить части: ввод исходных данных, их обработка и вывод результатов.
Части программы можно отлаживать в любом порядке. Однако желательно начать с той части, которая представляет суть задания. В большинстве случаев это часть обработки данных, и именно она наиболее сложна в отладке. Приступить к ней, минуя ввод исходных данных, позволяют следующие средства системы программирования:
задание начальных значений переменных,
подготовка, как рабочего, так и отладочного вариантов программы и быстрой замены одного варианта другим,
слежение в среде Visual C++ за значениями переменных и изменение их при выполнении программы в отладочном режиме,
использование различных способов приостановки программы и последующего продолжения её выполнения.
Рассмотрим эти приёмы и средства более подробно.
Отладочный вариант программы, помимо начальных значений исходных данных, может содержать коды задания значений промежуточным данным и отладочный вывод, которые должны отсутствовать в рабочем варианте программы. Реализуется возможность быстрого перехода от рабочего кода программы к отладочному (и обратно) с помощью директив условной компиляции.
Например, вставив в код программы директиву #define u1 (директива определения имени, в данном случае имени u1), везде ниже по тексту можем размещать конструкции
заставляя компилятор обрабатывать код между директивами #ifdef u1 (если u1 определено) и #endif (конец блока #ifdef ), то есть рассматривать его как часть кода про-
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
граммы. Чтобы исключить использование в программе отладочного кода, достаточно удалить директиву #define u1 или превратить строку с ней в комментарий.
Подобный результат можно получить для отдельной отладочной вставки с помощью конструкции
позволяющей добавить отладочный код в программу. Чтобы превратить всю конструкцию в комментарий достаточно в первой строке переместить первые два знака // в её конец (первая строка примет вид /*// и станет началом многострочного комментария).
Возможно использование рассмотренных конструкций и для временного удаления части кода рабочего варианта программы, если это ускорит процесс отладки других частей. Например, если программа требует ввода значительных объёмов исходных данных, то при её отладке целесообразно временно заменить ручной ввод заданием и редактированием начальных значений переменных.
Директив #define в программе может быть несколько. Чтобы определяемые директивами #define имена указывали на отладочный вариант программы в сочетании с директивой #ifdef , они должны быть информативными, например, #define debug1 , #define debug2 и тому подобными. Тогда временно удаляемые при отладке части кодов рабочей программы должны начинаться с директивы #ifndef (если имя не определено), а отладочные вставки кодов – с директивы #ifdef . Если в программе отладочный код должен замещать часть кода рабочей программы, то, например, при наличии директивы #define debug1 следует использовать конструкцию
#ifdef debug1 //если имя debug1 определено, добавить
. . . // код, используемый для
#else //иначе, т.е. если имя debug1 не определено, //использовать
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
Дополнительную информацию по директивам условной компиляции можно найти в справочной системе Visual C++.
Чтобы ускорить поиск и исправление ошибок в программе желательно подготовить в окне Visual C++ минимальные наборы инструментов панели отладки (Debug)
и панели редактирования текста (Edit)
Для этого в меню Tools следует выбрать пункт Customize… и в открывшемся окне
установить флажки на строках Debug и Text Editor. Затем на вкладке Commands,
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
выбрав в левом списке строку Edit, отбуксировать из правого списка на панель инструментов редактирования Edit окна Visual C++ недостающие значки. Аналогично выполнить настройку панели инструментов отладки, выбрав в левом списке окна Customize строку Debug. Чтобы удалить ненужные значки с панелей инструментов, их просто следует отбуксировать с панелей в любое место при открытом окне Customize.
Инструменты панели Debug имеют следующее назначение:
— запустить программу в обычном режиме, без использования отладочных средств среды Visual C++.
— запустить программу в режиме отладки. В этом режиме в программу будут автоматически добавлены коды, обеспечивающие использование отладочных средств (см. далее).
— завершить работу программы, запущенной в режиме отладки, и вернуться к редактированию её кода.
— добавить в окно наблюдения Watch строку слежения за текущим значением переменной или выражения: выражение следует выделить, а переменную либо выделить, либо поставить перед ней курсор и щелкнуть на этом значке. Можно также получить и всплывающую подсказку по значению, подведя курсор к переменной или выделенному выражению. (В VS C++ 2008 есть окно Autos, где автоматически отображаются локальные переменные текущего блока или оператора)
— выполнить шаг трассировки без захода в подпрограммы (трассировка без захода в подпрограммы – это выполнение программы строка за строкой при каждом щелчке на кнопке, без захода в вызываемые в строке функции).
— трассировка с заходом в подпрограммы (если в текущей строке программы есть вызовы функций, то после щелчка на кнопке появится код функции для выполнения его трассировки).
— завершение выполнения кода функции и возврат управления в вызвавшую её программу.
При отладке обычно используют точки безусловного и условного останова (последние рассматривать не будем). Строка программы является точкой безусловного останова, если при работе программы в отладочном режиме выполнение программы будет остановлено непосредственно перед этой строкой. Таких точек в программе может быть несколько. Сделать строку точкой безусловного останова можно выбором в контекстном меню строки пункта Breakpoint/insert Breakpoint. В результате на серой вертикальной по-
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
лосе перед строкой появится красный кружок – признак точки безусловного останова. Такую установку можно выполнить просто щелчком на указанной полосе, а отменить – щелкнув ещё раз.
Использование в отладочном варианте программы
начального значения переменной S и отключение её ввода директивами условной компиляции,
точек безусловного останова и
окна наблюдения за текущими значениями переменных и выражения sqrt(S*2/g)
поясняет следующий рисунок.
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
После запуска программы в отладочном режиме (щелчком на кнопке
) её выполнение будет приостановлено в первой точке безусловного останова, отмеченной красным кружком (перед выполнением строки T=sqrt(S*2/g); , отмеченной красным кружком), а при повторном щелчке на кнопке — перед строкой
printf( «%s T=%f» , Ruc( «Путь будет пройден за » ), T);
Ю. Е. Алексеев, А. В. Куров «Практикум по программированию на языке C в среде VS C++» Оглавление
What is the difference between _tmain() and main() in C++?
If I run my C++ application with the following main() method everything is OK:
I get what I expect and my arguments are printed out.
However, if I use _tmain:
It just displays the first character of each argument.
What is the difference causing this?
5 Answers 5
_tmain does not exist in C++. main does.
_tmain is a Microsoft extension.
main is, according to the C++ standard, the program’s entry point. It has one of these two signatures:
Microsoft has added a wmain which replaces the second signature with this:
And then, to make it easier to switch between Unicode (UTF-16) and their multibyte character set, they’ve defined _tmain which, if Unicode is enabled, is compiled as wmain , and otherwise as main .
As for the second part of your question, the first part of the puzzle is that your main function is wrong. wmain should take a wchar_t argument, not char . Since the compiler doesn’t enforce this for the main function, you get a program where an array of wchar_t strings are passed to the main function, which interprets them as char strings.
Now, in UTF-16, the character set used by Windows when Unicode is enabled, all the ASCII characters are represented as the pair of bytes \0 followed by the ASCII value.
And since the x86 CPU is little-endian, the order of these bytes are swapped, so that the ASCII value comes first, then followed by a null byte.
And in a char string, how is the string usually terminated? Yep, by a null byte. So your program sees a bunch of strings, each one byte long.
Windows API main functions
In this part of the Windows API tutorial, we will talk about main functions.
Advertisements The main function prototypes
The main function is an entry point to a C program. However, it is not the first program to run. When the entry point is main , the program execution actually begins in a function called mainCRTStartup . This function is located in the C runtime library. It initialises things like the memory manager, file I/O support, and the argv parameter. After that, the mainCRTStartup function will call the main function.
These are the function prototypes for the main function for the classic console program.
The above source code presents an example of a classic console C program.
This is the output of the ClassicConsole.exe program.
The wmain function prototypes
The previous main function prototypes could receive only ASCII characters. If we want a program that could receive wide characters from the command line, we will use the wmain function prototypes.
The above wmain function prototypes receive wchar_t characters on the command line. When we use these prototypes, the execution begins in a function called wmainCRTStartup which will later call the wmain function.
We have a wmain function which can receive wide characters. The example prints the first argument of the console program. To insert command line arguments in Pelles C, we go to Project options and select the General tab. There is an edit box called Command line arguments.
The wchar_t type of the second parameter of the wmain function tells us that the program input is in wide characters.
The GetStdHandle function returns a handle to the standard output.
In case of an error, we receive the INVALID_HANDLE_VALUE return code. For this situation we print an error message. The GetLastError function retrieves last error code value.
We use the WriteConsoleW function to write to the console in wide characters.
The CloseHandle function closes the opened handle to the standard output.
We pass a Russian word (compiler) as a parameter to our program. The program simply prints the parameter back to the console. Note that in order to see correct characters, we need to change the default font of the console to Lucida Console. We need a true type font to display wide characters correctly.
Advertisements The _tmain function prototypes
The _tmain function is a Microsoft extension. It enables programmers to easily create both ANSI and UNICODE builds of their programs. It is a C macro that translates to wmain or main functions, depending whether the _UNICODE constant is defined or not.
In the past it was common to create both ANSI and UNICODE builds. Nowadays, it is recommended to create Unicode programs, unless we have a specific reason to create an ANSI build.
These are the _tmain function prototypes. The TCHAR macro translates either to char or to wchar_t . It is controlled by the UNICODE constant.
The example prints its first argument if available.
Here we define two constants. These definitions mean that we are going to build a Unicode program. They translate C macros in C runtime and Windows header files. The _UNICODE constant translates macros in the C runtime. (These macros start with an underscore.) The UNICODE constant translates macros in the Windows header files.
If the build is ANSI, we include the <stdio.h> header.
We include the definition of the TCHAR macro. The macro is affected by the UNICODE constant.
We must include this header file for the _tmain and _tcslen macros. They are translated depending on the _UNICODE constant.
The _tmain function translates in our case to wmain and the TCHAR macro to wchar_t .
The WriteConsole macro is transleted to the WriteConsoleW function. The WriteConsoleW writes output to the console. The _tcslen macro is translated to wcslen function; it returns the lenght of the wide string.
The program takes another Russian word (operating system) as a parameter and prints it to the console.
The WinMain function prototypes
So far we had console main functions. For graphical user interface development, we use one of the WinMain function prototypes.
These three function prototypes are used for entry points for Windows GUI applications. The wWinMain function’s pCmdLine parameter contains the command-line arguments as a Unicode string. The WinMain function’s pCmdLine parameter contains the command-line arguments as an ANSI string. The _tWinMain is a C macro that translates to other two function prototypes, depending whether the _UNICODE constant is defined.
When the entry point is WinMain , the execution of the program begins in WinMainCRTStartup . In case of wWinMain , the execution begins in wWinMainCRTStartup .
This code shows a small message box on the screen. It displays the first command line argument.
The third parameter of the wWinMain function is a PWSTR (pointer to wide string). It accepts wide characters. Figure: A message box
In this part of the Windows API tutorial, we have mentioned main functions.
Int tmain int argc tchar argv что это

So normally I use Dev C++ which is a pretty straightforward and easy-to-use IDE. However, I tried downloading Visual Studio to try something new and I feel like it’s overly complicated.
Every new C++ project starts out with this stuff:
So, I can guess that «stdafx.h» is some header file with important stuff in it pertaining to Visual Studio only.
What I don’t understand is the «_tmain» function. I also don’t understand what its arguments are for. Is this just the same as «int main()» but for Visual Studio? What am I supposed to do with it?

geoff/classes/hmc.cs070.200401/notes/command-args.html
Its a really quick read on what these arguments mean.
I am assuming that _TCHAR is a replacement for the regular char , and _tmain is probably a replacement for the regular main .


«_tmain( )» is an extension of Microsoft’s C++ compiler and therefore, is non-standard. Considering that you’ve come from Dev-C++, I recommend that you use either Orwell Dev-C++ [1] (the modern version of the old Dev-C++), Code-Lite [2] or Code::Blocks [3] .
In my opinion, the change between Dev-C++ and Visual C++ is too big of a transition for you which is causing you confusion. With Code::Blocks or Orwell, the interface is far more friendly and easier to get-to-grips with.
[1] Orwell Dev-C++: http://orwelldevcpp.blogspot.co.uk/
[2] Code-Lite: http://codelite.org/
[3] Code::Blocks: http://www.codeblocks.org/downloads

> What am I supposed to do with it?
Delete it. And in its place write either
> In my opinion, the change between Dev-C++ and Visual C++ is too big of a transition for you which is causing you confusion.
Not really. Any IDE is confusing when one encounters it for the first time. It takes a small amount of time to get used to an IDE.

| Every new C++ project starts out with this stuff: |
No, they don’t. I generally begin with an «Empty Project» which has none of that cruft inserted. If you do that, you do need to select the console subsystem in the linker settings to get the behavior most people prefer when running a program from within the IDE (ie. make the program pause at the end of execution.)
Alternately you can select a «Win32 Console Application» and check the appropriate boxes in the wizard to make sure the boiler plate isn’t written for you. (Precompiled headers disabled, empty project selected.)