Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> Язык C

Освоение указателей и многомерных массивов в C

В языке C массив — это совокупность значений одного типа, хранящихся в непрерывных ячейках памяти. Каждый элемент массива (одномерного или многомерного) идентифицируется одним или несколькими уникальными целочисленными индексами.

С другой стороны, указатель хранит адрес переменной. Адрес 0-го элемента массива является указателем массива. Вы можете использовать «оператор разыменования» для доступа к значению, на которое ссылается указатель.

Вы можете объявить одномерный, двумерный или многомерный массив в C. Термин «размерность» относится к количеству индексов, необходимых для идентификации элемента в коллекции.

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

В одномерном массиве каждый элемент идентифицируется одним целым числом:

int a[5] = {1, 2, 3, 4, 5};

Здесь число «1» находится в нулевом индексе, «2» в индексе 1 и т. д.

Переменная, хранящая адрес 0-го элемента, является его указателем –

int *x = &a[0];

Проще говоря, имя массива тоже указывает на адрес 0-го элемента. Итак, вы также можете использовать это выражение –

int *x = a;

Пример

Поскольку значение указателя увеличивается на размер типа данных, «x++» перемещает указатель на следующий элемент массива.

#include <stdio.h>
int main(){
 int arr[] = {1, 2, 3, 4, 5};
 int length = sizeof(arr) / sizeof(arr[0]);
 int i = 0;
 int *ptr = arr;
 while (i < length){
 printf("arr[%d]: %d \n", i, *(ptr + i));
 i++;
 }
 
 return 0;
}

Вывод

Когда вы запустите этот код, он выдаст следующий результат –

arr[0]: 1
arr[1]: 2
arr[2]: 3
arr[3]: 4
arr[4]: 5

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

Если одномерный массив похож на список элементов, то двумерный массив похож на таблицу или матрицу.

Можно считать, что элементы двумерного массива логически расположены в строках и столбцах. Следовательно, местоположение любого элемента определяется двумя индексами:номером строки и номером столбца. Индексы строк и столбцов начинаются с «0».

int arr[2][2];

Такой массив представлен как —

Col0 Колонка 1 Кол2 Row0arr[0][0]arr[0][1]arr[0][2]Row1arr[1][0]arr[1][1]arr[1][2]Row2arr[2][0]arr[2][1]arr[2][2]

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

Здесь мы объявляем двумерный массив с тремя строками и четырьмя столбцами (число в первой квадратной скобке всегда относится к количеству строк) как —

int arr[3][4] = {
 {1, 2, 3, 4},
 {5, 6, 7, 8},
 {9, 10, 11, 12}
};

Компилятор выделит память для вышеуказанного двумерного массива построчно. Предполагая, что первый элемент массива находится по адресу 1000, а размер типа «int» составляет 4 байта, элементы массива получат следующие выделенные ячейки памяти —

Строка 0 Строка 1 Строка 2 Значение123456789101112Адрес100010041008101210161020102410281032103610401044

Мы присвоим адрес первого элемента массива num указателю ptr, используя адрес оператора &.

int *ptr = &arr[0][0];

Пример 1

Если указатель увеличивается на 1, он перемещается к следующему адресу. Доступ ко всем 12 элементам массива «34» можно получить в цикле следующим образом:

#include <stdio.h>
int main(){
 int arr[3][4] = {
 {1, 2, 3, 4},
 {5, 6, 7, 8},
 {9, 10, 11, 12},
 };
 // pointer ptr pointing at array num
 int *ptr = &arr[0][0];
 int i, j, k = 0;
 // print the elements of the array num via pointer ptr
 for (i = 0; i < 3; i++){
 for (j = 0; j < 4; j++){
 printf("%d ", *(ptr + k));
 k++;
 }
 printf("\n");
 }
 
 return 0;
}

Вывод

Когда вы запустите этот код, он выдаст следующий результат –

1 2 3 4 
5 6 7 8 
9 10 11 12

В общем случае адрес любого элемента массива можно получить по следующей формуле —

add of element at ith row and jth col = baseAddress + [(i * no_of_cols + j) * sizeof(array_type)]

В нашем массиве 34

add of arr[2][4] = 1000 + (2*4 + 2)*4 = 1044

Вы можете обратиться к приведенному выше рисунку, который подтверждает, что адрес «arr[3][4]» равен 1044.

Пример 2

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

#include <stdio.h>
int main(){
 // 2d array
 int arr[3][4] = {
 {1, 2, 3, 4},
 {5, 6, 7, 8},
 {9, 10, 11, 12}
 };
 int ROWS = 3, COLS = 4;
 int i, j;
 // pointer
 int *ptr = &arr[0][0];
 // print the element of the array via pointer ptr
 for (i = 0; i < ROWS; i++){
 for (j = 0; j < COLS; j++) {
 printf("%4d ",*(ptr + (i * COLS + j)));
 }
 printf("\n");
 }
 
 return 0;
}

Вывод

Когда вы запустите этот код, он выдаст следующий результат –

 1 2 3 4
 5 6 7 8
 9 10 11 12

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

Трехмерный массив — это массив двумерных массивов. Такой массив объявляется с тремя индексами —

int arr [x] [y] [j];

Этот массив можно рассматривать как количество слоев таблиц «x», каждая таблица имеет строк «x» и количество столбцов «y».

Пример 3D-массива:–

int arr[3][3][3] ={
 { {11, 12, 13}, {14, 15, 16}, {17, 18, 19} },
 { {21, 22, 23}, {24, 25, 26}, {27, 28, 29} },
 { {31, 32, 33}, {34, 35, 36}, {37, 38, 39} },
};

Указатель на 3D-массив можно объявить как —

int * ptr = &arr[0][0][0];

Зная, что имя самого массива является адресом 0-го элемента, мы можем записать указатель трехмерного массива как —

int * ptr = arr;

Каждый слой строк «x» и столбцов «y» занимает —

x * y * sizeof(data_type) 

Количество байтов. Предполагая, что память, выделенная для 3D-массива "arr", как указано выше, начинается с адреса 1000, второй уровень (с "i =1") начинается с позиции 1000 + (3 3) 4 =1036 байт.

ptr = Base address of 3D array arr 

Если JMAX — это количество строк, а KMAX — количество столбцов, то адрес элемента в 0-й строке и 0-м столбце 1-го среза равен —

arr[1][0][0] = ptr + (1 * JMAX * KMAX)

Формула для получения значения элемента в j-й строке и k-м столбце i-го среза может быть представлена как —

arr[i][j][k] = *(ptr + (i * JMAX*KMAX) + (j*KMAX + k))

Пример:печать 3D-массива с использованием разыменования указателя

Давайте воспользуемся этой формулой для печати 3D-массива с помощью разыменования указателя —

#include <stdio.h>
int main(){
 int i, j, k;
 int arr[3][3][3] = {
 { {11, 12, 13}, {14, 15, 16}, {17, 18, 19} },
 { {21, 22, 23}, {24, 25, 26}, {27, 28, 29} },
 { {31, 32, 33}, {34, 35, 36}, {37, 38, 39} },
 };
 int JMAX = 3, KMAX = 3;
 int *ptr = arr; // &arr[0][0][0];
 for(i = 0; i < 3; i++){
 for(j = 0; j < 3; j++){
 for(k = 0; k < 3; k++){
 printf("%d ",*(ptr+(i*JMAX*KMAX)+(j*KMAX+k)));
 }
 printf("\n");
 }
 printf("\n");
 }
 
 return 0;
}

Вывод

Когда вы запустите этот код, он выдаст следующий результат –

11 12 13 
14 15 16 
17 18 19 
21 22 23 
24 25 26 
27 28 29 
31 32 33 
34 35 36 
37 38 39

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

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


Язык C

  1. Наследование С#
  2. C Обработка файлов
  3. Вложенный класс С#
  4. C# — перечисления
  5. Руководство по операторам C# IF, Switch, For, While [Примеры]
  6. Циклы в C:операторы циклов For, While, Do While [Примеры]
  7. Передача массива в функцию в программировании на C++
  8. Модификаторы доступа (спецификаторы) в C# с примерами программ
  9. C - определение типа
  10. Учебное пособие по Powershell для начинающих:изучите сценарии Powershell