
- •Лекция 1. Понятие алгоритма. Свойства алгоритма
- •Лекция 2. Способы описания алгоритмов
- •Лекция 3. Типовые алгоритмы программ
- •Лекция 4. Принципы разработки схем алгоритмов программ
- •Лекция 5. Эволюция языков программирования Классификация языков программирования. Понятие системы программирования.
- •Лекция 6.
- •Структура программы. Назначение функции main. Объявление функции main. Назначение заголовочных файлов
- •Лекция 7. Переменные и данные. Основные типы данных. Объявление переменных. Инструкции присваивания
- •Лекция 8. Функции ввода-вывода Форматированный вывод на экран
- •Лекция 9. Стандартные математические функции
- •Лекция 10. Алгоритм и программы линейной структуры
- •Лекция 11.
- •Лекция 12. Ветвления
- •If (выражение) оператор;
- •Лекция 13. Оператор выбора (переключатель).
- •Циклы Лекция 14.
- •Лекция 15.
- •Массивы Лекция 16.
- •Лекция 17. Сортировка массивов.
- •Лекция 18. Многомерные массив.
- •Лекция 19. Указатели и ссылки.
- •Лекция 20. Указатели и массивы.
- •Лекция 21. Символы и символьные строки
- •Лекция 22. Графика
- •Лекция 23. Использование функций графических примитивов, работы с текстом в графическом режиме.
- •Функции Лекция 24.
- •Лекция 25. Прототип функции.
- •Лекция 26. Передача значений через глобальные переменные.
- •Лекция 29. Объединение.
- •Лекция 30 Файлы
- •Лекция 31. Работа с файлами на диске.
Лекция 26. Передача значений через глобальные переменные.
Областью действия описания программного объекта называется часть программы, в пределах которой действует (учитывается) это описание. Если переменная описана внутри некоторого блока, то она локализована в этом блоке и из других блоков, внешних по отношению к данному, «не видна». Если описание переменной находится вне блока и предшествует ему в тексте программы, то это описание действует внутри блока и называется глобальным. Глобальная переменная «видна» из блока. Например:
double x;
int funс1() {int у;... } void main() {float у;...}
Переменная х является глобальной по отношению к функциям funс1, main и, следовательно, может в них использоваться. В функциях funс1 и main имеются локальные переменные с одинаковым именем у. Однако это разные величины, никак не связанные друг с другом. Поскольку переменная х является общей для обеих функций, то они могут взаимодействовать через х друг с другом.
При обращении к функции передача значений возможна как через параметры, так и через глобальные переменные. Используя этот механизм, в программах на Си можно реализовывать функции, работающие подобно процедурам в Паскале. В следующей программе решается уже рассматриваемая нами задача получения наибольшего из трех значений.
Пример 6.
int z; //Описание глобальной переменной
void MAX(int х, int у)
{if (x>y) z=x; else z=y;}
#include <iostream.h>
void main()
{ int a,b,c;
cout«"a="; cin»a;
cout«"b="; cin»b;
cout«"c="; cin»c;
MAX(a,b);
MAX(z,c);
cout«"max="«z; }
Результат выполнения функции max заносится в глобальную переменную z, которая «видна» также и из основной функции. Поэтому при втором обращении эта переменная играет одновременно роль аргумента и результата. Здесь оператор обращения к функции выглядит подобно обращению к процедуре в Паскале, а глобальная переменная z играет роль var-параметра.
Классы памяти. Под всякую переменную, используемую в программе, должно быть выделено место в памяти ЭВМ. Выделение памяти может происходить либо на стадии компиляции (компоновки) программы - либо во время ее выполнения. Существуют 4 класса памяти, выделяемой под переменные:
автоматическая (ключевое слово auto);
внешняя (extern);
статическая (static);
регистровая (register).
Под глобальные переменные выделяется место во внешней памяти (не нужно думать, что речь идет о магнитной памяти; это оперативная память класса extern). Глобальную переменную можно объявить либо вне программных блоков, либо внутри блока с ключевым словом extern. Обычно это делается в тех случаях, когда программный модуль хранится в отдельном файле и, следовательно, отдельно компилируется.
Пусть, например, основная и вспомогательная функции хранятся в разных файлах.
Пример 7.
Файл 1: Файл 2:
int var void funcO
void main() { extern int var;
{var=5; var=10*var;
funcO; }
cout«var;
}
Здесь обмен значениями между основной и вспомогательной функцией f unc () происходит через общую глобальную переменную var, для которой во время компиляции выделяется место во внешнем разделе памяти. В результате выполнения данной программы на экран выведется число 50.
Локальные переменные, объявленные внутри блоков, распределяются в автоматической памяти, работающей по принципу стека. Выделение памяти происходит при входе выполнения программы в блок, а при выходе из блока память освобождается. Ключевое слово auto писать необязательно (подразумевается по умолчанию).
Статическая память выделяется под переменные, локализованные внутри блока, но в отличие от автоматической памяти не освобождается при выходе из блока. Таким образом, при повторном вхождении в блок статическая переменная сохраняет свое прежнее значение. Пример объявления статической переменной:
f О
{static int schet=10; ...}
Инициализация статической переменной происходит только при первом вхождении в блок. Если инициализация явно не указана, то переменной автоматически присваивается нулевое начальное значение. Статические переменные можно использовать, например, для организации счетчика числа вхождений в блок.
Регистровая память выделяется под локальные переменные. Регистры процессора — самый быстрый и самый маленький вид памяти. Они задействованы при выполнении практически всех операций в программе. Поэтому возможность распоряжаться регистровой памятью лучше оставить за компилятором.
Наконец рассмотрим пример, в котором используются различные способы описания переменных.
Пример 8.
int var //описана внешняя переменная var
main ()
{extern int var; // та же внешняя переменная var
}
funс1 ()
{extern int varl;//новая внешняя переменная varl
//внешняя var здесь также видна }
func2()
{... //здесь переменная var видна, а переменная
} // varl не видна
int varl; //глобально описана переменная varl
func3()
{ int var; //здесь var — локальная переменная,
//видна внешняя переменная varl }
func4 ()
{auto int varl; //здесь varl —локальная переменная,
//видна внешняя глобальная var
}
Лекция 27.
Рекурсивные определения функций.
Проиллюстрируем определение рекурсивной функции на классическом примере вычисления факториала целого положительного числа.
long Factor(int n)
{ if (n<0) return 0;
if (n==0) return 1;
return n*Factor(n-1); }
В случае если при вызове функции будет задан отрицательный аргумент, она вернет нулевое значение — признак неверного обращения.
Лекция 28.
Структуры
Это структурированный тип данных, представляющий собой поименованную совокупность разнотипных элементов. Тип структура обычно используется при разработке информационных систем, баз данных.
Правила использования структур обсудим на примере.
Сведения о выплате студентам стипендии требуется организовать в виде, показанном на рис. ниже.
Элементы такой структуры (фамилия, курс, группа, стипендия) называются полями. Каждому полю должно быть поставлено в соответствие имя и тип.
Формат описания структурного типа следующий:
struct имя_типа
{определения_элементов};
В конце обязательно ставится точка с запятой (это оператор). Для рассмотренного примера определение соответствующего структурного типа может быть следующим:
struct student {char fam[30]; int kurs;
char grup[3];
float stip;
};
После этого student становится именем структурного типа, который может быть назначен некоторым переменным. В соответствие со стандартом Си это нужно делать так:
struct student studl, stud2;
Правила Си++ разрешают в этом случае служебное слово struct опускать и писать
student studl, stud2;
Здесь studl и stud2 — переменные структурного типа. Допускаются и другие варианты описания структурных переменных. Можно вообще не задавать имя типа, а описывать сразу переменные:
struct {char fam[30]; int kurs;
char grup[3];
float stip;
studl, stud2, *pst;
}
В этом примере кроме двух переменных структурного типа объявлен указатель pst на такую структуру. В данном описании можно было сохранить имя структурного типа student.
Обращение к элементам (полям) структурной величины производится с помощью уточненного имени следующего формата:
имя_структуры.имя_элемента
Примеры уточненных имен для описанных выше переменных:
studl.fam; studl.stip
Значения элементов структуры могут определяться вводом, присваиванием, инициализацией. Пример инициализации в описании:
student studl={"Кротов", 3, "Ф32", 350}; Пусть в программе определен указатель на структуру
student *pst, studl;
Тогда после выполнения оператора присваивания
pst=&studl;
к каждому элементу структурной переменной studl можно обращаться тремя способами. Например, для поля f am
studl.fam или (*pst).fam или pst->fam
В последнем варианте используется знак операции доступа к элементу структуры: —>. Аналогично можно обращаться и к другим элементам этой переменной:
pst->FIO, pst->grup, pst->stip.
Поля структуры могут сами иметь структурный тип. Такие величины представляют многоуровневые деревья.
Допускается использование массивов структур. Например, сведения о 100 студентах могут храниться в массиве, описанном следующим образом:
student stud[100];
Тогда сведения об отдельных студентах будут обозначаться, например, так: stud [ 1 ] . fam, stud [ 5 ] . kurs и т. п. Если нужно взять первую букву фамилии 25-го студента, то следует писать:
stud[25].fam[0].
Пример 1. Ввести сведения об N студентах. Определить фамилии студентов, получающих самую высокую стипендию.
#include <stdio.h>
#include <conio.h>
void main()
{
const N=30; int i; float maxs; struct student {char fam[15];
int kurs;
char grup[3];
float stip;
}
student stud[N];
clrscr ();
for(i=0;i<N;i++)
{ printf ("%d-й студент", i) ;
printf("\n"Фамилия:");scanf("%s",&stud[i].fam);
printf ("Курс: ") ; scanf ("%d", &stud[i] . kurs) ;
printf("Группа:"); scanf("%s",&stud[i].grup);
printf("Стипендия:"); scanf("%f",&stud[i].stip);
}
maxs=0; for(i=0;i<N;i++)
if(stud[i].stip>maxs) maxs=stud[i].stip; printf("\n Студенты,получающие максимальную стипендию %f py6.",maxs);
for(i=0; i<N; i++)
if(stud[i].stip==maxs) printf("\n%s",stud[i].fam);
}