Если вы работаете с «объектами» в C, у вас, вероятно, есть это:
struct customer {
char *name;
char *address;
int id;
} typedef Customer;
Если вы хотите создать объект, вы должны сделать что-то вроде этого:
Customer *customer = malloc(sizeof Customer);
// Initialise state.
Мы используем указатель на struct
здесь, потому что struct
аргументы передаются по значению, и нам нужно работать с одним объектом. (Также: Objective-C, объектно-ориентированный язык-обертка для C, использует внутренние, но визуально указатели на struct
s.)
Если мне нужно сохранить несколько объектов, я использую массив:
Customer **customers = malloc(sizeof(Customer *) * 10);
int customerCount = 0;
Поскольку переменная массива в C указывает на первый элемент, я снова использую указатель ... Теперь у меня есть двойные указатели.
Но теперь представьте, что у меня есть функция, которая фильтрует массив и возвращает новый. Но представьте, что это невозможно с помощью механизма возврата, потому что он должен возвращать код ошибки - моя функция обращается к базе данных. Мне нужно сделать это с помощью аргумента по ссылке. Это подпись моей функции:
int filterRegisteredCustomers(Customer **unfilteredCustomers, Customer ***filteredCustomers, int unfilteredCount, int *filteredCount);
Функция принимает массив клиентов и возвращает ссылку на массив клиентов (которые являются указателями на struct
). Он также принимает количество клиентов и возвращает количество отфильтрованных клиентов (опять же, аргумент по ссылке).
Я могу назвать это так:
Customer **result, int n = 0;
int errorCode = filterRegisteredCustomers(customers, &result, customerCount, &n);
Я мог бы продолжать воображать больше ситуаций ... Это без typedef
:
int fetchCustomerMatrix(struct customer ****outMatrix, int *rows, int *columns);
Очевидно, я был бы ужасным и / или садистским разработчиком, если бы оставил это так. Итак, используя:
typedef Customer *CustomerArray;
typedef CustomerArray *CustomerMatrix;
Я могу просто сделать это:
int fetchCustomerMatrix(CustomerMatrix *outMatrix, int *rows, int *columns);
Если ваше приложение используется в отеле, где вы используете матрицу для уровня, вам, вероятно, понадобится массив для матрицы:
int fetchHotel(struct customer *****hotel, int *rows, int *columns, int *levels);
Или просто так:
typedef CustomerMatrix *Hotel;
int fetchHotel(Hotel *hotel, int *rows, int *columns, int *levels);
Не заставляйте меня даже начинать на множестве отелей:
int fetchHotels(struct customer ******hotels, int *rows, int *columns, int *levels, int *hotels);
… в виде матрицы (какая-то крупная гостиничная корпорация?):
int fetchHotelMatrix(struct customer *******hotelMatrix, int *rows, int *columns, int *levels, int *hotelRows, int *hotelColumns);
Что я пытаюсь сказать, так это то, что вы можете представить себе сумасшедшие приложения для нескольких косвенных ссылок. Просто убедитесь, что вы используете typedef
, если мульти-указатели являются хорошей идеей, и вы решили использовать их.
(Этот пост считается приложением для SevenStarDeveloper ?)