Почему параметр функции может содержать адреса или переменные в C

#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. Большое спасибо. Имеет смысл