Заполнение случайными числами

Пусть требуется заполнить массив равномерно распределенными случайными числами в интервале [a,b]. Поскольку для целых и вещественных чисел способы вычисления случайного числа в заданном интервале отличаются, рассмотрим оба варианта.

Описание функции-датчика случайных чисел находится в заголовочном файле stdlib.h. Удобно также добавить в свою программу функцию random:

int random (int N) { return rand() % N; }

которая выдает случайные числа с равномерным распределением в интервале [0,N-1].

Для получения случайных чисел с равномерным распределением в интервале [a,b]надо использовать формулу

k = random ( b – a + 1 ) + a;

Для вещественных чисел формула несколько другая:

x = rand()*(b - a)/RAND_MAX + a;

Здесь константа RAND_MAX– это максимальное случайное число, которое выдает стандартная функция rand.

//В приведенном ниже примере массив A заполняется случайными целыми числами в интервале [-5,10], а массив X - случайными вещественными числами в том же интервале.

#include <stdlib.h>

#include <stdio.h>

const int N = 10;

int random (int N) { return rand()%N; }

main()

{ system("CLS");

int i, A[N], a = -5, b = 10;

float X[N];

for ( i = 0; i < N; i ++ )

A[i] = random(b-a+1) + a;

for ( i = 0; i < N; i ++ )

X[i] = (float)rand()*(b-a)/RAND_MAX + a;

printf("\nЦелые\n");

for ( i = 0; i < N; i ++ )

printf("%4d",A[i]);

printf("\nВещественные\n");

for ( i = 0; i < N; i ++ )

printf("%6.2f",X[i]);

system("PAUSE");

return 0;

}

Многомерные массивы задаются указанием каждого измерения в квадратных скобках. Например, оператор int matr [6] [8]; задает описание матрицы из 6 строк и 8 столбцов. Нумерация строк и столбцов начинается с 0. При инициализации двумерного массива он представляется как массив из массивов, при этом каждый массив заключается в свои фигурные скобки, либо задается общий список в том порядке, в котором элементы располагаются в памяти:

int mas [] [2]= { {1,2}, {0,2}, {1,0}};

int mas [3][2]={1,2,0,2,1,0};

ВЫПОЛНЕНИЕ РАБОТЫ

Даны вещественные числа a,b. Значения функции (согласно вариантам) записать в массив. Вычислить значение интеграла, используя:

1) Формулу трапеций

I1=h*[f(a)/2+f(a+h)+f(a+2h)+…+f(a+(n-1)h)+f(b)/2]

2) Формулу Симпсона

I2=h/3*(f(a)+f(b)+4*(f(a+h)+f(a+2h)+…+f(a+(n-1)h))+

2*(f(a+2h)+f(a+4h)+…+f(a+(n-2)h)))

h=(b-a)/n, n=100.

Варианты заданий

1. f(x)=x2/(10+x3); a=-2; b=5;

2. f(x)=(2.5x2-0.1)/(tg x+sin x); a=4; b=6;

3. f(x)=(x+1)2√lg x; a=2; b=10;

4. f(x)=x2 ln x /(1+x)2; a=1; b=20;

5. f(x)=1/((0.5+0.1x3)√x); a=0.1; b=2.1;

6. f(x)=x 2√(2+3x)3; a=0.5; b=2.5;

7. f(x)=1/√(0.02+0.01x); a=1; b=30;

8. f(x)=(1+2x+x2)/(5+2x2); a=-2; b=2;

9. f(x)=(2x+lg x)/(1+lg x); a=1; b=10;

10. f(x)=√(2+x)3/x2; a=0.2; b=10;

11. f(x)=(1+x2)/(x3+√(1+x)); a=0.5; b=5;

12. f(x)=(1-x) lg x/√(1-lg x); a=2; b=7;

КОНТРОЛЬНЫЕ ВОПРОСЫ

4.1. Что такое массив? индекс элемента массива?

4.2. Как ввести и вывести элементы вектора в строку и в столбец?

4.3. Способы описания и инициализации массивов.

Лабораторная работа №5

Работа с символьными данными

1. ЦЕЛЬ РАБОТЫ: Изучение описания символьных данных и операций над ними.

ОСНОВНЫЕ СВЕДЕНИЯ

Символьная константа - это символ (единственный), заключенный в одиночные кавычки, как, например, 'Х'. Значением символьной константы является численное значение этого символа в машинном представлении набора символов. Все символы упорядочены в соответствии с принятым в ПК коде (например ASCII). При этом порядковый но­мер символов называется кодом (например, код латинского символа 'А ' равен 65; символа '3' равен 51). Для символьных данных не определены никакие арифметические операции, но они могут сравниваться по своим кодам, участвовать в чтении, печати, операторах присваивания.

Строка - это последовательность (массив) символов, заключенная в двойные кавычки, заканчивающаяся нуль-символом (\0 – символ с кодом равным нолю). По положению нуль-символа определяется фактическая длина строки. Например, длина строки char text[ ] = "Моя программа!" равна 14 байт (включая пробел).

Для форматного ввода и вывода символьных констант используется спецификатор %с, строк - %s и специальные функции: getchar(),gets()- ввод и putchar(), puts()-вывод. Библиотека Си содержит функции обработки строк, прототипы которых определяются в заголовочном файле string.h. Например:

strlen(str) – определяет длину строки str;

strcat(str1,str2) - сцепление строк в порядке их перечисления;

strncat(str1,str2,kol) – приписывает kol символов строки str2 к строке str1;

strcmp(str1,str2) – сравнивает две строки str1 и str2 и возвращает 0, если они одинаковы; результат отрицателен, если str1<str2 и положителен, если str1>str2;

strncmp(str1, str2, kol) – сравниваются части строк str1 и str2 из kol символов. Результат равен 0, если они одинаковы.

strcpy(str1,str2) – копирует строку str2 в строку str1.

Рассмотрим пример:

// lab6_1

#include <stdio.h>

#include <conio.h>

#include <string.h>

main ( )

{ char gwords [10] [40], temp [40];

int i=0;

printf (“Введите 10 слов, начинающихся с д: \n”);

while ( i < 10 )

{ gets (temp);

if (temp [0] != ‘д’) // проверка первого символа

printf (“ %s не начинается с д! \n”, temp);

else { strcpy (gwords [i], temp); i++;}

}

puts (“Следующие слова соответствуют условию:”);

for (i=0; i< 10; i++) puts (gwords [i] );

getch();

return 0;

}

Вводятся слова, сравнивается первый символ, если это не 'д', то вводится следующее слово, иначе слово копируется в новый массив слов gwords.

ВЫПОЛНЕНИЕ РАБОТЫ

1. Выполнить приведенную выше программу с разными исходными данными.

2. Текст вводится с клавиатуры в виде массива слов. Исходный текст и результаты распечатать. Составить программы согласно вариантам заданий.

Варианты заданий

1. Вывести на печать список слов, имеющих приставку (несколько букв), задаваемую с терминала.

2. Раздвинуть заданный текст, вставив введенную с клавиатуры последова­тельность символов после 1-го символа каждого слова.

3. В заданном тексте слова разделены запятыми. На­печатать список слов, начинающихся с символа, введенного с кла­виатуры.

4. Определить наличие слов в заданном тексте, содержащих соче­тание символов, задаваемое с экрана.

5. Из заданной последовательности слов удалить слова, содержащие числа.

6. Каждое слово текста переписать наоборот.

7. Подсчитать количество слов, содержащих k гласных букв (k-задается с экрана).

8. Из введенного текста сначала распечатать слова, заканчивающиеся на согласную букву, а потом на гласную букву.

9. Во введенном тексте найти повторяющиеся слова.

10. Список фамилий вводится через запятую в виде строки. Упорядочить фамилии по алфавиту.

11. Из введенного текста распечатать отдельно гласные и согласные каждого слова.

12. Из введенного текста распечатать слова, в порядке убывания частоты повторения.

КОНТРОЛЬНЫЕ ВОПРОСЫ

4.1. Ввод и вывод символов и строк.

4.2. Функции для работы со строками.

4.3. Чем отличается инициализация символа от инициализации строки?

Лабораторная работа № 6

Функции

1. ЦЕЛЬ РАБОТЫ: Изучение методов использования функций языка Си.

ОСНОВНЫЕ СВЕДЕНИЯ

Часто в программе требуется повторить определенную последовательность операторов в разных частях программы. Для того, чтобы описывать эту последовательность один раз, а применять многократно, в языках программирования применяются подпрограммы. Подпрограмма - автономная часть программы, выполняющая определенный алгоритм и допускающая обращение к ней из различных частей общей программы.

В языке Си существует один вид подпрограмм - функции. Каждая программа в своем составе должна иметьглавную функцию main(), служащую точкой входа в программу. Кроме функции main(), в программу может входить произвольное число функций, выполнение которых инициализируется либо прямо, либо вызовами из функции main(). Каждая функция по отношению к другой является внешней. Для того, чтобы функция была доступной, необходимо, чтобы до ее вызова о ней было известно компилятору. Форма записи функции:

<тип > <имя функции>(<формальные параметры>){<тело функции >}

Если тип возвращаемого функцией значения не указан, то подразумевается int. Если с именем функции не связан результат, то нужно указать тип функции void. Параметры, записываемые в обращении к функции, называются фактическими; параметры, указанные в описании функции - формальными. Фактические пара­метры должны соответствовать формальным по количеству, порядку следования и типу. Объекты, объявленные вне функции, действуют в любой функции и называются глобальны­ми. Объекты, объявленные в функции, действуют только в ней и называются локальными. В теле функции обычно присутствует оператор return <выражение>, определяющий возвращаемое функцией значение.

Все параметры функции, кроме массивов, передаются по значению, т.е. внутри функции создаются локальные копии параметров. Если необходимо передать саму переменную, а не её копию, то в функцию передаётся адрес этой переменной. Таким образом, через параметры можно передавать результат выполнения функции. То есть, параметры, с помощью которых результаты должны передаваться из функции в точку вызова, описываются как указатели. Вызов функции может быть оформлен в виде оператора, если с именем функции не связано возвращаемое значение, или в виде выражения, если возвращаемое значение связано с именем функции.

Прототип функции может указываться до вызова функции вместо описания функции для того, чтобы компилятор мог выполнить проверку соответствия типов аргументов и параметров. Прототип функции по форме такой же, как и заголовок функции. В конце него ставится «;».

Функции можно подключать с помощью директивы #include <имя файла>. Такие файлы с функциями удобно использовать в диалоговых программах с пользовательским меню, позволяющих выбрать один из режимов.

Пример 1:Функция с параметрами-значениями. Результат связан с именем функции. В программе объявляется прототип функции, а сама функция описывается ниже.

//lab8_1

#include <stdio.h>

#include <conio.h>

int max(int,int); //Прототип функции

void main()

{ int x,y,z;

printf(" input x,y ");

scanf("%d%d",&x,&y);

z=max(x,y); //Вызов функции с фактическими параметрами

printf("x=%d y=%d max=%d",x,y,z);

getch();

}

int max(int a ,int b) //Заголовок функции с формальными параметрами

{ int c;

if (a>b) c=a;

else c=b;

return c;

}

Пример 2:Функция с параметрами-указателями. Здесь передаются адреса фактических параметров, по которым и получаем результат. Функция меняет местами переменные x,y.

//lab8_2

#include <stdio.h>

#include <conio.h>

main()

{ float x,y;

void swap(float *, float *); // Прототип функции с параметрами - указателями

printf("\n введите x,y ");

scanf("%f%f",&x,&y);

swap(&x,&y); // Передаём адреса переменных

printf("\n x=%4.2f y=%4.2f ",x,y);

getch();

}

void swap(float * a, float * b)

{float c;

c=*a; // *a - содержимое по адресу a

*a=*b;

*b=c;

}

Пример 3:Подключение файлов с функциями и создание меню.

! Внимание! Следите за тем, чтобы константы, объявленные директивой #define, не переобъявлялись в функциях.

//lab8_3

#include <stdio.h>

#include <conio.h>

#include "lab3.c"

#include "lab5.c"

#include "lab6.c"

main()

{ int nom;

while(1)

{ clrscr();

printf("\n 1. Сумма ряда \n");

printf(" 2. Матрица \n");

printf(" 3. Строки \n");

printf(" 4. Выход \n");

scanf("%d",&nom);

switch(nom)

{

case 1:lab3();break;

case 2:lab5();break;

case 3:lab6();break;

case 4:return 0;

default:printf("Неверный режим");

}

}

getch();

}

Пример 4:Передача в функцию массива с использованием указателя. Результат – элементы массива возводятся в квадрат. Функция описывается до вызова, поэтому прототип не объявляется.

//lab8_4

#include <stdio.h>

#include <conio.h>

void quart(int n, float * x) // Можно void quart(int n, float x[])

{ int i;

for (i=0;i<n;i++)

x[i]=x[i]*x[i];

}

main()

{ float z[]={1,2,3,4};int j;

clrscr();

for (j=0;j<4;j++)

printf(" %6.2f",z[j]);

quart(4,z);

for (j=0;j<4;j++)

printf("\n %6.2f",z[j]);

getch();

}

ВЫПОЛНЕНИЕ РАБОТЫ

3.1. Проанализировать приведенные выше программы.

3.2. Оформить свои задания по лабораторным работам 5, 6, 7 в виде функций. Организовать меню с вызовом этих функций.

3.3. Используя функции, написать программу по своему варианту.

Варианты заданий

1. Написать функцию, выводящую в порядке возрастания элементы одномерного массива. В главной программе вызвать функцию для двух разных массивов.

2. Написать функцию вычисления произведения прямоугольной матрицы A размера k x m на прямоугольную матрицу B размера m x n. В главной программе обратиться к этой функции.

3. Написать функцию вычисления суммы ряда s=s(1)+…+s(n),

где s(n)=(-1)n x(2n-1)/(2n+1) с точностью до eps=0.001. В качестве параметров выбрать x и eps.

4. Написать функцию, которая вычисляет для заданной квадратной матрицы A её симметричную часть S(ij)=(A(ij)+A(ji))/2 и кососимметричную часть K(ij)=(A(ij)-A(ji))/2.

5. Написать функцию “шапочка” f(x), зависящую от параметров a и b: если |x| >a то f(x)=0 иначе f(x)=b*exp(-a2/(a2-|x|2)). В качестве параметров передать a,b,x.

6. Написать функцию поиска максимального и минимального элементов одномерного массива. В основной программе вызвать эту функцию для двух разных массивов.

7. Написать функцию, которая сортирует одномерный массив в порядке убывания методом пузырька. В основной программе вызвать эту функцию для двух разных массивов.

8. Написать функцию, которая по двум заданным одномерным массивам (A размера m и B размера n) вычисляет максимальное значение двумерного массива c(ij)=a(i)*b(j).

9. Написать функцию определителя квадратной матрицы A размера 3x3:

detA=a(1,1)a(2,2)a(3,3)+a(3,1)a(1,2)a(2,3)+a(2,1)a(3,2)a(1,3)-a(3,1)a(2,2)a(1,3)-a(1,1)a(3,2)a(2,3)-a(2,1)a(1,2)a(3,3).

10. Написать функцию вычисления суммы ряда y=sinx-(sin2x)/2+…

+(-1)n+1sin(nx)/n с точностью до eps=0.001. В качестве параметров передать x (в радианах) и eps.

11. Написать функцию вычисления ряда y=x+x3/3!+…+x2n+1/(2n+1)! с точностью до eps=0.0001. В качестве параметров передать x и eps.

12. Написать функцию обработки матриц A и B одинакового размера m x n. Получить матрицу C =max(a(i,j),b(i,j)), и матрицу D=min(a(i,j),b(i,j)). Матрицы C и D вывести в главной программе.

КОНТРОЛЬНЫЕ ВОПРОСЫ

4.1. Описание функции. Для чего объявляется прототип?

4.2. Что такое формальные и фактические параметры? Локальные и глобальные?

4.3. Как можно передавать массив в функцию?

4.4. Способы вызова функций.

Лабораторная работа № 7

Рекурсии

1. ЦЕЛЬ РАБОТЫ: Изучение методов использования алгоритмов и программ с рекурсиями в языке Си.

ОСНОВНЫЕ СВЕДЕНИЯ

В языке Си функции могут вызывать сами себя, т.е. обладать свойством рекурсивности. Рекурсивная функция обязательно должна содержать в себе условие окончания рекурсивности, чтобы не вызвать зацикливания программы. При каждом рекурсивном вызове создается новое мно­жество локальных переменных. Т.о. переменные, расположенные вне вызываемой функции, не изменяются.

Пример. Составить рекурсивную функцию, вычисляющую факториал числа n следующим образом: n!= 1 , если n<= 1 и n!= ( n -1 )! · n, если n > 1

long fact( int n)

{ if (n <=1) return l;

else return (n * fact ( n -1 )); // функция fact вызывает саму себя

}

Таким образом, последовательно вызываются функции f(n), f(n-1),f(n-2)…f(1).

Достоинством рекурсий является компактная запись, а недостатком – расход времени и памяти на повторные вызовы функции и передачу ей копий параметров.

ВЫПОЛНЕНИЕ РАБОТЫ

Составить алгоритмы и программы с использованием рекурсии в соответствии с вариантом задания.

Варианты заданий

1. Ввести с клавиатуры целое число N. Используя рекурсию, распечатать сначала последовательность, состоящую из N букв 'А', а затем из N букв 'В'.

2. Напечатать в обратном порядке последовательность чисел, признаком конца которой является 0.

3. Водится любое целое число b и вещественные a, c. Вычислить z=a b +c b ,

используя рекурсивную функцию x n

1, если n = 0

x n = 1/ x n , если n < 0

x × x n-1 , если n > 0

4. Для N=12 найти числа Фибоначчи, которые вычисляются следующим образом: F(0)=1, F(1)=2, F(N)=F(N-2)+F(N-1)

5. Методом деления отрезка пополам найти с точностью EPS=0,0001 корень уравнения cos(2/x)-2*sin(1/x)+1/x=0

6. Даны целые числа m и n, где 0<=m<=n. Вычислить рекурсивно число сочетаний по формуле:

7. Дана последовательность положительных чисел, признаком конца которых служит отрицательное число. Используя рекурсию, подсчитать количество чисел и их сумму.

8. Дана последовательность ненулевых целых чисел, признаком конца которых служит 0. Используя рекурсию, напечатать сначала все отрицательные, а потом – все положительные числа этой последовательности.

9. Дан вектор Х из N вещественных чисел. Найти минимальный элемент вектора, используя вспомогательную рекурсивную функцию, находящую минимум среди последних элементов вектора Х, начиная с N-го.

10. Дана строка символов, в конце которой стоит точка. Напечатать строку в обратном порядке.

11. Задан вещественный массив из N. Упорядочить его по возрастанию методом быстрой сортировки: выбрать средний элемент массива и переставить элементы так, чтобы слева от выбранного элемента были меньшие, а справа только большие (т.о. выбранный элемент окажется на окончательном месте). Затем применить этот способ рекурсивно к левой и правой части массива.

12. Имеется 10 населенных пунктов. Дана последовательность пар чисел пар чисел I и J (I<J), указывающих, что I –ый J-ый пункты соединены дорогой. Признак конца этой последовательности - пара нулей. Используя рекурсию, определить, можно ли по этим дорогам попасть из 1-го пункта в N-ый.

КОНТРОЛЬНЫЕ ВОПРОСЫ

4.1. Что такое рекурсия?

4.2. Как меняются локальные и глобальные переменные в рекурсиях?

4.3. Где находится окончание рекурсии?

Лабораторная работа № 8

Структуры

1. ЦЕЛЬ РАБОТЫ: Приобретение практических навыков в составлении алгоритмов и программ со структурами.

ОСНОВНЫЕ СВЕДЕНИЯ

Структура – это фиксированное число элементов одного или нескольких типов. Т.е. в отличие от массивов, в которых содержатся элементы одного типа, в структурах могут содержаться элементы как одного, так и разных типов. Элементами структуры могут быть базовые типы, массивы, указатели, структуры и т.д. Элементы структуры вместе с их описанием называются полями. Над полями можно выполнять действия, допустимые для данных этого типа.

Все структуры должны быть описаны до использования. Все идентификаторы полей в структуре должны быть различными.

Например, структуру Воок можно описать следующим образом:

struct card {char аuthor [15]; char title[20]; int year ; float cena;} Book;

или struct card { char аuthor [15]; char title[20]; int year ; float cena;};

stuct card Book;

Тип структуры (например, card) вводит только шаблон и с его именем не связан никакой конкретный объект. Объект (например, структура Book) должен быть также объявлен. Обращение к полю структуры выполняется с помощью составного имени, которое состоит из имени_структуры . имени_поля. Например, присвоить значения элементам записи Author и Title можно так: Book.author= “Довгаль С.И.”; Book.title=”Турбо Паскаль V 7.0”;

Ввод цены книги с клавиатуры : scanf (“%f”, &Book.cena);

Можно создавать массив структур: Struct card bibl[100];

Обращение к полю элемента массива: bibl[i].title;

Пример: Дана информация о 10 товарах: название, цена, количество. Вычислить общую стоимость товара, название которого вводится с клавиатуры.

//lab7_1

#include <stdio.h>

#include <conio.h>

#include <string.h>

#define n 10

main()

{

int i,k; float sum; //k-количество искомых товаров, sum- их общая стоимость.

struct tov {char name[10]; float c; int kol;} t; //Объявление структуры t

struct tov mag[n]; //объявление массива структур mag[n]

char nazv[10]; //Наименование искомого товара

clrscr();

printf(“\n Введите информацию о товарах \n“);

for (i=0;i<n;i++)

{ printf("\n наименование , цена, количество : ");

scanf("%s%f%d",&t.name,&t.c,&t.kol);//Заполнение информацией структуры t

mag[i]=t; //Присвоение i-му элементу массива структуры t целиком

}

printf("\n введите искомый товар: ");

scanf("%s",&nazv);

for (i=0,sum=0,k=0;i<n;i++)

if (strcmp(mag[i].name,nazv)==0)

{ sum+=mag[i].c*mag[i].kol;

k++;

}

printf("Товаров %s %d, их стоимость %5.2f ",nazv,k,sum);

getch();

}

ВЫПОЛНЕНИЕ РАБОТЫ

В соответствии с вариантом написать и выполнить программу.

Варианты заданий

1. Дана информация о пяти студентах. Запись имеет вид: фамилия, год рождения, факультет. Вывести дан­ные о студентах по факультетам.

2. Дана информация о пяти школах. Запись имеет вид: номер школы, год, количество выпускников, число поступивших в ВУЗы. Вывести данные об общем количестве выпускников и доле поступивших в ВУЗ.

3. Дана информация о пяти комнатах в общежитии. Запись имеет вид: фамилии, номер комнаты, факультет, площадь. Вывести данные о комнатах по факультетам, а также количество комнат на факультетах.

4. Дана информация о пяти рабочих цеха. Запись имеет вид: фамилия, размер зарплаты, стаж работы. Вывести данные о рабочем с наибольшей зарплатой и наименьшим стажем.

5. Дана информация о четырех вузах. Запись имеет вид: название вуза, число студентов, количество факультетов, коли­чество кафедр. Вывести данные об общем числе студентов, факультетов и кафедр.

6. Дана информация о шести вкладчиках в сберкассы. Запись имеет вид: фамилия, район, социальное положение, величина вклада. Вывести данные о том, сколько среди вкладчиков служащих, рабочих и колхозников.

7. Дана информация о пяти больных. Запись имеет вид: фамилия, возраст, пол, давление. Вывести данные о больных с повышен­ным давлением (больше 140) .

8.Дана информация о пяти квартирах. Запись имеет вид: фами­лия владельца, площадь, число комнат, этаж. Вывести данные о квартирах с площадью меньше 30 кв.м и подсчитать их ко­личество.

9. Дана информация о шести студентах. Запись имеет вид: фамилия, год рождения, место рождения, факультет. Вывести дан­ные о старших по возрасту студентах, предполагая что год рождения может быть одинаков.

10. Дана информация о пяти школах. Запись имеет вид: номер школы, год, количество выпускников, число поступивших в ВУЗы. Вывести данные о школе с самым большим отношением числа поступивших к числу выпускников.

11. Дана информация о пяти комнатах в общежитии. Запись имеет вид: фамилии, номер комнаты, факультет, площадь. Вывести данные о комнате, в которой наименьшая площадь.

12. Дана информация о пяти квартирах. Запись имеет вид: фами­лия владельца, площадь, число комнат, этаж. Вывести данные о квартирах с самой большой площадью и самой маленькой.

4. КОНТРОЛЬНЫЕ ВОПРОСЫ

4.1. Какие типы данных относятся к простым, какие к составным?

4.2. Как объявляются структуры и чем отличается структура от массива?

4.3 Как обращаться к полям структуры?

4.3. Какие операции допустимы над структурой в целом?

Лабораторная работа № 9

Наши рекомендации