Тема 4. Массивы и указатели. Работа с файлами.



Объявления массивов и указателей.

Массив представляет собой набор данных одного типа. Формат определения массива следующий:

тип_данных имя_массива[размер_массива];

Например, для представления данных о температуре можно воспользоваться следующим описанием:

int Temperatura[7];

Массив можно инициализировать во время определения:

int Temperatura[7]={ 20, 21, 17,16,27,22,19};

Если массив инициализируется, то его размер можно не указывать, например:

char Error[]=”Ошибка, файл не найден!”;

Многомерные массивы задаются указанием нескольких размеров, каждый из которых заключен в квадратные скобки:

double koordinate[8][2];

Такое описание определяет таблицу, содержащую два столбца и 8 строк.

При инициализации таких массивов можно не указывать только размер самого левого индекса:

int iarray[][3]={ {1,2,3},{9,11,4},{100,200,300}};

Многомерные массивы хранятся в памяти компьютера последовательно. Они группируются в порядке индексов, от правого к левому. В предыдущем примере элементы расположены следующим образом:

iarray[0][0],iarray[0][1],iarray[0][2],iarray[1][0],…,iarray[2][1],iarray[2][2].

Доступ к элементам массива.

Для доступа к элементу массива используется его имя, за которым следует номер элемента (индекс), заключенный в квадратные скобки, например:

for (int idx=0;idx<7;idx++)

       s+=Temperatura[idx];

Нумерация элементов массива начинается с нуля. Т.е. индекс массива определяет смещение используемого элемента относительно начала массива.

Передача массивов функциям.

Массивы можно передавать функциям. Для этого необходимо в объявлении параметров функции после имени массива поставить пару квадратных скобок:

int function(double a[],int size);

Обратите внимание, что размерность массива в функцию автоматически не передается. Это можно сделать, используя второй параметр, как показано в предыдущем примере.

При вызове функции необходимо просто указать имя фактического параметра:

x=function(myarray,50);

Функция получает доступ ко всем элементам массива и может их изменять. Для запрета изменения можно добавить модификатор const:

int function(const double a[],int size);

Указатели.

Указатель является переменной, которая содержит адрес другой переменной или функции. Описание указателя определяет тип данных, на которые ссылается указатель, оно имеет вид:

тип_указываемых данных *имя_указателя;

Для доступа к объекту, на который ссылается указатель, используется имя указателя со звездочкой перед ним. Эта операция называется разыменовыванием указателя, она корректно выполняется только, если указатель был предварительно инициализирован:

int i=100;// определяется целая переменная

int *point_i;// определяется указатель на целую переменную

pointi=&i;// указатель инициализируется адресом переменной i

printf(“%i”,*pointi); // выводится значение переменной,

// определяемое указателем. Оно равно значению переменной i (100).

Обратите внимание на операцию определения адреса (&). Она является противоположной разыменованию.

Массивы и указатели тесно связаны друг с другом. Имя массива соответствует указателю на начало массива. Поэтом можно присваивать указателю адрес первого элемента массива, используя имя массива.

int array[10];

int *iptr=array;

С указателями можно выполнять целочисленные арифметические операции. При этом происходит вычисление адреса соответствующего элемента массива, а не адреса в памяти компьютера. Размер элемента определяется типом указателя. Для типа void соответственно никакие операции выполнять нельзя.

Указатель можно индексировать как массив. Следующие два оператора эквивалентны:

array[3]=10;

*(array+3)=10;

Указатели вместо массивов целесообразно использовать тогда, когда требуется последовательный доступ к элементам массива. Такая операция выполняется значительно быстрее, например:

int *ptemp=array;

for(int i=1;i<10;i++)

       *(ptemp++)=0;

можно использовать для обнуления массива array.              

Динамическое выделение и освобождение памяти.

При компиляции программы память компьютера разбивается на четыре области, содержащие код программы, глобальные данные, стек и динамически распределяемую память ( иногда ее называют heap - куча). Heap – это свободная память, с которой можно работать с помощью функций new и delete. Для new аргументом является выражение, определяющее размер выделяемого массива, а возвращаемое значение – это указатель на начало массива:

int *array=new int[10];

Если память не может быть выделена, то оператор new возвращает указатель NULL . После каждой операции выделения памяти обязательна проверка указателя на NULL:

if(array==NULL)

       printf(“memory allocation error.”);

else

{

// действия при правильном выделении памяти

}

Выделенная динамически память автоматически не освобождается при выходе из блока или по завершению программы. Для ее освобождения обязательно необходимо выполнить команду delete[] имя_массива; (delete[] array; - для предыдущего случая).

 

Практическое задание.

Вариант1.

Вычислите скалярное произведение векторов  и  размерности n.

Размерность векторов и их координаты должны вводится с консоли.

Контрольные примеры:

                          

                          

                       

Вариант 2.

Вычислите произведение матрицы на вектор.

Размерности вектора  и матрицы A , координаты вектора и элементы матрицы должны вводится с консоли. Координаты вектора  распечатайте на экране.

Контрольные примеры:

                                      

          

                                   

Вариант 3.

Вычислите сумму матриц. . Размерности матриц и их элементы введите с консоли. Элементы матрицы C выведите на экран.

Контрольные примеры:

                                  

                   

                                      

Вариант 4.

Напишите процедуры умножения и сопряжения матриц и с их помощью вычислите

Размерности матриц и их элементы вводятся с консоли. Элементы матрицы C должны выводится на экран.

Контрольные примеры:

                      

                   

 

Тема 5. Ввод и вывод в языке С++.

В языке С имеется весьма развитая библиотека функций ввода-вывода. Однако в самом языке отсутствуют какие-либо предопределенные файловые структуры. Все данные обрабатываются как последовательность байт. Имеется три основных типа функций: потоковые, работающие с консолью и портами ввода-вывода и низкоуровневые.

Потоковые функции.

В потоковых функциях файлы данных рассматриваются как поток отдельных символов.

Когда программа открывает файл для ввода вывода при помощи потоковых функций, то открытый файл связывается с некоторой переменной типа FILE (определенной в stdio.h), содержащей базовую информацию об этом файле. После открытия потока с помощью функции fopen возвращается указатель на эту переменную. Этот указатель используется для ссылки к файлу при всех последующих операциях ввода-вывода и называется указателем потока.

Все потоковые функции обеспечивают буферизованный, форматированный или неформатированный ввод/вывод. Буферизация потока разгружает приложение. Однако следует иметь в виду, что при аварийном завершении программы содержимое буферов вывода может быть потеряно.

Аналогичным образом выглядят функции, работающие с консолью и портами. Они позволяют читать и писать на терминал или в порт ввода/вывода (например, в порт принтера). Функции портов ввода/вывода выполняют простое побайтное считывание или запись. Функции ввода/вывода на консоль обеспечивают несколько дополнительных возможностей, например можно определить момент, когда будет введен символ с консоли и т.п.

Для использования потоковых функций в программу должен быть включен заголовочный файл stdio.h. В нем содержатся описания прототипов функций ввода/вывода, а также - описания ряда констант. Константа EOF определяется как значение, возвращаемое при обнаружении конца файла, BUFSIZE - размер буферов потока, тип FILE определяет структуру, используемую для получения информации о потоке.

Поток открывается с помощью функций fopen(), fdopen() или freopen(). В момент открытия задаются режим файла и способ доступа. Эти функции возвращают указатель на переменную типа FILE, например

FILE *file1;

file1=fopen(“input.dat”,”r”);

открывает файл input.dat для чтения. Переменная file1 получает указатель на поток.

Возможные типы доступа:

“a” – запись в режиме добавления в конец файла,

”a+” –тоже, что и “a”, но возможно и чтение,

”r” – только для чтения,

”r+” – для чтения и записи,

”w” – открывается пустой файл для записи,

”w+” – открывается пустой файл для записи и чтения.

Когда начинается выполнение приложения, автоматически открывается следующие потоки: стандартное устройство ввода stdin, стандартное устройство вывода stdout, устройство сообщений об ошибках stderr, устройство печати stdprn и стандартное дополнительное устройство stdaux. Эти файловые указатели можно использовать во всех функциях ввода/вывода в качестве указателя на поток. Некоторые функции автоматически используют указатели на поток, например getchar() и putchar() используют stdin и stdout соответственно.

Для закрытия потоков используются функции fclose() и fcloseall(). Если программа не закрывает поток явно, то он закрывается автоматически по ее завершению.

Для перемещения по файлу можно использовать функции fseek(), ftell() и rewind().

Низкоуровневый ввод и вывод.

Функции низкоуровневого ввода-вывода не выполняю никакой буферизации и форматирования. Они непосредственно обращаются к средствам ввода/вывода операционной системы.

При открытии файла на этом уровне возвращается описатель файла (file handle), представляющий собой целое число, используемое затем для обращения к этому файлу при дальнейших операциях. Для открытия используется функция open(), для закрытия – функция close().

Функция read() читает данные в указанный массив, а write() – выводит данные из массива в файл, lseek() – используется для перемещения по файлу.

Низкоуровневые функции не требуют включения заголовочного файла stdio.h, вместо него используется файл io.h.

Низкоуровневая система ввода-вывода не вошла в стандарт ANSI C, поэтому ее не рекомендуют для дальнейшего использования.


Дата добавления: 2018-02-15; просмотров: 891; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!