2016-10-15 2 views
2

Глядя некоторые учебники онлайн, я заметил две разные MPI_SEND используют:Почему может функционировать параметр содержит адрес или переменные в C

Первый говорит начало буфера &a[500]:

MPI_Send(&a[500], 500, MPI_INT, 1, 0, MPI_COMM_WORLD); 

Второй говорит начало буфера b:

MPI_Send(b, 500, MPI_INT, 0, 0, MPI_COMM_WORLD); 

Я очень новой для C поэтому, возможно, что-то делать с выведенным по ссылке/значению.

Мое предположение, что b - это то же самое, что и &b, но в первом случае использование swe &a[500], потому что мы начинаем с адреса в середине массива ??

Но почему бы вам просто не сказать a[500] вместо &a[500]?

+1

Short: потому что 'a [500]' будет передавать * значение элемента * вместо его адреса. – usr2564301

+0

Предполагая, что программа также содержит строку 'void * b = & a [500];', магии не происходит. –

+0

'b' - это не то же самое, что' & b'. Если 'b' - массив, то' & b' является указателем на массив, который имеет разную семантику, чем указатель на первый элемент массива, хотя единственное, что интересует 'MPI_Send', а именно адрес, будет тоже самое.Если 'b' является указателем, то' & b' является указателем на указатель и несет совершенно другой адрес - передача его в 'MPI_Send', скорее всего, приведет к мусору или сбою. С другой стороны, 'b' эквивалентно' & b [0] '. Говорят, что имя массива распадается на указатель на первый элемент массива. –

ответ

3

Термин &a[500] является адресом a[500], то есть 500-го элемента массива a. Так что это указатель.

Термин b может быть либо массив (например, int b[1000]), в этом случае, без индекса, он преобразуется в указатель на начало массива (т.е. &b[0]) или ар реального указателя, указывающий на начало некоторый массив.

Примечания: a[500] (без амперсанда) будет значением 500-го элемента.

+0

Большое спасибо. Делает смысл –

4

Первыми вещами: оператор & является адресом оператора, а оператор * - это оператор разыменования. Оператор & получает адрес операнда, а оператор * получает значение переменной по значению операнда. Эти операторы обращаются друг к другу. В C массив почти похож на указатель. Указатель - это переменная с адресом другой переменной, установленной для нее. Несколько различий между указателем и массивом можно найти here Когда вы делаете int arr[10], вы выделяете 10 int s ценность памяти, а затем устанавливаете переменную arr на адрес начала этой части выделенной памяти. Например:

     |    allocated memory 
        |,---------------------/\-------------------------. 
Address (hex): arr |   012C | 0130 | 0134 | ... | 0170 | 
Value (hex) : 012C | arr[0] or *arr | arr[1] | arr[2] | ... | arr[9] | 

&arr[2] = 0x0134 

Что-то отметить: arr[i] такое же, как *(arr + i).

В своем вопросе вы передаете &a[500] в MPI_Send. Это действительно пропуск по ссылке. &a[500] - адрес 500-го элемента a. То, что передается на первый звонок MPI_Send, является адресом. Если в учебнике b является указателем на буфер, тогда адрес, сохраненный в b, является тем, что передается во втором вызове MPI_Send.

+0

Очень приятное подробное объяснение. благодаря –