Аргументы функции MAIN(). Передача аргументов в программу Передача аргументов командной строки

Главная / Windows 8

При автоматизированном создании консольного приложения в языке программирования С++, автоматически создается главная функция очень похожая на эту:

int main(int argc, char * argv)
{…}

Заголовок функции содержит сигнатуру главной функции main() с аргументами argс и argv .
Если программу запускать через командную строку, то существует возможность передать какую-либо информацию этой программе. Для этого существуют аргументы командной строки argc и argv .
Параметр argc имеет тип int , и содержит количество параметров, передаваемых в функцию main . Причем argc всегда не меньше 1, даже когда функции main не передается никакой информации, так как первым параметром считается имя приложения.
Параметр argv представляет собой массив указателей на строки. Через командную строку можно передать только данные строкового типа.

При запуске программы через командную строку Windows можно передавать ей некоторую информацию. При этом командная строка будет иметь вид:
Диск:\путь\имя.exe аргумент1 аргумент2 …

Аргументы командной строки разделяются одним или несколькими пробелами.

Аргумент argv содержит полное имя приложения:

#include
using namespace std;

cout << argv << endl;

Return 0;
}

Результат выполнения

Пример : вычисление произведения двух целых чисел
В программе используется функция преобразования строки в целое число StrToInt() отсюда .

#include
using namespace std;
int StrToInt(char *s) {…}
int main(int argc, char * argv) {

Int a = 0, b=0;

If (argc > 1)

a = StrToInt(argv);

If (argc > 2)

b = StrToInt(argv);

cout << a <<«*» << b << «= « << a*b << endl;

Return 0;
}

Запуск программы осуществляется как

Результат выполнения

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

Для передачи аргументов командной строки при отладке программы необходимо обратиться к меню Свойства проекта.


На вкладке Свойства конфигурации ->Отладка выбрать Аргументы команды и задать их значения.

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

Бывает, что данные в программу передаются из командной строки при ее вызове. Такие данные называются аргументами командной строки. Выглядит это так, например:

./a.out test.txt ls -lt /home/peter/

Здесь вызываются программы a.out (из текущего каталога) и ls (из одного каталога, указанного в переменной окружения PATH). Первая программа из командной строки получает одно слово - test.txt, вторая - два: -lt и /home/peter/.

Если программа написана на языке C, то при ее запуске управление сразу передается в функцию main() , следовательно, именно она получает аргументы командной строки, которые присваиваются ее переменным-параметрам.

До этого мы определяли функцию main() так, как-будто она не принимает никакие параметры и ничего не возвращает. На самом деле в языке C любая функция по-умолчанию (если не определено ничего иного) возвращает целое число. В этом можно убедиться. Если записать код таким образом:

main() { printf ("Hi\n " ) ; return 0 ; }

То никакого предупреждения или ошибки при компиляции не возникнет. То же самое будет, если записать int main() . Это доказывает, что функция по-умолчанию возвращает целое число, а не ничто (void). Хотя то, что возвращает функция всегда можно "переопределить", например, voidmain() или float main() .

При вызове программы из командной строки в нее всегда передается пара данных:

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

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

./a.out 12 theme 2

То первый аргумент программы имеет значение 4, а массив строк определяется как {"./a.out", "12", "theme", "2"}.

Обратите внимание на терминологию, есть всего два аргумента программы (число и массив), но сколько угодно аргументов командной строки. Аргументы командной строки "преобразуются" в аргументы программы (в аргументы функции main()).
Эти данные (число и указатель) передаются в программу даже тогда, когда она просто вызывается по имени без передачи в нее чего-либо: ./a.out. В таком случае первый аргумент имеет значение 1, а второй указывает на массив, состоящий всего из одной строки {"./a.out"}.

То, что в программу передаются данные, вовсе не означает, что функция main() должна их принимать. Если функция main() определена без параметров, то получить доступ к аргументам командной строки невозможно. Хотя ничего вам не мешает их передавать. Ошибки не возникнет.

Чтобы получить доступ к переданным в программу данным, их необходимо присвоить переменным. Поскольку аргументы сразу передаются в main() , то ее заголовок должен выглядеть таким образом:
main (int n, char *arr)

В первой переменной (n) содержится количество слов, а во второй - указатель на массив строк. Часто второй параметр записывают в виде **arr . Однако это то же самое. Вспомним, что сам массив строк, содержит в качестве своих элементов указатели на строки. А в функцию мы передаем указатель на первый элемент массива. Получается, что передаем указатель на указатель, т.е. **arr .

Задание
Напишите такую программу:

#include int main(int argc, char ** argv) { int i; printf ("%d\n " , argc) ; for (i= 0 ; i < argc; i++ ) puts (argv[ i] ) ; }

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

В программе мы использовали переменные-параметры argc и argv. Принято использовать именно такие имена, но на самом деле они могут быть любыми. Лучше придерживаться этого стандарта, чтобы ваши программы были более понятны не только вам, но и другим программистам.

Практическое значение передачи данных в программу

Если у вас есть опыт работы в командной строке GNU/Linux, вы знаете, что у большинства команд есть ключи и аргументы. Например, при просмотре содержимого каталогов, копировании, перемещении в качестве аргументов указываются объекты файловой системы, над которыми выполняется команда. Особенности ее выполнения определяются с помощью ключей. Например, в команде

Cp -r ../les_1 ../les_101

cp - это имя команды, -r - ключ, а../les_1 и../les_101 - аргументы команды.

Вообще чаще всего в программы при их запуске передаются адреса файлов и "модификаторы" (это ключи) процесса выполнения программы.

Напишем программу, которая открывает указанные пользователем в командной строке файлы на запись или добавление и записывает (добавляет) туда одну и туже информацию, которую пользователь вводит с клавиатуры в процессе выполнения программы:

#include #include main (int argc, char ** argv) { int i, ch; FILE * f[ 5 ] ; if (argc < 3 || argc > 7 ) { puts ("Неверное количество параметров" ) ; return 1 ; } if (strcmp (argv[ 1 ] , "-w" ) != 0 && strcmp (argv[ 1 ] , "-a" ) != 0 ) { puts ("Первый параметр может быть либо -w, либо -a" ) ; return 2 ; } for (i= 0 ; i < argc- 2 ; i++ ) { f[ i] = fopen (argv[ i+ 2 ] , argv[ 1 ] + 1 ) ; if (f[ i] == NULL) { printf ("Файл %s нельзя открыть\n " , argv[ i+ 2 ] ) ; return 3 ; } } while ((ch = getchar () ) != EOF) for (i= 0 ; i < argc- 2 ; i++ ) putc (ch, f[ i] ) ; for (i= 0 ; i < argc- 2 ; i++ ) fclose (f[ i] ) ; return 0 ; }

Пояснения к коду:

  1. Создается массив из пяти файловых указателей. Следовательно можно одновременно открыть не более пяти файлов. Файловый указатель первого файла будет хранится в элементе массива f, второго - в f и т.д.
  2. Проверяется количество аргументов командной строки. Их должно быть не меньше трех, т.к. первый - это имя программы, второй - режим открытия файла, третий - первый или единственный файл, в который будет производится запись. Поскольку программа позволяет открыть только пять файлов, то общее число аргументов командной строки не может быть больше семи. Поэтому если количество аргументов меньше 3 или больше 7, то программа завершается, т.к. оператор return приводит к выходу из функции, даже если после него есть еще код. Возвращаемое из функции значение неравное 0, может быть интерпретировано родительским процессом, как сообщение о том, что программа завершилась с ошибкой.
  3. Проверяется корректность второго аргумента командной строки. Если он не равен ни "-w", ни "-a", то условное выражение во втором if возвращает 1 (true). Функция strcmp() позволяет сравнивать строки и возвращает 0 в случае их равенства.
  4. В цикле for открываются файлы по указанным адресам, которые начинаются с третьего элемента массива argv. Именно поэтому к i прибавляется 2, чтобы получать элементы массива argv, начиная с третьего. Выражение argc-2 указывает на количество переданных имен файлов; т.к. в argc хранится общее число аргументов командной строки, первые два из которых не являются именами файлов.
  5. Выражение argv+1 позволяет "вырезать" из строки "-w" (или "-a") подстроку "w" (или "a"), т.к. argv по сути указатель на первый элемент строки. Прибавляя к указателю единицу, мы смещаем его к следующему элементу массива.
  6. Если файл отрыть не удается, то функция fopen() возвращает NULL. В таком случае программа завершается.
  7. Каждый символ, введенный пользователем с клавиатуры, записывается во все открытые файлы.
  8. В конце файлы закрываются.

Обратите внимание, в этой версии main() никаких параметров нет. Тем не менее, многие программы нуждаются в некоторых входных данных. Например, предположим, что вы пишете программу под названием Picture, которая принимает изображение в качестве входных данных, а затем делает из этого изображения миниатюру (уменьшенная версия изображения). Как функция Picture узнает, какое изображение нужно принять и обработать? Пользователь должен сообщить программе, какой файл следует открыть. Это можно сделать следующим образом:

// Программа: Picture #include #include int main() { std::cout << "Enter name of image-file to create a thumbnail for: "; std::string filename; std::cin >> filename; // Открываем файл-изображение // Создаём миниатюру // Выводим миниатюру }

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

Рассмотрим это детальнее.

Например, вы хотите создать миниатюры для всех файлов-изображений, которые находятся в определённом каталоге. Как это сделать? Вы можете запускать эту программу столько раз, сколько есть изображений в каталоге, введя каждое имя файла вручную. Однако, если есть сотни изображений, такой подход будет, мягко говоря, не очень эффективен! Решением здесь будет написать программу, которая перебирала бы каждое имя файла в каталоге, вызывая каждый раз Picture для каждого файла.

Теперь рассмотрим случай, когда у вас есть веб-сайт, и вы хотите, чтобы он создавал миниатюру каждый раз, когда пользователь загружает изображение на сайт. Эта программа не может принимать входные данные из Интернета и следует логический вопрос: «Как тогда вводить имя файла?». Выход есть: вызов веб-сервером функции Picture автоматически каждый раз после загрузки файла.

В обоих случаях нам нужно, чтобы внешняя программа передавала имя файла в качестве входных данных в нашу программу при её запуске, вместо того, чтобы Picture сам дожидался, пока пользователь вручную введёт имя файла.

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

Передача аргументов командной строки

Исполняемые программы могут запускаться в командной строке через вызов. Например, для запуска исполняемого файла MyProgram, который находится в корневом каталоге диска C в ОС Windows вам нужно ввести:

C:\>MyProgram

Чтобы передать аргументы командной строки в MyProgram, вам нужно будет их просто перечислить после имени исполняемого файла:

C:\>MyProgram SomeContent.txt

Теперь, при запуске MyProgram, SomeContent.txt будет предоставлен в качестве аргумента командной строки. Программа может иметь несколько аргументов командной строки, разделённых пробелами:

C:\>MyProgram SomeContent.txt SomeOtherContent.txt

Это также работает и с другими операционными системами, например, с Linux (хотя структура каталогов будет отличаться от структуры каталогов в Windows).

Если вы запускаете свою программу из среды IDE, то ваша IDE должна предоставить способ ввода аргументов командной строки.

Для пользователей Visual Studio : Щёлкните правой кнопкой мыши на нужный проект в Обозревателе Решений, а затем выберите «Свойства» :

Затем «Свойства конфигурации > Отладка» . На правой панели будет строка «Аргументы команды» . Вы сможете здесь ввести аргументы командной строки, и они будут автоматически переданы вашей программе при её запуске:

Пользователям Code::Blocks нужно выбрать «Project > Set program`s arguments»:

Использование аргументов командной строки

Теперь, когда вы знаете, как передавать аргументы командной строки в программу, следующим шагом будет доступ к ним из программы. Для этого используется уже другая форма функции main(), которая принимает два аргумента (argc и argv) следующим образом:

int main(int argc, char *argv)

Также вы можете увидеть и такой вариант:

int main(int argc, char** argv)

int main (int argc , char * * argv )

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

argc (англ. «arg ument c ount» = «количество аргументов») — это целочисленный параметр, содержащий количество аргументов, переданных в программу. argc всегда будет как минимум 1, так как первым аргументом всегда является имя самой программы. Каждый аргумент командной строки, который предоставляет пользователь, заставит argc увеличиться на 1.

argv (англ. «arg ument v alues» = «значения аргументов») — это место, где хранятся фактические значения аргументов. Хотя объявление argv выглядит немного пугающе, но это всего лишь массив . Длина этого массива — argc .

Давайте напишем короткую программу MyArguments, которая будет выводить значения всех аргументов командной строки:

// Программа: MyArguments #include int main(int argc, char *argv) { std::cout << "There are " << argc << " arguments:\n"; // Перебираем каждый аргумент и выводим его порядковый номер и значение for (int count=0; count < argc; ++count) std::cout << count << " " << argv << "\n"; return 0; }

// Программа: MyArguments

#include

int main (int argc , char * argv )

// Перебираем каждый аргумент и выводим его порядковый номер и значение

for (int count = 0 ; count < argc ; ++ count )

std :: cout << count << " " << argv [ count ] << "\n" ;

return 0 ;

Теперь, при вызове MyArguments с аргументами командной строки SomeContent.txt и 200 , вывод будет следующим:

There are 3 arguments:
0 C:\MyArguments
1 SomeContent.txt
2 200

Параметр 0 — это путь и имя текущей программы. Параметры 1 и 2 здесь являются аргументами командной строки, которые мы передали.

Обработка числовых аргументов

Аргументы командной строки всегда передаются в качестве строк, даже если предоставленное значение является числовым. Чтобы использовать аргумент командной строки в виде числа, вам нужно будет конвертировать его из строки в число. К сожалению, в C++ это делается немного сложнее, чем оно должно быть:

#include #include #include // для std::stringstream #include // для exit() int main(int argc, char *argv) { if (argc <= 1) { // В некоторых операционных системах, argv может быть просто пустой строкой, без имени программы // Обрабатываем случай, когда argv может быть пустым или не пустым if (argv) std::cout << "Usage: " << argv << " " << "\n"; else std::cout << "Usage: " << "\n"; exit(1); } std::stringstream convert(argv); // создаём переменную stringstream с именем convert, инициализируя её значением argv int myint; if (!(convert >> myint)) // выполняем конвертацию myint = 0; // если конвертация терпит неудачу, то задаём myint значение по умолчанию std::cout << "Got integer: " << myint << "\n"; return 0; }

#include

#include

#include // для std::stringstream

#include // для exit()

int main (int argc , char * argv )

if (argc <= 1 )

// В некоторых операционных системах, argv может быть просто пустой строкой, без имени программы

// Обрабатываем случай, когда argv может быть пустым или не пустым

if (argv [ 0 ] )

std :: cout << "Usage: " << argv [ 0 ] << " " << "\n" ;

else

std :: cout << "Usage: " << "\n" ;

exit (1 ) ;

В программы на языке Си можно передавать некоторые аргументы. Когда вначале вычислений производится обращение к main(), ей передаются три параметра. Первый из них определяет число командных аргументов при обращении к программе. Второй представляет собой массив указателей на символьные строки, содержащие эти аргументы (в одной строке - один аргумент). Третий тоже является массивом указателей на символьные строки, он используется для доступа к параметрам операционной системы (к переменным окружения).

Любая такая строка представляется в виде:

переменная = значение\0

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

Назовем аргументы функции main() соответственно: argc, argv и env (возможны и любые другие имена). Тогда допустимы следующие описания:

main(int argc, char *argv)

main(int argc, char *argv, char *env)

Предположим, что на диске A: есть некоторая программа prog.exe. Обратимся к ней следующим образом:

A:\>prog.exe file1 file2 file3

Тогда argv - это указатель на строку A:\prog.exe, argv - на строку file1 и т.д. На первый фактический аргумент указывает argv, а на последний - argv. Если argc=1, то после имени программы в командной строке параметров нет. В нашем примере argc=4.

Рекурсия

Рекурсией называется такой способ вызова, при котором функция обращается к самой себе.

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

Библиотечные функции

В системах программирования подпрограммы для решения часто встречающихся задач объединяются в библиотеки. К числу таких задач относятся: вычисление математических функций, ввод/вывод данных, обработка строк, взаимодействие со средствами операционной системы и др. Использование библиотечных подпрограмм избавляет пользователя от необходимости разработки соответствующих средств и предоставляет ему дополнительный сервис. Включенные в библиотеки функции поставляются вместе с системой программирования. Их объявления даны в файлах *.h (это так называемые включаемые или заголовочные файлы). Поэтому, как уже упоминалось выше, в начале программы с библиотечными функциями должны быть строки вида:

#include <включаемый_файл_типа_h>

Например:

#include

Существуют также средства для расширения и создания новых библиотек с программами пользователя.

Для глобальных переменных отводится фиксированное место в памяти на все время работы программы. Локальные переменные хранятся в стеке. Между ними находится область памяти для динамического распределения.

Функции malloc() и free() используются для динамического распределения свободной памяти. Функция malloc() выделяет память, функция free() освобождает ее. Прототипы этих функций хранятся в заголовочном файле stdlib.h и имеют вид:

void *malloc(size_t size);

void *free(void *p);

Функция malloc() возвращает указатель типа void; для правильного использования значение функции надо преобразовать к указателю на соответствующий тип. При успешном выполнении функция возвращает указатель на первый байт свободной памяти размера size. Если достаточного количества памяти нет, возвращается значение 0. Чтобы определить количество байтов, необходимых для переменной, используют операцию sizeof().

Пример использования этих функций:

#include

#include

p = (int *) malloc(100 * sizeof(int)); /* Выделение памяти для 100

целых чисел */

printf("Недостаточно памяти\n");

for (i = 0; i < 100; ++i) *(p+i) = i; /* Использование памяти */

for (i = 0; i < 100; ++i) printf("%d", *(p++));

free(p); /* Освобождение памяти */

Перед использованием указателя, возвращаемого malloc(), необходимо убедиться, что памяти достаточно (указатель не нулевой).

Препроцессор

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

Директива

#define идентификатор подстановка

вызывает замену в последующем тексте программы названного идентификатора на текст подстановки (обратите внимание на отсутствие точки с запятой в конце этой команды). По существу, эта директива вводит макроопределение (макрос), где "идентификатор" - это имя макроопределения, а "подстановка" - последовательность символов, на которые препроцессор заменяет указанное имя, когда находит его в тексте программы. Имя макроопределения принято набирать прописными буквами.

Рассмотрим примеры:

Первая строка вызывает замену в программе идентификатора MAX на константу 25. Вторая позволяет использовать в тексте вместо открывающей фигурной скобки ({) слово BEGIN.

Отметим, что поскольку препроцессор не проверяет совместимость между символическими именами макроопределений и контекстом, в котором они используются, то рекомендуется такого рода идентификаторы определять не директивой #define, а с помощью ключевого слова const с явным указанием типа (это в большей степени относится к Си++):

const int MAX = 25;

(тип int можно не указывать, так как он устанавливается по умолчанию).

Если директива #define имеет вид:

#define идентификатор(идентификатор, ..., идентификатор) подстановка

причем между первым идентификатором и открывающей круглой скобкой нет пробела, то это определение макроподстановки с аргументами. Например, после появления строки вида:

#define READ(val) scanf("%d", &val)

оператор READ(y); воспринимается так же, как scanf("%d",&y);. Здесь val - аргумент и выполнена макроподстановка с аргументом.

При наличии длинных определений в подстановке, продолжающихся в следующей строке, в конце очередной строки с продолжением ставится символ \.

В макроопределение можно помещать объекты, разделенные знаками ##, например:

#define PR(x, у) x##y

После этого PR(а, 3) вызовет подстановку а3. Или, например, макроопределение

#define z(a, b, c, d) a(b##c##d)

приведет к замене z(sin, x, +, y) на sin(x+y).

Символ #, помещаемый перед макроаргументом, указывает на преобразование его в строку. Например, после директивы

#define PRIM(var) printf(#var"= %d", var)

следующий фрагмент текста программы

преобразуется так:

printf("year""= %d", year);

Опишем другие директивы препроцессора. Директива #include уже встречалась ранее. Ее можно использовать в двух формах:

#include "имя файла"

#include <имя файла>

Действие обеих команд сводится к включению в программу файлов с указанным именем. Первая из них загружает файл из текущего или заданного в качестве префикса каталога. Вторая команда осуществляет поиск файла в стандартных местах, определенных в системе программирования. Если файл, имя которого записано в двойных кавычках, не найден в указанном каталоге, то поиск будет продолжен в подкаталогах, заданных для команды #include <...>. Директивы #include могут вкладываться одна в другую.

Следующая группа директив позволяет избирательно компилировать части программы. Этот процесс называется условной компиляцией. В эту группу входят директивы #if, #else, #elif, #endif, #ifdef, #ifndef. Основная форма записи директивы #if имеет вид:

#if константное_выражение последовательность_операторов

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

Действие директивы #else подобно действию команды else в языке Си, например:

#if константное_выражение

последовательность_операторов_2

Здесь если константное выражение истинно, то выполняется последовательность_операторов_1, а если ложно - последовательность_операторов_2.

Директива #elif означает действие типа "else if". Основная форма ее использования имеет вид:

#if константное_выражение

последовательность_операторов

#elif константное_выражение_1

последовательность_операторов_1

#elif константное_выражение_n

последовательность_операторов_n

Эта форма подобна конструкции языка Си вида: if...else if...else if...

Директива

#ifdef идентификатор

устанавливает определен ли в данный момент указанный идентификатор, т.е. входил ли он в директивы вида #define. Строка вида

#ifndef идентификатор

проверяет является ли неопределенным в данный момент указанный идентификатор. За любой из этих директив может следовать произвольное число строк текста, возможно, содержащих инструкцию #else (#elif использовать нельзя) и заканчивающихся строкой #endif. Если проверяемое условие истинно, то игнорируются все строки между #else и #endif, а если ложно, то строки между проверкой и #else (если слова #else нет, то #endif). Директивы #if и #ifndef могут "вкладываться" одна в другую.

Директива вида

#undef идентификатор

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

Рассмотрим примеры. Три следующие директивы:

проверяют определен ли идентификатор WRITE (т.е. была ли команда вида #define WRITE...), и если это так, то имя WRITE начинает считаться неопределенным, т.е. не подлежащим замене.

Директивы

#define WRITE fprintf

проверяют является ли идентификатор WRITE неопределенным, и если это так, то определятся идентификатор WRITE вместо имени fprintf.

Директива #error записывается в следующей форме:

#error сообщение_об_ошибке

Если она встречается в тексте программы, то компиляция прекращается и на экран дисплея выводится сообщение об ошибке. Эта команда в основном применяется на этапе отладки. Заметим, что сообщение об ошибке не надо заключать в двойные кавычки.

Директива #line предназначена для изменения значений переменных _LINE_ и _FILE_, определенных в системе программирования Си. Переменная _LINE_ содержит номер строки программы, выполняемой в текущий момент времени. Идентификатор _FILE_ является указателем на строку с именем компилируемой программы. Директива #line записывается следующим образом:

#line номер "имя_файла"

Здесь номер - это любое положительное целое число, которое будет назначено переменной _LINE_, имя_файла - это необязательный параметр, который переопределяет значение _FILE_.

Директива #pragma позволяет передать компилятору некоторые указания. Например, строка

говорит о том, что в программе на языке Си имеются строки на языке ассемблера. Например:

Рассмотрим некоторые глобальные идентификаторы или макроимена (имена макроопределений). Определены пять таких имен: _LINE_, _FILE_, _DATE_, _TIME_, _STDC_. Два из них (_LINE_ и _FILE_) уже описывались выше. Идентификатор _DATE_ определяет строку, в которой сохраняется дата трансляции исходного файла в объектный код. Идентификатор _TIME_ задает строку, сохраняющую время трансляции исходного файла в объектный код. Макрос _STDC_ имеет значение 1, если используются стандартно - определенные макроимена. В противном случае эта переменная не будет определена.

Необязательные и именованные аргументы

Необязательные аргументы

В версии C# 4.0 внедрено новое средство, повышающее удобство указания аргументов при вызове метода. Это средство называется необязательными аргументами и позволяет определить используемое по умолчанию значение для параметра метода. Данное значение будет использоваться по умолчанию в том случае, если для параметра не указан соответствующий аргумент при вызове метода. Следовательно, указывать аргумент для такого параметра не обязательно. Необязательные аргументы позволяют упростить вызов методов, где к некоторым параметрам применяются аргументы, выбираемые по умолчанию. Их можно также использовать в качестве "сокращенной" формы перегрузки методов .

Главным стимулом для добавления необязательных аргументов послужила необходимость в упрощении взаимодействия с объектами СОМ. В нескольких объектных моделях Microsoft (например, Microsoft Office) функциональность предоставляется через объекты СОМ, многие из которых были написаны давно и рассчитаны на использование необязательных параметров.

Пример использования необязательных аргументов показан ниже:

Using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { class Program { // Аргументы b и с указывать при вызове необязательно static int mySum(int a, int b = 5, int c = 10) { return a + b + c; } static void Main() { int sum1 = mySum(3); int sum2 = mySum(3,12); Console.WriteLine("Sum1 = "+sum1); Console.WriteLine("Sum2 = "+sum2); Console.ReadLine(); } } }

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

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

Именованные аргументы

Еще одной функциональной возможностью, которая добавилась в C# с выходом версии.NET 4.0, является поддержка так называемых именованных аргументов (named arguments) . Как известно, при передаче аргументов методу порядок их следования, как правило, должен совпадать с тем порядком, в котором параметры определены в самом методе. Иными словами, значение аргумента присваивается параметру по его позиции в списке аргументов.

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

имя_параметра: значение

Здесь имя_параметра обозначает имя того параметра, которому передается значение. Разумеется, имя_параметра должно обозначать имя действительного параметра для вызываемого метода.

© 2024 baraxlo2020.ru -- Немного о компьютере и современных гаджетах