Какова реальная разница между Указателями и Ссылками?

Это не пусто ... у вас просто нет разрешения на просмотр этой папки на устройстве.

Попробуйте в симуляторе, и он будет работать для вас, так как у вас есть root-доступ .

29
задан Iain 27 October 2008 в 10:35
поделиться

21 ответ

Это - все просто косвенность: способность не иметь дело с данными, но сказать "я направлю Вас к некоторым данным, там". У Вас есть то же понятие в Java и C#, но только в формате ссылки.

основные отличия - то, что ссылки являются эффективно неизменными указателями - они всегда указывают на что-то. Это полезно, и легко понять, но менее гибкий, чем модель указателя C. C указатели указатели, которые можно счастливо переписать. Вы знаете, что строка, которую Вы ищете, рядом с указываемой строкой? Ну, просто немного измените указатель.

Это связывает хорошо с C "язвительное низкоуровневое знание требуемый" подход. Мы знаем , что char* foo состоит из ряда символов, начинающихся в местоположении, на которое указывает указатель нечто. Если мы также знаем, что строка является по крайней мере 10 символами долго, мы можем изменить указатель на (foo + 5), чтобы указать на затем ту же строку, но запустить половину длины в.

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

79
ответ дан 28 November 2019 в 00:34
поделиться

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

существует две вещи, которые являются трудными с указателями:

  1. Указатели на указателях, обращении, и т.д. могут стать очень загадочными. Это приводит к ошибкам, и трудно читать.
  2. Память, на которую указывают указатели, часто выделяется от "кучи", что означает, что Вы ответственны за освобождение той памяти. Больше Ваше приложение добирается, тяжелее оно должно не отставать от этого требования, и Вы заканчиваете с утечками памяти, которые трудно разыскать.

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

0
ответ дан 28 November 2019 в 00:34
поделиться

Запишите больше чем 2 строки c или C++, и Вы узнаете.

Они - "указатели" на ячейку памяти переменной. Это похоже на передачу переменной ссылкой отчасти.

-3
ответ дан 28 November 2019 в 00:34
поделиться

Также просто что-то для замечания можно использовать указатели в C# (в противоположность нормальным ссылкам) путем маркировки блока кода как небезопасный. Затем можно обтекать изменяющиеся адреса памяти непосредственно и сделать адресную арифметику с указателями и весь тот забавный материал. Это является большим для очень быстрой обработки изображения (единственное место, я лично использовал его).

Насколько я знаю, Java и ActionScript не поддерживают небезопасный код и указатели.

0
ответ дан 28 November 2019 в 00:34
поделиться

Вам нужны они, если Вы хотите генерировать "объекты" во времени выполнения без пред, выделяют память на стеке

0
ответ дан 28 November 2019 в 00:34
поделиться

Параметр efficency - передача указателя (Интервал - 4 байта) в противоположность копированию целого (arbitarily большой) объект.

классы Java передаются через ссылку (в основном указатель) также btw, его просто, что в Java это скрыто от программиста.

0
ответ дан 28 November 2019 в 00:34
поделиться

Указатели важны! Они "указывают" на адрес памяти, и много внутренних структур представлены как указатели, IE, массив строк является на самом деле списком указателей на указатели! Указатели могут также использоваться для обновления переменных, переданных функциям.

0
ответ дан 28 November 2019 в 00:34
поделиться

Указатели являются самым прагматическим способом представить косвенность на языках программирования низшего уровня.

0
ответ дан 28 November 2019 в 00:34
поделиться

Честно говоря, большинство закаленных разработчиков посмеется (надо надеяться, дружественный), если Вы не будете знать указатели. В моем предыдущем Job у нас было два новых найма в прошлом году (просто дипломированный), который не знал об указателях, и что один была тема разговора с ними приблизительно в течение недели. Никто не мог верить, как кто-то мог получить высшее образование, не зная указатели...

2
ответ дан 28 November 2019 в 00:34
поделиться

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

Указатели явились результатом понимания, что ячейки памяти могли также содержать адрес других ячеек памяти, таким образом давая нам косвенность. Без указателей (на низком уровне) большинство сложных структур данных было бы невозможно. Никакие связанные списки, двоичные деревья или хеш-таблицы. Никакая передача ссылкой, только значением. Так как указатели могут указать на код, без них у нас также не было бы виртуальных функций, или функция ищут таблицы.

4
ответ дан 28 November 2019 в 00:34
поделиться

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

SomeObject store[100];
int a_ptr = 20;
SomeObject A = store[a_ptr];

Одна проблема с этим подходом состоит в том, что после того, как я изменил, я должен буду повторно присвоиться, он к 'хранилищу' выстраивает для изменений, чтобы быть постоянным:

store[a_ptr] = A;

Негласно, язык программирования делал несколько операций копии. Большую часть времени это не влияло на производительность. Это главным образом сделало код подверженным ошибкам и повторяющимся.

После того, как я учился понимать указатели, я переехал от реализации подхода обращения массива. Аналогия все еще довольно допустима. Просто полагайте, что массивом 'хранилища' управляет время выполнения языка программирования.

SomeObject A;
SomeObject* a_ptr = &A;
// Any changes to a_ptr's contents hereafter will affect
// the one-true-object that it addresses. No need to reassign.

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

  1. Для предотвращения дорогой операции объектной копии ради производительности.
  2. Некоторый другой фактор не разрешает операцию объектной копии.
  3. Вы хотите вызов функции иметь побочные эффекты на объекте (не передавайте объект, передавайте указатель к тому).
  4. На некоторых языках - если Вы хотите возвратить больше чем одно значение от функции (хотя обычно избежали).
1
ответ дан 28 November 2019 в 00:34
поделиться

Я нахожусь в настоящее время по пояс в разработке некоторого программного обеспечения предприятия высокого уровня, в котором на блоки данных (сохраненный в базе данных SQL, в этом случае) ссылаются 1 или более других объектов. Если блок данных остается, когда больше объектов не ссылается на него, мы тратим впустую устройство хранения данных. Если контрольные точки так данные это не присутствует, это - большая проблема также.

существует сильная аналогия, которая будет сделана между нашими проблемами и теми из управления памятью на языке, который использует указатели. Чрезвычайно полезно смочь говорить с моими коллегами с точки зрения той аналогии. Не удаление не имеющих ссылки данных является "утечкой памяти". Ссылка, которая не идет никуда, является "висячим указателем". Мы можем выбрать явный, "освобождает", или мы можем реализовать "сборку"мусора"" с помощью "подсчета ссылок".

, Таким образом, здесь, понимая управление памятью низкого уровня помогает разработать высокоуровневые приложения.

В Java Вы используете указатели все время. Большинство переменных является указателями на объекты - который является почему:

StringBuffer x = new StringBuffer("Hello");
StringBuffer y = x;
x.append(" boys");
System.out.println(y);

... печать "Привет мальчики" и не "Привет".

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

2
ответ дан 28 November 2019 в 00:34
поделиться

Я использую указатели и ссылки в большой степени в мое время на дневную работу... в управляемом коде (C#, Java) и неуправляемый (C++, C). Я узнал о том, как иметь дело с указателями и что они самим ведущим устройством... [Binky!!] [1] Ничто иное не должно быть сказано ;)

, различие между указателем и ссылкой - это. Указатель является адресом к некоторому блоку памяти. Это может быть переписано или другими словами, повторно присвоено некоторому другому блоку памяти. Ссылка является просто переименованием некоторого объекта. Это может только быть присвоено однажды! После того как это присвоено объекту, это не может быть присвоено другому. Ссылка не является адресом, это - другое название переменной. Выезд C++ FAQ для больше на этом.

Link1

LInk2

4
ответ дан 28 November 2019 в 00:34
поделиться

Если Вы не видели указатели прежде, Вы, конечно, пропускаете этот мини-драгоценный камень:

void strcpy(char *dest, char *src)
{    
        while(*dest++ = *src++);
}
4
ответ дан 28 November 2019 в 00:34
поделиться

Так как Вы программировали на объектно-ориентированных языках, позвольте мне поместить его этот путь.

Вы добираетесь, Объект A инстанцируют Объекта B, и Вы передаете его как параметр метода для Возражения C. Объект C изменяет некоторые значения в Объекте B. Когда Вы вернулись для Возражения коду A, Вы видите измененное значение в Объекте B. Почему это так?

, поскольку Вы передали в ссылка из Объекта B для Возражения C, не сделанному другой копией Объекта B. Так Объект A и Объект C оба содержат ссылки на тот же Объект B в памяти. Изменения от одного места и быть замеченным в другом. Это называет Ссылка.

Теперь, если Вы используете типы примитивов вместо этого, как интервал или плавание, и передаете их как параметры метода, изменения в Объекте C не могут быть замечены Объектом A, потому что Объект просто переданный копия вместо ссылки ее собственной копии переменной. Это называет Значение.

Вы, вероятно, уже знали это.

Возвращение на язык C, Функция передачи в Функцию B некоторые переменные. Эти параметры функции являются исходно копиями Значением. Для Функции B для управления копией, принадлежащей Функции A Функция, Необходимость передает указатель к переменной, так, чтобы это стало передачей Ссылкой.

"Эй, вот адрес памяти к моей целочисленной переменной. Поместите новое значение в то местоположение адреса, и я возьму позже".

Примечание понятие подобно, но не на 100% аналогично. Указатели могут сделать намного больше, чем просто передача "ссылкой". Указатели позволяют функциям управлять произвольными местоположениями памяти к любому требуемому значению. Указатели также используются для указания на новые адреса код выполнения для динамичного выполнения произвольной логики, не просто переменных данных. Указатели могут даже указать на другие указатели (двойной указатель). Это мощно, но также и довольно легко представить труднообнаруживаемые ошибки и уязвимости системы обеспечения безопасности.

5
ответ дан 28 November 2019 в 00:34
поделиться

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

Это очень похоже на программирование прямо сейчас. Существует потребность в разработке C/C++ на некотором программном обеспечении. Некоторыми примерами являются высокопроизводительные 3D игры, низкоуровневое встроенное программное обеспечение, вещи, где скорость является критической частью цели программного обеспечения, и более низкий язык уровня, который предоставляет Вам более близкий доступ к фактическим данным, которые должны быть обработаны, является ключевым для той производительности. Однако для большинства программистов дело обстоит не так и не знания указателей не наносит вред. Однако я действительно полагаю, что все могут извлечь выгоду из приобретения знаний о C и указателях и механических коробках передач также.

10
ответ дан 28 November 2019 в 00:34
поделиться

Это похоже на выяснение, эту одержимость “what инструкциями ЦП? Я пропускаю что-то, не опрыскивая инструкции x86 MOV повсеместно? ”

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

Так... Не беспокойтесь. Вы уже используете указатели - и без опасностей сделать так неправильно, также. :)

12
ответ дан 28 November 2019 в 00:34
поделиться

Вы пропускаете много! Понимание, как компьютерные работы на более низких уровнях очень полезны в нескольких ситуациях. C и ассемблер сделает это для Вас.

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

, Конечно, это не работает над современными системами. Операционная система является Господом и Ведущим устройством оперативной памяти. При попытке получить доступ к неправильной ячейке памяти, то Ваш процесс заплатит за свою гордость с его жизнью.

В C, указатели являются способом передать ссылки на данные. Когда Вы вызываете функцию, Вы не хотите копировать миллион битов в стек. Вместо этого Вы просто говорите, где данные находятся в оперативной памяти. Другими словами, Вы даете указатель к данным.

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

28
ответ дан 28 November 2019 в 00:34
поделиться

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

Вам решать, думаете ли Вы, что это - хорошая вещь сделать, но это - основание того, как что-либо сделано в C или ассемблере.

Высокоуровневые языки скрывают указатели негласно: например, ссылка в Java реализована как указатель почти в любой JVM, с которой Вы столкнетесь, который является, почему это назвало NullPointerException, а не NullReferenceException. Но это не позволяет программисту непосредственно получить доступ к адресу памяти, на который это указывает, и это не может быть изменено для принятия значения кроме адреса объекта корректного типа. Таким образом, это не предлагает то же питание (и ответственность), что указатели на низкоуровневых языках делают.

[Редактирование: это - ответ на вопрос, 'какова эта одержимость указателями?'. Все, что я сравнил, является assembler/C-style указателями со ссылками Java. Заголовок вопроса с тех пор изменился: я намеревался отвечать на новый вопрос, я, возможно, упомянул ссылки на языках кроме Java]

14
ответ дан 28 November 2019 в 00:34
поделиться

Строки фундаментальны для C (и другие связанные языки). При программировании в C необходимо управлять памятью. Вы только говорите "хорошо, мне будет нужен набор строк"; необходимо думать о структуре данных. В каком количестве памяти Вы нуждаетесь? Когда Вы выделите его? Когда Вы освободите его? Скажем, Вы хотите 10 строк, каждого больше чем без 80 символов.

Хорошо, каждая строка является массивом символов (81 символ - Вы не должны забывать пустой указатель, или Вы будете сожалеть!) и затем каждая строка находится самостоятельно в массиве. Конечным результатом будет многомерный массив что-то как

char dict[10][81];

Примечание, несущественно, что dict не является "строкой" или "массивом" или "символом". Это - указатель. То, когда Вы пытаетесь распечатать одну из тех строк, все, что Вы делаете, передает адрес отдельного символа; C предполагает, что, если он только начинает печатать символы, он в конечном счете поразит пустой указатель. И это предполагает, что, если Вы в начале одной строки, и Вы переходите вперед 81 байт, Вы будете в начале следующей строки. И, на самом деле взятие Вашего указателя и добавление 81 байта к нему только возможный путь для перехода к следующей строке.

Так, почему указатели важны? Поскольку Вы ничего не можете сделать без них. Вы не можете даже сделать, что-то простое как распечатывает набор строк; Вы , конечно не можете сделать ничего интересного как связанные списки реализации, или хешей, или очередей, или деревьев, или файловой системы, или некоторого кода управления памятью или ядра или... безотносительно. НЕОБХОДИМО понять их, потому что C просто вручает Вам блок памяти и позвольте нам, Вы делаете остальных, и выполнение чего-либо с блоком необработанной памяти требует указателей.

Также многие люди предполагают, что способность понять указатели коррелирует высоко с программированием навыка. Joel привел этот аргумент среди других. Например

Теперь, я свободно признаю, что программирование с указателями не нужно в 90% кода, написанного сегодня, и на самом деле, это совершенно опасно в производственном коде. Хорошо. Это прекрасно. И функциональное программирование просто не используется очень на практике. Согласованный.

, Но это все еще важно для некоторых самых захватывающих заданий программирования. Без указателей, например, Вы никогда не могли бы работать над ядром Linux. Вы не можете понять строку кода в Linux, или, действительно, любую операционную систему, действительно не понимая указатели.

От здесь . Превосходная статья.

2
ответ дан 28 November 2019 в 00:34
поделиться

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

void swap (int & a, int & b)

или

процедура Swap (var a, b: integer)

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

То же самое и с объектами - не думайте об идентификаторах объектов как об указателях или ссылках на "вещи". Вместо этого просто думайте о них как об ОБЪЕКТАХ, которым вы можете отправлять сообщения. Даже в примитивных языках, таких как C ++, вы можете пойти намного дальше намного быстрее, если будете думать (и писать) на как можно более высоком уровне.

Если у вас есть

void swap (int & a, int & b)

или

процедура Swap (var a, b: integer)

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

То же самое и с объектами - не думайте об идентификаторах объектов как об указателях или ссылках на "вещи". Вместо этого просто думайте о них как об ОБЪЕКТАХ, которым вы можете отправлять сообщения. Даже в примитивных языках, таких как C ++, вы можете пойти намного дальше намного быстрее, если будете думать (и писать) на как можно более высоком уровне.

Тот факт, что это реализуется путем передачи адресов переменных, просто отвлекает от цели.

То же самое и с объектами - не думайте об идентификаторах объектов как об указателях или ссылках на "вещи". Вместо этого просто думайте о них как об ОБЪЕКТАХ, которым вы можете отправлять сообщения. Даже в примитивных языках, таких как C ++, вы можете пойти намного дальше намного быстрее, если будете думать (и писать) на как можно более высоком уровне.

Тот факт, что это реализуется путем передачи адресов переменных, просто отвлекает от цели.

То же самое и с объектами - не думайте об идентификаторах объектов как об указателях или ссылках на "вещи". Вместо этого просто думайте о них как об ОБЪЕКТАХ, которым вы можете отправлять сообщения. Даже в примитивных языках, таких как C ++, вы можете пойти намного дальше намного быстрее, если будете думать (и писать) на как можно более высоком уровне.

0
ответ дан 28 November 2019 в 00:34
поделиться
Другие вопросы по тегам:

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