Можно объявить одномерный массив без указания числа элементов.
int nAr[][3]={{1,2,3},{2,3,4},…{7,5,8}} //не указано количество строк
Обращение к элементу массива. Оператор [].
Доступ к отдельным элементам массива может выполняться с помощью индексов (они нумеруются с 0, а не с 1). Индекс может быть любым целым выражением.
char Ar[10];
char c=Ar[0];
c=Ar[g];
c=Ar[i]; //i-int
c=Ar[i+g-k]; // c=Ar[3.48]; ERROR!!
float b;
c=Ar[(int)b]; //приводит к типу int (может быть потеря данных)
size of – количество памяти, которое занимает массив
char ar[]=”abc”;
size_t n=sizeof(ar)/sizeof(char)
n=sizeof(ar)/sizeof(ar[0]);
int ar[][3]={1,2,3,4,5,6,7};
size_t n=sizeof(ar)/sizeof(int);
n=sizeof(ar[0])/sizeof(ar[0][0]) //подсчёт элементов в строке
n=sizeof(ar)/sizeof(ar[0]); //подсчёт числа строк в массиве
ar[]={2,4,5,8};
n=sizeof(ar)/sizeof(ar[0]);
Связь массивов и указателей.
Имя одномерного массива компилятор интерпретирует как константный указатель на нулевой элемент массива.
ar[0]=1
ar[1]=2
ar[2]=3
ar[3]=4
ar[4]=5
ar
p
В памяти:
int *p=ar;
int *int [];
int tmp=ar[i];
равнозначно
tmp=p[i];
tmp=*(p+i);
tmp=*(ar+i);
переместим указатель к следующему элементу массива, но не ar++(ошибка!)
p++; //ar++i
Двумерные массивы.
Двумерные массивы можно представить как одномерный, каждым элементом которого является строка (т.е. одномерный массив). Имя двумерного массива компилятор интерпретирует как константный указатель на нулевую строку.
int ar[2][3]={{1;2;3},{4;5;6}};
ar[0][0]=1
ar[0][1]=2
ar[0][2]=3
ar[1][0]=4
ar[1][1]=5
ar[1][2]=6
int ar[N][M];
int sum!=0;
for (int i=0; i<N; i++)
{
for (int j=0; j<M; j++)
sum+=ar[i][j];
int *p=&ar[0][0];
for (int i=0; i<sizeof(ar)/sizeof(int); i++)
{
sum+=*p;
p++;
}
}
Трёхмерные массивы.
Имя трёхмерного массива компилятор интерпретирует как константный указатель на нулевой слой (нулевой двумерный массив).
int ar[2][3][4]={{{1,2,3,4},{5,6,7,8},{9,10,11,12}},{{-1,-2,-3,-4},{-5,-6,-7,-8},{-9,-10, -11,-12 }}}
Массивы указателей.
char *ar[20];
char *ar[]={ “One”,”Two”,”Three” };
char ar1[][6]={ “One”,”Two”,”Three” };
char ar1[3][6];
Т.к. в запрещённом режиме строковые литералы, расположенные в области памяти, защищены от записи, попытка изменить их вызовет ошибку времени выполнения.
ar1[1][1]= //ar[1][1]=”D”; - ошибка!
Динамическое распределение памяти.
malloc
calloc
realloc
free
int Mbyte=…;
int *p=static_cast<int*>(malloc(Mbyte));
if (p)…
size_t n=_msize(p)
calloc - обнуляет содержимое памяти
realloc - изменяет размер ранее захваченного блока памяти
p=ststic_cast<int*> realloc(p,2000);
free - освобождается выделенная память
free(p)
Управление памятью. Оператор new и delete.
Преимущество new и delete:
Необязательно явно указывать количество требуемых байт;
2. результатом выделившейся памяти с помощью malloc является указатель с типом <void *>, в случае использования new: компилятор неявно приводит тип указателя к указанному типу;
Оператор new совмещает выделившуюся память с вызовом инициализирующей функции;
int *p=new int; //sizeof(int)
malloc(4)
int *p=operator new (sizeof(int));
При динамическом выделении памяти из-за большого количества информации, «накладные» расходы достаточно велики.
delete(p);
Оператор new и массивы.
Создавать массивы следует только тогда, когда:
Все или некоторые размерности массива определяются только во время выполнения программы;