ELI5: Какой тип данных у `int * p []`

Я не понимаю, что это за тип данных. Если это указатель или массив. Пожалуйста, объясните простым языком. Процитировать то, что было в книге -

If you want to pass an array of pointers into a function, you can use the same method that you use to pass other arrays—simply call the function with the array name without any indexes. For example, a function that can receive array x looks like this:

void display_array(int *q[])
{
  int t;
  for(t=0; t<10; t++)
    printf("%d ", *q[t]);
}

Remember, q is not a pointer to integers, but rather a pointer to an array of pointers to integers. Therefore you need to declare the parameter q as an array of integer pointers, as just shown. You cannot declare q simply as an integer pointer because that is not what it is.

цитируйте: C++: The Complete Reference, 4th Edition by Herbert Schildt, page 122-123.

Может, этот сайт поможет. Книжка кстати неправильная, p не указатель.

nwp 05.12.2018 14:12

@nwp: p является указателем, если это объявление встречается в параметре функции. Но тогда книга ошибочна в другом смысле; p тогда является указателем на указатель (который может быть первым в массиве указателей).

Eric Postpischil 05.12.2018 14:25

Когда [] используется в качестве параметра функции, они абсолютно такие же, как и *: void display_array(int *q[]) - это то же самое, что и void display_array(int **q); int main(int argc, char **argv) такой же, как int main(int argc, char *argv[]); void foo(int a[]) такой же, как void foo(int *a).

pmg 05.12.2018 14:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
303
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

... pointer to an array of pointers to integers

Нет, это не так. q относится к типу int *[]. Это недопустимый (или, возможно, неполный, в зависимости от контекста) тип в C++ и допустимый только в некоторых местах в C. Массивы должны иметь размер.

Тип int *[] представляет собой (безразмерный) массив указателей на int. Сам по себе это не указатель.


Путаница, вероятно, возникает из-за того, что массив может разлагаться указывать на свой первый элемент.

Например, допустим, у нас есть этот массив:

int a[20];

Когда используется простой a, он распадается до указателя на свой первый элемент: a равен &a[0].

Извините, но снова У C++ есть темный угол :)

Quentin 05.12.2018 14:14

@Quentin Главное здесь то, что неограниченные массивы - это неполный. Вы можете использовать декларации, но вы не можете определять массив без размера.

Some programmer dude 05.12.2018 14:17

По поводу «Массивы должны иметь размер»: Ну, может быть где-то, но не обязательно внутри единицы трансляции. Вы даже можете использовать содержимое объекта с неполным типом: extern int *p[]; int foo(void) { return *p[3]; } строго соответствует требованиям C и компилируется без жалоб.

Eric Postpischil 05.12.2018 14:30
Ответ принят как подходящий

Вот как это устроено:

  • int - это тип "int".
  • int* - это тип "указатель на int"
  • int* [] - это тип "массив (неизвестной границы / длины) указателя на int"
  • int* p[] - это декларация переменной или параметра с именем п указанного выше типа.

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

Lundin 05.12.2018 14:56
   int *p[]
//      ^

п - это

   int *p[]
//       ^^

p равно массив неопределенного размера(возможно, незаконно, зависит от контекста)

   int *p[]
// ^^^^^

p - массив неопределенного размера указатели на int

Это означает, что каждый элемент p является указателем:

int foobar = 42;
p[0] = NULL;
p[1] = &foobar;

I don't understand what the datatype of this is

Если это хоть как-то утешает, то и автор книги, которую вы читаете, тоже.

Remember, q is not a pointer to integers, but rather a pointer to an array of pointers to integers.

Это Bullschildt.

  • До настройка параметров, q - это массив указателей на целые числа.
  • После настройки параметров, q - указатель на первый элемент массива указателей на целые числа. Эквивалент int** q, указатель на указатель на int.

Нигде нет «указателя на массив указателей на целые числа». Это был бы int* (*q)[].

Я бы посоветовал прекратить читать эту книгу.

Ключевым моментом здесь является то, что любой массив, который является частью списка параметров функции, корректируется («распадается») на указатель на первый элемент. Так что не имеет значения, наберете ли вы int* q[666] или int* q[], любой из них будет автоматически заменен компилятором с int** «за чертой».

Фактически это причина, по которой мы можем записать [] в список параметров - обычно пустой массив будет неполным типом, который нельзя использовать до завершения где-либо еще. Но поскольку параметры всегда корректируются, они никогда не относятся к типу массива, и не имеет значения, что исходный тип был неполным.

@DavidBowling К сожалению, это хорошо известный термин, изобретенный много десятилетий назад. И все же мы все еще страдаем от этих книг.

Lundin 05.12.2018 16:34

Другие вопросы по теме