Курс на Си. Подбельский. Курс программирования на Си. В., Фомин С. С. Курс программирования на языке Си Учебник
Скачать 1.57 Mb.
|
Глава 1 16 БАЗОВЫЕ ПОНЯТИЯ ЯЗЫКА 16 1.1.Алфавит, идентификаторы, служебные слова 17 1.2.Литералы 20 1.3.Переменные и именованные 27 константы 27 1.4. Операции 35 1.5. Разделители 44 1.6.Выражения 49 Контрольные вопросы 59 Глава 2 61 ВВЕДЕНИЕ 61 В ПРОГРАММИРОВАНИЕ НА СИ 61 2.1.Структура и компоненты простой программы 61 2.2.Элементарные средства 71 программирования 71 2.3. Операторы цикла 92 2.4. Массивы и вложение 108 операторов цикла 108 2.5.Функции 123 2.6.Переключатели 135 Контрольные вопросы 139 Глава 3 140 ПРЕПРОЦЕССОРНЫЕ СРЕДСТВА 140 3.1.Стадии и директивы препроцессорной обработки 141 HUB 143 3.2.Замены в тексте 145 3.3.Включение текстов из файлов 150 3.4.Условная компиляция 152 3.5.Макроподстановки средствами 157 препроцессора 157 3.6.Вспомогательные директивы 163 3.7.Встроенные макроимена 165 Контрольные вопросы 167 Глава 4 169 УКАЗАТЕЛИ, МАССИВЫ, СТРОКИ 169 4.1.Указатели на объекты 169 4.2.Указатели и массивы 178 4.3. Символьная информация и строки 193 Контрольные вопросы 201 Глава 5 204 ФУНКЦИИ 204 5.1. Общие сведения о функциях 204 5.2.Указатели в параметрах функций 209 5.3.Массивы и строки 214 как параметры функций 214 5.4.Указатели на функции 223 5.5.Функции с переменным 237 количеством аргументов 237 5.6.Рекурсивные функции 249 5.7.Классы памяти 252 и организация программ 252 5.8. Параметры функции main( ) 259 Контрольные вопросы 262 Глава 6 264 СТРУКТУРЫ И ОБЪЕДИНЕНИЯ 264 6.1.Структурные типы и структуры 264 6.2.Структуры, массивы и указатели 278 6.3.Структуры и функции 289 6.4.Динамические информационные структуры 293 6.5.Объединения и битовые поля 300 Контрольные вопросы 309 Глава 7 312 ВВОД И ВЫВОД 312 7.1. Потоковый ввод-вывод 312 7.2. Ввод-вывод нижнего уровня 349 Контрольные вопросы 359 Глава 8 360 ПОДГОТОВКА И ВЫПОЛНЕНИЕ 360 ПРОГРАММ 360 8.1.Схема подготовки программ 360 8.2.Подготовка программ 362 в операционной системе UNIX 362 8.3. Утилита make 364 8.4. Библиотеки объектных модулей 368 Контрольные вопросы 375 Приложение 1 376 ТАБЛИЦЫ КОДОВ ASCII 376 HUB 381 Приложение 2 384 Константы предельных значений 384 Приложение 3 386 Стандартная библиотека функций языка Си 386 Приложение 4 397 МОДЕЛИ ПРЕДСТАВЛЕНИЯ 397 ЧИСЕЛ НА РАЗЛИЧНЫХ 397 КОМПЬЮТЕРНЫХ ПЛАТФОРМАХ 397 Литература 400 Предметный указатель 401 printf("Объем цилиндра: %10.4f" , v); } В тексте программы несколько особенностей. Определена константа PI, то есть со значением 3.14159 связано имя PI, которое до конца выполнения программы будет именовать только это значение. Перед каждым вводом помещены (строки 9, 11) обращения к функции printf( ), выводящей на экран запрос-подсказку, вслед за которой на экране отображается набираемое на клавиатуре вводимое значение. Функция scanf( ) считывает только это значение, как только будет нажата клавиша Enter, что воспринимается как признак конца строки ввода. Поэтому очередное выполнение функции printf( ) выводит данные на следующую строку. В результатах выполнения программ радиус цилиндра r= 2.0 Здесь пользователь ввел 2.0 для r и 4.0 для h. Другой вариант: радиус цилиндра r= 4.0 высота цилиндра h= 2.0 объем цилиндра: 100.5309 Еще раз обратите внимание на использование в функции scanf( ) не имен переменных, а их адресов &r, &h. Кроме того, обратите внимание на спецификации преобразования %lf. Если бы переменные h и r имели тип float, то в форматных строках функций scanf( ) нужно было бы применять спецификации %f или %e. Сумма членов ряда Фибоначчи. Ряд Фибоначчи определен, если известны первые два его члена f1, f2, так как очередной член fi =f i-1 + f для i > 2. Необходимо вычислить сумму заданного количества (k) первых членов ряда Фибоначчи, если известны первые два: p = F1 и r = F2. Следующая программа решает эту задачу: /*Вычисление суммы членов ряда Фибоначчи*/ #include void main( ) Содержание 3 ПРЕДИСЛОВИЕ 12 Глава 1 16 БАЗОВЫЕ ПОНЯТИЯ ЯЗЫКА 16 1.1.Алфавит, идентификаторы, служебные слова 17 1.2.Литералы 20 1.3.Переменные и именованные 27 константы 27 1.4. Операции 35 1.5. Разделители 44 1.6.Выражения 49 Контрольные вопросы 59 Глава 2 61 ВВЕДЕНИЕ 61 В ПРОГРАММИРОВАНИЕ НА СИ 61 2.1.Структура и компоненты простой программы 61 2.2.Элементарные средства 71 программирования 71 2.3. Операторы цикла 92 2.4. Массивы и вложение 108 операторов цикла 108 2.5.Функции 123 2.6.Переключатели 135 Контрольные вопросы 139 Глава 3 140 ПРЕПРОЦЕССОРНЫЕ СРЕДСТВА 140 3.1.Стадии и директивы препроцессорной обработки 141 HUB 143 3.2.Замены в тексте 145 3.3.Включение текстов из файлов 150 3.4.Условная компиляция 152 3.5.Макроподстановки средствами 157 препроцессора 157 3.6.Вспомогательные директивы 163 3.7.Встроенные макроимена 165 Контрольные вопросы 167 Глава 4 169 УКАЗАТЕЛИ, МАССИВЫ, СТРОКИ 169 4.1.Указатели на объекты 169 4.2.Указатели и массивы 178 4.3. Символьная информация и строки 193 Контрольные вопросы 201 Глава 5 204 ФУНКЦИИ 204 5.1. Общие сведения о функциях 204 5.2.Указатели в параметрах функций 209 5.3.Массивы и строки 214 как параметры функций 214 5.4.Указатели на функции 223 5.5.Функции с переменным 237 количеством аргументов 237 5.6.Рекурсивные функции 249 5.7.Классы памяти 252 и организация программ 252 5.8. Параметры функции main( ) 259 Контрольные вопросы 262 Глава 6 264 СТРУКТУРЫ И ОБЪЕДИНЕНИЯ 264 6.1.Структурные типы и структуры 264 6.2.Структуры, массивы и указатели 278 6.3.Структуры и функции 289 6.4.Динамические информационные структуры 293 6.5.Объединения и битовые поля 300 Контрольные вопросы 309 Глава 7 312 ВВОД И ВЫВОД 312 7.1. Потоковый ввод-вывод 312 7.2. Ввод-вывод нижнего уровня 349 Контрольные вопросы 359 Глава 8 360 ПОДГОТОВКА И ВЫПОЛНЕНИЕ 360 ПРОГРАММ 360 8.1.Схема подготовки программ 360 8.2.Подготовка программ 362 в операционной системе UNIX 362 8.3. Утилита make 364 8.4. Библиотеки объектных модулей 368 Контрольные вопросы 375 Приложение 1 376 ТАБЛИЦЫ КОДОВ ASCII 376 HUB 381 Приложение 2 384 Константы предельных значений 384 Приложение 3 386 Стандартная библиотека функций языка Си 386 Приложение 4 397 МОДЕЛИ ПРЕДСТАВЛЕНИЯ 397 ЧИСЕЛ НА РАЗЛИЧНЫХ 397 КОМПЬЮТЕРНЫХ ПЛАТФОРМАХ 397 Литература 400 Предметный указатель 401 12 goto M1; 13 M2: printf("\n Первый член ряда p="); 14 scanf("%f",&p); 15 printf("\n Второй член ряда r="); 16 scanf("%f",&r); Содержание 3 ПРЕДИСЛОВИЕ 12 Глава 1 16 БАЗОВЫЕ ПОНЯТИЯ ЯЗЫКА 16 1.1.Алфавит, идентификаторы, служебные слова 17 1.2.Литералы 20 1.3.Переменные и именованные 27 константы 27 1.4. Операции 35 1.5. Разделители 44 1.6.Выражения 49 Контрольные вопросы 59 Глава 2 61 ВВЕДЕНИЕ 61 В ПРОГРАММИРОВАНИЕ НА СИ 61 2.1.Структура и компоненты простой программы 61 2.2.Элементарные средства 71 программирования 71 2.3. Операторы цикла 92 2.4. Массивы и вложение 108 операторов цикла 108 2.5.Функции 123 2.6.Переключатели 135 Контрольные вопросы 139 Глава 3 140 ПРЕПРОЦЕССОРНЫЕ СРЕДСТВА 140 3.1.Стадии и директивы препроцессорной обработки 141 HUB 143 3.2.Замены в тексте 145 3.3.Включение текстов из файлов 150 3.4.Условная компиляция 152 3.5.Макроподстановки средствами 157 препроцессора 157 3.6.Вспомогательные директивы 163 3.7.Встроенные макроимена 165 Контрольные вопросы 167 Глава 4 169 УКАЗАТЕЛИ, МАССИВЫ, СТРОКИ 169 4.1.Указатели на объекты 169 4.2.Указатели и массивы 178 4.3. Символьная информация и строки 193 Контрольные вопросы 201 Глава 5 204 ФУНКЦИИ 204 5.1. Общие сведения о функциях 204 5.2.Указатели в параметрах функций 209 5.3.Массивы и строки 214 как параметры функций 214 5.4.Указатели на функции 223 5.5.Функции с переменным 237 количеством аргументов 237 5.6.Рекурсивные функции 249 5.7.Классы памяти 252 и организация программ 252 5.8. Параметры функции main( ) 259 Контрольные вопросы 262 Глава 6 264 СТРУКТУРЫ И ОБЪЕДИНЕНИЯ 264 6.1.Структурные типы и структуры 264 6.2.Структуры, массивы и указатели 278 6.3.Структуры и функции 289 6.4.Динамические информационные структуры 293 6.5.Объединения и битовые поля 300 Контрольные вопросы 309 Глава 7 312 ВВОД И ВЫВОД 312 7.1. Потоковый ввод-вывод 312 7.2. Ввод-вывод нижнего уровня 349 Контрольные вопросы 359 Глава 8 360 ПОДГОТОВКА И ВЫПОЛНЕНИЕ 360 ПРОГРАММ 360 8.1.Схема подготовки программ 360 8.2.Подготовка программ 362 в операционной системе UNIX 362 8.3. Утилита make 364 8.4. Библиотеки объектных модулей 368 Контрольные вопросы 375 Приложение 1 376 ТАБЛИЦЫ КОДОВ ASCII 376 HUB 381 Приложение 2 384 Константы предельных значений 384 Приложение 3 386 Стандартная библиотека функций языка Си 386 Приложение 4 397 МОДЕЛИ ПРЕДСТАВЛЕНИЯ 397 ЧИСЕЛ НА РАЗЛИЧНЫХ 397 КОМПЬЮТЕРНЫХ ПЛАТФОРМАХ 397 Литература 400 Предметный указатель 401 Обратите внимание на строки 10-12, где выполняется проверка введенного значения k. Программа может правильно работать только при k>2, поэтому лишь в этом случае выполняется переход из строки 10 к метке М2 (строка 13). В противном случае печатается сообщение об ошибке (в строке 11), и после перехода к метке М1 запрашивается новое значение k. (Для полного понимания работы программы целесообразно составить трассировочную таблицу, выбрав подходящие значения k, p, r.) Результат (текст на экране) может быть, например, таким: Введите число членов ряда k=-4 Содержание 3 ПРЕДИСЛОВИЕ 12 Глава 1 16 БАЗОВЫЕ ПОНЯТИЯ ЯЗЫКА 16 1.1.Алфавит, идентификаторы, служебные слова 17 1.2.Литералы 20 1.3.Переменные и именованные 27 константы 27 1.4. Операции 35 1.5. Разделители 44 1.6.Выражения 49 Контрольные вопросы 59 Глава 2 61 ВВЕДЕНИЕ 61 В ПРОГРАММИРОВАНИЕ НА СИ 61 2.1.Структура и компоненты простой программы 61 2.2.Элементарные средства 71 программирования 71 2.3. Операторы цикла 92 2.4. Массивы и вложение 108 операторов цикла 108 2.5.Функции 123 2.6.Переключатели 135 Контрольные вопросы 139 Глава 3 140 ПРЕПРОЦЕССОРНЫЕ СРЕДСТВА 140 3.1.Стадии и директивы препроцессорной обработки 141 HUB 143 3.2.Замены в тексте 145 3.3.Включение текстов из файлов 150 3.4.Условная компиляция 152 3.5.Макроподстановки средствами 157 препроцессора 157 3.6.Вспомогательные директивы 163 3.7.Встроенные макроимена 165 Контрольные вопросы 167 Глава 4 169 УКАЗАТЕЛИ, МАССИВЫ, СТРОКИ 169 4.1.Указатели на объекты 169 4.2.Указатели и массивы 178 4.3. Символьная информация и строки 193 Контрольные вопросы 201 Глава 5 204 ФУНКЦИИ 204 5.1. Общие сведения о функциях 204 5.2.Указатели в параметрах функций 209 5.3.Массивы и строки 214 как параметры функций 214 5.4.Указатели на функции 223 5.5.Функции с переменным 237 количеством аргументов 237 5.6.Рекурсивные функции 249 5.7.Классы памяти 252 и организация программ 252 5.8. Параметры функции main( ) 259 Контрольные вопросы 262 Глава 6 264 СТРУКТУРЫ И ОБЪЕДИНЕНИЯ 264 6.1.Структурные типы и структуры 264 6.2.Структуры, массивы и указатели 278 6.3.Структуры и функции 289 6.4.Динамические информационные структуры 293 6.5.Объединения и битовые поля 300 Контрольные вопросы 309 Глава 7 312 ВВОД И ВЫВОД 312 7.1. Потоковый ввод-вывод 312 7.2. Ввод-вывод нижнего уровня 349 Контрольные вопросы 359 Глава 8 360 ПОДГОТОВКА И ВЫПОЛНЕНИЕ 360 ПРОГРАММ 360 8.1.Схема подготовки программ 360 8.2.Подготовка программ 362 в операционной системе UNIX 362 8.3. Утилита make 364 8.4. Библиотеки объектных модулей 368 Контрольные вопросы 375 Приложение 1 376 ТАБЛИЦЫ КОДОВ ASCII 376 HUB 381 Приложение 2 384 Константы предельных значений 384 Приложение 3 386 Стандартная библиотека функций языка Си 386 Приложение 4 397 МОДЕЛИ ПРЕДСТАВЛЕНИЯ 397 ЧИСЕЛ НА РАЗЛИЧНЫХ 397 КОМПЬЮТЕРНЫХ ПЛАТФОРМАХ 397 Литература 400 Предметный указатель 401 Сумма членов ряда: 660.000 Особенность и недостаток программы состоят в том, что она никогда не закончит вычислений, если не ввести допустимого значения k>2. 2.3. Операторы цикла Три формы операторов цикла. Как и в других языках программирования, в языке Си существуют специальные средства для организации циклов (операторы циклов), позволяющие упростить их программирование. В большинстве языков программирования оператор цикла состоит из двух элементов - заголовка и тела. Тело включает операторы, выполняемые в цикле, заголовок организует циклическое выполнение операторов тела. В соответствии с названием заголовок размещается непосредственно перед телом цикла. В языке Си равноправно используются три разных оператора цикла, обозначаемых соответственно служебными словами while, for, do. Циклы while и for построены по схеме: заголовок_цикла тело_цикла Цикл do имеет другую структуру - тело цикла как бы обрамлено (сверху и снизу) конструкциями, организующими циклическое выполнение тела. Поэтому говорить о заголовке цикла do в языке Си, по-видимому, некорректно. Введем форматы перечисленных операторов цикла и приведем примеры их использования. Предварительно отметим, что во всех трех операторах цикла тело цикла - это либо отдельный, либо составной оператор, то есть последовательность операторов, заключенная в операторные скобки {}. Тело цикла может быть и пустым оператором, то есть изображаться только как «;». Цикл while (цикл с предусловием) имеет вид: while (выражение_условие) тело_цикла В качестве выражения_условия чаще всего используется отношение или логическое выражение. Если оно истинно, то есть не равно 0, то тело цикла выполняется до тех пор, пока выражение_условие не станет ложным. Обратите внимание, что проверка истинности выражения осуществляется до каждого выполнения тела цикла (до каждой итерации). Таким образом, для заведомо ложного выражения_условия тело цикла не выполнится ни разу. Выражение_условие может быть и арифметическим выражением. В этом случае цикл выполняется, пока значение выражения_условия не равно 0. Цикл do (цикл с постусловием) имеет вид: do тело_цикла while (выражение_условие); Выражение_условие логическое или арифметическое, как и в цикле while. В цикле do тело цикла всегда выполняется по крайней мере один раз. После каждого выполнения тела цикла проверяется истинность выражения_условия (на неравенство 0), и, если оно ложно (то есть равно 0), цикл заканчивается. В противном случае тело цикла выполняется вновь. Цикл for (называемый параметрическим) имеет вид: for (выражение_1; выражение_условие; выражение_3) тело_цикла Первое и третье выражения в операторе for могут состоять из нескольких выражений, разделенных запятыми. Выражение_1 определяет действия, выполняемые до начала цикла, то есть задает начальные условия для цикла. Выражение_^словие - обычно логическое или арифметическое. Оно определяет условия окончания или продолжения цикла. Если оно истинно (то есть не равно 0), то выполняется тело цикла, а затем вычисляется выражение_3. Выражение_3 обычно задает необходимые для следующей итерации изменения параметров или любых переменных тела цикла. После выполнения выражения_3 вычисляется истинность выражения_условия, и все повторяется... Таким образом, выражение_1 вычисляется только один раз, а выражение_условие и выражение_3 вычисляются после каждого выполнения тела цикла. Цикл продолжается до тех пор, пока не станет ложным выражение_условие. Любое из трех, любые два или все три выражения в операторе for могут отсутствовать, но разделяющие их символы «;» должны присутствовать всегда. Если отсутствует выражение_условие, то считается, что оно истинно и нужны специальные средства для выхода из цикла. Схемы организации циклов while, do и for даны на рис. 2.3. Проиллюстрируем особенности трех типов цикла на примере вычисления приближенного значения для заданного значения x. Вычисления будем продолжать до тех пор, пока очередной член ряда остается больше заданной точности. Обозначим точность через eps, результат - b, очередной член ряда - г, номер члена ряда - i. Для получения i-го члена ряда нужно (1-1)-й член умножить на x и разделить на i, что позволяет исключить операцию возведения в степень и явное вычисление факториала. Опустив определения переменных, операторы ввода и проверки исходных данных, а также вывода результатов, запишем три фрагмента программ. в Рис. 2.3. Схемы организации циклов while, do, for: а - цикл с предусловием while; б - цикл с постусловием do; в - параметрический цикл for /* Цикл с предусловием */ i = 2; b = 1.0; r = x; while( r > eps 11 r < -eps ) { b=b+r; r=r*x/i; i++; } Так как проверка точности проводится до выполнения тела цикла, то для окончания цикла абсолютное значение очередного члена должно быть меньше или равно заданной точности. /* Цикл с постусловием */ i=1; b=0.0; r=1.0; do { b=b+r; r=r*x/i; i++; } while( r >= eps || r <= -eps ); Так как проверка точности осуществляется после выполнения тела цикла, то условие окончания цикла - абсолютное значение очередного члена строго меньше заданной точности. Соответствующие изменения внесены и в операторы, выполняемые до цикла. /* Параметрический цикл */ i=2; b=1.0; r=x; for( ; r > eps | | r < —eps ; ) { b=b+r; r=r*x/i; i=i+1; } Условие окончания параметрического цикла такое же, как и в цикле while. Все три цикла записаны по возможности одинаково, чтобы подчеркнуть сходство циклов. Однако в данном примере цикл for имеет существенные преимущества. В заголовок цикла (в качестве выра- жения_1) можно ввести инициализацию всех переменных: for ( i=2, b=1.0, r=x; r>eps || r<-eps ; ) { b=b+r; r=r*x/i; i=i+1; } В выражение_3 можно включать операцию изменения счетчика членов ряда: for( i=2, b=1.0, r=x; r>eps || r<-eps; i++) { b=b+r; r=r*x/i; } Можно еще более усложнить заголовок, перенеся в него все исполнимые операторы тела цикла: for(i=2, b=1.0, r=x; r>eps || r<-eps; b+=r, r*=x/i, i++); В данном случае тело цикла - пустой оператор. Для сокращения выражения_3 в нем использованы составные операции присваивания и операция ++. Приближенное значение экспоненты. Приведем полный текст программы для приближенного вычисления экспоненты: /*Приближенное значение экспоненты*/ #include void main( ) { int i; /*i - счетчик членов ряда*/ double eps,b=1.0, r,x;/*exp - абс. точность*/ /*b - значение экспоненты; r - очередной член*/ /* x - вводимое значение показателя экспоненты*/ printf("\n Введите значение x="); scanf("%lf",&x); do { printf("\n Введите точность eps="); scanf("%lf",&eps); } while( eps <= 0.0 ); for( i=2, r=x; r > eps || r < -eps; i++ ) { b=b+r; r=r*x/i; } printf(" Результат: %f\n",b); printf(" Погрешность: %f\n",r); printf(" Число членов ряда: %d\n",i); } В программе переменная b инициализирована (строка 6), то есть ей еще в процессе выделения памяти присваивается конкретное начальное значение (1.0). При вводе значения переменной eps предусмотрена защита от неверного задания точности (строки 11-15), для чего использован цикл do. В соответствии с правилами его работы выполняются операторы из строк 12 и 13, а затем проверяется введенное значение точности. Если значение eps недопустимо (eps<=0.0), то операторы тела цикла (строки 12, 13) выполняются снова. Цикл не закончится до тех пор, пока не будет введено допустимое значение точности. Результаты выполнения программы: Введите значение x=1 Введите точность eps=0.01 Результат: 2.708333 Погрешность: 0.008333 Число членов ряда: 6 Другой вариант выполнения программы: Введите значение x=1 Введите точность eps=-0.3 Введите точность eps=0.0001 Результат: 2.718254 Погрешность: 0.000025 Число членов ряда: 9 В последнем варианте вначале введено неверное значение eps=-0.3, и ввод пришлось повторить. Отметим, что в качестве погрешности выводится последнее значение учтенного члена ряда, что не вполне математически корректно. Оператор break. Как видно из предыдущего примера, принятый способ проверки исходных данных с повторным запросом значения точности eps не очень удобен, так как на экране отсутствует сообщение об ошибке. В примере, рассмотренном в предыдущем параграфе (сумма членов ряда Фибоначчи), на экран выводится конкретное указание о сделанной ошибке («Ошибка! k должно быть > 2 !»), что упрощает ее исправление. Однако в этом случае в программе использованы метки и оператор перехода, что считается некорректным с точки зрения структурного программирования. Добиться такого же результата можно, не нарушая принципов структурного программирования и применяя оператор цикла, если использовать в его теле оператор прерывания break. Этот оператор (рис. 2.4) прекращает выполнение оператора цикла и передает управление следующему за ним (за циклом) оператору. Необходимость в использовании оператора прерывания в теле цикла возникает, когда условие продолжения итераций нужно проверять не в начале цикла (как в циклах for и while) и не в конце тела цикла (как в цикле do), а в середине тела цикла. Наиболее естественна в этом случае такая структура тела цикла: { операторы if (условие) break; операторы } Рассмотрим пример с использованием оператора прерывания break в цикле ввода исходных данных. Сумма отрезка степенного ряда. Введя значения переменных n и п g, вычислить сумму с = У, g' , где n > 0. Задачу решает следующая /=1 программа: /* Сумма степенного ряда */ #include void main( ) { double g,c,p; /* c — сумма, р - член ряда */ int i,n; printf("\n Введите значение g="); scanf("%lf",&g); в Рис. 2.4. Схемы выполнения в циклах операторов breakи continue: a - цикл с предусловием while; б - цикл с постусловием do; в - параметрический цикл for 9 while(1) Содержание 3 ПРЕДИСЛОВИЕ 12 |