Работа с указателями

Если объявить

int mas[100], *р, а;

то:

1) для массива отводится память в адресном пространстве под 100 элементов типа int.

2) память отводится под указатель-константу с именем MAS, значением указателя является адрес массива.

3) память отводится под указатель-переменную с именем р.

Операция инициализации указателя может осуществляться только операцией "присвоить адрес некоторой переменной".

p = &a;

p = &mas[0]; или p = mas;

или присвоением p = NULL;, где NULL - константа, определенная через define в файле NULL.H.

Допустимо р=0, но не рекомендуется.

Ошибкой являются:

а=10;

р=а; // где р - указатель. Присвоение невозможно, т.к. типы int* и int.

p=10; // присвоение невозможно, т.к. типы int* и const int.

Указателю нельзя присваивать целые значения, но можно складывать и вычитать указатель и целые числа.

р+=10; - экв. р = р+10; - увеличение адреса на 10* масштабный множитель.

р-=2; уменьшение на 2* масшт. множителя.

р+=10; увеличивает на 10 содержимое ячейки, на которую ссылается р.

Например:

Если р=mas; то р+=10; эквивалентно р=р+10 и эквивалентно присвоению р=&mas[10];

*р+=10; эквивалентно mas[0]=mas[0]+10;

Если 2 указателя ссылаются на элементы одного и того же массива, то допускаются операции отношения над ними: = =; !=; <, >, и т.д.

Для указателей, ссылающихся на элементы разных массивов, результат сравнения не определен.

Допускается вычитание указателей.

Например, разработаем функцию вычисления длины строки:

int strlen(char *s)

{ char *p = s; // объявлен указатель и инициирован адресом // массива символов.

While(*p! = '\0') p++;

Return p-s;

}

Данная функция возвращает значение типа int, т.е. длина строки не может превышать значения, которое представимо типом int ( 2-х байтным целым ). Поэтому в реальных программах лучше пользоваться стандартной функцией strlen, которая описана в файле string.h. Эта функция умеет выбирать тип возврата в зависимости от модели памяти, используемой в программе. Для этого определен (define) тип ptrdiff_t в файле STDDEF.H.

 

4.12.Работа с памятью

Разработаем пример простой программы, распределяющей память. Функция static char allocbuf[ALLOCSIZE]; выделяет память из буфера static char allocbuf[ALLOCSIZE];, а функция void afree(char *p); освобождает память, распределенную в этом буфере. Память организована в виде стека, где базовым адресом основания стека является allocbuf, а на вершину стека указывает alloccp.

 

#include <stdio.h> //функции ввода-вывода

#include <string.h>//функция strlen()

#include <conio.h> //функции ввода-вывода на консоль(clrscr())

#define ALLOCSIZE 10000 //препроцессорная директива определения

//константы как равной 10000

static char allocbuf[ALLOCSIZE]; //буфер памяти (массив символов allocbuf длиной

//в 10000 символов

static char *allocp; //указатель константа на тип char

char * alloc(int n)//заголовок функции

{ //если размер оставшейся свободной памяти

if (allocbuf + ALLOCSIZE - allocp >=n)// не меньше запрашиваемого

//участка, то память выделяется.

{ //printf("%d\n",allocp);

allocp +=n; // alloccp

//printf("%d\n",allocp); // распределенная

return allocp; // память свободная память

} else//

return 0; //

} // allocbuf allocbuff+ALLOCSIZE

 

void afree(char *p) //

{

if (p>=allocbuf && p < allocbuf + ALLOCSIZE)//память освобождается,

allocp=p; //если адрес начала объекта принадлежит

} //нашей области allocbuf. void main (void)

{ char str[255],*p[1000]; //буфер ввода с клавиатуры str[255] и массив

int a,i,j;//для хранения списка указателей *p[1000];

a=0; i=0;

p[0]=NULL; i++;

while (((scanf("%s",str))!=EOF) && (p[i]=alloc(strlen(str)))!=0) //ввод строк

{ //пока не введен конец файла или исчерпан буфер свободной памяти.

printf("adress=%d", p[i]);

i ++;}

I--;

printf("Базовый адрес =%d", allocbuf);

for (j=0; j<=i; j++)

printf("\np[%d]=%d;",j,p[j]);

for (j=i;j>=0;j--)

{afree(p[j]); printf("\указатель стека =%d",p[j]);

}

}

 

Файлы

Файл – это организованный набор данных , расположенных на внешнем носителе.

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

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

Прежде чем читать или записывать информацию в файл, он должен быть открыт. Это можно сделать с помощью библиотечной функции fopen. Она берет внешнее представление файла (например C:\MY_FILE.TXT)­­­­ и связывает его с внутренним логическим именем, которое используется далее в программах. Логическое имя – это указатель на требуемый файл. Его необходимо объявлять, и делается это, например, так:

FILE *lst;

Здесь FILE - имя типа, описанное в стандартном определении stdlo.h, 1st - указатель на файл. Обращение к функции foреn в программе про­изводится так:

lst=fopen(спецификация файла, вид использования файла);

Спецификация файла может быть, например : C:\MY_FILE.TXT - для файла MY_FILE.TXT на диске C:; A:\MY_DIR\EX2_3.CPP - для файла ЕХ2_З.СРР в поддиректории A:\MY_DIR и т.п. Вид использования файла может быть:

r - открыть существующий файл для чтения;

w - создать новый файл для записи (если файл с указанным именем существует, то он будет переписан)

а - дополнить файл (открыть существующий файл для записи инфор­мации, начиная с конца файла, либо создать файл, если он не сущест­вует);

pb - открыть двоичный файл для чтения;

wb - создать двоичный файл для записи;

ab - дополнить двоичный файл;

rt - открыть текстовой файл для чтения;

wt - создать текстовой файл для записи;

at - дополнить текстовой файл;

г+ - открыть существующий файл для записи и чтения;

w+ - создать новый файл для записи и чтения;

а+ - дополнить или создать файл с возможностью записи и чтения;

r+b - открыть двоичный файл для записи и чтения;

w+b - создать двоичный файл для записи и чтения;

а+b - дополнить двоичный файл с предоставлением возможности записи и чтения.

Если режим t или b не задан (например, r, w или а), то он опре­деляется значением глобальной переменной _fmode. Если _fmode = 0_BINARY, то файлы открываются в двоичном режиме, а если _fmode =О_TEXT - в текстовом режиме. Константы 0_BINARY и O_TEXT определены в файле fсntl.h.

Строки вида r+b можно записывать и в другой форме: rb+. Если в результате обращения к функции foреn возникает ошибка, то она возв­ращает указатель на константу NULL. После окончания работы c файлом, он должен быть закрыт. Это делается с помощью библиотечной функции fclose. Она имеет следующий прототип:

int fclose(FILE *lst);

При успешном завершении функция fclose возвращает значение нуль.

Любое другое значение говорит об ошибке.

 

4.13.1.Вывод информации в файл

 

#include <stdio.h>

Void main (void)

{

char str[50];

FILE *rstr, *wstr, *pstr, *astr;

rstr = fopen ("c:\\my_file.txt", "rt");

wstr = fopen ("c:\\out_file.txt", "wt");

pstr = fopen ("prn", "wt");

astr = fopen ("c:\\out_plus.txt", "at");

while (fscanf (rstr, " %S ", str) !=EOF)

{

printf ( " Вывод на дисплей: %S\n", str);

fprintf (wstr, "%S\n", str);/*запись файла (прежнее содержание стирается)*/

fprintf (pstr, "%S\n", str); /* вывод на печать*/

fprintf (astr, "%S\n", str); /*дополнение файла*/

}








Дата добавления: 2016-04-14; просмотров: 589;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

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

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.016 сек.