- •Аннотация
- •Предисловие
- •Г л а в а 1. Введение в указатели
- •§1. Понятие указателя. Операции разыменования и разадресации
- •§2. Инициализация и присваивание указателей
- •§3. Передача параметров функций с помощью указателей.
- •§4. Распределение динамической памяти.
- •4.1. Операция new
- •4.2. Операция delete
- •Упражнения, тесты.
- •Указатели и массивы
- •§1. Связь указателей и массивов
- •1.1. Указатели и одномерные массивы
- •1.2. Указатели и матрицы
- •Int MyFun (int *X, int n)
- •§3. Операции над указателями при работе с массивами.
- •3.1. Арифметические операции
- •3.2. Операции сравнения.
- •§4. Использование операций над указателями при работе с одномерными массивами
- •4.1. Использование индексов
- •4.2. Указатель в качестве параметра цикла
- •4.3. Использование указателя и индекса
- •§5. Строки.
- •5.1. Общая характеристика строк.
- •5.2. Примеры алгоритмов работы со строками.
- •5.3. Анализ строковых функций.
- •§6. Использование операций над указателями при работе со статической матрицей.
- •Упражнения, тесты.
- •Массивы указателей
- •§1. Статический массив указателей
- •§2. Частично динамическая матрица.
- •Int arr_of_size[n];
- •§3. Статический массив строк
- •§4. Динамический массив указателей
- •4.1. Указатель на указатель
- •4.2. Динамические “матрицы”.
- •Int *arr_of_size;
- •4.3. Передача матрицы в функцию
- •Int a[10]; FunArr1(a, 10,…);
- •Упражнения, тесты.
- •Задачи второго среднего уровня.
- •Структуры и другие типы, определяемые пользователем
- •§1. Структуры
- •Объявление структуры
- •1.2. Работа со структурой.
- •1.3. Вложенные структуры и статические массивы в структурах
- •1.4. Статический массив структур
- •§2. Cтруктуры и указатели
- •2.1. Указатели в структуре.
- •2.2. Указатели на структуру
- •2.3. Динамический массив структур
- •2.4. Ссылка на структуру.
- •2.5. Указатели и вложенные структуры
- •§3. Cтруктуры и функции
- •3.1. Передача полей структуры в функцию.
- •Void MyFun1 (int X, float &y, int *u1, float *u2, char *s);
- •3.2. Передача всей структуры в функцию
- •Void Fun1 (tst s,…);
- •Void Fun2 (tst & s,…);
- •Void Fun3 (tst* s,…);
- •§4. Cтруктуры и классы.
- •§5. Объединения.
- •Представление вещественных чисел в памяти компьютера.
- •§6. Поля битов (битовые поля)
- •Ввод в ы в о д
- •Symbol Code16 Code10 Code2
- •§7. Перечисления
- •Какие из строк (//1 – //9) правильные?
Int a[10]; FunArr1(a, 10,…);
так и динамический:
int *d; int n; cin>>n; d= new int[n]; FunArr1(d, n, …);
В случае с матрицей это не совсем так. Пусть объявлена статическая матрица
const Nc=5, Mc=10; int C[Nc][Mc];
Передать её в функцию нельзя, то есть вызов
FunMatr(C, Nc, Mc);
приведёт к ошибке компиляции.
Пример. (+).
Передача матрицы в функцию с помощью указателей. Кроме этого здесь дополнительно показано, как передать формат стандартной функции вывода printf в качестве параметра функции.
void MyFun1 (int **X, int , int ); // или void MyFun1 (int *X[],int , int );
void MyFun2 (int *X[],int , int ); //или void MyFun2 (int **X,int , int );
void MyPrint (int **X, int , int, int, char* );
int main()
{
/* Создание “полностью” динамической матрицы, которая объявляется как динамический массив из N указателей. Обе размерности – переменные.*/
int ** A; int N=3, M=4;
A=new int *[N];
for (int i=0; i<N; i++) A[i]=new int [M];
/* В функцию передаём полностью динамическую матрицу. */
MyFun1(A,N,M);
/* Сначала выводим указанный текст, а затем матрицу A размерности N*M по формату “%5d” */
MyPrint(A,N,M,5,"\n The first test\n");
//Удаляем матрицу
for (int i=0;i<N;i++) delete[]A[i];
delete[]A;
/* Создание “частично” динамической матрицы, которая объявляется как статический массив указателей фиксированной размерности Nconst. Другими словами, количество “строк” фиксировано (Nconst), а количество элементов в строке произвольное: M2 – не константа, а переменная (см. 5.3) */
const Nconst=8; int M2=6;
int *B[Nconst];
/* Для такой полудинамической матрицы B=new int *[Nconst]; не надо. Будет ошибка!!!!!!! */
for (int i=0; i<Nconst; i++)
B[i]=new int [M2];
/* Передаём полудинамическую матрицу */
MyFun2(B,Nconst,M2);
MyPrint(B,Nconst,M2,3,"\n \nThe second test\n");
//Удаляем матрицу B
for (int i=0;i<Nconst;i++)
delete[]B[i];
getch(); return 0;
}
void MyFun1 (int **X, int n, int m)
// или void MyFun1 (int *X[], int n, int m)
{
for (int i=0; i<n; i++)
for (int j=0;j<m;j++)
X[i][j]=(i+1)*(j+1);
// Перестановка 0-й и (n-1)-й строк
int* t;
t=X[0]; X[0]=X[n-1]; X[n-1]=t;
}
void MyFun2 (int *X[], int n, int m)
// или void MyFun2 (int **X, int n, int m)
/* Определяем элементы матрицы. */
{
for (int i=0; i<n; i++)
for (int j=0;j<m;j++)
if (i%2) X[i][j]=(i+1)-(j+1);
else X[i][j]=(i+1)+(j+1);
}
void MyPrint (int **X, int n , int m, int L, char* t )
{
// Формируем формат “%Ld”, где L – переданное в функцию целое число…
char AnyFormat[10],
StrL[3];
/* … для хранения переведенного в строку c помощью встроенной функции itoa целого числа L */
strcpy(AnyFormat, "%");
strcat(AnyFormat,itoa(L,StrL,10));
strcat(AnyFormat,"d");
puts(t);
for (int i=0; i<n; i++)
{
for (int j=0;j<m;j++)
printf(AnyFormat,X[i][j]);
cout<<endl;
}
}
§5. Динамический массив строк (+).
По аналогии с динамической матрицей можно создать динамический массив строк. Для этого объявляем динамический массив указателей как указатель на указатель символа:
char **s;
Объявляем и определяем количество строк:
int n; cin>>n;
Аналогично резервируем память для массива указателей на строки
s=new char*[n];
В цикле резервируем память для каждой строки. Размер её определяем с помощью вспомогательной строки t, длина которой, а, значит и длина каждой строки, не более 40 символов:
char *t; t=new char[40];
for(int i=0; i<n; i++)
{ gets(t);
s[i]=new char[strlen(t)];
strcpy(s[i], t);
}
Работу с таким массивом рассмотрим на примере сортировки массива строк.
for(int j=0; j<n; j++)
for(int i=0; i<n-1; i++)
if (s[i][0]>s[i+1][0]) //Сравнение первых символов строк
//if (strcmp(s[i],s[i+1])>0) // или сравнение двух строк
{ // Перестановка двух строк
strcpy(t,s[i]); // копирование s[i] в t
strcpy(s[i],s[i+1]);
strcpy(s[i+1],t);
}
for(int i=0;i<n;i++) puts(s[i]); // Вывод строк
//Освобождение памяти особенностей не имеет.
for (int i=0; i<n;i++)
delete []s[i]; // Удаление каждой строки из памяти
delete []s; // Удаление массива указателей из памяти
delete []t; // Удаление вспомогательной строки из памяти
В качестве повторения заметим, что два варианта сравнения
if (s[i][0]>s[i+1][0]) …
и
if(strcmp(s[i],s[i+1])>0) …
выполняются по-разному. В первом случае сравниваются только первые символы соседних в массиве строк и независимо от результата следующие символы в сравнении не участвуют. С помощью функции strcmp выполняется сравнение так, как было описано в теме “строки” (см. §5 главы 2).