Опубликован: 02.02.2011 | Уровень: для всех | Доступ: платный
Лекция 11:

Массивы: одномерные массивы

< Лекция 10 || Лекция 11: 1234 || Лекция 12 >

Обращение к элементам одномерного массива

Адресация элементов массива осуществляется с помощью индексированного имени. Синтаксис обращения к элементу массива:

ИмяМассива[ВыражениеТипаКонстанты];

или

ИмяМассива[ЗначениеИндекса];

Обращаться к элементам массива можно также посредством механизма указателей.

Таким образом, чтобы обратиться к элементу массива, надо указать имя массива и номер элемента в массиве (индекс).

Например:

a[0]индекс задается как константа,

d[55]индекс задается как константа,

s[i]индекс задается как переменная,

w[4*p]индекс задается как выражение.

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

Определение размера памяти для одномерных массивов

Массив занимает непрерывную область памяти. Для одномерного массива полный объем занимаемой памяти в байтах вычисляется по формуле:

Байты = sizeof (тип) * размер массива

Массив представляет собой набор однотипных данных, расположенных в памяти таким образом, чтобы по индексам элементов можно было легко вычислить адрес соответствующего значения. Например, пусть одномерный массив A состоит из элементов, расположенных в памяти подряд по возрастанию индексов, и каждый элемент занимает по k байт. Тогда адрес i -того элемента вычисляется по формуле:

адрес(A[i]) = адрес(A[0]) + i*k

Пример 1. Определение размера памяти одномерного массива.

#include "stdafx.h"
#include <iostream>
using namespace std;
#define v 4
#define p 3

int _tmain(int argc, _TCHAR* argv[]){
  const int q=4, r=1;
  int i_mas[10]; 
  int k=sizeof(i_mas);
  cout << "i_mas[10] занимает " << k << " байт\n";
  
  float f_mas[7]={2.0,4.5,8.3,7.0,1.0};
  int t=sizeof(f_mas);
  cout << "f_mas[7]={2.0,4.5,8.3,7.0,1.0} занимает "<< t <<"байт\n";

  double d_mas[2*q-r];
  int w=sizeof(d_mas);
  cout << "d_mas[2*q-r] занимает " << w << " байт\n"; 

  double d1_mas[2*v/p];
  int w1=sizeof(d1_mas);
  cout << "d1_mas[2*v/p] занимает " << w1 << " байт\n";  

  char c_mas[]="Программирование";
  int s=sizeof(c_mas);
  cout << "c_mas[]=\"Программирование\"занимает"<< s <<"байт\n";

  system("pause");
  return 0;
}

Результат выполнения программы:

i_mas[10] занимает 40 байт – 4 байта (тип int ) * 10 (количество элементов массива)

f_mas[7] = {2.0,4.5,8.3,7.0,1.0} занимает 28 байт – 4 байта (тип float ) * 7 (объявленное количество элементов массива)

d_mas[2*q-r] занимает 56 байт – 8 байт (тип double ) * 7 (вычисленное через формулу количество элементов массива)

d1_mas[2*v/p] занимает 16 байт – 8 байт (тип double ) * 2 (вычисленное через формулу количество элементов массива)

c_mas[]="Программирование" занимает 17 байт – 1 байт (тип char ) * 17 (16 знаков + нулевой байт '\0' )

Указатели и одномерные массивы

В языке С++ между указателями и массивами существует тесная связь. Например, когда объявлен массив int array[25], этим определяет не только выделение памяти для двадцати пяти элементов массива, но и для указателя с именем array. В языке С++ имя массива без индексов трактуется как адрес начального элемента. То есть имя массива является указателем на массив. Таким образом, доступ к элементам массива осуществляется через указатель с именем array.

Поскольку имя массива является указателем, допустимо, например, такое присваивание:

int arrаy[25];
int *ptr;
ptr=array;

Здесь указатель ptr устанавливается на адрес первого элемента массива, причем присваивание ptr = arrаy можно записать в эквивалентной форме ptr=&arrаy[0].

Адрес каждого элемента массива можно получить, используя одно из трех выражений:

Адрес в памяти 1000 1002 1004 1008 1008 ...
Индекс 0 1 2 3 4 ... 24
Значения 1 2 3 4 5 ... 25
Адрес i - го элемента
array
&array[0]
ptr
array +1
&array[1]
ptr + 1
array +2
&array[2]
ptr + 2
array +3
&array[3]
ptr + 3
array +4
&array[4]
ptr + 4
...
array +24
&array[24]
ptr + 24

А обращение к пятому элементу массива можно записать как:

array[4],    *( array + 4),      *(рtr + 4).

Эти операторы вернут пятый элемент массива.

Таким образом, С++ дает два способа обращения к элементу массива:

  • с помощью индексированного имени;
  • посредством арифметики с указателями.

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

Пример 2.

#include "stdafx.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[]){
  int array[10]; 
  int *p;
  p=&array[0];
  /*эквивалентные операции присваивания*/
  *array=2; printf("%d\n", array[0]);
  array[0]=2; printf("%d\n", array[0]);
  *(array+0)=2; printf("%d\n", array[0]);
  *p=2; printf("%d\n", array[0]);
  p[0]=2; printf("%d\n", array[0]);
  *(p+0)=2; printf("%d\n", array[0]);
  system("pause");
  return 0;
}

В результате выполнения любой из эквивалентных операций присваивания в данном примере начальному элементу массива присваивается значение 2, но быстрее всего компьютер выполнит операции *array=2 и *p=2, так как в них не требуется выполнять операции сложения.

< Лекция 10 || Лекция 11: 1234 || Лекция 12 >
Денис Курбатов
Денис Курбатов
Владислав Нагорный
Владислав Нагорный

Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки?

Спасибо!

Ольга Замятина
Ольга Замятина
Россия, Калиниград, РГУ им. И. Канта, 2009
Эдуард Санин
Эдуард Санин
Украина, Харьков, ХАИ