Функция подкачки для массива - PullRequest
1 голос
/ 11 ноября 2011

Информация, которую мы имеем:

1) определение массива a[1000], a - адрес указателя.

2)

void swap(int &c, int &b)
{
    c=c+b;
    b=c-b;
    c=c-b;
} 
// this is a method of swapping two variables without using temp variable.
// We use call by reference for the swap to actually take place in memory.

Теперь, когда я вызываю эту функцию для двух записей, скажите a[i],a[j] ... что происходит ?? Получает ли функция адрес двух ячеек массива из-за некоторой внутренней конструкции C / C ++, или она получает адрес указателей, указывающих на a[i] и a[j]?

Ответы [ 7 ]

2 голосов
/ 11 ноября 2011

Я бы сказал, что за сценой он будет получать указатели на a[i] и a[j].

Запуск g++ -S в следующих двух программах дает одинаковые результаты:

#include<iostream>
extern "C" void swap(int&c,int&b){
    c=c+b;
    b=c-b;
    c=c-b;
}
int main(){
    int*a=new int[1000];
    a[10]=10;
    a[42]=42;
    swap(a[10],a[42]);
    std::cout << a[10] << " " << a[42] << std::endl;
    delete[] a;
    return 0;
}

и

#include<iostream>
extern "C" void swap(int*c,int*b){
    *c=*c+*b;
    *b=*c-*b;
    *c=*c-*b;
}
int main(){
    int*a=new int[1000];
    a[10]=10;
    a[42]=42;
    swap(a+10,a+42);
    std::cout << a[10] << " " << a[42] << std::endl;
    delete[] a;
    return 0;
}

, где я использовал extern "C", чтобы иметь возможность diff выходов, в противном случае искажение отличается.

Примечание, когда вы пишете, например, a+42компилятор вычислит адрес как a+sizeof(int)*42, учитывая, что a является указателем на int.Этот конкретный пример отображается как addl $168, %eax в сгенерированном источнике сборки.

2 голосов
/ 11 ноября 2011

a[i] соответствует ссылке на i-й элемент.Это эквивалент *(a+i), где a+i - указатель на i-й элемент.

Принцип работы внутренних ссылок определяется реализацией (вас это не должно волновать), но большинство (все)компиляторы используют указатели внутри.В этом случае они будут указателями на два элемента в массиве.

1 голос
/ 08 декабря 2011

Идея замены двух чисел без temp работает хорошо только в том случае, если сумма чисел находится в диапазоне значений; может храниться int (обычно power (2, sizeof (int))). В противном случае произойдет переполнение. Подойдя к вопросу,

int *a=new int;
a[1000];// if i have understood your question then....

Как упомянуто вами здесь A - указатель, а A [i] - массив, сформированный с A в качестве базового адреса. В c, когда вы говорите p [i] внутренне, он преобразуется в * (p + i), где p - базовый адрес. Аналогично, когда вы передаете по ссылочному адресу, передается значение.

Примечание: ссылки неявно постоянны, ссылкам нужно дать значение при объявлении.

Ссылки действуют как константный указатель, который неявно разыменовывается. Передача ссылок безопаснее, чем указателей, так как использование указателя может привести к segfaults. (Где нет динамического выделения памяти)

1 голос
/ 11 ноября 2011
  1. определение массива a[1000], a - адрес указателя.

Нет, это не так. a это массив. Во многих случаях он распадается на указатель на первый элемент, но это не адрес указателя (если, конечно, вы не создали массив указателей).

1 голос
/ 11 ноября 2011

Прежде всего, ваша функция подкачки - плохая идея, так как значение суммы может переполниться.Просто используйте переменную temp.

Когда вы вызываете swap (a [i], a [j]), аргументы функции - это два указателя на ячейки памяти a [i] и a [j].Указатели содержат адреса двух целых.Функция swap () не будет иметь понятия, что два целых числа находятся в одном массиве.

Объявление c и d в качестве ссылок аналогично передаче указателя, однако вы можете работать только со значениями, хранящимися в этомрасположение в памяти (эквивалентно разыменованию указателя), но не изменять адрес, на который указывает указатель.

1 голос
/ 11 ноября 2011

A) C и C ++ - два разных языка. Учитывая ваше swap(int &c, int &b) определение метода, это C ++

B) Поскольку это C ++, и вы передаете ссылки , вы получаете ссылку на элемент массива (который в памяти находится в a + i)

Если бы это был C, вы бы определили свою функцию как swap(int *c, int *d), и вы бы передавали указатель a + i, потому что массив ухудшает до указателей автоматически.

0 голосов
/ 11 ноября 2011

a[i] представляет значение, поэтому &a[i] = a + i будет передано (внутренне). Аналогично для a[j].

...