
- •Массивы
- •Указатели
- •Указатели и массивы
- •Арифметические операции над указателями
- •1. Одномерный массив
- •2. Двумерный массив
- •3. Использование дополнительного указателя
- •Динамическое распределение памяти
- •2. Одномерный массив
- •Выделение и освобождение памяти в стиле c
- •2 Освобождение памяти
- •Утечка памяти
- •Исползование ключевого слова const при объявлении указателей
- •Указатели и строки
- •Инициализация строки
- •Ввод строк в консольном приложении
- •Функции для работы со строками
- •Основные манипуляции со строками
- •Некоторые замечания по работе со строками
Выделение и освобождение памяти в стиле 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. Он всегда указывает на одну и ту же область памяти и значение, записанное по этому адресу, не может изменяться. |
Указатели и строки
|
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
#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;
}