Читайте также: |
|
int a = 30000;
float b;
........
b = (float) a * 12;
(переменная a целого типа явно преобразована к типу float; если этого не сделать, то результат будет потерян, т.к. a * 12 > 32767).
Преобразование типа также может использоваться для преобразования типов аргументов при вызове функций.
19.
В языке программирования C-51 используются арифметические операции, результат которых зависит от типа операндов:
+ суммирование
- вычитание
* умножение
/ деление
% вычисление остатка от целочисленного деления
Примеры выражений, использующие арифметические операции:
А+В
А+В-С
A*T+F/D
A*(B+C)-(D-E)/F
20.
К логическим операциям относятся операция логического И (&&) и операция логического ИЛИ (||). Операнды логических операций могут быть целого типа, плавающего типа или типа указателя, при этом в каждой операции могут участвовать операнды различных типов.
Операнды логических выражений вычисляются слева направо. Если значения первого операнда достаточно, чтобы определить результат операции, то второй операнд не вычисляется.
Логические операции не вызывают стандартных арифметических преобразований. Они оценивают каждый операнд с точки зрения его эквивалентности нулю. Результатом логической операции является 0 или 1, тип результата int.
Операция логического И (&&) вырабатывает значение 1, если оба операнда имеют нулевые значения. Если один из операндов равен 0, то результат также равен 0. Если значение первого операнда равно 0, то второй операнд не вычисляется.
Операция логического ИЛИ (||) выполняет над операндами операцию включающего ИЛИ. Она вырабатывает значение 0, если оба операнда имеют значение 0, если какой-либо из операндов имеет ненулевое значение, то результат операции равен 1. Если первый операнд имеет ненулевое значение, то второй операнд не вычисляется.
В языке программирования C-51 также определено несколько одноместных арифметических операций:
'-' изменение знака операнда на противоположное значение
'+' знак плюс не влияет на значение операнда
++ увеличение значения операнда на единицу
-- уменьшение значения операнда на единицу
Для одноместной операции требуется один операнд, которому она предшествует. Например:
P3 = -5; //Присвоить порту P3 значение числа -5
Бинарными (или двуместными) операциями в математике и программировании называют такие функции, которые принимают два аргумента (операнда), как правило, одного типа, и выдают одно значение в качестве результата.
Примеры:
арифметические операции (сложение, умножение, вычитание, деление, возведение в степень);
конкатенация (сложение) текстовых строк;
логические операции ("и", "или", "исключающее или", "импликация" и др.);
отношения ("больше", "меньше", "равно" и т.п.), если рассматривать их как операции, дающие истинностные значения.
Бинарные операции, как правило, записываются в инфиксном формате, когда знак операции (оператор) ставится между операндами. Например: A+B или X/Y.
21.
Адресные операции: указатели в адр. Опер-ях
Адресные операции
& Операция получения адреса операнда.
Операндом может быть любое l-выражение. Операция возвращает адрес объекта или функции, на который ссылается операнд. Операция невыполнима по отношению к объектам, определённым со спецификатором register, поскольку существует вероятность того, что они не располагаются в памяти и не имеют определённого адреса.
* Операция обращения по адресу или операция косвенного обращения.
Операндом может быть выражение, значением которого является адрес. Операция косвенного обращения называется также операцией разыменования, поскольку позволяет обращаться к объекту не употребляя при этом имени объекта.
22.
Массив – это упорядоченная совокупность переменных, которые имеют общее имя и одинаковый тип. Имя массива – это общее имя переменных, входящих в массив.
Если говорить упрощенно, то массив представляет собой компьютерный эквивалент таблицы. Они используются для упорядоченного хранения данных, к которым требуется многократные обращения в ходе выполнения программы.
Положение элемента в массиве однозначно определяется его индексом (для одномерного массива) или индексами (для многомерного массива). Размерность массива – это количество индексов у каждого элемента массива.
Каждый индекс изменяется в некотором диапазоне [a,b]. Диапазон [a,b] называется граничной парой, a - нижней границей, b - верхней границей индекса. При объявлении массива границы задаются выражениями. Если при объявлении массива все границы заданы константными выражениями, то число элементов массива известно в момент его объявления и ему может быть выделена память уже на этапе трансляции. Такие массивы называются статическими.
В языке С/C++ все массивы являются статическими; более того, все массивы являются 0-базируемыми. Это означает, что нижняя граница всех индексов массива фиксирована и равна нулю. Поэтому при описании массива указывается количество возможных значения для каждого индекса (начиная с 0).
Для размещения массива в памяти ЭВМ отводится поле памяти, размер которого определяется типом, длиной и размерностью массива. В языке C/C++ эта информация задается в разделе описаний. Массив описывается так:
int A[10]; // одномерный массив из 10 целых элементов. Индекс изменяется от 0 до 9.
Всякий раз, когда в выражении появляется идентификатор типа массива, он преобразуется в указатель на первый член массива. Из-за преобразований массивы не являются адресами. По определению операция индексирования [] интерпретируется таким образом, что E1[E2] идентично *((E1)+(E2)). В силу правил преобразования, применяемых к +, если E1 массив и E2 целое, то E1[E2] относится к E2-ому члену E1. Поэтому, несмотря на такое проявление асимметрии, индексирование является коммутативной операцией.
Это правило сообразным образом применяется в случае многомерного массива. Если E является n-мерным массивом ранга i*j*...*k, то возникающее в выражении E преобразуется в указатель на (n-1)-мерный массив ранга j*...*k. Если к этому указателю, явно или неявно, как результат индексирования, применяется операция *, ее результатом является (n-1)-мерный массив, на который указывалось, который сам тут же преобразуется в указатель.
23.
Одномерные массивы
Одномерный массив - это фиксированное количество элементов одного и того же типа, объединенных общим именем, где каждый элемент имеет свой номер. Нумерация элементов массива в С# начинается с нуля, то есть, если массив состоит из 10 элементов, то его элементы будут иметь следующие номера: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Одномерный массив в С# реализуется как объект, поэтому его создание представляет собой двухступенчатый процесс. Сначала объявляется ссылочная переменная на массив, затем выделяется память под требуемое количество элементов базового типа, и ссылочной переменной присваивается адрес нулевого элемента в массиве. Базовый тип определяет тип данных каждого элемента массива. Количество элементов, которые будут храниться в массиве, определяется размер массива.
В общем случае процесс объявления переменной типа массив, и выделение необходимого объема памяти может быть разделено. Кроме того на этапе объявления массива можно произвести его инициализацию. Поэтому для объявления одномерного массива может использоваться одна из следующих форм записи:
Форма записи
базовый_тип [] имя__массива;
Например:
int [] a;
Описана ссылка на одномерный массив, которая в дальнейшем может быть использована:
для адресации на уже существующий массив;
передачи массива в метод в качестве параметра
отсроченного выделения памяти под элементы массива.
базовый_тип [] имя__массива = new базовый_тип [размер];
Например:
int []a=new int [10];
Объявлен одномерный массив заданного типа и выделена память под одномерный массив указанной размерности. Адрес данной области памяти записан в ссылочную переменную. Элементы массива равны нулю.
Замечание. Надо отметить, что в C# элементам массива присваиваются начальные значения по умолчанию в зависимости от базового типа. Для арифметических типов - нули, для ссылочных типов - null, для символов - пробел.
базовый_тип [] имя__массива={список инициализации};
Например:
int []a={0, 1, 2, 3}; Выделена память под одномерный массив, размерность которого соответствует количеству элементов в списке инициализации. Адрес этой области памяти записан в ссылочную переменную. Значение элементов массива соответствует списку инициализации.
Обращения к элементам массива происходи с помощью индекса, для этого нужно указать имя массива и в квадратных скобках его номер. Например, a[0], b[10], c[i].
Многомерные массивы
Многомерные массивы имеют более одного измерения. Чаще всего используются двумерные массивы, которые представляют собой таблицы. Каждый элемент массива имеет два индекса, первый определяет номер строки, второй - номер столбца, на пересечении которых находится элемент. Нумерация строк и столбцов начинается с нуля.
Объявить двумерный массив можно одним из предложенных способов:
тип [,] имя__массива;
тип [,] имя__массива = new тип [размер1, размер2];
тип [,] имя__массива={{элементы 1-ой строки}, …, {элементы n-ой строки}};
тип [,] имя__массива= new тип [,]{{элементы 1-ой строки}, …,{элементы n-ой строки}};
строки}};
Например:
int [,] a;
int [,] a= new int [3, 4];
int [,] a={{0, 1, 2}, {3, 4, 5}};
int [,] a= new int [,]{{0, 1, 2}, {3, 4, 5}};
24.
Создание указателей
Указатель — это переменная специального типа. Она хранит не какое-то числовое значение, а адрес (номер первого байта в памяти компьютера), по которому хранится какая-то другая переменная. При создании указателя необходимо задать тип переменной, на которую он указывает. Синтаксис объявления указателя такой:
имя_типа * идентификатор;
Пример:
int * pi;
float * pf, f;
double * ps, * pt;
В первой строке этого примера объявлены переменная pi, являющейся указателем на тип int (то есть в ячейке памяти, на которую указывает pi должна хранится переменная типа int). Во второй строке объявлены переменная pf, являющейся указателем на тип float и переменная f типа float. Обратите особое внимание на эту строчку: для того, чтобы объявить несколько указателей в одной строке, необходимо перед идентификатором каждого из них поставить символ *. А еще лучше объявлять в одной строке только одну переменную. В третей строке объявляется два указателя на тип double: ps и pt.
Сразу после объявления значение указателя не определено, то есть он может указывать в произвольную ячейку памяти, поэтому пользоваться им нельзя. Иначе вы в лучшем случае получите ошибку segmentation fault, в худшем — программа будет работать непредсказуемо.
Создание массива при помощи оператора new
Для создания массива в динамической памяти используется оператор new с указанием размера создаваемого массива. Пример:
int * pi; // Объявить указатель pa
pi=new int[n]; // Создать массив из n элементов типа int
Теперь с pi можно работать, как с обычным массивом из n элементов типа int: становятся доступны элементы pi[0], pi[1],..., pi[n-1].
Существует единственное числовое значение, которое можно присвоить непосредственно указателю: это 0 (то есть присваивание pi=0 разрешено, а присваивание pi=1 — нет). Нулевой адрес — особый, по этому адресу не может хранится ни одна переменная. То есть указатель, имеющий нулевое значение указывает в "никуда", к такому указателю нельзя применить оператор разыменования.
Оператор new использует функцию операционной системы для выделения памяти. Если затребованный размер памяти слишком большой (а также при попытке создать массив из нуля или отрицательного числа элементов), операционная система не будет выделять память и оператор new вернет нулевое значение. Если это нулевое значение будет присвоено указателю, к которому впоследствии будет применен оператор разыменования или оператор обращения к элементу массива, то программа аварийно завершит работу с ошибкой segmentation fault. Чтобы быть уверенным, что оператор new был выполнен удачно, необходимо сразу после его вызова проверить значение, которое он вернул и в случае, если оно равно 0, выполнить какие-либо особенные действия, например, вывести сообщение о невозможности выделения необходимого объема памяти. Например:
int n=1000000000;
int *pi=new int[n];
if(pi==0)
{
cout<<"Невозможно создать массив из "<<n<<" элементов int";
return 1; // Завершаем работу функции main
}
Освобождение памяти
После окончания работы с массивом, когда выделенная ранее память перестанет быть нужной, ее необходимо освободить, чтобы дать возможность операционной системе использовать эту память по своему усмотрению, например, выделить другой программе. Для этого используется унарный оператор delete, единственный операнд которого — адрес, по которому начинается память, ранее выделенная оператором new, которую мы хотим освободить. Например:
delete pi;
При этом сам указатель pi не уничтожается, ему можно присвоить новое значение, однако разыменование этого указателя может привести к ошибке.
Связь между указателями и массивами
Итак, с указателем можно работать, как с массивом, в частности, к нему можно применять оператор доступа к элементу []. Верно и обратное — с массивом можно работать, как с указателем. Если мы объявили массив int arr[10], то мы можем использовать идентификатор arr без указания элемента массива, как синоним для указателя на начало массива. С массивами можно выполнять все операции, которые можно делать с указателями, кроме тех, которые меняют значение самого указателя: =, +=, -=, ++. --, то есть единственное отличие массивов от указателей заключается в том, что значение указателя можно изменить в программе, а значение массива (то есть адрес его начала) — нет.
25.
Обращение к элементам массива
Массив позволяет хранить несколько значений в одной и той же переменной. Для обращения к определенным значениям, хранящимся в массиве, используйте значение индекса, которое указывает на требуемый элемент. Например, для обращения к первому элементу массива test_scores вы должны использовать значение индекса 0. Для обращения ко второму элементу используйте индекс 1. Подобно этому, для обращения к третьему элементу используйте индекс 2. Как показано на рис. 16.1, первый элемент массива всегда имеет индекс 0, а значение индекса последнего элемента на единицу меньше размера массива:
Важно помнить, что C++ всегда использует 0 для индекса первого элемента массива, а индекс последнего элемента на единицу меньше размера массива. Следующая программа ARRAY. CPP создает массив с именем values, который вмещает пять целочисленных значений. Далее программа присваивает элементам значения 100, 200, 300, 400 и 500:
#include <iostream.h>
void main(void)
{
int values[5]; // Объявление массива
values[0] = 100;
values[1] = 200;
values[2] = 300;
values[3] = 400;
values [4] = 500;
cout << "Массив содержит следующие значения" << endl;
cout << values [0] << ' ' << values [1] << ' ' << values [2] << ' ' << values [3] << ' ' << values [4] << endl;
}
Как видите, программа присваивает первое значение элементу 0 (va lues[0]). Она также присваивает последнее значение элементу 4 (размер Массива (5) минус 1).
Использование индекса для обращения к элементам массива
Массив позволяет вашим программам хранить несколько значений внутри одной и той же переменной. Для обращения к определенному значению внутри массива программы используют индекс. Говоря кратко, значение индекса указывает требуемый элемент массива. Все массивы C++ начинаются с элемента с индексом 0. Например, следующий оператор присваивает значение 100 первому элементу массива с именем scores:
scores[0] = 100;
Когда ваша программа объявляет массив, она указывает количество элементов, которые массив может хранить. Например, следующий оператор объявляет массив, способный хранить 100 значений типа int.
int scores[100];
В данном случае массив представляет собой элементы от scores[0] до scores[99].
Использование индексной переменной
Если ваши программы используют массив, обычной операцией является использование индексной переменной для обращения к элементам массива. Например, предположим, что переменная / содержит значение 3, следующий оператор присваивает значение 400 элементу values[3J:
values[i] = 400;
Следующая программа SHOWARRA.CPP использует индексную переменную i внутри цикла for для вывода элементов массива. Цикл for инициализирует i нулем, так что программа может обращаться к элементу values[O]. Цикл for завершается, когда i больше 4 (последний элемент массива):
#include <iostream.h>
void main (void)
{
int values[5]; // Объявление массива int i;
values[0] = 100;
values[1] = 200;
values[2] = 300;
values[3] = 400;
values[4] = 500;
cout << "Массив содержит следующие значения" << endl;
for (i = 0; i < 5; i++) cout << values [i] << ' ';
}
Каждый раз, когда цикл for увеличивает переменную i, программа может обратиться к следующему элементу массива. Экспериментируйте с этой программой, изменяя цикл for следующим образом:
for (i = 4; i >= 0; i--) cout << values [i] << ' ';
В данном случае программа будет выводить элементы массива от большего к меньшему.
26.
Многомерные массивы
Многомерные массивы - это массивы с более чем одним индексом.
Чаще всего используются двумерные массивы.
При описании многомерного массива необходимо указать C++, что массив имеет более чем одно измерение.
Пример 1.
int t[3][4];
Описывается двумерный массив, из 3 строк и 4 столбцов.
Элементы массива:
t[0][0] t[0][1] t[0][2] t[0][3]
t[1][0] t[1][1] t[1][2] t[1][3]
t[2][0] t[2][1] t[2][2] t[2][3]
При выполнении этой команды под массив резервируется место. Элементы массива располагаются в памяти один за другим.
Пусть это линейка памяти:
Рисунок 1.7.1.
Пример 2.
int temp [3] [15] [10];
резервируется место под 3-х мерный массив.
В памяти многомерные массивы представляются как одномерный массив, каждый из элементов которого, в свою очередь, представляет собой массив.
Рассмотрим на примере двумерного массива.
int a[3][2]={4, l, 5,7,2, 9};
Представляется в памяти:
Таблица 1.7.3.
a[0][0] заносится значение 4
a[0][1] заносится значение 1
a[1][0] заносится значение 5
a[1][1] заносится значение 7
a[2][0] заносится значение 2
a[2][1] заносится значение 9
Второй способ инициализации при описании массива
int а[3][2]={ {4,1}, {5, 7}, {2, 9} };
Обращение к элементу массива производится через индексы.
cout<< а[0][0];
Выдаст значение 4.
cout << a[1][1];
Выдаст знaчение 7.
Программа, которая инициализирует массив и выводит его элементы на экран.
#include <iostream.h>
main ()
{
int a[3] [2]={
{1,2}, {3,4}, {5,6}
};
int i,j;
for (i=0; i<=2; i++)
for(j=0;j<=l;j++)
cout <<"\n a["<< i <<"," << j <<"] ="<< a[i]|j];
return 0;
}
Для того, чтобы убрать из программы явные значения размера и массива, можно воспользоваться директивой define
#include < iostream.h>
#define I 3
#define J 2
main()
{ int a[I][J]={ {l,2}, {3,4}, {5,6} };
int i, j;
for (i=0; i< I; i++)
for(j=0; j< J; j++)
cout <<"\n a["<< i <<"," << j << "] ="<< a[i][j];
return 0;
}
При передаче массива в функцию всегда происходит передача его адреса. Т.о. в C++ все массивы передаются по адресу.
27.
Любой текст состоит из символов. Для хранения одного символа предназначен тип данных char. Переменную типа char можно рассматривать двояко: как целое число, занимающее 1 байт и способное принимать значения от 0 до 255 (тип unsigned char) или от -128 до 127 (тип signed char) и как один текстовый символ. Сам же тип char может оказаться как знаковым, так и беззнаковым, в зависимости от операционной системы и компилятора. Поэтому использовать тип char не рекомендуется, лучше явно указывать будет ли он знаковым (signed) или беззнаковым (unsigned).
Как и целые числа, данные типа char можно складывать, вычитать, умножать, делить, а можно выводить на экран в виде одного символа. Именно это и происходит при выводе символа через объект cout. Если же нужно вывести числовое значение символа (также называемое ASCII-кодом), то значение символа необходимо преобразовать к типу int. Например:
#include<iostream>
using namespace std;
int main()
{ unsigned char c='A'; // Константы char заключаются в одинарные кавычки
cout<<c<<" "<<(int)c<<endl;
c=126; // char можно присвоить и числовое значение
cout<<c<<" "<<(int)c<<endl;
return 0; }
В этом примере переменной с типа char присваивается значение, равное символу 'A' (константы типа char записываются как символы в одинарных кавычках), затем на экран выводится значение c, как символа и его ASCII-код, потом переменной c присваивается значение 126 (то есть символ с ASCII-кодом 126) и снова выводится на экран символ и его ASCII-код.
Организовать последовательное посимвольное считывание всего входного потока можно при помощи цикла while:
#include<iostream>
using namespace std;
int main()
{
unsigned char c;
while(cin>>c) // Цикл пока считывание успешно
{ // Делаем необходимые действия
}
return 0;
}
В этом примере программа будет посимвольно считывать входной поток (по умолчанию — ввод с клавиатуры), пока не встретит признак конца файла. Для того, чтобы сообщить программе о завершении файла при вводе с клавиатуры необходимо нажать клавиши Ctrl-d в системе Linux и Ctrl-z в системе Windows.
Эта программа при считывании данных будет игнорировать символы–разделители: пробелы, символы новой строки и табуляции. Если нужно, чтобы в переменную c считывались все символы, в том числе и разделители, то необходимо для потока ввода cin установить манипулятор noskipws при помощи инструкции cin>>noskipws;.
Строки в языке C++
Текстовую строку можно представить, как массив символов типа char, но в языке C++ для хранения текстовых строк был создан более удобный тип string. По сути, тип данных string и является массивом символов. Например, если мы объявили переменную S как string S, а затем присвоили ей значение "школа" (текстовые строки заключаются в двойные кавычки), то мы можем обращаться к отдельным символам строки S, представляя S, как массив символов, например, S[0]=='ш', S[1]=='к' и т.д. Для того, чтобы узнать длину строки используется метод length(), вызываемый в виде S.length().
Строковые данные можно считывать с клавиатуры, выводить на экран, присвавать переменным типа string. Также строки можно складывать друг с другом: например, при сложении строк "Hello, " и "world!" получится строка "Hello, world!". Такая операция над строками называется конкатенацией.
Основные приемы работы с объектами string проиллюстрированы в программе:
string S, S1, S2; // Объявление трех строк
cout<<"Как вас зовут? ";
cin>>S1; // Считали строку S1
S2="Привет, "; // Присвоили строке значение
S=S2+S1; // Использование конкатенации
cout<<S<<endl; // Вывод строки на экран
cout<<S.length(); // Длина строки S
При считывании строк из входного потока считываются все символы, кроме символов–разделителей (пробелов, табуляций и новых строк), которые являются границами между строками. Например, если при выполнении следующей программы
string S1, S2, S3; // объявили 3 строки
cin>>S1>>S2>>S3;
ввести текст `Мама мыла раму' (с произвольным количеством пробелов между словами), то в массив S1 будет записана строка "Мама", в S2 — "мыла", в S3 — "раму".
Таким образом, организовать считывание всего файла по словам, можно следующим образом:
string s;
while(cin>>s) // Цикл пока считывание успешно
{ // Делаем необходимые действия
}
Если нужно считать строку со всеми пробелами, то необходимо использовать функцию getline следующим образом:
string S;
getline(cin,S);
В данном случае если запустить эту программу и ввести строку "Мама мыла раму", то именно это значение и будет присвоено строке S. Считать же весь входной поток по строкам можно при помощи следующего кода:
string s;
while (getline(cin,S)) // Цикл пока считывание успешно
{ // Делаем необходимые действия
}
28.
Массивы указателей; указатели указателей
Так как указатели сами являются переменными, то вы впол-не могли бы ожидать использования массива указателей. Это действительно так. Мы проиллюстрируем это написанием прог-раммы сортировки в алфавитном порядке набора текстовых строк, предельно упрощенного варианта утилиты SORT операци-
онной систем UNIX. В главе 3 мы привели функцию сортировки по шеллу, кото-рая упорядочивала массив целых. Этот же алгоритм будет рабо-тать и здесь, хотя теперь мы будем иметь дело со строчками текста различной длины, которые, в отличие от целых, нельзясравнивать или перемещать с помощью одной операции. Мы нуж-даемся в таком представлении данных, которое бы позволяло удобно и эффективно обрабатывать строки текста переменной длины. Здесь и возникают массивы указателей. Если подлежащие
сортировке сроки хранятся одна за другой в длинном символь-ном массиве (управляемом, например, функцией ALLOC), то к каждой строке можно обратиться с помощью указателя на ее первый символ. Сами указатели можно хранить в массиве. Две строки можно сравнить, передав их указатели функции STRCMP.Если две расположенные в неправильном порядке строки должны быть переставлены, то фактически переставляются указатели в массиве указателей, а не сами тексты строк. Этим исключаются сразу две связанные проблемы: сложного управления памятью ибольших дополнительных затрат на фактическую перестановку строк. Процесс сортировки включает три шага:
чтение всех строк ввода
их сортировка
вывод их в правильном порядке
Как обычно, лучше разделить программу на несколько функций в соответствии с естественным делением задачи и выделить веду-щую функцию, управляющую работой всей программы.Давайте отложим на некоторое время рассмотрение шага сорти-ровки и сосредоточимся на структуре данных и вводе-выводе.
Функция, осуществляющая ввод, должна извлечь символы каждой строки, запомнить их и построить массив указателей строк. Она должна также подсчитать число строк во вводе, так как эта информация необходима при сортировке и выводе. так как функция ввода в состоянии справиться только с конечным чис-
лом вводимых строк, в случае слишком большого их числа она может возвращать некоторое число, отличное от возможного числа строк, например -1. Функция осуществляющая вывод, дол-жна печатать строки в том порядке, в каком они появляются в массиве указателей.
ясность - способы многооценивания проги
краткость - оценка стиля записи выражений
эффективность - минимум памяти, максимум быстродействия и использования ресурсов
язык
стиль
размер
имя1_имя2 Имя1 Имя2
имя программы
автор
среда разработки
дата создания
дата посл. модификации
автор модиф.
краткое описение проги
спецификация ф-ций (обычно перед ф-цией)
запись проги: лесерка, правило отступа(требов. структ. прогр.)
комментарии разбиение на файлы
Дата добавления: 2015-07-26; просмотров: 71 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Функция gets(). 1 страница | | | Функция gets(). 3 страница |