- •Часть 2
- •Общие сведения Сведения об эумк
- •Методические рекомендации по изучению дисциплины
- •Рабочая учебная программа
- •Учреждение образования
- •«Белорусский государственный университет
- •Информатики и радиоэлектроники»
- •Протокол согласования учебной программы по изучаемой учебной дисциплине с другими дисциплинами специальности
- •Задачи изучения дисциплины. В результате изучения дисциплины «Основы информатики и программирования» студенты должны:
- •Содержание дисциплины
- •1. Название тем лекционных занятий, их содержание, объем в часах
- •2. Перечень тем лабораторных занятий,
- •Теоретический раздел Лекции
- •Int I; // I - счетчик членов ряда
- •X, // аргумент функции
- •Int newton(double (*f)(double), // Функция
- •1. Типы данных – простые и составные.
- •2. Агрегирование данных.
- •3. Генерация «псевдослучайных» данных.
- •4. Абстрактные типы данных.
- •5. Статические и динамические структуры данных.
- •6. Последовательности (динамические массивы).
- •7. Реализация операций над последовательностями.
- •Int nMaxSize; // Размер выделенной области памяти
- •Int nSize; // Количество элементов последовательности
- •1. Понятие стека. Операции над стеком.
- •2. Программная реализация стека на основе статического массива.
- •3. Использование стека при организации связи функций в языке Си и в операционной системе.
- •4. Понятие очереди. Операции над очередями. Кольцевая очередь. Деки.
- •5. Программная реализация очереди на основе статического массива.
- •1. Структура данных «список».
- •4. Реализация списков на основе динамических структур.
- •5. Двусвязный список и его программная реализация.
- •6. Кольцевые списки
- •7. Многосвязные (слоеные) списки
- •Фаза 1 сортировки: построение пирамиды
- •Фаза 2: собственно сортировка
- •Разделение массива
- •Общий алгоритм
- •Практический раздел
- •Контрольные работы
- •Контрольная работа №1
- •Указания по выбору варианта
- •Варианты контрольных заданий
- •Теоретическая часть (вопросы)
- •Практическая часть Контрольное задание №1. Организация распределения продукции в логистической системе
- •Исходные данные к контрольному заданию №1
Int newton(double (*f)(double), // Функция
double (*f1)(double), // Производная функция
double x0, // Начальное приближение
double *x, // Значение корня
double eps) // Требуемая точность
{
int i=0; // i - количество шагов
do
{
x0=*x;
*x=x0-func(x0)/derfunc(x0);
i++;
} while (fabs(x0-*x)>eps);
return i;
}
///////////////////////////////////////////
void main()
{
int i;
double a=1.0,b=3.0,eps=0.00000000001,x;
x=b;
i = newton(func, derfunc,2.0,&x, eps);
printf ("\nRoot= %.20lf\n",x);
printf ("number of steps: %u\n",i);
getch();
}
Основные понятия структур данных
1. Типы данных – простые и составные.
Вычислительные алгоритмы обычно оперируют с достаточно простыми по устройству структурами данных. В первую очередь, это отдельные переменные и их массивы фиксированного объема. В языке Си встроенными типами данных являются:
-
Целочисленные
С плавающей точкой
Строковые и символьные
integer (4)
float (4)
char [n]
short (2)
double (8)
char (1)
long (4)
char (1)
Указание типа переменной позволяет транслятору отвести для значения переменной определенный объем памяти.
Кроме указанных простых типов, могут использоваться и составные типы. Основой для их создания служат структуры. Структура представляет собой объект, объединяющий в своем составе группу элементов, каждый из которых обладает своим, произвольно выбираемым типом. Каждая структура размещается в одном участке памяти, но среда программирования обычно через установку специальных режимов позволяет выбирать способ распределения этой памяти.
Пусть имеется структура
struct Str1
{
char cCode;
int nWeight;
char cSymbol;
}
В зависимости от установленного режима трансляции возможны следующие варианты размещения элементов структуры в памяти:
2. Агрегирование данных.
Переменные произвольных типов данных могут группироваться в массивы, причем размеры массивов при их описании должны быть фиксированными:
int Array[12];
const int DIM=5;
double dMat[DIM][DIM];
При описании массива его размерность не может быть задана не константной переменной.
В случае использования массивов память под значения его элементов выделяется единым участком. В случае многомерных массивов значения располагаются в такой последовательности, которая позволяет получить доступ к конкретному элементу, воспользовавшись формулой:
для массива A[n][m][p]элементaijkимеет смещение от начала(i*m+j)*p+k. Т. о. для массива А[2][3][2] последовательность элементов будет
a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121
Кроме массивов фиксированной размерности, привлекая механизм указателей, можно использовать динамические массивы, т.е. массивы, размерность которых является вычисляемой величиной и задается в процессе выполнения программы, а не в момент ее написания.
int *pArray, nDim;
scanf (“%u”, &nDim);
pArray = (int*)malloc((unsigned int)nDim);
if (pArray == NULL)
{ printf (“Out of memory!\n”);
exit(-1);
}
pArray[i] = …
В случае многомерных динамических массивов доступ к их отдельным элементам может осуществляться с использованием указателей на указатели:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <conio.h>
void main()
{
int **ppArr;
int n=4, m=5, i, j ,k;
ppArr = (int**)malloc(n*sizeof(int*));
if (ppArr == NULL)
printf ("Out of memory!\n");
for (i=0; i<n; i++)
{
ppArr[i] = (int*)malloc(m*sizeof(int));
if (ppArr[i] == NULL)
{
printf ("Out of memory!\n"); exit(-1);
}
}
for (j=0; j<n; j++)
for (k=0; k<m; k++)
scanf("%u",&ppArr[j][k]);
for (j=0; j<n; j++)
{ printf("\n");
for (k=0; k<m; k++)
printf("%u ",ppArr[j][k]);
}
for (i=0; i<n; i++)
free(ppArr[i]);
free(ppArr);
getch();
}
Распределение памяти, осуществляемое в этом случае, показано на рисунке: