Функции с параметрами по умолчанию.
При описании функции можно инициализировать некоторые параметры функции. Формальные параметры инициализируются значениями или глобальными константами, которые определены с помощью директивы define.
При вызове такой функции в качестве фактических параметров достаточно указать только те, которые соответствуют не инициализированным формальным. При этом для создания динамического варианта функции в качестве значений формальных инициализированных параметров будут использоваться те значения, которые были указаны при описании. Если для инициализированного параметра при вызове функции указан фактический параметр, то алгоритм использует значение этого фактического параметра.
Правила:
1. Формальные инициализированные параметры должны располагаться подряд после неинициализированных, т.е. секция инициализированных параметров должна быть последней в списке формальных параметров.
2. При вызове функции фактические параметры, соответствующие инициализированным формальным, должны располагаться подряд с начала секции инициализации.
Пример:
Нахождение длины отрезка
<тип значения><идент.>(<тип пар.>[=<знач.>]{, <тип пар.>[=<знач.>]})
float par (float, float = 1, float = 1);
float par (float &x, float &y, float &z)
{
return x*y*z;
}
void main ()
{
float a, b, c;
int n;
cout<<”1. Dlina otrezka ”<<endl;
cout<<”2. Ploshad’ pryamougol’nika ”<<endl;
cout<<”3. Obyom pryamougol’nogo parallelipipeda ”<<endl;
cout<<”Nomer punkta ? ”;
cin>>n;
switch (n)
{
case 1:
cout<<”Dlina ? ”;
cin>>a;
cout<<”Dlina otrezka = “<<par(a);
break;
case 2:
cout<<”Dlina I shirina ? ”;
cin>>a>>b;
cout<<”Ploshad’ = ”<<par(a, b);
break;
case 3:
cout<<”Dlina, shirina i visota ? ”;
cin>>a>>b>>c;
cout<<”Obyom = ”<<par(a,b,c);
break
default
cout<<”Nepravil’niy nomer punkta”;
}
}
Тип структура в Си.
Этот тип является аналогом типа “запись” в Turbo Pascal. Позволяет объединить данные различных типов.
<тип структура> ≡ struct
{
<резерв. пам.>;
{<резерв. пам.>;}
}
Компоненты этого типа называются членами структуры.
Описание переменной с типом <структура>:
Сначала определяется идентификатор типа <структура>, затем описываются переменные с использованием этого идентификатора.
<определение типа> ≡ typedef <тип><идент. типа>
Пример:
typedef struct
{
char F[15], I[15], O[15];
int B[4];
float SB;
}
rez;
rez GR [25];
GR[5].F //Фамилия 6-го студента группы//
GR[5].B[1] //Оценка этого студента на втором экзамене//
Ввод фамилии, имени и отчества можно организовать с помощью оператора cin, т.к. эти переменные не будут содержать пробелов.
Тип указатель.
Программные объекты, которые порождаются с помощью соответствующих описаний называются статическими. Память за ними закрепляется на все время работы программы.
Данные, созданием и уничтожением которых управляет сам программист, внутренне строение которых формируется по особому закону, но количество, взаимное расположение и взаимосвязи которых могут изменяться в процессе выполнения программы, называются динамическими.
При объявлении данных динамической структуры в разделе описания указывается не сама переменная, а только ссылка на нее. Такая организация данных позволяет динамически занимать и освобождать память в процессе работы блока программы.
Это осуществляется с помощью типа указателя.
Синтаксис:
typedef <тип >* <тип указатель>; <тип указатель> <идентификатор>;
Или
<тип> *<идентификатор>;
Над указателями выполняются следующие простейшие действия:
1.Объявление переменной
int *p;
char *s;
2.Выделение области памяти
Это осуществляется с помощью процедуры new, она выделяет область памяти из области «куча» соответствующий тому типу, который описан для указателя и записывает ее адрес в указатель.
p=new float;
3.Операция взятия указателя
Для этого служит унарная операция ”&”.
int *p;
int n;
…
p=&n;
Операция &n даст адрес величины n и в программе его значение будет присвоено указателю p.
4.Занесение информации
*p:=1;
*n:=2;
5.Операция сравнения
if (p!=NULL)
…
6.Копирование информации
*p=*n;
В область памяти одной переменной заносится значение, хранившееся в другой.
7.Копирование адреса
p=n;
Обе ссылочные переменные ссылаются на одну и ту же область памяти.
8.Освобождение памяти
<освобождение памяти>≡delete <выр.>.
Процедура освобождает область памяти на которую указывает ссылочная переменная, после чего эта область становится доступной для распределения под другие динамические переменные.
Два способа для работы с динамическими переменными.
1. Резервирование памяти под дин. переменные производится с помощью операции new <тип>; где <тип>, - тип динам. переменной; new, - знак операции. Результат операции – адрес области памяти (указатель); операнд – любой тип в TC.
Пример:
float *p;
p=new float;
*p, - динамическая переменная.
Резервирование памяти под динамические переменные – “захват”.
<освобождение памяти>≡delete <выр.>.
Выражение должно иметь тип указатель.
Динамические массивы.
Динамические массивы – массивы, под которые выделяется область памяти “куча”. Работать с такими массивами так же, как и с динамическими переменными.
Резервирование памяти производится с помощью операции new <тип> []. Результат операции – адрес области памяти (указатель); операнд – любой тип в TC.
Пример:
a=new float [10], - захват памяти под 10 элементов действительного типа; значение a – указатель; работа с такими массивами так же, как и со статичными.
<освобождение памяти>≡delete [] <выражение>; при этом выражение должно иметь значение указателя на динамический массив.
NULL, - отсутствие ссылки; принадлежит любому значению типа указатель.
Списки.
Teg – описание структуры.
<определение типа структура с помощью тега>≡
struct <идент.>
{
<резервирование памяти>;
{< резервирование памяти >;}
};
Пример: Определим тип элемента односвязного списка.
struct tinfo
{
float x, y;
}
struct tel
{
tinfo info;
tel *link;
}
typedef tel* ptel;
Организация односвязного списка по принципу ссылки вперед.
Пример:
b, t, p – указатели на первый, текущий и на предшествующий элементы соответственно.
Блок – схема:
Текст программы:
void VVKL (ptel &b, int &n)
{
ptel t, p;
n=0;
do
{
t=new tel;
n++;
cout<<”Znachenie pervogo chlena ? ”;
cin>>t->info.x;
cout<<” Znachenie vtorogo chlena ? ”;
cin>>t->info.y;
if (n==1) b=t; else p->link=t;
p=t;
}
while (printf(“Prodolgit’ vvod? y/n ? ”)&&getchar()==’y’);
t->link=NULL;
}
Файлы.
Файл – упорядоченная совокупность произвольного числа компонентов, расположенная на внешнем запоминающем устройстве, и имеющая имя, называемое физическим именем файла. В программе файлу соответствует внутреннее логическое имя файла <идент.>. На языке С файл имеет сложную организацию и рассматривается как структура.
Работа с файлами в С реализуется через буфер. В С существует два вида файлов: текстовые и бинарные (двоичные). Текстовый – это файл, содержащий текстовые данные, как правило, организованные в виде строк. Бинарный (двоичный) – это файл, содержащий последовательность произвольных байтов. Байты состоят из бит, т.е. двоичных цифр. Текстовые файлы являются частным случаем двоичных файлов, и, таким образом, в широком значении слова под определение «двоичный файл» подходит любой файл.
Внутреннее логическое имя файла <идент.> должно быть объявлено в программе:
<резерв. памяти под указатель на буфер файла>≡FILE* <идент.>
Например:
FILE *prfl;
после объявления имя prfl будет являться указателем на некоторый файл.
Над файлами можно производить некоторые действия, такие, как открытие файла, чтение и запись, закрытие файла.
1.Прежде чем читать файл или записывать в него информацию, его необходимо открыть с помощью библиотечной функции:
<открытие файла >≡fopen(“<имя файла>; <атрибут файла>”)
атрибуты: w - чтение, r - запись, q;
значение функции – указатель на буфер.
<идент.>≡fopen (“имя файла”, “<атрибут>”); - связывает имя файла с буфером.
Для работы с существующим файлом можно использовать следующую структуру
if ((<идент.>=fopen(“<имя файла>”,”r”))!=NULL)
{
…
//работа с файлами//
…
}
else
cout<<”fayl ne nayden”<<endl;
2. После окончания работы с файлом он должен быть закрыт с помощью функции:
<закрытие файла >≡fclose(<идент>)
Она возвращает значение 0, если файл закрыт успешно, и ненулевое значение в противном случае.
Функции 1 и 2 работают с текстовыми файлами с буферизацией. Под буферизацией понимается то, что вводимые и выводимые данные запоминаются во временно области памяти, называемой буфером. Функция fclose() позволяет освободить частично заполненный буфер при закрытии файла, иначе информация может быть потеряна.
3.Функции форматированного ввода и вывода в файл имеют следующий вид: <форматированный вывод в файл>≡fprintf(<идент.>,<шаблон вывода>,<список вывода>);
<форматированный ввод из файла>≡fscanf(<идент.>,<шаблон вывода>,<список вывода>)
Действие этих функции аналогично действию функций scanf() и printf(), но здесь дополнительно вводится указатель на файл <идент.>, который в отличие от предыдущих функций используется в качестве первого аргумента.
getc(), - функция, считывающая символ, на который указывает указатель чтения.
Пример:
getc()!=EOF.
