- •Министерство образования Российской Федерации
- •Контрольные вопросы
- •Задания для выполнения
- •Варианты задания
- •Классы памяти. Массивы, операция индексации Цель работы
- •Контрольные вопросы
- •Варианты заданий
- •Массивы. Связь массивов и указателей Цель работы
- •Методические указания
- •Контрольные вопросы
- •Варианты заданий
- •Символьные строки
- •Контрольные вопросы
- •Варианты заданий
- •Функции. Основные правила использования функций
- •Контрольные вопросы
- •Варианты заданий
- •Функции. Использование массивов и функций в качестве формальных параметров
- •Контрольные вопросы
- •Варианты заданий
- •Контрольные вопросы
- •Варианты заданий
- •Файлы Цель работы
- •Методические указания
- •Функция
- •Контрольные вопросы
- •Варианты заданий
Контрольные вопросы
1. Что передается функции, если единственный аргумент массив?
2. Как передать адрес строки двумерного массива?
3. Каковы составляющие синтаксиса описания имени типа?
4. Каковы правила описания указателя на функции?
5. Как описать массив указателей на функцию?
6. Каким образом описать функцию в роли формального параметра?
7.Каким образом описать функцию в роли типа возврата?
Варианты заданий
1. Функция принимает массив символов S1, читает с клавиатуры последовательность символов S2 и возвращает количество совпадений символов в массивах S1 и S2.
В вариантах 2-15 использовать указатели на функции.
2. Создать три функции, которые вычисляют сумму, разность и произведение двух массивов.
3. Решить задачу 2., используя массив указателей на функции.
4. Найти корень уравнения x*x-cos(x)=0 методами Ньютона, итераций и половинного деления.
5. Решить задачу 4., используя массив указателей на функции.
6. С помощью двух различных функций найти минимальный и максимальный элементы массива.
7. Решить задачу 6., используя массив указателей на функции.
8. С помощью двух различных функций упорядочить элементы массива по убыванию и возрастанию.
9. Решить задачу 8., используя массив указателей на функции.
10. Для выбора максимального элемента заданного массива по указателю вызвать одну из функций.
11. Решить задачу 10., используя массив указателей на функции.
12. Вычислить f(x)/g(x), где в качестве f(x) и g(x) могут быть четыре различные функции, возвращающие вещественные значения.
13. Решить задачу 12., используя массив указателей на функции,
14. В соответствии с номером выбранного пункта меню выполнить ту или иную функцию.
15. Решить задачу 14., используя массив указателей на функции. 16- Передать функции массив имен и приветствовать всех заданных в массиве по имени (например, «Здравствуйте, Вася!»).
17. Описать функцию, которая принимает массив и транспонирует его.
18. С помощью функции, возвращающей указатель на двумерный массив, с точностью до трех верных знаков решить систему Ах == х по формуле
– длина
вектора хi
х0
= {1,0,
...,0},i=
0,1,2,...,
А – заданная n*n матрица.
19. Определить массив номеров i максимальных коэффициентов c(i,n)=n!/(i!(n-i)!), 0<i<n<10 для различных n.
20. Вычислить значение полинома
Pn(x)=anxn+ an-1xn-1... +a2x2+a1x + а0 по схеме Горнера
Рn(х)=((an)x+an-1)x+an-2)x +ап-з)х +... +a1x +a0 и значение функции
z(x)= Pn(x)/ Рm(х) при различных значениях х и массивах коэффициентов полиномов.
21. В заданном массиве символов S1 все символы увеличить на величину axn2+bxn+c(п – позиция символа в строке, а, b, с - аргументы функции), из полученного массива символов S2 восстановить исходный массив другой функцией. Вернуть количество ошибок восстановления.
22. Вычислить массив коэффициентов c(i,n) при всех степенях полинома (1+х)". Использовать формулы
c(0,n)==c(n,n)=l; c(i,n)=c(i,n-l)+c(i-l,n-l): 0<i<n.
23. Вычислить длину самой длинной строки в массиве строк.
24. Вычислить количество слов в массиве строк и вернуть массив, содержащий количество слов в каждой строке.
25. Преобразовать массив символов в массив целых и вернуть его.
Лабораторная работа № 14
С Т Р У К Т У Р Ы
Цель работы
Изучение производных типов данных. Структуры и объединения.
Методические указания
Назначение структур
Структура – это составной объект, в который входят элементы любых типов, за исключением функций. В отличие от массива, все элементы которого должны быть одного типа, структура объединяет элементы разных типов. Структуру можно рассматривать как набор из одной или нескольких переменных, которые для удобства работы с ними сгруппированы под одним именем.
Описание структурных переменных
Для описания структурных переменных прежде всего необходимо указать тип структуры, который определяется так:
struct
{
<список описаний элементов>
} список переменных;
Элементы структуры могут иметь базовый тип, либо быть массивом, указателем, объединением или структурой. Элемент структуры не может быть структурой того же типа, в которой он содержится. Однако он может быть описан как указатель на тип структуры, в которую он входит. Это позволяет создавать связанные списки структур.
Пример:
struct
{
int k; /* список */
float l; /* описаний */
char m; /* элементов */
} список переменных ;
Для описания структурных переменных существуют несколько способов:
а) без имени структуры.
В этом случае структурные переменные описываются так:
<тип данных> <список имен структурных переменных>,
где <тип данных > – это тип структуры для переменных, имена которых указаны в списке. Ниже приведены примеры описания структурных переменных.
Пример.
Конструкция
struct
{
int x;
float y;
} a, b, c ;
описывает три структурные переменные a, b и c, каждая из которых представляет собой структуру, состоящую из двух элементов x и y.
Пример.
Дата состоит из нескольких частей: день, месяц, год. Для представления даты можно использовать структуру, которая будет иметь элементы: day (день), month (месяц), year (год).
Конструкция
struct
{
int day; /* день */
int month; /* месяц */
int year; /* год */
} date1;
определяет структурную переменную date1.
б) через определение типа структуры.
При использовании этого способа сначала в программе с типом структуры связывается некоторое имя с помощью ключевого слова typedef:
typedef struct
{
<список описания элементов>
} <имя типа структуры>;
В дальнейшем это <имя типа структуры> можно использовать в программе для определения структурных переменных. Например, для представления комплексного числа можно использовать структуру:
typedef struct
{
float real; /* действит. часть */
float imag; /* мнимая часть */
}
COMPLEX;
Теперь, чтобы определить в программе два комплексных числа, достаточно записать:
COMPLEX A1, A2;
в) через метку структуры.
В этом случае с типом структуры связывается метка структуры:
struct <метка структуры>
{
<список описаний элементов>
};
Теперь, используя метку структуры, можно определить структурные переменные с помощью конструкции:
struct <метка структуры> <список имен структурных переменных>;
Например, пусть дано описание
struct DATE /*DATE – это метка структуры */
{
int day; /* день */
int month; /* месяц */
int year; /* год */
};
Тогда конструкция
struct DATE date2, date3, date4;
определяет три структурные переменные date2, date3, date4.
Способы б) и в) применять целесообразнее, если структура используется в различных функциях.
Обращение к элементам структур
Обращение к элементу структуры осуществляется с помощью составного имени, которое состоит из имени самой структуры и имени элемента, разделенных точкой:
<имя структуры>. <элемент>
Примеры:
date2. day = 1;
date3. month = 7;
date4. day = 3.
Инициализация структур, ввод–вывод
Если структура является глобальной или статической, то ее можно инициализировать непосредственно в месте определения, поместив вслед за ее определением список инициализаторов для элементов.
Список инициализаторов – это последовательность значений, разделенных запятыми. Список инициализаторов заключается в фигурные скобки. Каждый инициализатор в списке представляет собой либо константное выражение, либо, в свою очередь, список инициализаторов. Ниже приведен пример инициализации статической структуры.
struct A
{
int b;
char c;
};
static struct A a1 = {1, ‘R’};
Значения константных выражений из каждого списка инициализаторов присваиваются элементам структуры в порядке их следования. Так, в приведенном выше примере элементу b структуры a1 присваивается значение 1, а элементу c – значение ‘R’.
Если в списке инициализаторов меньше элементов, чем в структуре, то оставшиеся элементы структуры неявно инициализируются нулевыми значениями. Если же число инициализаторов больше, чем требуется, то выдается сообщение об ошибке.
Ниже приведен пример, иллюстрирующий инициализацию структуры и ввод–вывод элементов структуры.
# include < stdio.h>
struct person
{
char name [25]; /* фамилия */
int year; /* год рождения*/
};
struct person p = {“Иванов”, 1980};/*инициализация элементов структуры p*/
void main ( )
{
printf (“\n Фамилия: % s”, p. name);
printf (“\n Год рождения: %d”, p. year);
printf (“\n Введите фамилию: “);
scanf (“%s”, p.name);
printf (“\n Введите год рождения: “);
scanf (“%d”, & p.year);
printf (“\n\n Фамилия: %s”, p.name);
printf (“\n Год рождения: %d\n”, p.year);
}
Массивы структур
Пусть, например, ведомость, содержащая сведения о ста служащих, состоит из следующих граф: фамилия, должность, год рождения. Эту ведомость можно описать как массив структур:
struct person
{
char name [25]; /* фамилия */
сhar post [25]; /* должность */
int year; /* год рождения */
};
struct person Vedomost [100]; /* Vedomost – массив структур */
В этом примере определяется массив Vedomost, элементы которого являются структурами. Массив состоит из 100 элементов. Каждый элемент массива – это структура, состоящая из трех компонентов с именами name, post, year.
Пример:
Vedomost [0]. year = 1950; /* присвоить значение 1950 */
/* компоненту year структуры, */
/* которая имеет индекс 0 */
Вложенные структуры
Допускается использование структуры в качестве элемента другой структуры.
Пример.
С помощью структуры можно описать учетную карточку служащего:
struct employee
{
char name [25]; /*фамилия */
struct DATE birthdate; /* дата рождения */
};
Структура employee содержит в себе структуру типа DATE (структурный тип DATE был описан выше).
Определим структурную переменную e1:
struct employee e1;
Тогда e1.birthdate.month будет ссылаться на месяц рождения служащего.
Указатели на структуры
Допускается использование указателя на структуру.
Например, конструкция
struct DATE *pd, date5;
определяет указатель pd на структуру типа DATE и структурную переменную date5. Для использования указателя pd в программе, ему необходимо сначала присвоить значение, например
pd = &date5; /* присвоить указателю pd адрес структурной переменной date5 */
Обращение к элементам структур через указатели
Если p – указатель на структуру, то с помощью записи вида
p – > элемент
можно обратиться к конкретному элементу структуры.
Пример:
pd year
Доступ к элементу структуры через указатель можно осуществить и другим способом:
(*p). элемент
где p – указатель на структуру. Таким образом, конструкции
pd year
и
(*pd). year
эквиваленты.
Примеры обращений к элементам структуры через указатель:
pd month
(*pd).day
Использование структур в функциях
Если аргументом функции является структура, то можно передавать параметры одним из трех способов:
передавать элементы структуры по отдельности;
передавать всю структуру целиком;
передавать указатель на структуру.
Функция в качестве значения может возвращать структуру. Рассмотрим пример, демонстрирующий использование указателей на структуры в функциях.
Пусть, например, нужно выполнять сложение и вычитание комплексных чисел. Для представления комплексного числа будем использовать структуру, а для сложения и вычитания комплексных чисел – функции add и sub. Аргументами этих функций являются указатели c1, c2, c3 на структуры (c1, c2 – это указатели на структуры, которые служат исходными данными для операций сложения и вычитания, c3 – это указатель на структуру, которая является результатом выполнения этих операций).
#include <stdio.h>
typedef struct
{ float real;
float imag;
} COMPLEX;
void assign_real(COMPLEX *c,float r) /* Присвоить значение r */
{ /* действительной части */
c->real=r; /* комплексного числа */
}
void assign_imag(COMPLEX *c,float i) /* Присвоить значение i */
{ /* мнимой части */
c->imag=i; /* комплексного числа */
}
void add(COMPLEX *c1,COMPLEX *c2,COMPLEX *c3)
{
c3->real=c1->real+c2->real;
c3->imag=c1->imag+c2->imag;
}
void sub(COMPLEX *c1,COMPLEX *c2,COMPLEX *c3)
{
c3->real=c1->real-c2->real;
c3->imag=c1->imag-c2->imag;
}
void print_complex(COMPLEX *c)
{
printf("\n Действительная часть = % f, мнимая часть = % f’’, с – > real,
c – > imag);
}
/* пример использования функций для работы с комплексными числами */
void main()
{
COMPLEX a1,a2,a3; /* три комплексных числа */
assign_real(&a1,5); /* пусть дейст. часть 1-го комплексного числа равна 5 */
assign_imag(&a1,7); /* пусть мнимая часть 1-го комплексного числа равна 7*/
assign_real(&a2,3); /* пусть действ. часть 2-го комплексного числа равна 3 */
assign_imag(&a2,4); /* пусть мнимая часть 2-го комплексного числа равна 4*/
printf("\n Первое комплексное число:”);
print_complex(&a1);
printf("\n Второе комплексное число:");
print_complex(&a2);
add(&a1,&a2,&a3); /* Сложить комплексные числа a1 и а2*/
printf("\n Результат сложения двух комплексных чисел:");
print_complex(&a3);
sub(&a1,&a2,&a3); /* а1 – а2 */
printf("\n Результат вычитания комплексных чисел :");
print_complex(&a3);
}
Объединения
Объединение позволяет в различные моменты времени хранить в одной и той же области памяти значения различных типов. Объединения описываются также, как и структуры, но вместо ключевого слова struct используется ключевое слово union.
Пример.
union
{
int x;
float y;
double Z;
} A, B; /* определение двух переменных типа объединение */
Пример.
union number
{
int x;
float y;
double Z;
};
union number F; /* определение переменной F типа объединение */
Все элементы объединения размещаются в одной и той же области памяти с одного и того же адреса. В каждый момент времени в переменной типа объединение хранится только одно значение. Контроль за тем, какого типа значение хранится в данный момент в объединении, возлагается на программиста. Память, которая выделяется переменной типа объединение, определяется размером наиболее длинного из элементов объединения.
Обращение к элементу объединения осуществляется так:
<имя объединения>. <элемент>
Пример.
F. x = 5; /* присвоить элементу x значение 5 */
F.y = 3.2; /* присвоить элементу y значение 3.2 */
