Анатомия C Run-Time, или Как сделать программу немного меньшего размера
Страница 3. Точка входа в программу
Функция [w]main или [w]WinMain, с которой начинается выполнение программы, вовсе не является точкой входа исполняемого модуля! На самом деле, программа на C++ начинает работу с выполнения специальной процедуры инициализации. Что касается Win32, то адрес этой процедуры и содержится в поле AddressOfEntryPoint заголовка Portable Executable (PE) выполняемого файла.
Она представляет собой обычную функцию C, описанную с соглашением о вызовах __stdcall. В зависимости от настроек проекта, в Visual C++ эта функция может называться [w]mainCRTStartup, [w]WinMainCRTStartup или _DllMainCRTStartup (символ ‘w’ добавляется к имени для Unicode-проектов). Конкретно же для сборки приложения имя функции-точки входа можно задать опцией линкера /entry. Умолчанием для Visual C++ является «mainCRTStartup». Все сказанное справедливо и для некоторых других компиляторов C++ для Win32.
ТОЧКА ВХОДА В ПРОГРАММУ «ПУТЬ К УСПЕХУ»
Что же происходит во время ее выполнения? Вот типичный сценарий работы такой функции (случай DLL здесь не рассматривается).
- Инициализируются переменные CRT (такие, как errno и osver). Многопоточная библиотека требует особой инициализации.
- Происходит инициализация динамической памяти (кучи).
- Инициализируется среда обработки ошибок в вычислениях с плавающей точкой. Это необходимо не только для библиотечных функций (таких, как sqrt), но и для преобразований между целочисленными и плавающими типами данных.
- Получаются значения аргументов командной строки программы и переменных среды.
- В случае необходимости, происходит инициализация консоли и привязка стандартного вывода к файловым дескрипторам C. При старте исполняемого файла, у которого в уже упомянутом заголовке PE значение поля Subsystem равно 3 (Windows character-mode executable), создается консоль. Это значение можно задать опцией линкера /subsystem. Выбор подсистемы выполнения также влияет на выбор стартовой функции (если ее имя не задано явно). Умолчанием является «console».
- Происходит вызов цепочки функций инициализации CRT и конструкторов глобальных переменных (подробнее об этом — в следующем разделе).
- И лишь после этого вызывается функция [w]main или [w]WinMain. Коротко можно сказать, что функция xxxCRTStartup вызывает соответствующую функцию xxx.
- Программа работает.
- Выполняется последовательность действий по очистке, к которой мы еще вернемся.
- И, наконец, происходит завершение процесса.
Теперь, наконец, можно ответить на мой вопрос: он был задан некорректно :). В самом деле, результат сборки будет зависеть от набора опций компоновщика, установленных в проекте или по умолчанию.
Так, например, при вызове компилятора в командной строке таким образом:
cl test.cpp user32.lib
мы получим консольную программу и сообщение «Hello from main()» (вспомните, что говорилось об умолчаниях).
Как найти идеальную точку входа?
А вызвав компилятор вот так:
cl test.cpp user32.lib /link /entry:WinMainCRTStartup /subsystem:console
мы получим «чудо чудное»: программу, у которой выполняется функция WinMain, но создается окно консоли.
Источник: tdoc.ru
Статья Точка входа в программу на языке C#
Если говорить простым языком, то точка входа это место, в языке c# представленное статическим методом Main, с которого начинает выполнение ваша программа при условии, что данная программа (приложение) является исполняемым, то есть будет иметь расширение (.exe).
То есть даже если ваш класс или несколько классов будут содержать 20, 30 или более разных методов, всё равно выполнение программы начинается со статического метода Main.
В вашем приложении Вы так же можете создать несколько классов и в каждый из них поместить статический метод Main, в результате ваша программа будет иметь несколько точек входа. Данный способ можно применять, например, для отладки ваших приложений при большом количестве исходного кода.
Но, тогда возникает вопрос, если точек входа несколько, тогда с какого места начнёт выполнение ваша программа?
Для примера добавим в исходный код нашей программы ещё один класс по имени Test, внутри которого поместим точно такой же статический метод Main, как в классе Program.
namespace Example < class Program < static void Main() < System.Console.WriteLine(«метод 1»); System.Console.ReadLine(); >> class Test < static void Main() < System.Console.WriteLine(«метод 2»); System.Console.ReadLine(); >> >
Если сейчас попытаться выполнить код, то компилятор выдаст ошибку:
Error Program ‘E:c# projectSLLab1objx86DebugLab1.exe’ has more than one entry point defined: ‘Example.Program.Main()’. Compile with /main to specify the type that contains the entry point.
Данная ошибка возникает, потому что в программе присутствует два статических метода Main, что приводит к возникновению конфликта, если сейчас перейти в свойства текущего проекта (картинка ниже), то можно найти пункт: startup object, который по умолчанию имеет значение: Not set.
Это значит, что если ваше приложение содержит хотя бы один статический метод Main, то тогда по умолчанию данный метод и будет являться точкой входа в программу, но если в приложении несколько таких методов, как в нашем примере, то тогда необходимо явно указать точку входа в программу.
Как явно указать точку входа?
Перейдите в окно Solution Explorer и нажмите правую кнопку мыши на имени проекта, в нашем случае имя проекта Lab1. После чего в списке выберите пункт Properties, в результате должно появиться вот такое окно.
Находим пункт startup object и в выпадающем списке явно указываем класс, который будет содержать точку входа в программу. Для примера выберем Example.Test, таким образом, мы явно укажем, что в качестве точки входа в нашей программе мы будем использовать статический метод Main, который находиться в классе Test, пространства имён Example.
Если сейчас запустить нашу программу, то получим вот такой результат.
Если точка входа не найдена, то есть наша программа не будет содержать статический метод Main, или данный метод будет иметь не правильную синтаксическую конструкцию, к примеру он не будет иметь ключевое слово static, то Вы так же получите ошибку на этапе компиляции.
- Создание первого приложения на языке c#. Часть вторая.
- Как найти все цифры в строке?
- Почему у меня в Data Source нет пункта Mysql Database?
Источник: codeby.net
Точка входа в программу (функция main)
Си — язык программирования высокого уровня разработанный в начале 1970-х годов сотрудниками исследовательского центра ” Bell Telephone Laboratories ” Денисом Ритчи. Первоначально язык Си был создан, для новой по тем временам операционной системе UNIX. Позднее он был перенесен на многие другие операционные системы и стал одним из самых используемых языков программирования. Дописать
Этапы написания программы
Разработка программ предложенных в данной брошюре должна состоять из следующих пунктов.
Постановка задачи. На этом этапе задача, составленная в терминах предметной области, переводится в термины наиболее близкие к программированию. Другими словами формулируется техническое задание.
Проектирование поставленной задачи. Данный пункт, включает в себя разработку и описание процессов поставленной задачи. Создание алгоритма работы программы. Разработку пользовательского интерфейса. Этот этап также определяет, сколько времени может занять тот или иной проект.
Кодирование программы. На этом этапе готовый алгоритм, переводится программистом в программный код. Ошибка многих начинающих программистов заключается в том, что они бросаются кодировать понятные им куски кода программы, пропуская первых два пункта. Это, как правило, приводит к существенному удлинению сроков написания программ. В результате на свет появляются непроработанные “кривые” программные модули исправление ошибок, в которых занимает очень много времени.
Отладка программы. Отладка предназначена для выявления и исправления существующих синтаксических ошибок. Надо отметить, что отладчик не коим образом не сможет отладить ваши смысловые ошибки. Поэтому так важно не упустить этап создания алгоритма.
Тестирование программы. Тестирование программы проверяет правильность работы программы и устойчивость ее к введению неправильных данных. Часто у программистов существует “замыленность” взгляда при тестирование своих программ. Они сами не осознавая вводят данные допустимые для ввода, где-то на бессознательном уровне понимая, что другие данные вводить нельзя. Поэтому не лишним будет отдать программу на тестирование некому постороннему лицу, чтобы он сумел объективно подойти к проблеме тестирования.
Язык Си как и все языки программирования содержит свой алфавит. Алфавит состоит из идентификаторов, символов, специальных символов, разделителей, знаков пунктуации, знаков операций, зарезервированных слов, неиспользуемых символов. Подробнее о алфавите языка программирования Си можно посмотреть [1]. Мы будем предполагать, что читатель знаком с азами программирования на языке Паскаль или Бейсик из школьного курса, однако постараемся изложить данный материал наиболее доступно.
В языке Си существуют следующие простые типы данных:
Таблица типы данных
Тип; | Представление значений в памяти; | Область величины; |
char; | 1 байт; | -128 до 127; |
int; | зависит от реализации; | |
short; | 2 байта; | -32768 до 32767 |
long; | 4 байта; | -2.147.483.648 до 2.147.483.647; |
unsigned char; | 1 байт; | 0 до 255; |
unsigned; | зависит от реализации; | |
unsigned short; | 2 байта; | 0 до 65535; |
unsigned long; | 4 байта; | 0 до 4.294.967.295; |
float; | 4 байта | IEEE соглашение; |
double; | 8 байт; | IEEE соглашение; |
Наряду с простыми типами в языке Си существуют и составные типы, такие как массивы, структуры, объединения и файловый тип. Рассмотрим некоторые операции языка Си (Таблица Операции). Приведем здесь лишь операции характеризующие рассматриваемый язык. Такие общие операции как сложение умножение и т.д. присущие всем алгоритмическим языкам мы рассматривать не будем.
Таблица Операции
Операция | Наименование | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
! | Логическое НЕ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
~ | Побитовое дополнение | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
% | Остаток | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Сдвиг влево | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
>> | Сдвиг вправо | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
== | Равно | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
!= | Не равно | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
>= | Сдвиг вправо с присваиванием | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Сдвиг влево с присваиванием | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
>или ” ”. Если подключается файл из стандартной библиотеке языка Си, то принято его размещать между символов < >, все остальные файлы заключаются в кавычки.
#include ”my_file.h” Приведем короткий список некоторых библиотек используемых в языке Си. Таблица Типы заголовочных файлов
После описания подключаемых файлов следует раздел описаний глобальных переменных и констант. Напомним, что константы – это выражение, которые состоят из констант знаков операций, круглых скобок и некоторых стандартных функций. Причем значение этого выражения является постоянным на всем этапе выполнения программы. Глобальная переменная это переменная, которая определена и существуют на протяжение всей работы программы. Значение данной переменной доступно в любом месте программы. Пример определения констант и глобальных переменных приведен ниже. Пример описания функций приведем позже, когда будем рассматривать раздел подпрограмм в языке Си. Рассмотрим основную функцию в программах на языке Си — main. Данная функция является точкой входа в программу, т.е с этой функции начинается выполнение программы. Без этой функции программа работать не будет. Функция main имеет следующий формат записи. main (int argc, char **argv) Здесь argc и argv два необязательных параметра, а тип определяет возвращаемый функцией результат. Эти параметры передаются из внешнего окружения. Первый параметр служит для передачи числа передаваемых строк, второй для передачи самих строк. Функция main может иметь и третий параметр, который принято называть argp, и который служит для передачи в функцию main параметров операционной системы (среды) в которой выполняется программа на языке программирования С. Однако во многих случаях функция main используется без параметров вообще. Все действия, выполняемые внутри функции заключаются в системных скобках < >– это аналог связки begin-end в языке Паскаль. Приведем пример программы пустой программы. Данная программа не производит никаких действий, однако успешно компилируется и запускается. Следует заметить, что если тип программы не void, то необходимо вернуть выходное значение с помощью комбинации return. Комбинация символов встречаемая в примере // предназначена для записи комментариев. Все, что стоит в строке после символов // будет закомментировано. Для комментирования большой части текста его заключают между символами /* */. Внутри любой функции в том числе и функции main можно производить вызов стандартных и созданных функций, проводить арифметические и логические операции использовать ключевые слова и операторы. Список операций и их назначение приведен в таблице операции. Все операции имеют свой приоритет. Например операции «() и []» имеет наивысший приоритет, а операция «,» самый низкий приоритет. К операциям также относятся операция условия «?:» и операция «sizeof». Операция «?:» единственная операция имеющая три операнда. Она имеет следующий вид: Вычисляется выражение выр1. Если это выражение имеет ненулевое значение, то вычисляется выражение выр2. Результатом операции будет значение выражения выр2. Если значение выражения равно нулю, то вычисляется выражение выр3 и его значение будет результатом операции. Например найти наибольшее из двух чисел x и y можно следующим образом: Операция sizeof вычисляет целочисленное значение величины типа или выражения в байтах. Например: Приведем список ключевых слов используемых в языке Си. Список ключевых слов:
Заметим, что ключевые слова не могут быть переопределены. Практически не одна программа не обходится без функций ввода и вывода. Рассмотрим некоторые функции ввода и вывода в языке Си. Функция printf() предназначен для форматированного вывода в стандартный поток ввода/вывода. Для ее использования необходимо подключить библиотеку ввода вывода stdio.h. Она имеет следующей набор параметров: int printf( const char *format, арг1, арг2, … ); Параметр «format» является управляющей последовательностью. Он имеет следующий вид: Остальные необязательные параметры обозначенные символом арг1, арг2, … являются списком выводимых переменных. Их количество и тип задаются (определяется) в управляющей последовательности. Флаги могут принимать одно из следующих значений приведенных в таблице Флаги, а некоторые значения типов приведены в таблице Значения типов. Флаги
Значения типов
Функция scanf() предназначен для форматированного ввода данных. Для ее использования также необходима библиотека ввода вывода stdio.h. Она имеет почти эквивалентный набор параметров, что и функция printf(). Единственное отличие это знак арг1, // производим присваивание переменных Источник: stydopedya.ru Где у Java приложения точка входа?В обычном Java приложении всегда должен быть main class, содержащий метод main . С него начинается исполнение всей программы. Main class-ом может быть не только класс, но и интерфейс или енам. Для JavaFX приложения главный класс должен реализовывать javafx.application.Application . main обязательно public static . Дополнительно, методу разрешено иметь модификатор strictfp. На аннотации и список исключений ограничений не накладывается. В главном методе должен быть объявлен единственный аргумент – массив строк. Обе конструкции String[] и String. компилируются в один и тот же байт-код, так что приемлемы оба варианта. Название массива может быть любым, а значение будет содержать аргументы командной строки. Когда приложение запускается как classpath, главный класс передается параметром командной строки. Если выполняется единственный исходник, он и описывает main class. Для исполняемого jar-файла ( java -jar MyJar.jar ), его главный класс должен быть указан в манифесте. Внутри архива, в файл META-INF/MANIFEST.MF добавляется строчка вида Main-Class: ru.itsobes.MyClass . Иначе запуск завершается ошибкой «no main manifest attribute». В случае, когда в указанном главном классе не оказывается метода, который бы удовлетворял всем критериям главного метода, программа падает с ошибкой «Main method not found». В апплетах вместо main входной точкой служат методы init и start . Начиная с версии Java 9 технология апплетов объявлена устаревшей, а с 11 – совсем удалена. Не будем останавливаться на них подробнее. Источник: itsobes.ru
Загрузка ...
|