#c #mpi #pass-by-reference #memory-address
#c #mpi #передача по ссылке #адрес памяти
Вопрос:
Просматривая некоторые учебные пособия в Интернете, я заметил два разных использования MPI_SEND:
В первом говорится, что начало буфера равно amp;a[500]
:
MPI_Send(amp;a[500], 500, MPI_INT, 1, 0, MPI_COMM_WORLD);
Во втором говорится, что начало буфера равно b
:
MPI_Send(b, 500, MPI_INT, 0, 0, MPI_COMM_WORLD);
Я очень новичок в C
so, возможно, это как-то связано с передачей по ссылке / значению.
Я предполагаю, что b
это то же amp;b
самое, что и, но в первом случае мы используем amp;a[500]
, потому что мы начинаем с адреса в середине массива??
Но почему вы не можете просто сказать a[500]
вместо amp;a[500]
?
Комментарии:
1. Коротко: потому
a[500]
что передаст значение элемента вместо его адреса.2. Предполагая, что программа также содержит строку
void* b = amp;a[500];
, никакого волшебства не происходит.3.
b
это не то жеamp;b
самое , что . Еслиb
это массив, тоamp;b
это указатель на массив, семантика которого отличается от семантики указателя на первый элемент массива, хотя единственное, что интересуетMPI_Send
, а именно адрес, будет тем же самым. Еслиb
это указатель, тоamp;b
это указатель на указатель и содержит совершенно другой адрес — передача егоMPI_Send
, скорее всего, приведет к мусору или сбою. С другой стороны,b
эквивалентноamp;b[0]
. Один говорит, что имя массива распадается на указатель на первый элемент массива.
Ответ №1:
Перво-наперво: amp;
оператор — это адрес operator , а *
оператор — оператор разыменования. amp;
Оператор получает адрес операнда, в то время *
как оператор получает значение переменной в значении операнда. Эти операторы являются обратными друг другу. В C массив почти как указатель. Указатель — это переменная, для которой задан адрес другой переменной. Несколько различий между указателем и массивом можно найти здесь, когда вы это делаете int arr[10]
, вы выделяете память на 10 int
секунд, а затем устанавливаете переменную arr
в адрес начала этой части выделенной памяти. Например:
| allocated memory
|,---------------------/-------------------------.
Address (hex): arr | 012C | 0130 | 0134 | ... | 0170 |
Value (hex) : 012C | arr[0] or *arr | arr[1] | arr[2] | ... | arr[9] |
amp;arr[2] = 0x0134
Что-то отметить: arr[i]
это то же самое, что *(arr i)
.
В вашем вопросе вы переходите amp;a[500]
к MPI_Send . Это действительно передача по ссылке. amp;a[500]
является адресом 500-го элемента a
. То, что передается первому вызову MPI_Send
, — это адрес. Если в учебном пособии b
это указатель на буфер, то адрес, хранящийся в b, передается при втором вызове MPI_Send
.
Комментарии:
1. Очень хорошее подробное объяснение. Спасибо
Ответ №2:
Термин amp;a[500]
— это адрес a[500]
, то есть 500-й элемент массива a . Итак, это указатель.
Термин b
может быть либо массивом (например int b[1000]
), в этом случае без индекса он преобразуется в указатель на начало массива (т.Е. amp;b[0]
), либо в вещественный указатель p, указывающий на начало некоторого массива.
Примечания: a[500]
(без амперсанда) будет значением 500-го элемента.
Комментарии:
1. Большое спасибо. Имеет смысл