Каково различие между передачей ссылкой в Java и передачей указателя в C?

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

private double dist;

public double getDist() {
   return dist;
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);

    for (Circle circle : circles) {
        circle.draw(g);
        if (selectedCircle != null && selectedCircle == circle) {
            selectedCircle.drawSelected(g);
        }
    }

    for (int i = 0; i < circles.size(); i++) {
        Circle c1 = circles.get(i);
        for (int j = i + 1; j < circles.size(); j++) {
            Circle c2 = circles.get(j);

            dist = c1.getPoint().distance(c2.getPoint()) + 1;
            double dx = (c2.x - c1.x) / dist / dist;
            double dy = (c2.y - c1.y) / dist / dist;
            c1.x += dx;
            c1.y += dy;
            c2.x -= dx;
            c2.y -= dy;

        }
    }

}
15
задан mmcdole 1 March 2009 в 22:21
поделиться

9 ответов

Ни Java, ни C не имеют передачу ссылкой. Они - оба строго передача значением.

Семантика передачи ссылкой означает, что, когда Вы изменяете значение параметра в методе, вызывающая сторона будет видеть что изменение в аргументе.

Теперь, можно думать: "Но это имеет место в Java! Если я изменяю объект во время метода, вызывающая сторона видит то изменение". Объект не является параметром. Параметр является просто переменной - и если Вы измените значение той переменной, то вызывающая сторона не будет видеть это. Например:

public void foo(Object x)
{
    x = null;
}

public void caller()
{
    Object y = new Object();
    foo(y);
    // y is still not null!
}

Если параметр был действительно передан ссылкой, y было бы пустым впоследствии. Вместо этого значение y просто ссылка, и что ссылка передается значением. Это сбивает с толку, потому что слово "ссылка" находится в обоих терминах, но они - разные вещи.

Можно хотеть посмотреть на мою статью о передаче параметров C# для наблюдения то, что было бы возможно, если бы Java действительно имел семантику передачи ссылкой, как C# делает, когда (и только когда) Вы используете ref ключевое слово.

Можно также хотеть посмотреть на комментарии к моему ответу Переполнения стека, связанному с темой.

39
ответ дан 1 December 2019 в 00:05
поделиться

Я думал, что различие было то, что в Java вся передача объектов сделана с указателями автоматически, где как в C нужно на самом деле опрыснуть небольшие звездочки и амперсанды тут и там.

Концептуальный, это совершенно правильно. Если мы педантичны (и это - хорошая вещь), мы можем даже сказать, что объекты не передаются вообще в Java. То, что передается, является только когда-либо "указателем", который в Java называют ссылкой. Вся косвенность сделана автоматически. Таким образом, когда Вы делаете "objref-> нечто" вместо "objref.foo" в C и не можете использовать точку, потому что Вы работаете с указателем, в Java можно все еще использовать точку, потому что это не знает ничто больше участникам доступа так или иначе. В C можно передать указатель (и здесь, это на самом деле называют указателем), и можно передать сам объект, в этом случае копия передается. В C Вы получаете доступ к объекту, который указатель отсылает к косвенно использованию звезды или "->". В Java единственный способ, которым к объектам получают доступ так или иначе, использует точку (objref.member).

Если мы педантичны снова (теперь более важный снова), ни в Java, ни в C существует "передача ссылкой". То, что мы передаем в Java, является ссылкой/указателем на объект и в C мы любая передача копия объекта (очевидный случай), или мы передаем снова просто копию указателя на объект. Так в обоих случаях - Java и C - что мы передаем, являются адресами объектов. Не говоря о примитивных типах Java, которые копируются и в Java и в C - даже при том, что можно передать их адрес в C также, нет никакого различия между составным типом (т.е. структура) и "типом примитива" в C в том отношении.

7
ответ дан 1 December 2019 в 00:05
поделиться

Различия являются тонкими. На уровне ассемблера в обоих случаях адрес объекта передается функции. Однако в случае указателя параметр является независимым указателем, который может использоваться для изменения целевого объекта (*pch = 'x') или может использоваться для доступа к другому объекту (pch = "newstr"). В ссылочном случае параметр автоматически indirected к целевому объекту.

3
ответ дан 1 December 2019 в 00:05
поделиться

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

С уважением

2
ответ дан 1 December 2019 в 00:05
поделиться

Несколько вещей

  • C не имеет никаких ссылок (несмотря на C++)
  • Java не имеет никаких указателей
  • Различие между указателями и ссылками, что указатели являются практически адресами памяти, с которыми можно вычислить. Ссылки не могут быть вычислены с
  • Java и передача C значением (При передаче объекта в Java, ссылка копируется в функцию),
2
ответ дан 1 December 2019 в 00:05
поделиться

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

В Java это не возможно, потому что ссылки на объект передаются значением.

2
ответ дан 1 December 2019 в 00:05
поделиться

Существует недавняя статья Eric Lippert об этом. Он - программист на компиляторе C#, но независимо от того, что он говорит, там имеет достаточно общности, которая будет расширена на другие языки GC, такие как Java:

http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx

Кавычка от статьи:

Указатели строго "более мощны", чем ссылки; что-либо, что можно сделать со ссылками, которые можно сделать с указателями. [...]

Указатели обычно реализуются как адреса. Адрес является числом, которое является смещением в "массив байтов", который является всем виртуальным адресным пространством процесса. [...]

По всем этим причинам мы не описываем ссылки как адреса в спецификации. Спецификация просто говорит, что переменная ссылочного типа "хранит ссылку" на объект и оставляет его абсолютно неопределенным относительно того, как это могло бы быть реализовано. Точно так же переменную указателя хранилища "адрес" объекта, который снова, оставляют довольно неопределенной. Нигде мы не говорим, что ссылки совпадают с адресами.

Так, в C# ссылка является некоторой неопределенной вещью, которая позволяет Вам сослаться на объект. Вы ничего не можете сделать со ссылкой кроме, разыменовывают его и сравнивают его с другой ссылкой для равенства. И в C# указатель идентифицируется как адрес.

В отличие от этого, со ссылкой, можно сделать намного больше с указателем, который содержит адрес. Адресами можно управлять математически; можно вычесть один от другого, можно добавить целые числа к ним и так далее. Их легальные операции указывают, что они - "необычные числа", которые индексируют в "массив", который является виртуальным адресным пространством процесса.

1
ответ дан 1 December 2019 в 00:05
поделиться

Если Вы изучаете C (а не C++), то нет никаких ссылок.

Термин "передача ссылкой" в C просто означает передачу указателя как адреса, в котором будет сохранено значение, так, чтобы функция могла изменить свое значение. Иначе Вы являетесь передающими значением, что означает, что копия переменной сгенерирована на стеке, и модификации не оказывают влияния.

Во многих отношениях это подобно тому, что Вы видите в Java, за исключением того, что в Java Вы не должны явно превратить вещи в указатель или разыменовать их. Другими словами, при передаче указателя адрес копируется на стеке, поэтому если функция изменяет указатель (а не данные, это указывает на), изменения исчезают, когда Вы сделаны с функцией. Точно так же при передаче ссылки на объект в Java можно изменить содержание объекта (например, путем вызывания функций), но изменение переменной для указания на объект anothr не будет иметь никакого эффекта, после того как Вы уезжаете.

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

1
ответ дан 1 December 2019 в 00:05
поделиться

Я не уверен в Java, но в C# или VB.net, который можно передать значением или ссылкой

передача в качестве примера ссылкой

    static void Main(string[] args)
    {
        int x = 1;
        Foo(ref x);
        Console.WriteLine(x.ToString());//this will print 2
    }

    private static void Foo(ref int x)
    {
        x++;
    }

заметьте, что x равен 1, но когда Вы называете метод Foo и передающий x ссылкой, когда x увеличен одним в Foo, исходное значение увеличено также

0
ответ дан 1 December 2019 в 00:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: