Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Otveti_k_programm.doc
Скачиваний:
0
Добавлен:
26.09.2019
Размер:
1.55 Mб
Скачать

Двумерные массивы

С позволяет создавать многомерные массивы. Простейшим видом многомерного массива является двумерный массив. Двумерный массив – это массив одномерных массивов. Двумерный массив объявляется следующим образом:

тип имя_массива [ размер второго измерения][размер первого измерения];

Следовательно, для объявления двумерного массива целых с размером 10 на 20 следует написать:

int d[10][20];

Двумерные массивы сохраняются в виде матрицы, где первый индекс отвечает за строку, а второй за столбец.

Число байт в памяти, требуемых для размещения двумерного массива, вычисляется следующим образом:

число байт = размер второго измерения * размер первого измерения * sizeof(базовый тип)

  1. Массивы. Связь массивов и указателей. Доступ к элементам массива с помощью указателей.

Любой указатель может быть проиндексирован, как будто это массив. Например:

int *p, i[10];

p = i;

p[5] = 100; /* присвоение с помощью указателя */

(p+5) = 100; / * присвоение с помощью арифметики с указателями */

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

Для этого используется оператор разыменования ∗. Индексация производится с помощью операторов +,− и перегруженных операторов ++, −−.

Следующий пример иллюстрирует такой способ доступа к элементам массива.

void f() {

typedef unsigned long int* paddr_t;

char hello[] = "Hello world!";

char* ptr = hello;

char* first = hello;

cout.setf(std::ios_base::dec,std::ios_base::basefield);

while ( *ptr ) {

cout << ptr - first << "\'s element:" << *ptr << endl;

ptr++;

}

}

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

Код C++ Обычная передача символьного массива в функцию

==================

#include <conio.h>

#include <iostream.h>

const maxL=256;

void get_array(char S[])

{

S[0]='9'; //изменили первый символ

cout<<S<<endl;

}

void main()

{

clrscr();

char S[maxL]=""; //Инициализируем строку для очистки от мусора

cin.getline(S,maxL); //Ввели символьный массив с клавиатуры

get_array(S); //Передали массив в функцию

getch();

return;

}

==================

Код C++ Передача символьного массива в функцию с помощью указателя

==================

#include <conio.h>

#include <iostream.h>

const maxL=256;

void get_array(char *S)

{

S[0]='9'; //изменили первый символ

}

void main()

{

clrscr();

char S[maxL]=""; //Инициализируем строку для очистки от мусора

cin.getline(S,maxL); //Ввели символьный массив с клавиатуры

get_array(S); //Передали массив в функцию

cout<<S<<endl;

getch();

return;

}

==================

Код C++ Передача символьного массива в функцию с помощью ссылки

==================

#include <conio.h>

#include <iostream.h>

const maxL=256;

void get_array(char (&S)[maxL])

{

S[0]='9'; //изменили первый символ

}

void main()

{

clrscr();

char S[maxL]=""; //Инициализируем строку для очистки от мусора;

cin.getline(S,maxL); //Ввели символьный массив с клавиатуры

get_array(S); //Передали массив в функцию

cout<<S<<endl;

getch();

return;

}

==================

  1. Операторы свободной памяти new и delete.

унарные операторы new и delete служат для управления свободной памятью. Что такое свободная память? Свободная память - это предоставляемая системой область памяти для объектов, время жизни которых напрямую управляется программистом. Программист создает объект с помощью ключевого слова new (переводится с английского как ''новый''), а уничтожает его, используя delete (переводится с английского как ''удалить'').

В С++ оператор new принимает следующие формы:

new имя_типа;

new имя_типа (инициализатор);

new имя_типа [выражение];

В каждом случае происходит по крайней мере два эффекта. Во-первых, выделяется надлежащий объем свободной памяти для хранения указанного типа. Во-вторых, возвращается базовый адрес объекта (в качестве значения оператора new ). Когда память недоступна, оператор new возвращает значение 0 (NULL). Следовательно, мы можем контролировать процесс успешного выделения памяти оператором new. Рассмотрим следующий пример использования оператора new:

int *p, *q;

p=new int (5); //выделили память и инициализировали

q=new int [10]; //получаем массив от q[0] до q[9]

В этом фрагменте указателю на целое р присваивается адрес ячейки памяти, полученный при размещении целого объекта. Место в памяти, на которое указывает р, инициализируется значением 5. Такой способ обычно не используется для простых типов вроде int, так как гораздо удобнее и естественнее объявить переменную привычным для нас образом. А вот использование примера с указателем q на массив встречается значительно чаще. Это, так называемые, динамические массивы (пример использования динамического массива приводится в конце данного материала).

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

delete выражение;

delete [] выражение;

Первая форма используется, если соответствующее выражение new размещало не массив. Во второй форме присутствуют пустые квадратные скобки, показывающие, что изначально размещался массив объектов. Оператор delete не возвращает значения, поэтому можно сказать, что возвращаемый им тип - void.

  1. Работа с динамическими массивами.

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

Описание массива:

Создание динамического массива

#include <iostream>

using namespace std;

int main()

{

int num; // размер массива

cout << "Enter integer value: ";

cin >> num; // получение от пользователя размера массива

int *p_darr = new int[num]; // Выделение памяти для массива

for (int i = 0; i < num; i++) {

// Заполнение массива и вывод значений его элементов

p_darr[i] = i;

cout << "Value of " << i << " element is " << p_darr[i] << endl;

}

delete [] p_darr; // очистка памяти

return 0;

}

Синтаксис выделения памяти для массива имеет вид указатель = new тип[размер]. В качестве размера массива может выступать любое целое положительное значение.

  1. Строки в языке С++.

Си не поддерживает отдельный строковый тип данных, но он

все же предусматривает два слегка отличающихся подхода к опре- 101

делению строк. Один состоит в использовании символьного масси-

ва, другой заключается в использовании указателя на символ.

Рассмотрим использование символьного массива для определе-

ния строки:

#include<string.h>

main ()

{

char msg[30];

strcpy(msg, "Hello, world");

puts(msg);

}

Выражение [30] после msg предписывает компилятору выделить

память для 29 символов, т.е. для массива из 29 переменных типа

char (30-е знакоместо должно быть заполнено нулевым символом –

\0.

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

строк, – это указатель на символы. Рассмотрим программу:

main()

{

char *msg;

msg = "Hello, world";

puts(msg);

}

Звездочка (*) впереди msg указывает компилятору, что msg яв-

ляется указателем на символ. Другими словами, msg может хранить

адрес некоторого символа.

s.assign(str) - присваивает строке s значение строки str. Аналогично записи s=str;

int i=s.begin() - записывает в i индекс первого элемента строки

int i=s.end() - аналогично, но последнего

s.clear() - как следует из названия, отчищает строку. Т.е. удаляет все элементы в ней

s.compare(str) -сравнивает строку s со строкой str и возвращает 0 в случае совпадение (на самом деле сравнивает коды символов и возвращает из разность)

s.copy(куда, сколько, начиная с какого) - копирует из строки s в куда (там может быть как строка типа стринг, так и строка типа char). Последние 2 параметра не обязательные (можно использовать функцию с 1,2 или 3 параметрами)

bool b=s.empty() - если строка пуста, возвращает true, иначе false

s.erase(откуда, сколько) удаляет n элементов с заданной позиции

s.find(str,позиция) - ищет строку str начиная с заданной позиции

s.insert(позиция,str, начиная, beg, count) - вставляет в строку s начиная с заданной позиции часть строки str начиная с позиции beg и вставляя count символов

int len=s.length() - записывает в len длинну строки

s.push_back(symbol) - добавляет в конец строки символ

s.replace(index, n,str) - берет n первых символов из str и заменяет символы строки s на них, начиная с позиции index

str=s.substr(n,m) - возвращает m символов начиная с позиции n

s.swap(str) меняет содержимое s и str местами.

s.size() - возвращает число элементов в строке.

Вот собственно большинство необходимых функция для работы со строками в с++.

  1. Пользовательские типы данных: структуры. Определение, инициализация, доступ к полям структуры.

Структура – это конгломерат элементов различного типа. До-

пустим, вы хотите сохранить информацию о звезде: ее имя, спек-

тральный класс, координаты и т.д. Вы можете описать это следую-

щим образом:

typedef struct {

char name[25];

char class;

short subclass;

float decl,RA,dist;

} star ;

Здесь определена структура (struct) типа star.

Сделав такое опи-

сание в начале своей программы, вы можете дальше использовать

этот определенный вами тип данных:

main()

{

star mystar; 111

strcpy(mystar.name,"Епсилон Лебедя");

mystar.class = 'N';

mystar.subclass = 2;

mystar.decl = 3.5167;

mystar.RA = -9.633;

mystar.dist = 0.303;

/* конец функции main() */

}

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

// Определение массива структур и указателя на структуру:

struct {

char f1o[30];

int date, code;

double salary;

}staff[100], *ps;

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

struct{

char fio[30];

int date, code;

double salary;

}worker = {"Страусенке". 31. 215. 3400.55};

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

struct complex{

float real, im;

} compl [2][3] = {

{{1. 1}. {1. 1}. {1. 1}}. // строка 1. TO есть массив compl[0]

{{2. 2}. {2. 2}. {2. 2}} // строка 2. то есть массив compl[1]

};

Доступ к полям структуры выполняется с помощью операций выбора . (точка) при обращении к полю через имя структуры и -> при обращении через указатель, например:

Worker worker, staff[100], *ps;

worker.fio = "Страусенке";

staff[8].code = 215;

ps->salary = 0.12;

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

struct А {int а; double х;};

struct В {А а; double х;} х[2];

х[0].а.а = 1;

х[1].х = 0.1;

Как видно из примера, поля разных структур могут иметь одинаковые имена, поскольку у них разная область видимости. Более того, можно объявлять в одной области видимости структуру и другой объект (например, переменную или массив) с одинаковыми именами, если при определении структурной переменной использовать слово struct, но не советую это делать — запутать компилятор труднее, чем себя.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]