Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/75: Рейтинг темы: голосов - 75, средняя оценка - 4.55
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32

Ссылки vs указатели - в чем разница?

21.11.2015, 20:04. Показов 16754. Ответов 150
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Навеяно соседней темой. Не понимаю в чем разница, хотя несколько раз честно пробовал почитать на эту тему, правда без должного внимания и усердия. Зато программировал на ассемблере и чистом С, понимаю абстракцию "адрес ячейки памяти" и "размер типа в байтах", с арифметикой указателей и указателями на указатели сложностей вроде не испытываю Есть переменная, если она не регистровая - то лежит в какой-то ячейке памяти (или нескольких, зависит от разрядности памяти и структуры типа переменной), адрес этой ячейки (ака указатель) я могу запоминать в другую переменную типа указателя, передавать/возвращать ее из функций, инкрементировать/декрементировать для движения по массиву переменных (если я его предварительно нарезал в той области памяти конечно), разыменовывать и получать/изменять значение. Вроде все. При чем тут термин "ссылки"? А еще оказывается бывают смартпоинтеры, умные указатели и прочие страшные слова
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.11.2015, 20:04
Ответы с готовыми решениями:

Указатели и ссылки: в чем разница
Здравствуйте, объясните, пожалуйста, в чем разница между "ссылается" и "указывает"?

Указатели и ссылки: в чём их разница и сходство?
Я начал учить с++ и не могу кое в чём разобраться. Кто знает ответы на эти вопросы может ответить или скинуть какую нибудь ссылку где это...

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

150
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
22.11.2015, 00:38
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от ct0r Посмотреть сообщение
Кстати, кто-нибудь упоминал, что ссылки нельзя переназначать, а указатели можно?
вроде нет. Также, например, массив ссылок нельзя сделать.
0
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
22.11.2015, 00:56  [ТС]
Пока я ходил на каток, похоже, пропустил много интересного и уже безвозвратно зачищенного
По-хорошему, надо курить ссылку от Nosey. Но на уровне манки-ламера можно наверное сформировать некоторый условно похожий на правду образ семантического эквивалента данных абстракций, не вдаваясь в детали. В конце концов, в одном известном мне языке нет прямого доступа к памяти, более того - он вообще интерпретируемый, но при этом возможно указать вариант передачи параметра в функцию - по значению или по ссылке - с соответствующим предсказуемым поведением.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.11.2015, 01:23
Цитата Сообщение от ct0r Посмотреть сообщение
А если переменной по этому адресу уже нет, то будет все равно больно.
Ну так это и значит невалидные данные. Но даже локальная ссылка которую вернули была ведь инициализирована. А весь сыр бор был :
Цитата Сообщение от Croessmah Посмотреть сообщение
она не может быть не инициализирована, а невалидные данные - пожалуйста, сколько влезет.
с чем я и согласился.
Хотя конечно, если кратко, то ссылка отличается от указателя тем, что она ссылка. Все остальные варианты будут страдать неполнотой, даже если горы книжек перепечатать.
1
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
22.11.2015, 01:37  [ТС]
Пробую собрать зачатки мыслей на уровне манки-кодера, без л-р-х-валью.

Указатели - это про память. Это прямой адрес памяти (реальный/виртуальный - неважно). Что при этом лежит по данному адресу - неизвестно. Вообще-то типизирован, но можно запросто перетипизировать - и прочитать/записать по адресу стартовой ячейки совсем другой тип: например, записали 4 байта инта, потом перетипизировали к чару и прочитали 4 однобайтовых чара по смещению. Море возможностей - море ответственности и вариантов отстрелить ногу. Можно делать указатели на указатели и т.п. и складывать их в любые контейнеры. Является значением первого класса - может передаваться/возвращаться из функций и присваиваться переменным, можно прибавлять/вычитать смещения и получать новые адреса памяти.

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

Много я неправ? Много я упустил?
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
22.11.2015, 01:58
Цитата Сообщение от _Ivana Посмотреть сообщение
можно запросто перетипизировать
тип переменной в памяти не изменить - все манипуляции с кастами это новая временная переменная.

Цитата Сообщение от _Ivana Посмотреть сообщение
Нельзя делать больше ничего
Еще используется для читаемости вложенных структур, к примеру, rapidjson дерево - куча вложеностей и всё такое.
C++
1
rapidjson::Value& imgURL = document['root']['img'][i]['url'];
Так же хочется отметить, что просматривая чужой код
C++
1
2
    MyArray arr;
    f(arr);
то, что
C++
1
f(MyArray& obj);
можно и не заметить - подразумивая, что передали по значению.
0
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
22.11.2015, 02:32
Цитата Сообщение от _Ivana Посмотреть сообщение
Ссылки - это про вариант передачи параметров в функцию - и все. Нельзя делать больше ничего.
Ещё как минимум можно возвращать ссылку, тем самым давая возможность изменять данные, либо не давая если юзать const.

Цитата Сообщение от _Ivana Посмотреть сообщение
ни записать в переменную
Ссылки записываются в переменную, но соответственно при записи в поле класса, компилятор сгенерит переменную как указатель.

Цитата Сообщение от rikimaru2013 Посмотреть сообщение
тип переменной в памяти не изменить - все манипуляции с кастами это новая временная переменная.
Малое уточнение. Если под переменной понимать - символы в исходном коде, то да, если же под переменной понимать область в памяти - то нет.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.11.2015, 02:55
_Ivana, это конечно в основном для передачи в функцию сделано, но если напрячься можно здорово оттянуться. Вот Андрей смотри какой счетчик. Совершенно безопасный. Деревянный можно сказать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
using namespace std;
 
int &fooCount()
{
static int initialVal=0;
static int garbage=0;
if(garbage>10)garbage=0;
if(garbage<0){
garbage=initialVal;
return initialVal;
}else
initialVal=garbage;
return garbage;
}
 
int  main(void)
{
int counT=0;
while(counT<3){
cout<<fooCount()++<<" ";
if(!fooCount()){counT++;cout<<endl;}
}
    cout << endl;
    system("pause");
    return 0;
}
1
4949 / 2289 / 287
Регистрация: 01.03.2013
Сообщений: 5,991
Записей в блоге: 32
22.11.2015, 03:07  [ТС]
IGPIGP, отформатировал для читаемости и разбираю ваш пример. Функция возвращает именно ссылку на свою статическую переменную, и поэтому можно в месте вызова интрементировать ее? Да, этот вариант я не предполагал
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.11.2015, 11:04
Цитата Сообщение от _Ivana Посмотреть сообщение
Функция возвращает именно ссылку на свою статическую переменную
Да.
Цитата Сообщение от _Ivana Посмотреть сообщение
и поэтому можно в месте вызова интрементировать ее?
Делать всё что позволяет левостороннее значение. Присваивать, например: foo()=123;


Добавлено через 22 минуты
Цитата Сообщение от _Ivana Посмотреть сообщение
разбираю ваш пример.
Да шутка это. Кстати для записи рекурсивных вызовов штука забавная.
А вот ещё весёлое место. Посмотрим тело функции не глядя в сигнатуру:
C++
1
2
3
4
5
6
7
if(garbage<0){
garbage=initialVal;
return initialVal;
}else
initialVal=garbage;
return garbage;
}
и кажется что
C++
1
2
3
4
5
6
if(garbage<0)
garbage=initialVal;
else
initialVal=garbage;
return initialVal;
}
просто компатнее/лучше.
И это только кажется.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
22.11.2015, 12:01
На всякий случай. Пример с ссылками и эквивалентный им код с указателями
Сравнение указателей и ссылок.

Добавлено через 3 минуты
Ссылки и указатели
Можно ли для стд::вектор'а взять адрес и-го элемента?
4
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.11.2015, 14:14
Цитата Сообщение от _Ivana Посмотреть сообщение
Много я неправ? Много я упустил?
идеологически, ссылка - псевдоним имени объекта.
обращение к ссылке,
это на самом деле обращение к оригинальному объекту.

вам нужно ответить себе на один единственный вопрос:

вот есть у вас указатель.

чем является реультат разыменовывания указателя?

C++
1
   *pointer; //<--- какой тип данных будет иметь результат выражения

ответите на этот вопрос, и все встанет на свои места.
2
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.11.2015, 14:23
Цитата Сообщение от hoggy Посмотреть сообщение
вам нужно ответить себе на один единственный вопрос
Неужели ссылка?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.11.2015, 14:25
Цитата Сообщение от IGPIGP Посмотреть сообщение
Неужели ссылка?
гениальное - просто
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.11.2015, 14:33
Цитата Сообщение от hoggy Посмотреть сообщение
просто
Обычно говорят о инициализированном, константном указателе (который авторазыменовывается)).
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.11.2015, 14:35
Цитата Сообщение от IGPIGP Посмотреть сообщение
Обычно говорят о инициализированном, константном указателе (который авторазыменовывается)).
из-за поведенческих подобий создаются иллюзии,
из-за которых неокрепшие умы начинают путать причину и следствие.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.11.2015, 14:38
Цитата Сообщение от hoggy Посмотреть сообщение
из-за которых неокрепшие умы начинают путать причину и следствие
Бедолаги. Если будет время и желание поинтересуйтесь от кого сие исходит. Я не могу это присвоить, потому как не я это придумал.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.11.2015, 14:49
Цитата Сообщение от IGPIGP Посмотреть сообщение
Если будет время и желание поинтересуйтесь от кого сие исходит.
в книжках для начинающих совершаются различные допущения,
что бы упростить материал.

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

я приведу пример.


поскольку ссылка - всевдоним оригинального объекта,
а все действия над ссылкой - есть действия над оргинальным объектом,

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

и вот здесь мы можем попадать на интересные порадоксы:

может ли размер отдельного члена класса быть больше, чем размер всего класса вместе взятого?
да не вопрос:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
 
struct some
{
    
    some(int (&refArr)[3])  : m_ref(refArr) 
    {
        
        if(sizeof(some) < sizeof( m_ref))
           std::cout<< "trololo\n";
    }
 
    int (&m_ref)[3] ;
};
 
 
int main()
{
    std::cout << "Hello, world!\n";
    
    int a[] ={1,2,3};
    
    some obj(a);
}
свойства ссылочных типов широко используются в метапрограммировании.
в областях, где важны свойства типов.


но для обычного прикладного программиста - разница между ссылкой,
и автиоразыменовывающимсчя указателем должна быть не принципиальной.
2
 Аватар для Nosey
1379 / 406 / 144
Регистрация: 22.10.2014
Сообщений: 872
22.11.2015, 14:57
Цитата Сообщение от IGPIGP Посмотреть сообщение
Бедолаги. Если будет время и желание поинтересуйтесь от кого сие исходит. Я не могу это присвоить, потому как не я это придумал.
А вот и доказательство:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef _FUNCTION_NAME_
#ifdef __FUNCSIG__
#define _FUNCTION_NAME_ __FUNCSIG__
#else
#define _FUNCTION_NAME_ __PRETTY_FUNCTION__
#endif
#endif
 
template<class T>
void whatIs(T&&)
{
    std::cout << _FUNCTION_NAME_ << std::endl;
}
 
 
int main()
{
    int* a = new int();
    whatIs(*a);
 
    return 1;
}
Для понимания, нужно баловаться верхней штукой, этак денёк, скармливая получаемые параметры, поля структур, возвращаемые значения...
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.11.2015, 15:06
Цитата Сообщение от hoggy Посмотреть сообщение
в книжках для начинающих совершаются различные допущения,
что бы упростить материал.
Дык мы же в разделе новичков. Всё что тут есть - для них, в первую очередь. Есть ещё 2 раздела и там иногда говорят о ссылках && и move семантике.
Цитата Сообщение от hoggy Посмотреть сообщение
все действия над ссылкой - есть действия над оригинальным объектом,
согласен. На запрос sizeof() ссылка не отвечает как самостоятельный тип. Ссылку нельзя перенаправить и эта её скрытая константность не присуща больше никаким типам. Моё личное мнение, ссылка - внутренне противоречивая вещь и тут я с Вами совершенно согласен.
А для новичков главное понять как работает передача аргументов в параметры-ссылки. Этого вполне достаточно чтобы вдоволь поучиться.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.11.2015, 15:17
Цитата Сообщение от Nosey Посмотреть сообщение
А вот и доказательство:
мало того, что ничего не доказывает,
так ещё и не компилируется.

когда вы уже научитесь по человечесчки выкладывать материал?


пример:

по возможности указываем ссылку на онлайн компилятор,
с примером-иллюстрацией

http://rextester.com/CKLP43241


далее выкладываем исходный код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <cassert>
 
template<class T>
bool isReference(T&& obj)
{
    if( std::is_reference< decltype(obj) > :: value)
        return std::cout << "reference\n", true;
    
    return std::cout << "other\n", false;
}
 
 
int main()
{
    int v = 10;
    
    
    int* p = &v;
    const auto success = isReference(*p);
    
    assert(success  && "ERROR: expected reference" );
    
}
особое внимание: код должен без вопросов компилироваться.

бегать за вами, и подбирать после вас недостающие куски кода - это неуважение к чужому времени.

Добавлено через 6 минут
Цитата Сообщение от IGPIGP Посмотреть сообщение
и эта её скрытая константность не присуща больше никаким типам.

более того.

на самом деле, ссылка - единственный тип данных на языке с++,
который в принципе не обладает квалификатором const.

лично я однажды обжегся на этом в метапрограммировании:

обычно константными ссылками называют ссылки,
которые ссылаются на неизменяемые объекты.
но в реальности это - полная фигня.

потому что :

http://rextester.com/ENTQ87083
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
 
int main()
{
    std::cout << "Hello, world!\n";
    
    
    const int v = 10;
    
    const int& r = v;
    
    enum { is_const = std::is_const<   decltype(r)  >::value };
    
    if(!is_const)
        std::cout << "const int& r is not const\n";
    else
        std::cout << "const int& r is const\n";
    
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.11.2015, 15:17
Помогаю со студенческими работами здесь

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

Ссылки и указатели
Добрый день. Возможно было. В чем существенная разница между передачей данных в функцию по ссылке или указателю. В каких случаях вы бы...

Указатели и ссылки [С++]
Всем привет. я тут программу делаю. Цель: определить,принадлежит ли точка заданному промежутку(а точнее лежит внутри или снаружи фигуры)....

Ссылки и указатели
Вот есть код в котором я проверял как ведут себя указатели : using namespace std; int* first() { int p = 5; cout &lt;&lt;...

Ссылки и указатели
Здравствуйте, может кто объяснить в чем будет отличие при передаче в функцию по **, *, *&amp;, &amp;(**), желательно на примерах простых


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Хитросплетение родственных связей пантеона греческих богов.
russiannick 14.05.2026
Однооконник, позволяющий узреть и изучить отдельных героев древней Греции. <!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible". . .
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов. import "math" func angleClock(hour int, minutes int) float64 { . . .
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html и его же старой инструкции по установке Lazarus с gtk2. . .
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер. Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром. возможно получится прикрутить интерпретатор питон для кастомизации игровой логики. что есть на текущий момент:. . .
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2. Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru