Скачать презентацию Параметры функции main void main int argc char argv Скачать презентацию Параметры функции main void main int argc char argv

лекция2.pptx

  • Количество слайдов: 26

Параметры функции main void main(int argc, char *argv[], char *env[]) q Программы на C Параметры функции main void main(int argc, char *argv[], char *env[]) q Программы на C используют три параметра в main, q Параметр argc содержит количество аргументов командной строки, передаваемых в вашу программу. q Параметр argv представляет собой массив указателей на символьные строки, каждая из которых соответствует одному параметру командной строки. q Параметр env представляет собой массив указателей на символьные строки, указывающих на переменные среды. q Оба набора представлены в виде массивов указателей, причем последний указатель в каждом из массивов имеет значение NULL. q Имена argc и argv являются традиционными, но не обязательными. Эти два параметра в функции main() можно назвать как угодно.

Использование аргументов командной строки Аргументы командной строки это дополнительные информационные элементы, передаваемые программе во Использование аргументов командной строки Аргументы командной строки это дополнительные информационные элементы, передаваемые программе во время запуска. Они задаются в командной строке и отделяются от имени программы и друг от друга пробелами. . /prog 12 aaa qwe

q argv[0] имя вызываемой программы q argv[1] … argv[1] переданные в программу аргументы q q argv[0] имя вызываемой программы q argv[1] … argv[1] переданные в программу аргументы q argv[argc] = NULL q argc >= 1 echo Здравствуй, мир!

# ls -l dir 1 argc = 3 argv[0]= ‘ls’ argv[1]= ‘ l’ argv[2]= # ls -l dir 1 argc = 3 argv[0]= ‘ls’ argv[1]= ‘ l’ argv[2]= ‘dir 1’ argv[3]= NULL $ a. out a 1 a 2 a 3 argc = 4 argv[0] = "a. out" argv[1] = "a 1" argv[2] = "a 2" argv[3] = "a 3" argv[4] = NULL

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

#include <stdio. h> /* Эхо аргументов командной строки, версия 1 */ main(int argc, char #include /* Эхо аргументов командной строки, версия 1 */ main(int argc, char *argv[]) { int i; for (i = 1; i < argc; i++) printf("%s%s", argv[i], (i < argc-1) ? " " : ""); printf("n"); return 0; @ echo Здравствуй, мир! } Здравствуй, мир! Можно цикл организовать так: while (--argc > 0) Инструкцию printf можно было бы написать и так: printf((argc > 1) ? "%s " : "%s", *++argv);

Использование переменных окружения q ОС UNIX предоставляет каждой выполняемой программе среду выполнения. q Начальные Использование переменных окружения q ОС UNIX предоставляет каждой выполняемой программе среду выполнения. q Начальные параметры окружающей среды процесса устанавливаются при входе пользователя в систему. q Каждый параметр имеет вид: переменная=строка. q Эти переменные называются переменными окружения. q В последующем они могут быть изменены. q Такие переменные используются для изменения долгосрочного поведения процессов, в отличие от аргументов командной строки. USER — содержит имя текущего пользователя; HOME — содержит путь к начальному каталогу текущего пользователя; PATH — содержит разделенный двоеточиями список каталогов, которые операционная система просматривает в поиске вызванной программы.

Использование переменных окружения Использование переменных окружения

Использование переменных окружения POSIX int main(int argc, char *argv[], char *envp[]); ANSI int main(int Использование переменных окружения POSIX int main(int argc, char *argv[], char *envp[]); ANSI int main(int argc, char *argv[]); extern char **environ;

 Программа выводит все переменные окружения Программа выводит все переменные окружения

Управление переменными окружения #include <stdio. h> #include <stdlib. h> #include <unistd. h> #include <string. Управление переменными окружения #include #include #include #include extern char ** environ; int main (int argc, char ** argv) { int i; if (argc < 2) { fprintf (stderr, "environ: Too few argumentsn"); exit (1); } for (i = 0; environ[i] != NULL; i++) { if (!strncmp (environ[i], argv[1], strlen (argv[1]))) { printf ("'%s' foundn", environ[i]); exit (0); } } printf ("'%s' not foundn", argv[1]); exit (0); }

Управление переменными окружения #include <stdlib. h> char *getenv(const char *name) – получить значение переменной Управление переменными окружения #include char *getenv(const char *name) – получить значение переменной окружения int putenv(const char *string) – установить конкретное значение переменной окружения Int setenv(const char *string) – создать переменную окружения Int unsetenv(char *name) – удалить переменную окружения Введенное значение переменной будет доступно в данном процессе и его дочерних. Поэтому, для того, чтобы увидеть результат действия, надо выводить список переменных окружения в той же программе, где происходит установка значения.

Управление переменными окружения #include <stdio. h> #include <stdlib. h> #define FL_OVWR 0 Первый параметр Управление переменными окружения #include #include #define FL_OVWR 0 Первый параметр - имя переменной окружения, второй параметр - ее значение, третий - флаг указывающий нужно ли затереть значение переменной, (0 - не затирать, != 0 - затереть). int main (int argc, char ** argv) { if (argc < 3) { fprintf (stderr, "setenv: Too few argumentsn"); exit (1); } if (setenv (argv[1], argv[2], 0) != 0) { fprintf (stderr, "setenv: Cannot set '%s'n", argv[1]); exit (1); } printf ("%s=%sn", argv[1], getenv (argv[1])); exit (0); }

Контроль программных ошибок В программе на C код возврата указывается в операторе return в Контроль программных ошибок В программе на C код возврата указывается в операторе return в функции main или при выполнении вызова функции exit(). Процесс может быть завершен и по независящим от него обстоятельствам, например вследствие получения сигнала. В этом случае функция exit() будет вызвана ядром от имени процесса. #include void exit(int status); Аргумент stratus - код возврата программы - возвращается родительскому процессу. Код завершения равен : • ноль, если программа завершена успешно (через вызовы процедур ABORT или EXIT или закончится работа процедуры main) • ненулевое 16 -разрядное целое число при наличие ошибки. Удобно различными ненулевыми кодами обозначать разные ошибочные ситуации. Расширенная информация об ошибках сохраняются в специальной переменной errno • макрос asssert() • функция atexit(): • обработка значений переменной errno

Макрос asssert() Используется для включения диагностики в программе. q правильности аргументов функций, q выполнения Макрос asssert() Используется для включения диагностики в программе. q правильности аргументов функций, q выполнения входных и выходных условий при вызове функций q наличия непредвиденных возвращаемых значений. #include assert (expression, [error_string]) Аргумент булево выражение. Если expression=TRUE программа продолжается Если expression=FALSE (или 0) программа завершается и выдает сообщение об ошибке с указанием исходного файла, номера строки, а также текста выражения, приведшего к ошибке. При этом разработчику предоставляется выбор окончательно прервать работу программы (Abort), переключиться в окно отладчика (Retry) или продолжить работу (Ignore).

Макрос asssert() ASSERT отслеживает программные ошибки только в отладочной версии #define DEBUG (стоит по Макрос asssert() ASSERT отслеживает программные ошибки только в отладочной версии #define DEBUG (стоит по умолчанию). Если программа компилируется как релиз ASSERT убирается препроцессором как комментарии. #define NDEBUG В качестве дополнительного параметра assert может принимать также сообщение, которое надо напечатать в случае срабатывания. assert ( fopen( s. File ), "Couldn't open filen" );

Макрос asssert() #include <assert. h> #include <stdio. h> #include <stdlib. h> void main() { Макрос asssert() #include #include #include void main() { int value; value = 3; while (value) { assert(value > 1); printf("Passed assert (%d > 1)n", value); value--; } }

#define DEBUG #include <assert. h> #define NDEBUG #include <assert. h> for (i = 0; #define DEBUG #include #define NDEBUG #include for (i = 0; i < 100; ++i) assert (funct()); программа будет останавливаться при успешном выполнении функции. функция funct() вообще не будет вызвана Надо так #define DEBUG #include for (i = 0; i < 100; ++i) { int status = funct(); assert (status == 0); }

Процедура ATEXIT #include <stdio. h> #include <stdlib. h> void handler 1() { printf(“handler 1n”); Процедура ATEXIT #include #include void handler 1() { printf(“handler 1n”); } void handler 2() { printf(“handler 2n”); } void handler 3() { printf(“handler 3n”); } int main() { atexit(&handler 1); atexit(&handler 2); atexit(&handler 3); return(0); } При успешном завершении программы кроме передачи кода возврата, функция exit() производит ряд дополнительных действий, в частности выводит буферизованные данные и закрывает потоки вводавывода. Такие действия называются обработкой выхода. Процедура ATEXIT - регистровая процедура, которая регистрирует функцию обработки выхода, адрес которой передается ей в качестве параметра. Вызываются эти обработчики по принципу LIFO. handler 3 handler 2 handler 1

Понятие системных вызовов Взаимодействие оболочки с ядром происходит с помощью системных вызовов. Системный вызов Понятие системных вызовов Взаимодействие оболочки с ядром происходит с помощью системных вызовов. Системный вызов – это требование к ОС (к ядру) произвести аппаратно (системно) специфическую или привилегированную операцию. Ø Каждому системному вызову соответствует функция (функции) с тем же именем, хранящаяся в библиотеке языка C. Ø Эти функции выполняют необходимое преобразование аргументов и вызывают требуемую процедуру ядра. В этом случае библиотечный код выполняет только роль оболочки, в то время как фактические команды, расположены в ядре ОС (написанные на С или Assemblere). Ø Помимо системных вызовов программисту предлагаются функции общего назначения. Ø Они не являются точками входа в ядро ОС, хотя в ходе выполнения могут выполнять системные вызовы. Ø Эти функции хранятся в системной библиотеке С.

Основные ситуации, приводящие к сбоям системных вызовов: Лимит ресурсов. В системе могут закончиться ресурсы Основные ситуации, приводящие к сбоям системных вызовов: Лимит ресурсов. В системе могут закончиться ресурсы или программа может исчерпать лимит ресурсов, наложенный на нее системой. (Запрос слишком большого объема памяти, или от крытия большого количества файлов одновременно). Ограничение прав доступа. Про грамма пытается выполнить операцию при отсутствии должных привилегий. (Попытка записи в доступный только для чтения файл, обращения к памяти другого процесса или уничтожить программу другого пользователя). Ошибочные аргументы. Ошибочно введенные пользователем данные, либо из за ошибки самой программы (передача системному вызову неправильного адреса памяти или неверного дескриптор файла). Другой вариант ошибки — попытка открыть каталог вместо обычного файла или наоборот. Ошибки устройств. Доступ к аппаратным устройствам, работающих некорректно или не поддерживающим требуемую операцию, либо в дисковод просто не вставлен диск. Внешние воздействия. Например, получение сигнала. Это не обязательно означает ошибку, но ответственность за перезапуск системного вызова возлагается на программу.

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

Переменная errno Текст диагностического сообщения хранится в предопределенном массиве sys_errlist, хранящийся в стандартной библиотеке. Переменная errno Текст диагностического сообщения хранится в предопределенном массиве sys_errlist, хранящийся в стандартной библиотеке. Переменная sys_nerr содержит размер этого массива. Переменная errno может использоваться как индекс в этом массиве errno error. String number EPERM Operation not permitted 1 ENOENT No such file or directory 2 ESRCH No such process 3 EINTR Interrupted function 4 EIO I/O error 5 … … … В UNIX имеются функции обработки значения errno • strerror() возвращает строковый эквивалент кода ошибки. • perror() по значению errno берет из таблицы sys_errlist соответствующее значение и записывает его непосредственно в поток вывода.

Попытка сделать некоторый системный вызов. Если это не получается, выводится сообщение об ошибке и Попытка сделать некоторый системный вызов. Если это не получается, выводится сообщение об ошибке и программа завершает свою работу. #include ………… extern int errno; extern char *sys_errlist[]; int value; if((value = sys_call(. . . )) < 0 ){ printf("Error: %s(%d)n", sys_errlist[errno], errno ); exit(errno); /*принудительное завершение программы*/ }

Попытка открыть файл. Если это не получается, выводится сообщение об ошибке и программа завершает Попытка открыть файл. Если это не получается, выводится сообщение об ошибке и программа завершает свою работу. #include #include ……… fd = open("inputfile. txt", O_RDONLY); if(fd == -1) { fprintf(stderr, "error opening file: %sn", strerror(errno)); exit (1); }

#include<stdio. h> #include <errno. h> ………. . int main(void) { char s[]= #include #include ………. . int main(void) { char s[]="Hello, World!"; if (printf("%sn", s)>0) { perror("Can't print"); return -1; } return 0; } Попытка вывести на экран текст. Если это не получается, выводится сообщение об ошибке и программа завершает свою работу.