Borland С++ поддерживает три аргумента main(). Первые два - это традиционные argc и argv. Это единственные аргументы функции main(), определяемые стандартом ANSI С. Они позволяют передавать аргументы командной строки в программу. Аргументы командной строки - это информация, следующая за именем программы в командной строке операционной системы. Например, когда программа компилируется с помощью строчного компилятора Borland, набирается, как правило, bcc имя_ программы
Где имя_программы - это программа, которую необходимо откомпилировать. Имя программы передается компилятору в качестве аргумента.
Параметр argc содержит число аргументов командной строки и является целым числом. Он всегда равен, по крайней мере, 1, поскольку имя программы квалифицируется как первый аргумент. Параметр argv - это указатель на массив символьных указателей. Каждый элемент данного массива указывает на аргумент командной строки. Все аргументы командной строки - это строки. Все числа конвертируются программой во внутренний формат. Следующая программа выводит «Hello», а затем имя пользователя, если его набрать прямо за именем программы:
#include
{
if(argc!=2)
{
printf ("You forgot to type your name\n");
return 1;
}
printf("Hello %s", argv);
return 0;
}
Если назвать данную программу name, а имя пользователя Сергей, то для запуска программы следует набрать:
name Сергей.
В результате работы программы появится:
«Hello Сергей».
Аргументы командной строки должны отделяться пробелами или табуляциями. Запятые, точки с запятыми и им подобные символы не рассматриваются как разделители. Например:
Состоит из трех строк, в то время как
Herb,Rick,Fred
Это одна строка - запятые не являются разделителями.
Если необходимо передать строку, содержащую пробелы или табуляции в виде одного аргумента, следует ее заключить в двойные кавычки. Например, это один аргумент:
"this is a test"
Важно правильно объявить argv. Наиболее типичным методом является:
Пустые скобки указывают на то, что массив не имеет фиксированной длины. Можно получить доступ к отдельным элементам с помощью индексации argv. Например, argv указывает на первую строку, всегда содержащую имя программы. argv указывает на следующую строку и так далее.
Ниже приведен небольшой пример по использованию аргументов командной строки. Он отсчитывает в обратном порядке от значения, указанного в командной строке, и при достижении нуля подает сигнал. Обратим внимание, что первый аргумент содержит число, преобразованное в целое число с использованием стандартной функции atoi(). Если в качестве второго аргумента присутствует строка "display", то на экране будет отображаться сам счетчик.
/* программа отсчета */
#include
#include
# include
int main(int argc, char *argv)
{
int disp, count;
if(argc<2)
{
printf("You must enter the length of the count\n");
printf ("on the command line. Try again.\n");
return 1;
}
if (argc==3 && !strcmp(argv,"display")) disp = 1;
else disp = 0;
for(count=atoi(argv); count; -count)
if (disp) printf("%d ", count);
printf("%c", "\a"); /* на большинстве компьютеров это звонок */
return 0;
}
Обратим внимание, что если не указаны аргументы, появляется сообщение об ошибке. Это наиболее типично для программ, использующих аргументы командной строки для выдачи инструкций, если была попытка запустить программу без правильной информации.
Для доступа к отдельным символам командной строки следует добавить второй индекс к argv. Например, следующая программа выводит все аргументы, с которыми она вызывалась, по одному символу за раз:
#include
int main(int argc, char *argv)
{
int t, i;
for(t=0; t
i = 0;
while(argv[t][i])
{
printf("%c", argv[t][i]);
}
printf (" ");
}
return 0;
}
Надо помнить, что первый индекс предназначен для доступа к строке, а второй - для доступа к символу строки.
Обычно argc и argv используются для получения исходных команд. Теоретически можно иметь до 32767 аргументов, но большинство операционных систем не позволяют даже близко подойти к этому. Обычно данные аргументы используются для указания имени файла или опций. Использование аргументов командной строки придает программе профессиональный вид и допускает использование программы в командных файлах.
Если подсоединить файл WILDARGS.OBJ, поставляемый с Borland С++, то можно будет использовать шаблоны в аргументах типа *.EXE. (Borland С++ автоматически обрабатывает шаблоны и соответствующим образом увеличивает argc.) Например, если подсоединить к следующей программе WILDARGS.OBJ, она выдаст, сколько файлов соответствует имени указанного в командной строке файла:
/* Скомпонуйте данную программу с WILDARGS.OBJ */
#include
int main(int argc, char *argv)
{
register int i;
printf("%d files match specified name\n", argc-1);
printf("They are: ");
for(i=1; i
return 0;
}
Если назвать данную программу WA, затем запустить ее как указано ниже, получим число файлов, имеющих расширение ЕХE, и список имен этих файлов:
Помимо argc и argv Borland С++ также предоставляет третий аргумент командной строки -env. Параметр env позволяет программе получить доступ к информации о среде операционной системы. Параметр env должен следовать за argc и argv и объявляется следующим образом:
Как можно видеть, env объявляется так же, как и argv. Так же, как и argv, это указатель на массив строк. Каждая строка - это строка среды, определенная операционной системой. Параметр env не имеет аналога параметра argc, который сообщал бы, сколько имеется строк среды. Вместо этого последняя строка среды нулевая. Следующая программа выводит все строки среды, определенные на текущий момент в операционной системе:
/* данная программа выводит все строки окружения */
#include
int main(int argc, char *argv, char *env)
{
int t;
for(t=0; env[t]/ t++)
printf("%s\n", env[t]);
return 0;
}
Обратим внимание, что хотя argc и argv не используются программой, они должны присутствовать в списке параметров. С не знает имена параметров. Вместо этого их использование определяется по порядку объявления параметров. Фактически можно обозвать параметр как угодно. Поскольку argc, argv и env - это традиционные имена, то лучше их использовать и далее, чтобы любой человек, читающий программу, мог мгновенно понять, что это аргументы функции main().
Для программ типичной задачей является поиск значения, определенного в строке среды. Например, содержимое строки PATH позволяет программам использовать пути поиска. Следующая программа демонстрирует, как найти строки, объявляющие стандартные пути поиска. Она использует стандартную библиотечную функцию strstr(), имеющую следующий прототип:
Char *strstr(const char *str1, const char *str2);
Функция strstr() ищет строку, на которую указывает str1 в строке, на которую указывает str2. Если такая строка найдена, то возвращается указатель на первое положение. Если не найдено соответствий, то функция возвращает NULL.
/* программа ищет среди строк окружения строку, содержащую PATH */
#include
#include
int main (int argc, char *argv, char *env)
{
int t;
for(t=0; env[t]; t++)
{
if(strstr(env[t], "PATH"))
printf("%s\n", env[t]);
}
return 0;
}
При создании консольного приложения в языке программирования С++, автоматически создается строка очень похожая на эту:
Int main(int argc, char* argv) // параметры функции main()
Эта строка — заголовок главной функции main() , в скобочках объявлены параметры argс и argv. Так вот, если программу запускать через командную строку, то существует возможность передать какую-либо информацию этой программе, для этого и существуют параметры argc и argv . Параметр argc имеет тип данных int , и содержит количество параметров, передаваемых в функцию main . Причем argc всегда не меньше 1, даже когда мы не передаем никакой информации, так как первым параметром считается имя функции. Параметр argv это массив указателей на строки. Через командную строку можно передать только данные строкового типа. Указатели и строки — это две большие темы, под которые созданы отдельные разделы. Так вот именно через параметр argv и передается какая-либо информация. Разработаем программу, которую будем запускать через командную строку Windows, и передавать ей некоторую информацию.
// argc_argv.cpp: определяет точку входа для консольного приложения.
#include "stdafx.h"
#include // код Code::Blocks // код Dev-C++ // argc_argv.cpp: определяет точку входа для консольного приложения.
#include После того как отладили программу, открываем командную строку Windows и перетаскиваем в окно командной строки экзэшник нашей программы, в командной строке отобразится полный путь к программе(но можно прописать путь к программе в ручную), после этого можно нажимать ENTER
и программа запустится (см. Рисунок 1). Рисунок 1 — Параметры функции main Так как мы просто запустили программу и не передавали ей никаких аргументов, появилось сообщение Not arguments . На рисунке 2 изображён запуск этой же программы через командную строку, но уже с передачей ей аргумента Open . Рисунок 2 — Параметры функции main Аргументом является слово Open , как видно из рисунка, это слово появилось на экране. Передавать можно несколько параметров сразу, отделяя их между собой запятой. Если необходимо передать параметр состоящий из нескольких слов, то их необходимо взять в двойные кавычки, и тогда эти слова будут считаться как один параметр. Например, на рисунке изображен запуск программы, с передачей ей аргумента, состоящего из двух слов — It work . Рисунок 3 — Параметры функции main А если убрать кавычки. То увидим только слово It . Если не планируется передавать какую-либо информацию при запуске программы, то можно удалить аргументы в функции main() , также можно менять имена данных аргументов. Иногда встречается модификации параметров argc и argv , но это все зависит от типа создаваемого приложения или от среды разработки. При автоматизированном создании консольного приложения в языке программирования С++, автоматически создается главная функция очень похожая на эту: int
main(int
argc, char
* argv) Заголовок функции содержит сигнатуру главной функции main()
с аргументами argс
и argv
. При запуске программы через командную строку Windows можно передавать ей некоторую информацию. При этом командная строка будет иметь вид: Аргументы командной строки разделяются одним или несколькими пробелами. Аргумент argv
содержит полное имя приложения: #include
cout << argv << endl; Return
0; Результат выполнения Пример
: вычисление произведения двух целых чисел #include
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; Запуск программы осуществляется как Результат выполнения Для передачи аргументов командной строки при отладке программы необходимо обратиться к меню Свойства
проекта. При запуске программы в режиме отладки введенные аргументы будут восприниматься программой как аргументы командной строки.
В программы на
языке Си можно передавать некоторые
аргументы. Когда вначале вычислений
производится обращение к 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, если используются стандартно
- определенные макроимена. В противном
случае эта переменная не будет определена. Бывает, что данные в программу передаются из командной строки при ее вызове. Такие данные называются аргументами командной строки. Выглядит это так, например:
./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() . При вызове программы из командной строки в нее всегда передается пара данных: Следует иметь в виду, что само имя программы также считается. Например, если вызов выглядит так:
./a.out 12 theme 2
То первый аргумент программы имеет значение 4, а массив строк определяется как {"./a.out", "12", "theme", "2"}. Обратите внимание на терминологию, есть всего два аргумента программы (число и массив), но сколько угодно аргументов командной строки. Аргументы командной строки "преобразуются" в аргументы программы (в аргументы функции main()). То, что в программу передаются данные, вовсе не означает, что функция main() должна их принимать. Если функция main() определена без параметров, то получить доступ к аргументам командной строки невозможно. Хотя ничего вам не мешает их передавать. Ошибки не возникнет. Чтобы получить доступ к переданным в программу данным, их необходимо присвоить переменным. Поскольку аргументы сразу передаются в main() , то ее заголовок должен выглядеть таким образом: В первой переменной (n) содержится количество слов, а во второй - указатель на массив строк. Часто второй параметр записывают в виде **arr . Однако это то же самое. Вспомним, что сам массив строк, содержит в качестве своих элементов указатели на строки. А в функцию мы передаем указатель на первый элемент массива. Получается, что передаем указатель на указатель, т.е. **arr . Задание
#include Она выводит количество слов в командной строке при ее вызове и каждое слово с новой строки. Вызовите ее без аргументов командной строки и с аргументами. В программе мы использовали переменные-параметры argc и argv. Принято использовать именно такие имена, но на самом деле они могут быть любыми. Лучше придерживаться этого стандарта, чтобы ваши программы были более понятны не только вам, но и другим программистам. Если у вас есть опыт работы в командной строке GNU/Linux, вы знаете, что у большинства команд есть ключи и аргументы. Например, при просмотре содержимого каталогов, копировании, перемещении в качестве аргументов указываются объекты файловой системы, над которыми выполняется команда. Особенности ее выполнения определяются с помощью ключей. Например, в команде Cp -r ../les_1 ../les_101
cp - это имя команды, -r - ключ, а../les_1 и../les_101 - аргументы команды. Вообще чаще всего в программы при их запуске передаются адреса файлов и "модификаторы" (это ключи) процесса выполнения программы. Напишем программу, которая открывает указанные пользователем в командной строке файлы на запись или добавление и записывает (добавляет) туда одну и туже информацию, которую пользователь вводит с клавиатуры в процессе выполнения программы: #include Пояснения к коду:
{…}
Если программу запускать через командную строку, то существует возможность передать какую-либо информацию этой программе. Для этого существуют аргументы командной строки argc
и argv
.
Параметр argc
имеет тип int
, и содержит количество параметров, передаваемых в функцию main
. Причем argc
всегда не меньше 1, даже когда функции main
не передается никакой информации, так как первым параметром считается имя приложения.
Параметр argv
представляет собой массив указателей на строки. Через командную строку можно передать только данные строкового типа.
Диск:\путь\имя.exe аргумент1 аргумент2 …
using namespace
std;
}
В программе используется функция преобразования строки в целое число StrToInt()
отсюда .
using namespace
std;
int
StrToInt(char
*s) {…}
int
main(int
argc, char
* argv) {
}Отладка программы с аргументами командной строки
На вкладке Свойства конфигурации ->Отладка
выбрать Аргументы команды
и задать их значения.
Рекурсия
Библиотечные функции
Эти данные (число и указатель) передаются в программу даже тогда, когда она просто вызывается по имени без передачи в нее чего-либо: ./a.out. В таком случае первый аргумент имеет значение 1, а второй указывает на массив, состоящий всего из одной строки {"./a.out"}.
main (int n, char *arr)
Напишите такую программу:Практическое значение передачи данных в программу