Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
c++ / L_4.doc
Скачиваний:
105
Добавлен:
02.04.2015
Размер:
120.83 Кб
Скачать

Выделение и освобождение памяти в стиле c

1 Выделение памяти

void *malloc(size_t num_bytes);

size_t – разновидность целочисленного типа

num_bytes – количество байтов запрашиваемой памяти

Функция malloc() возвращает указатель типа void, который играет роль обобщенного указателя.

Чтобы из этого обобщенного указателя получить указатель на нужный тип, надо использовать операцию приведения типов. В результате успешного вызова функция возвратит указатель на первый байт области динамической памяти. Если памяти не окажется, то функция malloc() возвращает нулевой указатель.

2 Освобождение памяти

void free (void *ptr);

ptr – указатель на ранее выделенную память.

НЕ СЛЕДУЕТ СМЕШИВАТЬ функции malloc() и free() с операторами new и delete в одной программе

4. Пример

#include <iostream.h>

#include <conio.h>

#include <stdlib.h> // Необходимо подключение библиотеки

int main()

{

int *p;

p=(int *) malloc(sizeof (int));

if (!p)

{ cout << “Нет памяти\n";

return 1;

}

*p=10;

cout << *p<<endl;

free(p);

getch();

return 0;

}

Утечка памяти

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

unsigned short int *p;

p=new unsigned short int;

*p=100; // надо delete p;

p=new unsigned short int;

*p=120;

// память, содержащая значение 100 – не доступна

Исползование ключевого слова const при объявлении указателей

const int *pOne;

pOne-указатель на константу int

Значение, на которое он указывает, изменять нельзя

int *const pTwo;

pTwo является константным указателем на тип int.

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

const int *const pThree;

pThree объявлен как константный указатель на константу типа int.

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

Указатели и строки

  • Строка – это массив символов, заканчивающийся нулевым байтом \0

  • Если строка должна содержать N символов, то в описании массива следует указать N+1 символ для учета нулевого байта

char str[80];

char *p1,ch;

p1=str; // имя массива без индекса образует указатель на начало

//массива

ch=str[4];// обращение к 5-ому элементу массива

ch=*(p1+4); // обращение к 5-ому элементу массива

Инициализация строки

char a[]={"Пример”};//строковая константа; Нулевой байт поставит

//компилятор

printf("%s",a);

Ввод строк в консольном приложении

Функция

Назначение

scanf(“%s”,&s1)

Вводит символы до первого пробельного символа

gets(s1)

Позволяет вводить строки, содержащие пробелы

Функции для работы со строками

Функция

Что делает

strcpy(s1,s2)

Копирует содержимое строки s2 в строку s1

Нельзя присваивать s1=s2 !!!

strcat(s1,s2)

Присоединяет строку s2 к строке s1 и помещает в массив s1.

strcmp(s1,s2)

Сравнивает строки s1 и s2 и возвращает 0, если строки равны. Если s1 лексиграфически (в смысле словаря) больше s2 ,то возвращается положительное значение,

если меньше - отрицательное

strlen(s1)

Возвращает длину строки s1,без учета нулевого байта \0

#include <string.h> // подключение библиотеки обязательно

……..

char s1[10],s2[10]; // объявлены строки

strcpy(s1,"Пот");

strcpy(s2,"Пол");

printf("=%i",strcmp(s1,s2)); // число положительное, т.к. т>л

Пример – Разбор предложения на лексемы

#include <stdio.h>

#include <conio.h>

main()

{

char str[80];

char token[80];

char *p,*q;

for (int i=0;i<80;i++)// заполнение массива нулевыми байтами

{

str[i]='\0';

token[i]='\0';

}

puts("Input text\n");

gets(str);

p=str; // указатель на 1-й символ строки-массива str

while (*p) // Пока в строке обнаруживается ненулевой символ

{

q=token; //указатель на начало массива token

while ((*p !=' ') && *p) //пока не найден пробел и не достигнут //конец строки (не найден символ 0) считываются символы из //строки str в строку token.

{

*q=*p;

q++; p++; // увеличение адресов

}

if (*p= = ' ') p++;// если найден пробел, то пропуск пробела

*q='\0';// завершение лексемы нулевым символом

printf("%s\n",token); // печать лексемы и перевод строки

}

getch();

}

Массивы строк

char str_arr[10][80] // объявление массива для хранения 30 строк

// длиной 80 символов

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

gets(str_arr[2])


Пример

#include <iostream>

#include <cstdio>

using namespace std;

int main()

{

int i;

char text[5][80];

char v[80];

сhar *k;

for (int t=0; t<5; t++)

{

cout<<t<<": ";

gets(text[t]);

if (!text[t][0]) break; // Выход из цикла по пустой строке

}

for (int t=0; t<5 ;t++) // Отображение строк на экране

{

cout<<text[t]<<endl;

}

strcpy(v,text[2]);

cout<<v<<endl;

k=new char[80]; // динамическое выделение памяти

// k=new char[strlen(text[0])+1]; // можно так

strcpy(k,text[2]); // копирование строки в новую область

// памяти

cout<<k<<endl;

delete [] k;

system("pause");

return 0;

}

Класс string

  • Класс string обеспечивает альтернативу для строк с завершающим нулем

  • Для использования строкового класса необходимо включить заголовок <string>

Причины для включения класса string:

  • самостоятельный тип данных

  • безопасность ( границы массива не могут быть нарушены)

  • удобство для программиста

Для объектов класса string определены операторы

Оператор

Описание

=

Присваивание

+ и +=

Конкатенация и присваивание с конкатенацией

==

Равенство

!=

Неравенство

< и <=

Меньше и меньше или равно

> и >+

Больше и больше или равно

<<

Вывод

>>

Ввод

Пример с использованием класса string

#include <iostream>

#include <string>

using namespace std;

int main()

{

string s1,s2,s3;

s1="aaaaaaa";

s2=s1;

s3=s1+s2;

cout<< s1<<endl;

cout<< s2<<endl;

cout<< s3<<endl;

system(“pause”);

return 0;

}

Соседние файлы в папке c++