Главная

Категории:

ДомЗдоровьеЗоологияИнформатикаИскусствоИскусствоКомпьютерыКулинарияМаркетингМатематикаМедицинаМенеджментОбразованиеПедагогикаПитомцыПрограммированиеПроизводствоПромышленностьПсихологияРазноеРелигияСоциологияСпортСтатистикаТранспортФизикаФилософияФинансыХимияХоббиЭкологияЭкономикаЭлектроника






Указатели, массивы и арифметика указателей.


Уже отмечалось, что имя массива является указателем на первый (нулевой) элемент массива. Следующий пример иллюстрирует это утверждение:

int tacs[3];

tacs[0] = 43; // присваиваем значение нулевому элементу

*tacs = 2; // или так присваиваем новое значение нулевому элементу

*(tacs + 1) = 4; // присваиваем значение первому элементу

 

По видимому, нет необходимости обращаться к i-му элементу массива, используя выражение *(tacs + i), а не tasc[i].Однако знать о такой возможности следует.

Такой же принцип доступа к элементам массива сохраняется и для многомерных массивов. Так, доступ к элементу двумерного массива можно получить обычным способом: mass[i][j],а можно так: *(mass[i] + j) или *(* (mass +i)+j).

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

С указателями можно выполнять следующие операции: разыменования (*), присваивания, сложение с константой, вычитание указателей, инкремента (++), декремента (--), приведения типов.

Из приведенного выше примера можно понять, что операция инкремента перемещает указатель к следующему элементу массива, а декремента – к предыдущему. Само значение указателя изменяется на величину, соответствующего типа, выраженного в байтах. Например,

int *pint = new int [3]; // выделена память под массив из трех элементов

p++; // значение увеличивается на 4

Разность двух указателей дает число, равное разности адресов, деленное на размер типа, выраженное в байтах. Не допускается сложение указателей.

При использовании нескольких операций, следует помнить об их приоритете. Так выражение

*pint++ = 12;

следует понимать так

*pint = 12; pint++; // по адресу связанному с pint пишется значение 12

// затем значение pint увеличивается

 

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

(*pint)++; // значение по адресу pint увеличивается на единицу &&&&

Следующий фрагмент кода копирует элементы массива в другой массив[5]. Из возможных способов выбран тот, который иллюстрирует особенности арифметики указателей:

int a [100], b[100];

int *pa = a; // или int *pa = &a[0];

int *pb = b;

for (int i=0;i<100; i++)

*pb++ = *pa++; // или b[i]=a[i];

Контрольные вопросы и задания.

1. Почему в приведенной ниже программе значение элемента массива p[2] становится неопределнным? Почему p[0] становится равным 2?

#include <iostream.h>

Void main()

{ int na =0;

int *p = new int[3];

p[0]=0;

p[1]=2;

p[2]=3;

cout<<p<<endl; // адрес элемента p[0];

*p++=12;

cout <<p[0]<<'\t'<<p[1]<<'\t'<<p[2];

}

2. Измените предыдущую программу, заменив выражение *p++ на (*p)++ . Что получится со значениями элементов массива?

Структуры

v Структуры - это составной объект, в который входят элементы любых типов, за исключением функций.

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

Struct student // за ключевым именем struct следует имя нового типа

{ // открывающиеся скобки

char name[20]; //

Int age; // элементы структуры

int id; //

}; // скобки и точка с запятой заканчивают описание

Где следует размещать определение структуры? Возможные варианты – внутри функции main() или перед ней. Чаще используют внешнее определение структуры, так как в этом случае возможно использование ее во всех функциях, следующих далее.

В приведенном примере шаблон student описывает новый тип данных, поэтому можно создавать переменные этого типа:

student victor;

Для обращения к элементам структуры используется оператор принадлежности ‑ точка (.), например,victor.age.

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

Структуры могут образовывать массив структур, например:

student group[35];

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

#include <iostream.h>

// определение нового типа данных

Struct time

{

int hours;

int mins;

}; // конец определения структуры, не забудьте точку с запятой

Void main()

{

time day1={5,45}; // определение и инициализация структуры

time day2={4,55}; // типа time

time sumt;

sumt.mins=(day1.mins+day2.mins)%60;

sumt.hours=(day1.hours+ day1.hours)+(day1.mins+day2.mins)/60;

cout<<sumt.hours<<” hours ”<<sumt.mins<<” minutes\n”;

}

Так как для размещения структуры может понадобиться значительный объем памяти, для этого типа данных также предусмотрено динамическое связывание с помощью оператора new.Для структуры time из последнего примера сначала выделим память, достаточную для размещения структуры:

time * pday = new time;

При этом pday – не имя структуры, а ее адрес. Доступ к элементам динамически созданной структуры осуществляется с помощью стрелочного оператора (->). Таким образом, pday->hours – это элемент hoursуказанной структуры.

#include <iostream.h>

Struct time

{

int hours;

int mins;

};

Void main()

{

time *pday=new time;

pday->hours=60;

cout<<pday->hours;

delete pday;

}

þ Помните, если для объявления структуры используется имя структуры, используйте точку. А если идентификатор – указатель на структуру, используйте стрелочный оператор.

После использования динамически объявленной структуры следует очистить область памяти с помощью оператора delete.

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



Последнее изменение этой страницы: 2016-07-22

headinsider.info. Все права принадлежат авторам данных материалов.