У меня есть этот код, который работает. Но меня смущает, как работают массивы указателей, разве вам не нужно инициализировать массив? Как этот блок кода может просто иметь &arr[i]
. Во-вторых, почему нам не нужно разыменовывать указатель, чтобы манипулировать данными, хранящимися в том месте, на которое указывает указатель (массиве)?
int *arr = malloc(size(int)*size);
for(int i = 0; i < size; i++) {
scanf(" %d", &arr[i]);
}
Я бы подумал, что вам нужно разыменовать указатель, чтобы манипулировать данными, на которые он указывает. Поэтому я подумал, что это сработает:
int *arr = malloc(size(int)*size);
for(int i = 0; i < size; i++) {
scanf(" %d", &*arr[i]);
}
Кроме того, когда мы пытаемся получить доступ к массиву. Почему нет *
перед array[i]
работой?
//sums value of elements in array
while (i < size ) {
sum += *array[i];
i++;
}
Выражение *array[i]
означает получить указатель по адресу array[i]
и использовать его (т. е. разыменовать его) для извлечения значения. Но array
— это массив целых чисел, а не указателей, поэтому выражение незаконно. Компилятор уже должен был вам об этом сказать.
Но меня смущает, как работают массивы указателей, разве вам не нужно инициализировать массив?
Да, malloc
не обеспечивает никакой инициализации.
Да, этот код выполняет некоторую инициализацию. Он использует scanf
для чтения значений во все элементы в выделенной памяти.
Как этот блок кода может просто иметь «&arr[i]».
Scanf
ожидает адрес переменной int
, в которой будут храниться преобразованные входные данные. Использование &
позволяет получить адрес элемента массива i
.
Во-вторых, почему бы нам не разыменовать указатель, чтобы манипулировать данными, хранящимися в том месте, на которое указывает указатель (массиве)?
Вы не хотите манипулировать содержимым. Вы хотите scanf
сделать это за вас. Поэтому вам необходимо указать адрес.
int *arr = malloc(size(int)*size);
for(int i = 0; i < size; i++) {
scanf(" %d", &arr[i]);
}
Вероятно, этот код является незаконным. Что должен означать size(int)
? Вам нужен sizeof
.
Я бы подумал, что вам нужно разыменовать указатель, чтобы манипулировать данными, на которые он указывает. Поэтому я подумал, что это сработает:
См. выше. Вы не хотите манипулировать данными здесь.
&*arr[i]
Это не имеет смысла. &
и *
нейтрализуют друг друга.
Это то же самое, что arr[i]
, что вызовет предупреждение, поскольку вы должны указать адрес:
Кроме того, когда мы пытаемся получить доступ к массиву. Почему * перед массивом [i] не работает?
//sums value of elements in array
while (i < size ) {
sum += *array[i];
i++;
}
Ваш массив не содержит указателей. Он содержит int
ценности. Нет необходимости разыменовывать значение int
.
Вероятно, вам придется вернуться к учебному материалу, посвященному массивам и указателям.
Но меня смущает, как работают массивы указателей.
В вашем коде такого нет. Есть массивы и есть указатели. Во многих ситуациях имя массива, когда оно используется в выражении, «превращается» в указатель на первый элемент. По этой же причине мы можем иметь явно объявленный указатель на первый элемент массива, что и происходит с malloc
.
вам не нужно инициализировать массив?
Вам никогда не придется делать это с массивом в C, независимо от того, как он был выделен. Зачастую это хорошая практика, но если вы собираетесь просто перезаписать содержимое первым делом, инициализация массива бессмысленна.
Основное различие между malloc
и calloc
заключается в том, что последний инициализирует массив нулями, но по этой причине он также немного медленнее, чем malloc
.
Как этот блок кода может просто иметь
&arr[i]
. Во-вторых, почему бы нам не использовать указатель для манипулирования данными, хранящимися в том месте, на которое указывает указатель (массиве)?
Он работает так же, как любой массив. Фактически оператор []
всегда применяется к указателю, а не к массиву. Если массив плана объявлен в локальной области int arr[n]
, то при использовании в выражении []
он превращается в указатель (обратите внимание, что []
имеет более высокий приоритет, чем &
). Но в случае динамического распределения у нас уже есть указатель, поэтому распада не произойдет.
Как только у нас есть указатель, операторы []
определяются так, что arr[i]
гарантированно будет на 100% эквивалентно *(arr + i)
. Итак, это арифметика указателей, вычисление индекса элемента с помощью arr + i
с последующим разыменованием. Таким образом, разыменование встроено в оператор []
.
Кроме того, когда мы пытаемся получить доступ к массиву. Почему * перед массивом [i] не работает?
Потому что *array[i]
— это то же самое, что и **(array + i)
, и это не имеет никакого смысла.
size(int)
==>sizeof(int)