передача 2D-массива в функцию ** vs [] [N] [дублировать]

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

function dump_error_to_file($errno, $errstr) {
    file_put_contents('/tmp/php-errors', date('Y-m-d H:i:s - ') . $errstr, FILE_APPEND);
}
set_error_handler('dump_error_to_file');

16
задан Shahbaz 17 October 2013 в 09:52
поделиться

4 ответа

Давайте начнем с обсуждения правового кода. То, что вы написали (предполагая символ перед каждой декларацией), не будет компилироваться по нескольким причинам: у вас слишком много инициализаторов (шесть символов для arr [0], а его размер равен 5) и, конечно, char ** p не имеет типа, совместимого с char arr [2] [5]. Исправляя эти проблемы, получаем:

char arr[2][6] = { "hello", "hai" };
char (*p)[6] = arr;

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

char* pc = *arr;

будет работать, если вы хотите получить доступ к символам из первого элемента в обр.

C ++ не имеет двухмерных массивов. Первое определение выше определяет массив [2] или массив [6] символа. Массив implicite для преобразования указателя приводит к указателю на массив [6] символа. После этого, конечно, нет никакого массива для преобразования указателя, потому что у вас больше нет массива.

1
ответ дан James Kanze 21 August 2018 в 19:29
поделиться

Я попытаюсь нарисовать, как

int array[10][6];

и

int **array2 = malloc(10 * sizeof *array2);
for (int i = 0; i < 10; ++i)
    array2[i] = malloc(6 * sizeof **array2);

выглядят в памяти и как они отличаются (и что они не могут

array выглядит так:

 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
| | | | | | | | | | | | | ..............| | | (10*6 elements of type int)
 - - - - - - - - - - - - - - - - - - - - - -
< first row >< second row> ...

array2 выглядит так:

 _ _ _ _ _ _ _ _ _ _ 
| | | | | | | | | | | (10 elements of type int *)
 - - - - - - - - - - 
 | |     ....      |     _ _ _ _ _ _
 | |                \-->| | | | | | | (6 elements of type int)
 | |                     - - - - - -
 | |
 | |      _ _ _ _ _ _
 |  \ -->| | | | | | | (6 elements of type int)
 |        - - - - - -
 |
 |
 |      _ _ _ _ _ _
  \ -->| | | | | | | (6 elements of type int)
        - - - - - -

Когда вы говорите array[x][y], он переводится в *(((int *)array)+x*6+y)

. Хотя, когда вы говорите array2[x][y], он переводится в *(*(array2+x)+y)

. То есть статический 2d-массив является фактически массивом 1d с строками, помещенными в одну строку. Индекс рассчитывается по формуле row * number_of_columns_in_one_row + column.

Динамический массив 2d, однако является всего лишь 1d массивом указателей. Затем каждый указатель динамически выделяется для указания на другой 1-й массив. По правде говоря, этот указатель может быть любым. Может быть NULL или указывать на одну переменную или указывать на другой массив. И каждый из этих указателей устанавливается индивидуально, поэтому они могут иметь разные натуры.

Если вам нужно передать указатель array где-то, вы не можете направить его на int ** (представьте, что бы int значения ячеек array интерпретируются как указатели и разыменованные -> Bam! Ошибка сегментации!). Однако вы можете думать о array как о 1d массиве int [6] s; это 1-й массив элементов с типом int [6]. Чтобы записать это, вы говорите

int (*p)[6] = array;
40
ответ дан M.M 21 August 2018 в 19:29
поделиться

Создание массива указателей для каждой строки для получения объекта, который «выглядит», как многомерный массив переменной размерности , является дорогостоящим выбором дизайна для синтаксического сахара . Не делайте этого.

Правильный способ создания многомерного массива переменного размера - это что-то вроде:

if (w > SIZE_MAX/sizeof *m/h) goto error;
m = malloc(w * h * sizeof *m);
if (!m) goto error;
...
m[y*w+x] = foo;

Если вы хотите, чтобы он выглядел красиво, чтобы вы могли напишите m[y][x], вы должны использовать другой язык, возможно, C ++.

8
ответ дан Shahbaz 21 August 2018 в 19:29
поделиться
  • 1
    Мой вопрос - почему и как он работает. – Thangaraj 17 December 2010 в 14:49
  • 2
    вы можете использовать массивы переменной длины, чтобы компилятор выполнил вычисление смещения для вас: int (*foo)[cols] = malloc(sizeof *foo * rows) позволяет использовать знакомый синтаксис foo[i][j]; – Christoph 17 December 2010 в 17:57
  • 3
    @ Кристоф: Действительно, если у вас есть компилятор C99, это работает. Вам нужно организовать правильное измерение размеров любых вызовов функций, которые вы передаете массиву. – R.. 17 December 2010 в 18:23
8
ответ дан Shahbaz 4 November 2018 в 16:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: