** РЕДАКТИРОВАТЬ: Я изменил идентификаторы, когда скопировал код из своего проекта, поэтому я мог пропустить некоторые из них. Дайте мне знать, если вы что-то нашли.
* EDIT: добавлено #define MAX_COL 5;
для ясности.
Мне нужна помощь, чтобы разобраться в этой конкретной проблеме.
Допустим, у меня есть 2-мерный массив с инициализированными значениями. Меня просят найти:
- самую длинную последовательность целых чисел в массиве и
- адрес конкретного значения в начале этой последовательности.
Для этого я использую функцию, которая принимает:
- массив,
- целые числа, представляющие строку и столбец,
- указатель на адрес самой длинной последовательности (инициализируется адресом первого элемента массива),
- указатель на целое число для хранения длины последовательности.
max_seq(signed int arr[][5], int row, int col, signed int* ptr, int* seq_len);
Ниже это код:
#include <stdio.h>
#include <stdlib.h>
#define MAX_COL 5;
int** max_seq(signed int arr[][5], int row, int col, signed int* ptr, int* seq_len);
int main(void)
{
signed int arr[4][5] = { -5, 6, 0, 2, 2,
2, 2, 2, 9, 3,
3, 3, 2, 1, -8,
7, -2, 6, 0, 4 };
signed int *address_seq = &(**arr);
int seq_length = 0;
address_seq = max_seq(arr, 4, 5, address_seq, &seq_length);
return 0;
}
signed int** max_seq(signed int arr[][5], int row, int col, signed int* ptr, int* seq_len)
{
int i = 0, j = 0, /* sentinels */
temp_r = 0, temp_c = 0,
seq = 0, new_seq = 0;
int temp_val = (**arr);
/* assign the address of the 2dim array to the pointer ptr */
ptr = &(**arr);
/* within the ith row */
for (i = 0; i < row; ++i)
{
/* within the jth col */
for (j = 0; j < col; ++j)
{
/* if the new_seq counter exceeds the (old) seq counter, then retains the new seq counter,
also trace back the row and col values of the value at the start of that sequence */
if (new_seq > seq)
{
seq = new_seq;
int temp_seq = seq - 1;
temp_r = i;
temp_c = j;
while (temp_seq > 0)
{
--temp_c;
--temp_seq;
if (temp_c == 0 && temp_seq > 0)
{
--temp_r;
temp_c = MAX_COL;
--temp_c;
--temp_seq;
}
}
}
if (*(*(arr + i) + j) == *(*(arr + i) + j + 1))
{
temp_val = *(*(arr + i) + j);
++new_seq;
}
else if (*(*(arr + i) + j) != *(*(arr + i) + j + 1)) {
temp_val = *(*(arr + i) + j);
new_seq = 1;
continue;
}
}
}
*seq_len = seq;
ptr = &(*(*(arr + temp_r) + temp_c));
return ptr;
}
Особая проблема, которую я хочу понять, заключается в том, что когда я запускаю это в Visual Studio 19, я получаю предупреждение:
/* for the function call in main */
main.c(89,87): warning C4047: '=': 'int *' differs in levels of indirection from 'int **'
/* for the returned pointer value at the end of the function max_seq() */
main.c(146,12): warning C4047: 'return': 'int **' differs in levels of indirection from 'int *'
Несмотря на предупреждения, я по-прежнему получил то, что хотел, то есть адрес значения в начале самой длинной последовательности. Однако меня по-прежнему беспокоит, что указанная переменная, которую я объявил в main (), не совсем указатель на указатель.
Если я не ошибаюсь, имя любого массива вырождается в указатель при передаче в функцию. Следовательно, двумерный массив должен иметь 2 уровня косвенности. Однако, когда я изменил
signed int *address_seq = &(**arr);
на signed int **address_seq = arr;
, компилятор VS19 сгенерировал дополнительные предупреждения, а возвращенный ptr вообще не указывает на правильный блок данных.