2013-07-02 5 views
11

Может ли кто-нибудь сказать мне точную разницу между вызовом по указателю и вызовом по ссылке. На самом деле, что происходит в обоих случаях?Diff между вызовом по ссылке и вызовом по указателю

Например:

вызова по ссылке:

void swap(int &x, int &y) 
{ 
    int temp; 
    temp = x; /* save the value at address x */ 
    x = y; /* put y into x */ 
    y = temp; /* put x into y */ 

    return; 
} 

swap(a, b); 

Вызов по указателю:

void swap(int *x, int *y) 
{ 
    int temp; 
    temp = *x; /* save the value at address x */ 
    *x = *y; /* put y into x */ 
    *y = temp; /* put x into y */ 

    return; 
} 

    swap(&a, &b); 
+3

В java нет указателей. –

+2

Почему это помечено * java *? – Nawaz

+0

Этот вопрос не имеет ничего общего с Java. –

ответ

13

Оба случая делают то же самое.

Однако небольшая разница заключается в том, что ссылки никогда не являются нулевыми (и внутри функции вы уверены, что они ссылаются на действительную переменную). С другой стороны, указатели могут быть пустыми или могут указывать на недопустимое место в памяти, вызывая AV.

+0

Какова будет ссылка 'x' в следующем вызове:' swap (* (int *) 0, y) '? –

+0

@ ValeriAtamaniouk, что было бы неопределенным поведением. – juanchopanza

+0

@ValeriAtamaniouk Что важно, это было бы неопределенным поведением * даже до ввода функции *. – Spook

0

В вашем примере, нет никакой разницы.

В C++ ссылка реализована с использованием указателей.

Edit: для тех, кто считает, ссылка не может быть NULL:

int calc(int &arg) 
{ 
    return arg; 
} 

int test(int *arg) 
{ 
    return calc(*arg); 
} 

Guess, каков будет результат для test(0)?

+3

... за исключением того, что указатели могут быть NULL и ссылки не могут ... – trojanfoe

+0

@trojanfoe Ссылка может указывать на NULL. Хотя это не обычный случай. –

+0

Пожалуйста, покажите код для этого. – trojanfoe

3

Семантически эти вызовы имеют одинаковые результаты; под капотом ссылки реализуются с указателями.

Важное различие между использованием ссылок и указателями - это ссылки, в которых у вас гораздо меньше веревки, которые можно повесить на себя. Ссылки всегда указывают на «что-то», где указатели могут указывать на что-либо. Например, это вполне возможно сделать что-то вроде этого

void swap(int *x, int *y) 
{ 
    int temp; 
    temp = *x; /* save the value at address x */ 
    ++x; 
    *x = *y; /* put y into x */ 
    *y = temp; /* put x into y */ 

    return; 
} 

И теперь этот код мог бы сделать что-нибудь, аварию, бегать, у обезьян вылетают из вашего NoEs, ничего.

В случае сомнений предпочитайте ссылки. Это более высокий, более безопасный уровень абстракции на указателях.

0

Ваш код - код на C++. В Java нет указателей. Оба примера делают то же самое, функционально нет разницы.

0

Я точно не знаю, почему это было отмечено как jave, поскольку нет указателей. Однако для концепции вы можете использовать оба указателя и ссылку взаимозаменяемо, если вы работаете над атрибутом value. например i = 4 или * i = 4. Преимущество использования указателей заключается в том, что вы можете манипулировать самим адресом. Иногда вам нужно будет изменить адрес (указать его на что-то еще ...), когда указатели отличаются для ссылок; указатели позволяют работать непосредственно на адрес, ссылка не будет

Смежные вопросы