Методические_указания_по_языку_C_(часть_1) ПРАВ..

Формат документа: odt
Размер документа: 0.27 Мб




Прямая ссылка будет доступна
примерно через: 45 сек.



  • Сообщить о нарушении / Abuse
    Все документы на сайте взяты из открытых источников, которые размещаются пользователями. Приносим свои глубочайшие извинения, если Ваш документ был опубликован без Вашего на то согласия.

Министерство образования и науки Российской федерации
Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования
Алгоритмические языки и основы
программирования
язык СиМЕТОДИЧЕСКИЕ УКАЗАНИЯ, ЗАДАНИЯ И ПРИМЕРЫ ВЫПОЛНЕНИЯ ЛАБОРАТОРНЫХ РАБОТ № 1 – 6
ДЛЯ СТУДЕНТОВ НАПРАВЛЕНИЯ 20010062 «Приборостроение» (профиль Авиационные приборы и измерительно-вычислительные комплексы)

Ульяновск
2011
ЯЗЫК СИ
Тема №1. Функции стандартного ввода–вывода, вычисление математических функцийЗадание: составить программу для проведения математических вычислений по индивидуальным вариантам заданий, которые представлены далее по тексту; все исходные данные, необходимые для вычислений, вводить с клавиатуры.
Программа должна после запуска на исполнение выводить информацию об авторе, назначении программы (приводится лабораторное задание полностью), перед запросом ввода данных с клавиатуры обязательно должно быть сообщение о типе и количестве вводимых данных.
Краткая теоретическая справка и рекомендации по выполнению
Кроме выполнения вычислений заданием предусмотрено изучение наиболее распространенных математических функций, даже если они не используются при выполнении задания.
Для каждой функции обратите внимание на тип обрабатываемых данных, например, результатом функции abs(–3.7) будет число 3.0, а не 3.7 как ожидалось, т.к. функция abs может работать только с целыми числами.
Перечень математических функций для изучения (в тригонометрических функциях углы измеряются в радианах):
abs (fabs) – абсолютная величина целого числа (числа с плавающей точкой),
acos – вычисление арккосинуса,
asin – вычисление арксинуса,
atan – вычисление арктангенса,
atan2 – вычисление арктангенса (вычисляет угол по значению катетов),
atof – преобразует строку в число с плавающей точкой,
cabs – вычисляет абсолютную величину комплексного числа,
ceil – округление до ближайшего целого в большую сторону,
cos – косинус,
cosh – гиперболический косинус,
exp – экспонента,
floor – округление до ближайшего целого в меньшую сторону,
fmod – остаток целочисленного деления двух чисел,
frexp – вычисляет значение мантиссы m и показателя степени n для преобразования числа с плавающей точкой к виду ,
hypot – вычисляет значение гипотенузы по значениям катетов,
ldexp – по значению мантиссы m и показателя степени n вычисляет число с плавающей точкой по формуле ,
log – вычисляет натуральный логарифм числа,
log10 – вычисляет десятичный логарифм числа,
modf – разбивает число с плавающей точкой на целую и дробную части,
poly – вычисляет полином вида ,
pow – вычисляет число в степени,
pow10 – вычисление числа 10 в степень,
sin – вычисление синуса угла,
sinh – вычисление гиперболического синуса,
sqrt – вычисление квадратного корня,
tan – вычисление тангенса угла,
tanh - вычисление гиперболического тангенса угла.
Пример выполнения задания по теме № 1/* Блок директив препроцессору */
#include <math.h>
#include <stdio.h>
#define g 9.81
/* Объявление глобальной переменной */
float H;
/* Блок главной функции программы */
int main()
{
/* Объявление локальной переменной */
float V;
printf("\nЛабораторная работа N1 вариант N12");
printf("\n\nВыполнила студентка гр.Пд-11 Петрова Н.В.");
printf("\nВертикально вверх бросают камень со скоростью V.");
printf("\nОпределите максимальную высоту подъема камня.");
printf("\nВведите начальную скорость в м/c (от 0 до 100) V=");
scanf("%f",&V);
H=pow(V,2);
H=H/(2*g);
printf("\nМаксимальная высота подъема камня H=%5.2f м",H);
return 0;
}
Обратите внимание на то, что программа состоит из нескольких блоков, первый из которых включение (include) заголовочных файлов для обращения к библиотекам языка Си. В отличие от языка Паскаль ни одна библиотечная функция языка Си не может быть использована без указания места расположения ее прототипа. Кроме того, не забудьте, что язык Си различает регистр написания букв. Поэтому компилятор примет написание имени функции printf, но укажет, что printf – это неизвестный идентификатор.
Найдите описание функций, которые относятся к используемым в программе библиотекам: математической (math), библиотеке стандартного ввода-вывода (stdio). Более пристального внимания требуют функции форматного ввода-вывода (scanf и printf), особенно вопросы задания формата вводимых и выводимых данных, так как в Паскале выбор формата выводимых данных определял компилятор по типу переменной, а здесь выбор (как и многое другое) определяет программист. Не забудьте, что функция scanf требует адреса переменной.
Блок объявления главной функции, операторные скобки и локальные переменные требуют несколько более пристального внимания (опять из-за привычки к синтаксису языка Паскаль). Здесь чаще всего встречаются следующие ошибки:
лишняя точка с запятой после объявления функции main(),
объявление локальной переменной до фигурной скобки,
забыты круглые скобки после идентификатора функции при ее объявлении или вызове на исполнение (напомним, что скобки обязательны, даже если функция не содержит параметров).
Формулы для решения задачПлощадь треугольника:
где а – основание,h – высота треугольника.
Формула Герона для вычисления площади треугольника:

где p – полупериметр треугольника, a, b, c – стороны треугольника,
r – радиус вписанной окружности.
Теорема синусов:
– углы, противолежащие соответствующим сторонам,
R – радиус описанной окружности.
Теорема косинусов:
Длина биссектрисы треугольника:
Длина медианы треугольника:
Площадь эллипса:
Тригонометрические формулы:

Варианты заданий По значению сторон треугольника определить все его высоты.
По координатам вершин квадрата вычислить площадь, вписанного в него круга.
По значениям внешнего и внутреннего радиусов кругового кольца, а также по значению центрального угла, вычислить площадь сегмента.
По сторонам треугольника вычислить биссектрисы всех его углов.
По сторонам треугольника вычислить площадь вписанного в него круга.
По сторонам и основаниям трапеции вычислить её диагонали.
По сторонам треугольника вычислить его площадь и углы.
По координатам вершин квадрата вычислить площадь описанного круга.
По сторонам треугольника вычислить его медианы.
По радиусу окружности и расстоянию до внешней точки вычислить угол, образованный касательными из внешней точки к окружности.
По сторонам прямоугольника вычислить площадь описанного вокруг него круга.
По координатам трех точек на плоскости вычислить радиус окружности, проходящей через эти точки.
По радиусу окружности и хорде вычислить площадь равнобедренного треугольника, вписанного в эту окружность (основание треугольника - хорда).
По величине высот, проведенных из центра окружности до хорд и углу между хордами определить расстояние от центра окружности до точки пересечения хорд.
По сторонам треугольника определить площадь описанного вокруг него круга.
По стороне правильного шестиугольника вычислить его площадь.
По сторонам прямоугольника вычислить площадь вписанного в него эллипса.
Контрольные вопросы по теме № 11. Что может быть в качестве параметров в функциях scanf, printf (по типам данных, но без файлового ввода/вывода)?
2. В чем отличие scanf и cscanf, printf и cprintf?
3. Как задать формат вывода чисел в функции printf?
4. Дайте общую характеристику библиотечных математических функций.
5. Как запустить программу на исполнение?
6. Как откомпилировать программу?
7. Где находится результат компиляции программы?
8. Как загрузить и сохранить текст программы?
9. Что означает директива препроцессору #include?
Тема №2. Ветвление программы (использование операторов ветвления и переключателя switch)Задание: используя операторы ветвления (if и if … else), составить программу для вычисления составной (сложной) функции, имеющей различный вид на разных участках аргумента. С помощью переключателя (switch) указать на каком отрезке находится введенное с клавиатуры значение аргумента, и вывести значение функции в данной точке.
Все исходные данные, необходимые для проведения вычислений, вводить с клавиатуры. Начертить блок-схему алгоритма вычисления. Комментарии на неочевидные части программы обязательны.
Варианты заданий Таблица 1
№ варианта
Функция
Участки аргумента
1
y1=x3
–2<=x1<0
y2=x2
0<=x2<1
y3=4*ln(x)
1<=x3<1.5
y4=-10*(x-1.6)2
1.5<=x4<=2
2
y1=1/x
–1<=x1< – 0.05
y2=19*e(-x)
–0.05<=x2<1
y3=sin(10x)+7.6
1<=x3<2.05
y4=13+5*(x-3)3
2.05<=x4<=3
3
y1=0.5*(1+x4)
–3<=x1<–2
y2=cos(3x)+1
–2<=x2<2
y3=ln10x+1.3
2<=x3<3
y4=2.2+5*sin(x-3)
3<=x4<= 4
4
y1=e(-5*x)+x3
– 5<=x1< – 0.3
y2=-4*arcsin(3x)
– 0.3<=x2<0.25
y3=(x-2.5)/(x+0.4)
0.25<=x3<2.05
y4=5*(x-3)3+4
2.05<=x4<=3
5
y1=20*x
–1<=x1<– 0.5
y2=-160*x4
– 0.5<=x2<0.5
y3=-20*sin(5(x-0.5))-10
0.5<=x3<1.5
y4=(x-1.75)2*190-3
1.5<=x4<=2
6
y1=(1+x2)
–2<=x1<0
y2=(2-(sin(1+x)))
0<=x2<1
y3=cos(4(1+x)+1.1)
1<=x3<1.5
y4=-4*(x-1.5)+0.2
1.5<=x4<=2
7
y1=(-x)3+sin(x)
–1<=x1<– 0.05
y2=(x2+ex)-1
0.05<=x2<2
y3=13-ln(x)*4
2<=x3<3
y4=8+10*sin(x-3)
3<=x4<=4
Продолжение таблицы 1
№ варианта
Функция
Участки аргумента
8
y1=arcsin(x)
– 1<=x1<1
y2=2*cos(10x)+
1<=x2<2
y3=-x3+x2+8
2<=x3<2.5
y4=(x-4)4-6.4
2.5<=x4<=3
9
y1= cos(x) +tg(x)
– 1<=x1<– 0.5
y2=2*arcsin(x)+1.4
– 0.5<=x2<0.5
y3=-x6*ln(1+x)+2.45
0.5<=x3<1
y4=-3*(x-1.6)2+2.8
1<=x4<=2
10
y1=ex+x
– 4<=x1<– 3
y2=e-x*sin(x)
– 3<=x2<0
y3=0
0<=x3<1.5
y4=-4*(x-1.5)
1.5<=x4<=2
11
y1=3*cos(2*x)+4*sin(10*x)
– 1<=x1<– 0.05
y2=ex
– 0.05<=x2<1
y3=ln(x)+xe+1.7
1<=x3<2.05
y4=13.8+5*(x-3)3
2.05<=x4<=3
12
y1= 7sin(x)
– 1<=x1<– 0.5
y2=(x+1)*(x2+1)-1
– 0.5<=x2<0.5
y3=1.2sin(2x)
0.5<=x3<1
y4=-(x-0.6)2+1.25
1<=x4<=2
13
y1=arcsin(x)*ln(x+2)
– 4<=x1<– 3
y2=2*cos(10*x)+3
– 3<=x2<0
y3=30*(x-2.25)2+2.25
0<=x3<1.5
y4=15*(x-2.5)+4
1.5<=x4<=2
Пример выполнения лабораторного задания № 2Пусть требуется вычислить составную функцию, заданную на 4-х отрезках изменения аргумента. В данном примере приведем программу в соответствии со всеми указанными ранее требованиями, в том числе подробным описанием задания и комментариями (внутри фигурных скобок) по тексту программы.
Обратите внимание на отступы вправо, принятые при записи программ.
Условный оператор специально используется в двух форматах: с применением и отсутствием альтернативной части (else).
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{ /* задание переменной перечисляемого типа */
enum {def,o1,o2,o3,o4} otr; /* номер отрезка, def – выбор по умолчанию */
float x,y;
printf(" Лабораторная работа N 2 вариант 27 \n");
printf("Тема: Ветвление программы \n");
printf(" Задание: Используя оператор if, составить программу \n");
printf("для вычисления составной функции вида: \n");
printf("1> sqr(x) при x от -2.0 до 1.0\n");
printf("2> sqrt(x) при x от 1.0 до 2.0\n");
printf("3> y=sqrt(x-2)+sqrt(2) при x от 2.0 до 3.0\n");
printf("4> y=1+sqrt(x-1) при x от 3.0 до 4.0\n");
printf("указать отрезок, где находится введенный с клавиатуры \n");
printf("аргумент и вывести значение функции в данной точке. \n");
printf(" Автор: Путилов Александр Петрович, гр. Пд-11 \n");
printf("Введите x=");
scanf("%f",&x); printf("\n");
/* Выбор отрезка */
otr=def;
if ((x>=-2.0) && (x<1.0)) otr=o1;
else if ((x>=1.0) && (x<2.0)) otr=o2;
if ((x>=2.0) && (x<3.0)) otr=o3;
if ((x>=3.0) && (x<=4.0)) otr=o4;
/* Вычисление значения функции */
switch (otr)
{
case o1: y=pow(x,2); break;
case o2: y=sqrt(x); break;
case o3: y=sqrt(x-2)+sqrt(2); break;
case o4: y=1+sqrt(x-1); break;
default: printf("Число вне диапазона."); getch(); exit(1);
}
printf ("Промежуток %d: y= %3.2f; ",otr,y);
return 0;
}
Обратите внимание, что в примере использована еще одна библиотека stdlib. Часть функций этой библиотеки уже известна по математической библиотеке, а другие функции надо будет изучать по мере необходимости.
Новым является использование перечисляемого типа данных (enum). Объявление перечисления задает тип переменной перечисления и определяет список именованных констант, называемый списком перечисления. Значением каждого имени списка является некоторое целое число. Переменная типа перечисления может принимать значения одной из именованных констант списка. Именованные константы списка имеют тип int. Поэтому переменной перечисляемого типа можно присвоить любое значение типа int. Фатальной ошибки при этом не будет, только предупреждение (Assign int to enum) о том, что переменной перечисляемого типа присвоено целое значение. Допускаете ли вы такую вольность или нет, решайте сами, так как последствия могут быть неожиданными.
При использовании операторов ветвления программы (if, else), несколько существенных особенностей, отличающих синтаксис языков Паскаль и Си и дающих наибольшее число ошибок:
в языке Си результатом логической операции служит целое число, любое целое число, не равное 0, интерпретируется как истина;
поразрядные (битовые) логические операторы: & , | , ^ , ~ ;
логические операторы: && , || , ! ;
логическое выражение после слова if обязательно должно быть в круглых скобках;
выражение перед альтернативной частью (else) должно заканчиваться точкой с запятой;
оператор проверки на равенство обозначается двойным знаком «равно», а проверка на неравенство – «восклицательный знак равно».
Для того чтобы начертить блок-схему алгоритма вычисления составной функции и прочих алгоритмов в курсе АЯиОП, познакомьтесь с ГОСТ 19.003-80.doc «СХЕМЫ АЛГОРИТМОВ И ПРОГРАММ. ОБОЗНАЧЕНИЕ УСЛОВНЫЕ ГРАФИЧЕСКИЕ»
Блок-схема алгоритма вычисления составной функции Блок-схема выбора функции
Контрольные вопросы к лабораторной работе № 2Как используются операторы логических операций (и, или, исключающее или) в условных выражениях?
Начертите таблицы истинности логических операций.
Укажите тип переменной оператора switch, по значению которой выполняется переключение.
Какое действие может быть выполнено в операторе switch по умолчанию?
Какой синтаксис записи метки в операторе switch?
Как использовать окно Watch?
Как выполнить программу по шагам (Step over и Trace into)?
Как средствами встроенного редактора производится копирование и вклейка фрагмента текста?
Тема №3. Циклы, символьный (литерный) тип данных Задание: написать программу при помощи оператора цикла for (без применения массивов и прямой адресации курсора) для распечатки на экране монитора указанного в варианте набора символов. Начертить блок-схему к программе.
При выполнении заданий в первую очередь обратите внимание на то, что в языке Си литерный тип данных – это число (один байт). Поэтому с ним можно выполнять все операции, предусмотренные для работы с числами.
Второе – цикл for. Формат использования цикла for имеет следующий вид:
for ( [действие до цикла]; [предусловие цикла]; [последнее действие]).
Любое действие в прямоугольных скобках может отсутствовать. Предусловие (условие выполнения цикла) – это любое действие, результат которого будет интерпретироваться как int. Если результат равен нулю, то условие ложно, в противном случае истинно.
Третье, на что надо обратить внимание – цикл do…while будет повторяться, если условие в конструкции while – истинно.
Примеры выполнения задания по теме №3.Распечатать на экране монитора таблицу символов, используя только циклы (без использования массивов и строк)
A
C
E
G
I
I
A
C
E
G
G
I
A
C
E
E
G
I
A
C
C
E
G
I
A
Используя замеченные закономерности можно предложить следующий алгоритм решения:
надо организовать счет по строкам от первой до пятой (цикл по счетчику i), при каждом повторении этого цикла, т.е. внутри него будет выполняться три действия, объединенные в составном операторе:
распечатка строки символов (сначала A C E G I, а потом и других),
переход на следующую строку,
вычисление значения первого символа в следующей строке;
в каждой строке необходимо организовать счет (переменная j) по символам (с 1-ого до 5-ого); при каждом повторении цикла будет выполняться три действия (опять нужен составной оператор):
будет проверяться значение печатаемого символа (переменная C), и если окажется, что оно больше ‘I’, тогда переменной C присваивается значение ‘A’,
значение переменной C выводится на экран монитора,
переменной C присваивается новое значение (следующее за следующим, т.е. символы следуют через один).
Как при описании алгоритма, так и по тексту программы, действия внешнего цикла обозначены римскими цифрами, а внутреннего – арабскими. Решение записано в двух вариантах: подробном и сокращенном для демонстрации возможностей цикла for.
#include <conio.h>
#include <stdio.h>
int main() // ПОДРОБНЫЙ ВАРИАНТ ЗАПИСИ ПРОГРАММЫ
{
int i,j; /* Счетчики */
char c='A'; /* Переменная для хранения значения первого символа
в строке */
// Цикл по строкам
for (i=1; i<=5; i++)
{ /* Начало действий внутри цикла по строкам */
/**** I) Печать строки символов */
for (j=1; j<=5; j++)
{ /* Начало тела цикла печати строки */
if (c>'I') c='A'; /*** 1) Проверка значения символа */
printf ("%2c",c); /*** 2) Вывод символа на экран */
c++; c++; /*** 3) Новое значение символа */
} /* Конец тела цикла печати строки */
/**** II) Переход на следующую строку */
printf ("\n");
/**** III) Подготовка первого символа следующей строки */
c--;
c--;
} /* Конец действий внутри цикла по строкам */
getch();
return 0;
}
После подробно описанного алгоритма работы, особенностей, на которые можно было бы обратить внимание в первой программе, совсем немного. Это инициализация переменной C во время объявления и изменение значения литерной переменной C оператором декремента («минус-минус»), хотя С – переменная литерного типа.
Вторая программа (сокращенный вариант записи программы) также содержит особенности свойственные языку Си:
переменные i и j - литерного типа, но потом будут использованы как целочисленные;
в циклах for использован оператор запятая, позволяющий сделать программу более компактной.
Несмотря на перечисленные особенности, нетрудно заметить, что алгоритм решения задачи и в первом и во втором случае один и тот же.
#include <conio.h>
#include <stdio.h>
int main() // СОКРАЩЕННЫЙ ВАРИАНТ ЗАПИСИ ПРОГРАММЫ
{
char i, j, c;
for (i=1,c='A'; i<=5; printf ("\n"),c-=2,i++)
{
for (j=1; j<=5; c+=2,j++)
{
if (c>'I') c='A';
printf ("%2c",c);
}
}
return 0;
}
Блок-схема к программе


Вторая программа рисует ту же таблицу, но используется цикл while и другой алгоритм:
#include <stdio.h>
#include <conio.h>
char First; /* Первый символ в строке */
char C; /* Текущий символ в строке */
int main()
{
First='K'; /* Первый символ в первой строке */
while (First>='C')
{
/* Печать первой части строки символов */
C=First;
while (C<='I')
{
printf("%2c",C); // Печать очередного символа
C+=2; // Вычисление следующего значения
}
/* Печать второй части строки символов */
C='A';
while (C<First)
{
printf("%2c",C); // Печать символа
C+=2; // Вычисление следующего значения
}
/* Переход на другую строку */
printf("\n");
/* Вычисление значения первого символа */
First-=2;
}
getch();
return 0;
}
Варианты заданий1.
2.
3.
4.
A
D
G
J
M
A
B
C
D
E
A
B
C
D
E
F
A
M
D
G
J
M
B
C
D
E
B
C
D
E
F
G
B
C
M
J
G
J
M
C
D
E
C
D
E
F
G
H
D
E
F
M
J
G
J
M
D
E
D
E
F
G
H
I
-
-
-
-
M
J
G
D
M
E
E
F
G
H
I
J
F
E
D
M
J
G
D
A
F
G
H
I
J
K
C
B
A
5.
6.
7.
8.
A
B
C
D
E
F
G
H
I
A
B
C
D
E
A
E
D
C
B
A
B
C
D
E
B
C
D
E
F
G
H
E
A
C
D
E
B
E
D
C
A
A
B
C
D
C
D
E
F
G
E
D
A
D
E
C
E
D
B
A
A
B
C
D
E
F
E
D
C
A
E
D
E
C
B
A
A
B
E
E
D
C
B
A
E
D
C
B
A
A
E
D
C
B
A
9.
10.
11.
12.
I
A
+
+
O
+
+
F
I
G
B
A
B
+
O
O
O
+
E
F
I
G
E
C
B
A
B
C
O
O
O
O
O
D
E
F
I
G
E
C
D
C
B
A
B
C
D
+
O
O
O
+
C
D
E
F
I
G
E
C
A
C
B
A
B
C
+
+
O
+
+
B
C
D
E
F
B
A
B
A
B
C
D
E
F
A
13.
14.
15.
16.
A
A
D
B
E
C
A
E
D
C
B
A
C
E
G
I
B
C
C
A
D
B
E
B
A
E
D
C
B
D
F
H
J
D
E
F
E
C
A
D
B
C
B
A
E
D
C
E
G
I
K
G
H
I
J
B
E
C
A
D
D
C
B
A
E
D
F
H
J
L
K
L
M
N
O
D
B
E
C
A
E
D
C
B
A
E
G
I
K
M
17.
18.
19.
20.
A
B
C
D
E
A
D
G
J
M
E
A
B
C
D
E
F
Z
B
C
D
E
B
E
H
K
N
D
E
B
C
D
E
F
Y
Z
C
D
E
C
F
I
L
O
C
D
E
C
D
E
F
X
Y
Z
D
E
D
G
J
M
P
B
C
D
E
D
E
F
W
X
Y
Z
E
E
H
K
N
Q
A
B
C
D
E
E
F
F
21.
22.
23.
24.
I
H
G
F
E
N
M
L
K
J
A
A
H
G
F
E
M
L
K
J
B
C
A
*
B
G
F
E
L
K
J
D
E
F
A
*
B
*
C
F
E
K
J
G
H
I
J
A
*
B
*
C
*
D
E
J
K
L
M
N
O
A
*
B
*
C
*
D
*
E
Контрольные вопросы к теме № 3Как использовать цикл for в языке Си?
Что означают операторы «++», «– –», «+=» и т.д.?
Назначение оператора break в языке Си?
К какому типу относится цикл for (с пред- или пост- условием)?
Как использовать цикл while?
Как использовать цикл do…while?
Чем отличаются циклы с пред-и пост-условиями?
Тема №4. Функции в языке СиЗадание: реализуйте задачу по теме №3 с использованием функций.
Пример решения задачи по теме №3 с использованием функций.
Для иллюстрации решения рассмотрим алгоритм, представленный для языка Паскаль. Сделаем «перевод» с языка Паскаля на язык Си, указав отличия.
Во-первых, нет необходимости процедуры определения предыдущего элемента перед предыдущим, так как эта операция в языке Си делается в одно действие.
Во-вторых, напомним, что в языке Си нет понятия «процедура», но есть функция, которая не возвращает никакого значения.
В-третьих, не ставьте знак «точка с запятой» после закрывающей круглой скобки в перечне параметров.
В-четвертых, для каждого параметра обязательно укажите тип, а параметры разделяйте запятыми.
Пятое – при вызове функции на исполнение, если даже у нее нет параметров, круглые скобки обязательны.
Шестое – локальные переменные пишутся внутри операторных скобок, определяющих тело функции.
#include <stdio.h>
#include <conio.h>
//Описание функции печати части строки
void Part(char First, char Last)
{ char C;
C = First;
Last --;
while (C <= Last)
{
printf("%2c",C);
C+=2;
}
}
//Основная часть программы
int main()
{
const int F1= 'K';
const int F2='A';
char First1 =F1, First2 =F2;
while (First1>='C')
{
Part(First1,F1); // Печать первой части строки
Part(First2,First1); // Печать второй части строки
printf("\n");
First1 -=2;
}
return 0;
}
}
Контрольные вопросы по теме №4Что такое глобальные переменные?
Для чего нужны параметры в функции?
Назначение функций?
Что такое локальные переменные?
Что такое параметры-переменные?
Что такое параметры-значения?
Что такое рекурсия?
Что такое условие выхода из рекурсии?
Что такое формальные параметры?
Что такое фактические параметры?
Тема №5. Обработка одномерных массивовЗадание: заполните один или несколько одномерных массивов (по индивидуальному заданию). Распечатайте результат заполнения. Проведите преобразование (по индивидуальному заданию) и упорядочивание (сортировку) массивов. Распечатайте результирующие массивы. Сортировки проведите тремя методами. При использовании каждого из методов желательно использовать свой массив. Если количество массивов меньше трех, то один из массивов перед сортировкой надо скопировать в дополнительный массив и провести его сортировку.
Краткая теоретическая справка и рекомендации по выполнениюДля переменных типа массив в языке Си всегда в качестве индекса используется целое число. Это связано с тем, что переменная типа массив является указателем на начало этого одномерного массива. Аналогично в математике и физике определяется относительная система координат. А индекс – это смещение относительно начала отсчета в этой системе. Причем компилятор языка Си не отслеживает правильность использования индекса. По этой причине при неаккуратном программировании может возникнуть множество проблем, вплоть до «зависания» компьютера, если только операционная система не «отследит» обращение по некорректному адресу.
Самый безобидный вариант некорректного использования индексов приведен в следующем коротком фрагменте программы:
int x; int y[2]; int z;
void main()
{
x=1; z=4;
y[0]=2; y[1]=3; // Корректное обращение к элементам массива
y[-1]=5; y[2]=6; // Некорректное обращение к элементам массива
}
Здесь три глобальные переменные x, y, z расположены друг за другом. Так как они глобальные, то в такой же последовательности они будут располагаться в оперативной памяти. Поэтому присваивание элементу y[–1] значения 5, приведет к изменению переменной x, а изменение элемента y[2] изменит переменную z. На этом же примере легко можно убедиться, что при объявлении переменной типа массив, в квадратных скобках указывается общее количество элементов массива. Если количество элементов переменной типа массив было N, то первый элемент будет с индексом 0, а последний – с индексом (N–1).
Для одномерных массивов также распространена другая форма обращения к отдельному элементу. В записи *(y+1), в соответствии с порядком выполнения операций языка Си, сначала вычисляется адрес размещения переменной в оперативной памяти (y+1), а потом определяется сам элемент с помощью оператора «звездочка» (разыменование). При выполнении лабораторного задания необходимо хотя бы в одном месте использовать обращение к элементу массива через указатель.
В следующей программе для заполнения массива символами в случайном порядке используется именно такая форма записи. Функции генератора случайных чисел берутся из стандартной библиотеки языка Си stdlib. Для большей наглядности задана константа Povtor, имеющая значение 1, то есть истина. Она пригодится при анализе необходимости повторного поиска случайного значения. Алгоритм поиска неповторяющихся чисел или символов имеет существенные отличия по сравнению с аналогичным алгоритмом в языке Паскаль, где есть множества. Большие ограничения вносит требование не использовать библиотеку string для работы со строками языка Си. Поэтому задачу придется решать, проводя поэлементное сравнение нового элемента со всеми элементами уже записанными в массив.
Так как задача заполнения массива случайными неповторяющимися элементами встречается достаточно часто, рассмотрим алгоритм ее решения подробнее. Алгоритм заполнения содержит три цикла: в первом цикле выбираем номер заполняемого элемента (переменная i); внутри первого цикла выполняется цикл (do...while), который будет выполняться еще раз, если потребуется повтор; внутри цикла (do…while) выполняются еще три действия: вычисляется значение нового элемента, переменной x задается значение «не повторять» и запускается третий цикл – сравнения вычисленного значения со всеми предыдущими (цикл for по переменной j).
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <time.h>
#define N 20
#define Povtor 1
inline void rus() // Русификация вывода в консольное окно
{
setlocale( LC_CTYPE, ".1251" );
setlocale( LC_MONETARY, ".1251" );
}
void randomize()
{
srand(time(0));
}
unsigned int random(int range)
{
return (rand() % range);
}

int main()
{
char c[N];
int i, j, x,range;
rus();
randomize();
printf("Заполнение одномерного массива символами \n");
printf("в случайном порядке. Символы не должны повторяться. \n");
printf("Коды символов расположены в диапазоне от 33 до 90.\n");
range = 90-33+1;
*c=random(range) + 33; // Первый элемент
for (i=1;i<N; i++) // Цикл заполнения элементов,
{ // i – номер очередного элемента
do
{
*(c+i)=random(range) + 33; // Новое значение
x = !Povtor; // Считаем, что повтор поиска не нужен
for(j=0; j<i; j++) // Цикл сравнения со всеми предыдущими
if (*(c+i)==*(c+j))
{
x = Povtor; // Элементы совпали, надо повторить поиск
break;
}
}
while (x==Povtor);
}
// Вывод одномерного массива символов
printf("Распечатка массива \n");
for (i=1; i<N; i++) //заметьте еще раз, проверяется условие i<N
printf("%c",(*(c+i)));
return 0;
}
Реализуйте в качестве тренировки указанный пример с помощью функций. Например, функция, проверяющая повторился элемент y в массиве x или нет, может иметь следующий вид (считаем, что количество элементов в массиве x равно n).
int povtor(int *x, int n, int y)
{ int Povtor, i;
Povtor = 0;
for (i=0;i<n;i++) {if (x[i]==y) Povtor=1;}
return Povtor;
}
Обратите внимание на запись параметра-переменной x. Указывается только адрес начала массива.
Варианты заданий1. Заполнить два массива, размером 20 и 30 элементов, соответственно, случайными целыми числами в диапазоне от -50 до 50. Из полученных двух массивов выделить в два массива отдельно отрицательные и положительные числа. Произвести сортировку полученных массивов и исходного массива по возрастанию. Для контроля результата сделать распечатку массивов, в том числе исходного.
2. Заполнить два массива размером 20 и 30 элементов случайным образом буквами латинского алфавита. Заполнить третий массив теми буквами, которые входят и в первый и во второй массив, четвертый массив – оставшимися буквами из первого и второго. Произвести сортировку полученных массивов. Для контроля результата также сделать распечатку массивов, в том числе исходного.
3. Из исходного массива символов, заполненного случайным образом символами с кодами в диапазоне от 21 до 254, выделить в отдельные массивы буквы латинского алфавита, как заглавные, так и прописные. Произвести сортировку полученных массивов. Для контроля результата сделать распечатку массивов, в том числе исходного.
4. В исходном массиве символов, заполненном случайным образом символами с кодами в диапазоне от 21 до 254, выделить в отдельные массивы заглавные гласные и заглавные согласные буквы латинского алфавита. Произвести сортировку полученных массивов. Для контроля результата сделать распечатку массивов, в том числе исходного.
5. Два массива размером 200 и 5 элементов, соответственно, заполните в случайном порядке символами, коды которых расположены в диапазоне от 40 до 200. Проверить входит ли меньший массив полностью в больший и, если это так, то в большем массиве все элементы, принадлежащие меньшему массиву, заменить символом "пробел". Выполните сортировку полученных массивов. Для контроля результата сделайте распечатку массивов, в том числе исходного.
6. В исходном массиве (размер 100 элементов), заполненном символами латинского алфавита и цифр, замените все повторные вхождения каждого символа пробелом, а все повторяющиеся символы поместите во второй массив. Выполните сортировку полученных массивов. Для контроля результата сделайте распечатку массивов, в том числе исходного.
7. Заполните случайным образом массив (100 элементов) поочередно буквами латинского алфавита от A до H и символами цифр от 1 до 8. Проверьте, есть ли в данном массиве записи, сходные с записью ходов коня по шахматной доске, и, если есть заполните ими второй массив. Выполните сортировку полученных массивов. Для контроля результата сделайте распечатку массивов, в том числе исходного.
8. В исходном массиве символов, заполненном случайным образом символами с кодами в диапазоне от 21 до 254, выделить в отдельные массивы строчные гласные и строчные согласные буквы латинского алфавита. Произвести сортировку полученных массивов. Для контроля результата сделать распечатку массивов, в том числе исходного.
9. В виде массива символов дан текст (ввод с клавиатуры). Случайным образом заполните второй массив из 26 элементов символами, отличными от букв латинского алфавита и друг от друга, причем каждый символ должен встречаться один раз. Будем считать, что первый элемент второго массива соответствует букве «а», второй букве «b» и т.д. Требуется зашифровать текст из первого массива, заменяя буквы первого массива символами из второго. Произведите сортировку массивов. Для контроля результата сделать распечатку массивов, в том числе исходного.
10. В массив символов вводится текст на русском языке, состоящий из нескольких слов. Учитывая, что строчные буквы русского алфавита в операционной системе MSDOS расположены не подряд, а разбиты на два диапазона (от «а» до «п» и от «р» до «я»), слова, состоящие только из букв одного из диапазонов поместите в один массив, а другие во второй. Проведите сортировку полученных массивов. Для контроля результата сделайте распечатку массивов, в том числе исходного.
11. Введите с клавиатуры текст в массив символов. Определите, какие из слов в массиве состоят из букв с возрастающими кодами, какие с убывающими и какие из смешанных. Разместите эти слова в отдельные массивы. Произведите сортировку полученных массивов. Для контроля результата сделайте распечатку массивов, в том числе исходного.
12. Дан массив содержащий текст. Среди литер текста особую роль играет знак # , появление которого означает отмену стоящей перед ним буквы, несколько знаков # означает отмену соответствующего числа букв. Создать массив заполненный текстом из первого массива с учетом роли этого знака. (например, ХЭ#E##НЕLO#LO = HELLO). Произвести сортировку полученных массивов. Для контроля результата сделать распечатку массивов, в том числе исходного.
13. Из исходного массива символов, заполненного случайным образом символами с кодами в диапазоне от 21 до 254, выделить в отдельные массивы символы цифр и знаков препинания. Провести сортировку полученных массивов. Для контроля результата сделать распечатку массивов, в том числе исходного.
14. Заполнить два массива, размером 40 и 30 элементов, соответственно, случайными целыми числами в диапазоне от -50 до 50. Из полученных двух массивов создать два массива отдельно, один из которых содержит числа от -10 до 10, а другой – от 20 до 50. Произвести сортировку полученных массивов по возрастанию. Для контроля результата сделать распечатку массивов, в том числе исходного.
15. Заполните случайным образом массив (100 элементов) поочередно буквами латинского алфавита от A до H и символами цифр от 1 до 8. Проверьте, есть ли в данном массиве записи, сходные с записью ходов ладьи по шахматной доске, и, если есть, заполните ими второй массив. Выполните сортировку массивов. Для контроля результата сделайте распечатку массивов, в том числе исходного.
16. Заполните случайным образом массив (100 элементов) поочередно буквами латинского алфавита от A до H и символами цифр от 1 до 8. Проверьте, есть ли в данном массиве записи, сходные с записью ходов ферзя по шахматной доске, и, если есть, заполните ими второй массив. Выполните сортировку массивов. Для контроля результата сделайте распечатку массивов, в том числе исходного.
Контрольные вопросы по теме № 5Какого типа могут быть индексы массивов?
Что такое размерность массивов?
Для чего нужен «барьер» в сортировке методом прямого включения?
Каков алгоритм поиска минимума или максимума в одномерном массиве?
Как найти индекс элемента в одномерном массиве по его значению?
Алгоритм поиска минимума или максимума в двумерном массиве.
Назначение функций random и randomize?
Сортировка элементов двумерного массива.
Как обратиться к элементу массива по указателю?
Тема №6. Строки и использование библиотечных функций для их обработкиЗадание: Введите с клавиатуры предложение, выделите из предложения отдельные слова в массив слов, проведите преобразование предложения и слов в соответствии с индивидуальным заданием, распечатайте результат обработки на экран монитора. Используйте как можно больше библиотечных функций для работы со строками.
Индивидуальные задания на лабораторную работу даны в конце описания к теме № 6. Длина вводимого предложения не более 80 символов (ширина экрана). При выполнении задания необходимо во всех случаях, где это можно, использовать функции для работы со строками. Все задания подразумевают необходимость применения не менее трех разных функций.
Краткая теоретическая справка и рекомендации по выполнениюСтрока в языке Си представляет собой одномерный массив символов, последним элементом которой является символ конца строки – нуль (строка, завершающаяся нулем, то есть NULL terminated string).
Объявление переменной типа строка в языке Си возможно тремя способами, два из которых инициализируют строку во время объявления. Первый способ ничем не отличается от объявления массива символов (не забудьте добавить место для завершающего нуля):
char s[40+1];
Второй способ предусматривает присваивание строковой переменной начального значения (при этом длину строки компилятор может вычислить сам):
char s[] = "Пример инициализации строки";
Справа от знака присваивания записана строковая константа. В конце строки автоматически добавляется ноль ('\0'). Константы символьных строк помещаются в класс статической памяти.
В третьем способе явно не указывается, что используется массив. В левой части от знака присваивания указывается указатель на символ:
char *s="Второй вариант инициализации";
Переменная s будет указателем на то место в оперативной памяти, где располагается строковая константа. В такой форме записи кроется потенциальная ошибка, заключающаяся в том, что указатель на символ часто называют строкой. Представленная ниже запись – это только указатель на символ, так как для размещения строки место не предусмотрено:
char *s;
Для работы со строками есть набор функций. Для ввода со стандартного устройства ввода (клавиатуры) чаще всего используются библиотечные функциями из модуля стандартного ввода-вывода: scanf и gets.
Для ввода строки с помощью функции scanf, использует формат «%s», причем обратите внимание на то, что перед идентификатором строки не используется знак адреса «&», так как одномерный массив уже представлен указателем на его начало:
scanf("%s", s);
Функция gets() считывает символы до тех пор, пока не достигнет символа перехода на новую строку. Функция принимает все символы вплоть до символа перевода строки, но не включает его. К концу строки добавляется завершающий ноль ('\0'). Функция gets() помещает считанную с клавиатуры последовательность символов в параметр типа строка и возвращает указатель на эту строку (если операция завершилась успешно), или NULL (в случае ошибки). В приведенном ниже примере при успешном завершении операции, на экран будет выведено две одинаковые строки:
#include <stdio.h>
int main()
{ char s[50];
char *p;
p=gets(s);
printf(" \n Введена строка %s. ",s);
if (p) printf(" \n Введена строка %s. ",p);
return 0;
}
Попутно заметим, что функция gets часто используется для ввода любых данных с клавиатуры в виде строки с целью дальнейшего преобразования функцией sscanf к нужному формату или для предварительного анализа вводимых данных, например:
#include <string.h>
#include <stdio.h>
#include <conio.h>
int main()
{ char s[50]; int x, err;
do
{ printf(" \n Введите целое число -> ");
gets(s);
err=sscanf(s, "%d",&x);
if (err!=1) printf(" \n Ошибка ввода. ");
} while (err!=1);
printf("\n Введено целое число -> %d", x);
return 0;
}
Для вывода строк на стандартное устройство вывода (экран монитора) можно использовать две функции printf и puts. В функции printf в качестве формата передается "%s". Удобство использования этой функции заключается в том, что помимо строки можно сразу выводит данные других типов. Особенность функции puts заключается в том, что после вывода строки автоматически происходит переход на следующую строку.
Для преобразования строк в языке Си предусмотрена библиотека string. Каждая из функций имеет свой формат записи (прототип). Некоторые из функций представлены ниже. Более подробное описание функций смотрите в указанных библиографических источниках.
void *strcat(char *s1,const char *s2) – дополняет строку s1 строкой s2.
char *strncat(char *s1,const char *s2, size_t n) – дополняет строку s1 символами из строки s2, но не более чем n штук.
char *strcpy(char *s1,const char *s2) – копирует строку, указанную указателем s2, на место, указанное указателем s1; возвращает s1.
char *stpcpy(char *dest, const char *src) – копирует строку, указанную указателем src, на место, указанное указателем dest; не копирует символ конца строки;
char *strncpy(char *s1, const char *s2, size_t n) – – копирует строку, указанную указателем s2, на место, указанное указателем s1; возвращает s1; копируется не более чем n символов.
int strcmp(const char *s1,const char *s2) – сравнивает строки, указанные указателями s1 и s2; символы строк сравнивают с помощью значений их кодов; функция возвращает 0, если строки одинаковы; значение, которое меньше 0, если первая строка меньше второй; и значение, превышающее 0, если первая строка больше второй.
int strncmp(const char *s1,const char *s2, size_t n ) – сравнивает первые n символов или до первого пустого символа строки, указанные указателями s1 и s2.
int stricmp(const char *s1,const char *s2) – сравнивает строки, указанные указателями s1 и s2, игнорируя регистр символов (строчные или заглавные);
int strcmpi(const char *s1,const char *s2) – сравнивает строки, указанные указателями s1 и s2, игнорируя регистр символов (строчные или заглавные);
chat *strchr(const chat *s, int c) – ищет первое появление c (преобразованного в char) в строке, указанной указателем s; пустой символ является частью строки; возвращает указатель на первое появление или NULL, если ничего не найдено.
chat *strrchr(const chat *s, int c) – ищет последнее появление символа c в строке, то есть поиск идет с конца строки, заданной указателем s; пустой символ является частью строки; возвращает указатель на первое появление или NULL, если ничего не найдено.
char *strstr(const chat *s1, const char *s2) – возвращает указатель на положение первого появления последовательности символов из s2 в строке s1 (исключая завершающие пробелы); возвращает NULL, если совпадений не найдено.
chat *strtok(chat *s1,const chat *s2) – эта функция переформирует строку s1 в отдельные знаки; строка s2 содержит символы, которые используются в качестве разделителей. Функция вызывается последовательно. Для первого вызова s1 должен указывать на строку, которую необходимо разбить на знаки. Функция находит разделитель, который следует за символом, не являющимся разделителем, и заменяет, его пробелом. Она возвращает указатель на строку, содержащую первый знак. Если ни оного знака не найдено, она возвращает NULL. Чтобы найти следующий знак в строке, необходимо вызвать функцию опять, но первым аргументом поставить NULL. Каждый последовательный вызов возвращает указатель на следующий знак или на NULL, если больше знаков не найдено.
int strlen(const char *s) – возвращает число символов (исключая завершающие пробелы) в строке s.
void setmem(void *dest, unsigned length, char value) – присваивает значение value диапазону памяти, начиная с адреса dest;
size_t strspn(const char *s1, const char *s2) – находит начальный сегмент строки s1, которая состоит из символов строки s2; возвращает длину найденного сегмента.
size_t strсspn(const char *s1, const char *s2) – находит начальный сегмент строки s1, которая не состоит из символов строки s2; возвращает длину найденного сегмента.
char *strdup(const char s) – резервирует оперативную память и помещает на это место копию строки s; возвращает указатель на зарезервированную область памяти.
char *strlwr(char *s) – преобразует все символы строки к нижнему регистру (от a до z); возвращает указатель на строку s.
char *strupr(char *s) – преобразует все символы строки к верхнему регистру (от A до Z); возвращает указатель на строку s.
char *strpbrk(const char *s1, const char *s2) – сканирует строку s1 на присутствие любого символа строки s2; возвращает указатель на найденный символ или NULL, если совпадение не найдено.
char *strrev(char *s) – переписывает символы в строке в обратной последовательности; возвращает указатель на строку s.
char *strset(char *s, int ch) – все символы в строке делает равными ch; возвращает указатель на строку s.
size_t strxfrm(char *s1, char *s2, size_t n) – символы строки s2 заменяет на соответствующие символы строки s1, но не более чем n символов; возвращает количество замененных символов.
Кроме функций для работы со строками в библиотеке string есть ряд функций для преобразования одномерных массивов байтов памяти:
int memcmp (const void *s1, const void *s2, size_t n) – сравнивает два блока памяти, начинающиеся с адресов s1 и s2, но не более, чем n байтов; возвращает 0, если блоки равны, число меньшее 0, если первый блок меньше второго, число большее 0, если первый блок больше второго.
void *memcpy (void *dest, const void *src, size_t n) – копирует блок памяти src в блок памяти dest, но не более, чем n байтов; если блоки пересекаются, то результат не определен.
void *memccpy(void *dest, const void *src, int c, size_t n) – копирует блок памяти src в блок памяти dest; копирование останавливается по достижении количества в n байтов или после копирования символа c.
void *memmove(void *dest, const void *src, size_t n) – копирует блок памяти src в блок памяти dest, но не более, чем n байтов; копирование корректное даже если блоки памяти пересекаются.
void *memchr (const void *s, int c, size_t n) – в блоке памяти в n байтов ищет символ c, начиная с адреса s; если символ найден – возвращается указатель на найденный элемент, в противном случае NULL.
Пример выполнения лабораторного задания № 6Индивидуальное задание: Слова исходного предложения расположить в обратном порядке. Расположение знаков препинания не менять.
Решение предусматривает выполнение нескольких действий:
Вывод информации о назначении программы (заголовок программы).
Ввод исходного предложения.
Выделение из предложения слов.
Выделение из предложения разделительных знаков.
Сборка нового предложения из слов и знаков поочередно.
Распечатка результата.
В соответствии с общим заданием на лабораторную работу каждое из перечисленных действий должна выполнять отдельная функция. Далее дадим краткие пояснения к каждой из функций. Но сначала опишем общую структуру программы. Программа может строиться так же, как и на языке Паскаль, – сначала объявление функций, а потом основная часть программы. Здесь используем другую форму: сначала будет предварительное объявление функций, потом основная функция, и только потом подробное описание предварительно записанных функций.
Напомним, что при объявлении функций записываются формальные параметры. Параметры могут быть переменными и значениями. Если параметр – это указатель, то это – параметр переменная, в противном случае – это значения. Параметр также будет значением, если он записан как константа.
Функция Title() – без параметров, так как только лишь выводит на экран набор строк.
Функция ввода предложения InpPredl (char predl[]) имеет один параметр – предложение, которое надо заполнить. В записи этого параметра есть сразу два момента, на которые надо обратить внимание: во-первых, в качестве параметра передается одномерный массив символов, то есть указатель (параметр переменная), во-вторых, в записи массива не указана размерность массива, а только открывающие и закрывающие квадратные скобки, так как достаточно передать только адрес начала строки.
Выделение из предложения слов и разделительных знаков реализуется одним алгоритмом, поэтому могут выполняться одной и той же функцией выделения Select(const char *predl, char m[][N],char *sel, int *n). Функция имеет четыре параметра:
predl – предложение, из которого идет выделение,
m – массив слов результата (под каждое слово предусмотрен размер в N символов),
sel – адрес символов, располагаемых между выделяемыми элементами,
указатель на переменную, в которой будет располагаться количество выделенных элементов, этот параметр используется как переменная, так как есть необходимость сохранить изменения.
Функция сборки нового предложения Constructor(char slova[][N], char razd[][N], int sl, int rz) – это действительно функция, так как возвращает указатель на первый символ полученного предложения. Назначение параметров понятно по названиям: массив слов, массив разделителей, количество слов, количество разделителей.
Вывод предложения функцией OutPredl(char *s1, char *s2) использует два параметра: исходное предложение и результат.
Функция strdup служит для создания в оперативной памяти дубликата передаваемой в качестве параметра строки. Функция strdup запрашивает у операционной системы оперативную память динамически, то есть в процессе работы программы, получает ее и возвращает указатель на занятую область. По завершении работы программы необходимо память опять отдать операционной системе. Это действие выполняется функцией free.
Главная функция последовательно использует (вызывает на исполнение) перечисленные функции одну за другой. Даже если функции используются в программе всего один раз, программа становится гораздо проще и понятнее. Перед вызовом некоторых функций делаются подготовительные операции, например, строчные и заглавные буквы объединяются в единый массив.
Теперь можете проанализировать весь текст программы:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#define N 20
// ПРЕДВАРИТЕЛЬНОЕ ОБЪЯВЛЕНИЕ ФУНКЦИЙ
// Заголовок программы
void Title();
// Ввод предложения
void InpPredl (char predl[]);
// Выделение из предложения
void Select(const char *predl, char m[][N],char *sel, int *n);
// Сборка предложения
char *Constructor(char slova[][N], char razd[][N], int sl, int rz);
// Вывод результата
void OutPredl(char *s1, char *s2);
inline void rus() // Русификация вывода в консольное окно
{
setlocale( LC_CTYPE, ".1251" );
setlocale( LC_MONETARY, ".1251" );
}
// ОСНОВНАЯ ФУНКЦИЯ
int main()
{
// ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ
char predl[80]; // Введенное предложение
char *res; // Результирующее предложение
char slova[N][N]; // Массив слов в предложении
char razd [N][N]; // Массив разделителей в предложении
int sl=-1, rz=-1; // Счетчики слов и разделителей
char buk[80]; // все буквы алфавита
char *bs="йцукенгшщзхъфывапролджэячсмитьбю";// Буквы строчные
char *bz ="ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ";/* заглавные */
char *r="`!;:,.?- _"; // Разделительные знаки
//ВЫЗОВ ФУНКЦИЙ НА ИСПОЛНЕНИЕ
rus();
// Заголовок программы
Title ();
// Ввод предложения
InpPredl (predl);
// Выделение из предложения слов
Select (predl, slova, r, &sl);
// Выделение из предложения разделителей
strcpy(buk,"");
strcat (buk, bs);
strcat (buk, bz);
Select (predl, razd, buk, &rz);
// Сборка предложения
res = Constructor(slova, razd, sl, rz);
// Вывод результата
OutPredl (predl, res);
free (res);
return 0;
}
// ОПИСАНИЕ ИСПОЛЬЗУЕМЫХ ФУНКЦИЙ
// Заголовок программы
void Title()
{
puts (" Лабораторное задание по теме № 6\n");
puts (" Во введенном предложении расположите слова");
puts (" в обратной последовательности.");
puts(" Порядок следования знаков препинания не менять.");
puts(" В предложении используются русские буквы и знаки. \n");
}
// Ввод предложения
void InpPredl(char *s)
{
puts("Введите предложение \n");
strcpy (s,"Верите ли вы, что задача решена?");
// gets (s);
}
// Вывод результата
void OutPredl (char *s1, char *s2)
{
puts ("Исходное предложение");
puts (s1);
puts (" Результат ");
puts (s2);
}
// Выделение из предложения
void Select(const char *predl, char m[][N], char *sel, int *n)
{
char *p, *s;
s=strdup (predl); // Сделать копию исходного предложения
// так как передается константа, strtok требует
// внесения изменений при своей работе
p = strtok (s, sel);
while (p)
{
(*n)++;
strcpy (m[*n],p);
p = strtok (NULL, sel);
}
free (s);
}
// Сборка предложения
char *Constructor(char slova[][N], char razd[][N], int sl, int rz)
{
int i, j;
char res[80];
char *s;
*res=0; // Начальное значение результата
i = sl;
j=-1;
while ((i>=0)||(j<=rz))
{
if ((i>=0)) strcat (res, slova[i]); // Добавление слова
i--;
j++;
if ((j<=rz)) strcat (res, razd[j]); // Добавление знаков
}
s = strdup (res);
return s;
}
Варианты заданий1. В двух предложениях найти и распечатать совпадающие слова.
2. В предложении найти слово, состоящее из наибольшего количества гласных букв.
3. Распечатать слова, из которых состоит предложение, в порядке возрастания длины слова.
4. В предложении найти все однокоренные слова. Корень слова также задан с клавиатуры.
5. Удалить в предложении все повторные вхождения слов и распечатать получившееся предложение.
6. Найти в предложении слово, состоящее из наибольшего количества разных букв.
7. Выделить из предложения слова, содержащие две или более одинаковые буквы.
8. Напечатать слова, входящие в предложение, в алфавитном порядке.
9. Удалить из предложения все предлоги. Список предлогов задан во втором предложении.
10. Все буквы каждого слова в предложении записать в обратном порядке и распечатать получившееся предложение.
11. Во всех словах предложения удалить гласные буквы и распечатать получившееся предложение.
12. Дополнить каждое слово предложения пробелами так, чтобы его длина была равна длине самого длинного слова. Распечатать получившееся предложение.
13. Исходное предложение, состоящее из четырех слов, каждое из которых состоит из четырех букв, например, "Было утро, рано петь." распечатать в виде: Бурп ытае, лрнт оооь. Первое слово состоит из первых букв слов, второе - из вторых, и так далее.
14. С клавиатуры ввести две строки. Одна строка - предложение на русском языке, а вторая (под ней) состоит из пробелов и знаков "минус" или "равно" (будем считать это подчеркиванием). Выделить и распечатать подчеркнутые слова. Например, надо выделить слова «мест» и «слагаемых» в предложении:
От перемены мест слагаемых сумма не меняется.
----- ========
15. Проверьте на совпадение два предложения. Количеством пробелов между словами пренебрегать. Знаки препинания - учитывать.
16. Удалить в предложении все слова, имеющие символы цифр и распечатать получившееся предложение.
17. Предложение состоит из записи символов цифр, например:
123434 53423 2344 6564.
Распечатать слова в порядке возрастания.
Контрольные вопросы к теме № 6Представление строк в языке Си.
Примеры инициализации строк в теле программы.
Библиотечные функции языка Си для обработки строк.
Библиотечные функции ввода-вывода строк.
ОглавлениеТема №1. Функции стандартного ввода–вывода, вычисление математических функций2
Пример выполнения задания по теме № 13
Формулы для решения задач4
Варианты заданий 6
Контрольные вопросы по теме № 16
Тема №2. Ветвление программы (использование операторов ветвления и переключателя switch)8
Варианты заданий 8
Пример выполнения лабораторного задания № 29
Контрольные вопросы к лабораторной работе № 213
Тема №3. Циклы, символьный (литерный) тип данных 15
Примеры выполнения задания по теме №3.15
Варианты заданий20
Контрольные вопросы к теме № 321
Тема №4. Функции в языке Си22
Контрольные вопросы по теме №423
Тема №5. Обработка одномерных массивов24
Краткая теоретическая справка и рекомендации по выполнению24
Варианты заданий27
Контрольные вопросы по теме № 530
Тема №6. Строки и использование библиотечных функций для их обработки31
Краткая теоретическая справка и рекомендации по выполнению31
Пример выполнения лабораторного задания № 635
Варианты заданий39
Контрольные вопросы к теме № 640
Оглавление40
X