Помогите с пониманием работы указателя и массива

78
24 августа 2021, 18:50

Читал, что массив в качестве аргумента в параметр другой функции работает так: типо массив громоздкий, и поэтому в параметр другой функции передается только первый элемент массива. Вот код:

void mem(int *ptr) {
 *ptr=5;
}
int main() {
 int A[]={1,2,3};
 cout<<A[0];
 mem(A);
 cout<<A[0];
 return 0;
}

Но так же слышал, что массив может передаваться полностью в параметр другой функции:

#include <iostream>
void passValue(int value) // здесь value - эта копия аргумента
{
    value = 87; // изменения value здесь не повлияют на фактическую переменную value
}
void passArray(int array[5]) // здесь array - это фактический массив
{
    array[0] = 10; // изменения array здесь изменят исходный массив array
    array[1] = 8;
    array[2] = 6;
    array[3] = 4;
    array[4] = 1;
}
int main()
{
    int value = 1;
    std::cout << "before passValue: " << value << "\n";
    passValue(value);
    std::cout << "after passValue: " << value << "\n";
    int array[5] = { 1, 4, 6, 8, 10 };
    std::cout << "before passArray: " << array[0] << " " << array[1] << " " << array[2] << " " << array[3] << " " << array[4] << "\n";
    passArray(array);
    std::cout << "after passArray: " << array[0] << " " << array[1] << " " << array[2] << " " << array[3] << " " << array[4] << "\n";
    return 0;
}

Я так и не понял, массив передается полностью в параметр или только первый элемент?

Answer 1

массив передается полностью в параметр или только первый элемент

Не так, и не эдак.

Объявления

void mem(int *ptr)
void mem(int ptr[])
void mem(int ptr[5])

эквивалентны. Во всех случаях функция будет получать указатель ptr типа int *. А уж что за указатель вы туда будете предавать - это зависит только от вас. Можете передать указатель на первый элемент массива, а можете - на десятый элемент массива, а можете вообще не на элемент массива

int a[100];
mem(a);
mem(&a[10]);
int b;
mem(&b);
Answer 2

Абсолютно идентичные записи. В обоих случаях передается указатель на первый элемент. Размер массива в объявлении функции не обязателен, она все равно ничего не знает о его размере.

Answer 3

Массив в Си/C++ - это и есть указатель на первый элемент, но с выделением определённого количеством памяти.

То есть две следующие строки по своей сути эквивалентны(но в первом случае блок памяти выделяется в стэке, а второй в куче):

int a[10];
int* b = reinterpret_cast<int*>(malloc(10 * sizeof(int)));

В доказательство тому попробуйте вывести массив без обращения к элементу

std::cout<<a<<endl;

Стоит отметить что к элементу массива объявленного через указатель можно обратиться так же как и к обычному массиву

b[0] = 1;
b[1] = 2;
std::cout<<b[0]<<std::endl<<b[1];

Иными словами оператор a[1] эквивалентен такой записи *(a + 1)

Что же касательно вашего вопроса, то ответ прост - передаётся указатель на первый элемент массива

READ ALSO
Почему всегда выводится 0?

Почему всегда выводится 0?

Почему всегда выводится 0?

135
Забить столбцы и строки значениями

Забить столбцы и строки значениями

Знаю, вопрос для подавляющего большинства травиальныйНо я уже не вижу ошибки

112
volatile register int

volatile register int

Имеет ли смысл такая запись?

127
Угол между камерами с проекционной матрицей 3x4

Угол между камерами с проекционной матрицей 3x4

Есть проекционная матрица 3x4 полученная из R и T в результате стерео калибровки камерыКак из нее получить угол между камерами?

83