На этой странице можно скачать этот файл совершенно бесплатно и без регистрации и без отправки смс, а также без различного рода ограничений.
Скачивайте и учитесь, надеемся, наш сайт помог вам "погрызть гранит науки"
Функции
Лабораторная работа №6 Функции В языке Си функция - это логически самостоятельная именованная часть программы, которой могут передаваться параметры и которая может возвращать значение. Стандарт ANSI языка Си предполагает следующий формат определения функции: [возвр тип данных] имя_функции (список аргументов | void) { описание локальных данных операторы, в т. ч. Вызова других функций [return] (выражение) } Совокупность предложений в фигурных скобках - тело функции. По синтаксису языка Си нельзя в теле одной функции определять другую - т. е. не допускается вложенное определение функций. Если поле возвращаемый тип опущено, считается, что возвращаемый тип - целый, а при слове void - функция не возвращает значения. Поле имя функции - это особый тип указателя на функцию; его значение - адрес входной точки функции. В поле список параметров - любая комбинация типов и имен, разделенных запятой и составляющих список формальных параметров. При каждом вызове функции происходит замена формальных параметров значениями фактических с размещением их в стеке. Список формальных параметров может быть и пустым или содержать слово void. Стандарт ANSI требует для функций, возвращающих не целое значение предварительного объявления, называемого прототипом функции: float func1(int,char *,unsigned); char * func2(int var1,int var2); В прототипах функций можно указывать только типы формальных параметров без имен переменных, так как прототип содержит только заголовок функции без тела - это только объявление, которое служит компилятору для проверки правильности составления определения функции и вызовов ее на выполнение. Функция в процессе выполнения извлекает копии аргументов из стека. При передаче параметров в функцию (в стек) выполняется дополнительно преобразование их к типу, который указан в прототипе. Существует 2 способа передачи параметров: ? передача значений; ? передача адресов переменных. Вызов функции с передачей адресов позволяет строить функции с доступом к массивам и другим протяженным структурам данных. В Си допускается наличие функций с переменным числом аргументов - признаком такой функции является многоточие в списке параметров прототипа. Такая функция должна иметь способ определения точного числа параметров при каждом вызове - или число передаваемых параметров задается первым аргументом, или последний параметр должен быть индикатором конца списка, т. е. иметь обусловленное значение, которое не может принимать ни один параметр. Функции с переменным числом аргументов должны иметь хотя бы 1 фиксированный параметр, чтобы было к чему привязаться при извлечении их из стека. Для упрощения работы с переменным числом аргументов определен особый тип, который и используется для описания указателя на начало списка фактических аргументов: typedef void* va_list; Для задания начального значения указателю типа va_list используется макро va_start: void examp(int arg1,. ) { va_list ptr; va_start(ptr,arg1); } Доступ к значениям в списке фактических параметров выполняется через макро va_arg(): void example(int,. ); const EOL=0 /*ограничитель списка параметров */ void main(void) {int var1=5,var2=6,var3=7,var4=8,var5=9; example(var1,EOL); example(var1,var2,EOL); example(var1,var2,var3,var4,var5,EOL); }
void example(int arg1,. ) {int number=1,value; va_list ptr; va_start(ptr,arg1); value=va_arg(ptr,int); Здесь можно проверить value на 0 - не конец ли списка . } Си поддерживает рекурсивные вызовы функций - как непосредственные (самой себя), так и опосредованные (вызов текущей функции из вызванной ею функции). Функция main в этом смысле не является исключением, хотя ее опосредованные вызовы - это все же экзотика. Преимуществом рекурсии есть компактный код, а недостатки - потери времени на вызовы и возможность переполнения стека. Извлечение аргументов из командной строки Многие программы требуют после начала выполнения уточняющих задачу аргументов и эти аргументы удобнее всего задать сразу после имени программы в командной строке. Си предоставляет 2 таких возможности - либо оформлением главной функции main() с параметрами, в которые специально прикомпонованным к любой Си-программе загрузчиком будут помещены количество слов в командной строке, массив указателей на эти слова и массив указателей на строки среды окружения, либо глобальные переменные из модуля dos.h _argc, _argv, environ, содержащие ту же информацию. Пример 1. #include conio.h main(int arg_count, char* word[], char* env[]) { clrscr(); //Очистим экран //Выводим количество слов в командной строке cprintf("В командной строке %d слов, разделенных пробелами \r\n", arg_count); //Выводим сами слова командной строки cprintf("Слова командной строки: \r\n"); //Что-то вроде заголовка for(int i=0;i arg_count;i++) //Цикл вывода слов cprintf("%s\r\n",word[i]); //Выводим строки среды, сформированные командами DOS path, set cprintf("Строки среды окружения: \r\n"); //Опять заголовок for(i=0;env[i];i++) //Опять цикл вывода строк cprintf("%s\r\n",env[i]); getch(); //Ожидаем нажатия произвольной клавиши } Другой способ получения той же информации состоит в использовании глобальных переменных с именами _argc (количество слов в командной строке), _argv (массив указателей на слова в командной строке), environ (массив указателей на строки окружения) из файла dos.h. В этом случае функция main() может оформляться без параметров, но становится обязательной директива включения #include dos.h : Пример 2. #include dos.h #include conio.h main() { clrscr(); //Выводим количество слов в командной строке cprintf("В командной строке %d слов, разделенных пробелами \r\n", _argc); //Выводим сами слова командной строки cprintf("Слова командной строки: \r\n"); for(int i=0;i _argc;i++) cprintf("%s\r\n", _argv[i]); //Выводим строки среды, сформированные командами DOS //prompt, path, set cprintf("Строки среды окружения: \r\n"); for(i=0;environ[i];i++) cprintf("%s\r\n",environ[i]); getch(); //Ожидаем нажатия произвольной клавиши }
Лабораторная работа №6 Задания 1. Написать программу, в которой считается, что экран состоит из 25 строк по 80 символов и содержащую функции: - point_(x,y) - line_(x1,y1,x2,y2) - rectangle(x1,y1,x2,y2) которые имитируют построение точки, линии и прямоугольника по заданным координатам при помощи символа ’*’. 2. Написать программу, вычисляющую факториал числа, которое пользователь вводит в командной строке. Вычисление факториала оформить как функцию. 3. Добавить в предыдущую программу рекурсивную функцию вычисления факториала. Сравнить результаты выполнения функций. 4. Написать программу для игры пятнашки. На квадратном поле размером 4 на 4 с помощью генератора случайных чисел расставлены 15 фишек с номерами с 1 по 15. 11 1 12 7 Имеется одна свободная позиция. Расставить фишки по возрастанию их номеров. Передвигать фишку можно только на соседнюю свободную позицию. Перемещаемую фишку и ее новую позицию указывать с помощью курсора (после выбора фишка 10 14 5 9 3 2 13 8 4 15 6 перерисовывается другим цветом). Перерисовку фишки и обновление игрового поля после перестановки оформить в виде функций.