Стрикелева Л.В. Программирование
114.61K
Category: programmingprogramming

Структуры. Объединения. Поля битов в структурах и объединениях. (Лекция 17)

1. Стрикелева Л.В. Программирование

Лекция 17
Структуры. Объединения.
Поля битов в структурах и объединениях

2.

Функция main() – это относительная точка входа в программу, а не абсолютная
(перед вызовом функции, в отличие от всех других, компилятор генерирует
невидимый программисту стартовый блок кода – пролог, а после завершения –
эпилог всей программы )
crt0.c
{
//пролог
вызов main()
//эпилог
}
void f1();
int main()
{
atexit(f1);
Хороший стиль –
int main() и return 0;
}
Точка входа – одна.
Точки выхода:
• по закрывающей скобке main()
- корректное завершение программы
• по инструкции return
• по функции exit()
• по функции abort() - аварийное завершение (немедленное завершение, открытые файлы
не закрываются, буферы потоков не очищаются, atexit() не обрабатывается,…)

3.

Посмотрим на задания из лабораторной 6
(повторение материала 1-го семестра)

4.

6.1. ** Выполнить задание с использованием функций и циклов
1. Дано целое число N>0. Найти сумму: N2 +(N+1)2 + (N+2)2 +…+(2N)2
Чтобы избежать целочисленного переполнения, вычислять слагаемые этой
суммы с помощью вещественной переменной, не используя функцию
возведения в степень.
1. Дано натуральное n. Получить все натуральные числа, меньшие n,
взаимно простые с ним.
6.2. ***Выполнить задание с использованием функций и массивов
Реализовать задание с использованием функций (ввод матрицы, вывод
матрицы, вычисление суммы) и цикла for для вычисления суммы.
Изменение индексов задавать в заголовке цикла.
Организовать проект в виде двух заголовочных и двух программных файлов.
Выполнить многофайловую компиляцию. Тестирование проводить на
целочисленной матрице 5-го порядка, все элементы которой равны 1.
Дана действительная матрица порядка n. Найти сумму элементов,
расположенных в закрашенной части матрицы:

5.

Многофайловая программа
Многофайловая программа – это возможность следования принципу
абстракции. При создании большой системы хорошо бы ее разбивать на
отдельные части, и отвлекаться (абстрагироваться), при необходимости, от
того, что внутри какой-то из них, а работать с другой.
Многофайловая программа – это возможность разрабатывать программу
нескольким программистам одновременно (кто-то делает графику, кто-то –
смысловую начинку и пр.).
Многофайловая программа – это возможность раздельной компиляции
модулей: модули (исходные файлы .cpp ) можно компилировать раздельно, что
позволяет проверить компилируемость модуля отдельно и увеличить скорость
повторной компиляции (если изменялся только один, например, файл, то не
компилировать заново остальные). За счет этого происходит увеличение
быстродействия при компиляции больших проектов.

6.

Многофайловая компиляция
Раздельной компиляции способствует механизм precompiled headers (прикомпайл
хэдэр) – предварительно собранные заголовки. Технология предназначена для
ускорения сборки проектов, но пользу (выигрыш) от этой нее можно заметить, если в
проекте много файлов.
Препроцессирование – процесс, на вход которого подаётся текстовый файл, во время
работы препроцессора исходный текстовый файл видоизменяется, в том числе,
удаляются из текста все комментарии, и только изменённый текстовый файл в
дальнейшем попадает на компиляцию. Команды препроцессора (директивы)
начинаются с символа #, который должен первым непробельным символом в строке
(например, #include и #define).
Если посмотреть в проекте *.cpp файлы, то можно заметить, что во многие
включаются одни и те же наборы заголовочных файлов. Это приводит к тому,
что препроцессор в компиляторе вновь и вновь выполняет идентичную работу
(читает одни и те же файлы, вставляет их друг в друга) – происходит
дублирование одних и тех же операций. Можно существенно сократить объем
работы, которую должен проделать препроцессор при компиляции проекта,
если заранее препроцессировать группу файлов и затем просто подставлять
готовый фрагмент текста.

7.

Многофайловая компиляция
prog.cpp
prog1.cpp
prog.obj
stdafx.h
stdafx.cpp
stdafx1.cpp
prog.pch
structura.h
prog.exe
stdafx.obj
func.cpp
func1.cpp
func.obj
prog1.cpp func1.cpp stdafx1.cpp получены в результате работы препроцессора,
хранятся временно, только при компиляции
prog.pch –
файл precompiled headers для проекта prog
stdafx.obj – файл предварительно скомпилированных типов

8.

Многофайловая компиляция
При создании нового проекта в Visual Studio с помощью мастера wizard (вэжэд)
создаётся два файла: stdafx.h и stdafx.cpp и одновременно автоматически
выставляются опции компиляции :
• для всех *.cpp файлов включается «использование precompiled headers» : Project
Properties Configuration Properties C/C++ «Precompiled Header»: «Use (/Yu)»;
• для файла stdafx.cpp для параметра «Precompiled Header» выставляется значение
«создание precompiled headers»: «Create (/Yc)»).
Для ускорения повторной компиляции в stdafx.h нужно включить заголовочные
файлы, которые будут заранее препроцессироваться.
А во все файлы *.cpp следует добавить #include "stdafx.h" и удалить из них
заголовки, которые уже включаются с помощью stdafx.h.
В файле stdafx.cpp содержится одна единственная строка: #include "stdafx.h".
После компиляции stdafx.cpp возникает файл *.pch, который уже содержит
precompiled headers, а имя файла обычно совпадает с названием проекта.
Заголовочный файл «stdafx.h» должен включаться в *.cpp файл самым
первым! Иначе возникнут ошибки компиляции.
Все файлы, включающие «stdafx.h», зависят от его содержимого. Изменение в
одном файле, включенном в «stdafx.h», может повлечь полную
перекомпиляцию всего проекта.

9.

6.3. ***Выполнить задание с использованием шаблонов функций и
динамических массивов
Для заданного k (целого и вещественного типов) получить квадратную
матрицу заданного порядка n:
k/1
0

0
0
(k-1)/2

0

0
0

(k-n-1)/n

10.

6.3. ***Выполнить задание с использованием шаблонов функций и
динамических массивов
1-ый способ задания параметров шаблона
template < class T>
T ** mem_ar (size_t n , size_t m); // шаблон выделения памяти матрице
template < class T , size_t n , size_t m>
void zapol (T**, T k);
// шаблон заполнения матрицы, k – значение
для заполнения
2-ой способ задания параметров шаблона
template < class T , size_t n, size_t m >
void vyvod_ar (T**);
// шаблон вывода матрицы
int main()
{
const size_t n=5;
cout << "1" << endl;
cout << "2" << endl;
double k1 = n;
double** mas1 = mem_ar<double>(n, n);
int k = n;
int** mas = mem_ar<int>(n, n);
zapol<int, n, n>(mas, k);
vyvod_ar<int, n, n>(mas);
system ("pause");
return 0;
}
zapol<double, n, n>(mas1, k1);
vyvod_ar<double, n, n>(mas1);

11.

int **ar
int *ar[n]
int ar[n] [m]
template <class T>
T ** mem_ar ( size_t n, size_t m )
{
T** ar = new T*[n]; //выделяется память под массив указателей
if (ar == NULL)
{ cout << "ar == 0 " << endl; _getch(); exit(-1); } //проверка!!! выделения памяти
// Функция exit (code) завершает работу программы
//аргумент code указывает статус завершения
// «неуспешное» завершение – отличное от нуля значение или EXIT_FAILURE
for ( size_t i = 0; i < n; i++)
{
ar[i] = new T [m]; // цикл выделения памяти под строку массива
if (ar[i] == NULL)
{ cout << "ar[i]==0" << endl; _getch(); exit (-2); }
//обратить внимание на проверку выделения памяти!!!
}
return ar;
}

12.

template < class T, size_t n, size_t m >
void zapol(T** mas, T k)
{
for (size_t i = 0; i < n; i++)
for (size_t j = 0; j < m; j++)
if ( i != j ) mas[i][j] = 0;
else mas[i][j] = (k-i)/n;
}
template <class T, size_t n, size_t m>
void vyvod_ar(T **mas)
{
for (size_t i = 0; i < n; i++)
{
for (size_t j = 0; j < m; j++)
cout << setw(7) << mas[i][j];
cout << endl;
}
}

13.

template <class T, size_t n, size_t m >
T ** mem_ar ( );
int** mas = mem_ar<int, n, n>();
template <class T, size_t n, size_t m > 2-ой способ задания параметров шаблона
T ** mem_ar ( )
{
T** ar = new T*[n]; //выделяется память под массив указателей на строки
if (ar == NULL)
{ cout << "ar == 0 " << endl; _getch(); exit(-1); } //проверка!!! выделения памяти
// Функция exit (code), завершает работу программы
//аргумент code указывает статус завершения
//аварийное завершение – отличное от нуля значение или EXIT_FAILURE
for ( size_t i = 0; i < n; i++)
{
ar[i] = new T [m]; // цикл выделения памяти под строку массива
if (ar[i] == NULL) { cout << "ar[i]==0" << endl; _getch(); exit (-2); }
//обратить внимание на проверку выделения памяти!!!
}
return ar;
}

14.

template < class T >
void mem_ar1 (T**&, size_t n, size_t m );
int** mas;
mem_ar1<int >(mas, n, n);
template <class T >
void mem_ar1 (T**& ar, size_t n, size_t m )
{
ar = new T*[n]; //выделяется память под массив указателей на строки
if (ar == NULL)
{ cout << "ar == 0 " << endl; _getch(); exit(-1); } //проверка!!! выделения памяти
// Функция exit (code), завершает работу программы
//аргумент code указывает статус завершения
//аварийное завершение – отличное от нуля значение или EXIT_FAILURE
for ( size_t i = 0; i < n; i++)
{
ar[i] = new T [m]; // цикл выделения памяти под строку массива
if (ar[i] == NULL) { cout << "ar[i]==0" << endl; _getch(); exit (-2); }
//обратить внимание на проверку выделения памяти!!!
}
return ar;
}
Функция выделения памяти матрице, 2-ой способ

15.

template < class T, size_t n, size_t m >
int** mas;
void mem_ar1 (T**&);
mem_ar1<int, n, n >(mas);
template <class T, size_t n, size_t m >
void mem_ar1 (T**& ar)
{
ar = new T*[n]; //выделяется память под массив указателей на строки
if (ar == NULL)
{ cout << "ar == 0 " << endl; _getch(); exit(-1); } //проверка!!! выделения памяти
// Функция exit (code), завершает работу программы
//аргумент code указывает статус завершения
//аварийное завершение – отличное от нуля значение или EXIT_FAILURE
for ( size_t i = 0; i < n; i++)
{
ar[i] = new T [m]; // цикл выделения памяти под строку массива
if (ar[i] == NULL) { cout << "ar[i]==0" << endl; _getch(); exit (-2); }
//обратить внимание на проверку выделения памяти!!!
}
return ar;
}
Функция выделения памяти матрице, 2-ой способ
2-ой способ задания параметров шаблона
English     Русский Rules