Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.87/46: Рейтинг темы: голосов - 46, средняя оценка - 4.87
 Аватар для gomodril
6 / 6 / 0
Регистрация: 10.10.2012
Сообщений: 140

Расскажите популярно про ссылки и указатели

04.01.2013, 16:05. Показов 10648. Ответов 110
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите разобраться со ссылками и указателями на различные объекты. Запутался вообще в них полностью. Когда читаю книгу про них, то вроде все понятно написано, но примеров для меня видимо не достаточно, что бы как то их различать. В итоге начинаю решать задачи и ни чего не выходит.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.01.2013, 16:05
Ответы с готовыми решениями:

Популярно объясните про указатели
Что-то плохо даётся мне тема про указатели. Я хорошо уяснил, что вот так создаётся указатель: int *pointer; Я так же хорошо...

Пояснить про указатели и ссылки
есть переменное и указатель.. Значение нашей переменной случайный адрес, Как менять адрес указателя, таким образом, что бы она стала...

Что нужно знать про указатели и ссылки?
Привет, завтра кр по теме указатели и ссылки в с++, пишите сюда что необходимо знать.

110
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
04.01.2013, 16:23
Указатель содержит в себе адрес некоего объекта и не стесняется этого. Для обращения непосредственно к объекту используется разыменование (*), адрес в указателе можно заменить на другой. То, что тип - указатель, обозначается звёздочкой (заметим, при обозначении типов и создании переменных у звёздочки смысл именно "указатель", а вот при использовании уже готовых указателей, её смысл - разыменование).
Ссылка "маскируется" под какой-то конкретный объект. Доступ к объекту по ссылке происходит так же, как если бы это был сам объект, "перенастроить" ссылку на другой объект нельзя, поэтому она всегда гарантированно ссылается на один и тот же объект, что часто помогает оптимизации. То, что тип - ссылка, обозначается символом & в составе типа (при использовании с готовыми переменными символ & имеет смысл взятия адреса, такой адрес как раз и можно залить в соответствующий указатель).
Это так, общая ориентировка для начала... Дальше уже по конкретным вопросам
1
 Аватар для gomodril
6 / 6 / 0
Регистрация: 10.10.2012
Сообщений: 140
04.01.2013, 17:00  [ТС]
Хорошо, тогда к примеру указатель на символ я правильно объявляю?

char si = 'H';
int si_1 = (int&) si;

В этом случае в si_1 будет адрес переменной si. А если я сделаю как в книжке написано:

char si = 'H';
char * si_1 = & si;

то в переменной si_1 будет HMMM. Вот я и стал путаться.
0
погромист
 Аватар для coloc
415 / 251 / 30
Регистрация: 27.08.2012
Сообщений: 550
04.01.2013, 17:05
C++
1
2
3
char s = 'H';
char* ps = &s;
cout << *ps;
В переменной si_1 будет адрес si, а не символы
0
 Аватар для gomodril
6 / 6 / 0
Регистрация: 10.10.2012
Сообщений: 140
04.01.2013, 17:08  [ТС]
Цитата Сообщение от coloc Посмотреть сообщение
C++
1
2
3
char s = 'H';
char* ps = &s;
cout << *ps;
В этом случае будет выведена Н, тогда смысл вообще от этих ссылок и указателей, если можно просто вывести значение переменной s...
0
погромист
 Аватар для coloc
415 / 251 / 30
Регистрация: 27.08.2012
Сообщений: 550
04.01.2013, 17:13
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 #include <iostream>
 
using namespace std;
 
void func (char a)
{
     a = 'l';
     cout << "\nin func a = " << a;
} 
 
int main(){
    char a = 'H';
    cout << "\nin main a = " << a;
    func (a);
    cout << "\nafter func a = " << a;
    system ("PAUSE");
    return 0;
 }
Допустим, нам нужно, чтобы функция поменяла значение а. Тогда делаем через указатели
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 #include <iostream>
using namespace std;
 
void func (char* a)
{
     *a = 'l';
     cout << "\nin func a = " << *a;
} 
 
int main(){
    char a = 'H';
    cout << "\nin main a = " << a;
    func (&a);
    cout << "\nafter func a = " << a;
    system ("PAUSE");
    return 0;
 }
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.01.2013, 17:22
Указатель есть данное, хранящее адрес подпрограммы, или другого данного. Указатель на не указатель называется простым, указатель на указатель кратным, указатель на указатель на не указатель двойным, указатель на указатель на указатель на не указатель тройным и так далее. Сколько указателей надо пройти, чтоб добраться до неуказателя, в том числе, до составного данного, содержащего в том числе, но не только указатели, такова кратность.

Добавлено через 2 минуты
Цитата Сообщение от Nick Alte Посмотреть сообщение
Для обращения непосредственно к объекту используется разыменование (*),
разыменование есть операция, "говорящая" компилятору, что на низком уровне указатель должен быть использован для косвенной адресации, то есть операция разыменования читает из своего операнда (указателя) его значение, которое есть адрес и осуществляет доступ по этому адресу.

Добавлено через 4 минуты
Цитата Сообщение от Nick Alte Посмотреть сообщение
Ссылка "маскируется" под какой-то конкретный объект.
Ссылка - это синоним другого данного. Можно считать, что ссылка - это нечто, ведущее себя как указатель, неявно (то есть без прямого на то указания в исходном тексте) разыменуемый при каждом обращении к нему. Но стандарт не гарантирует, что ссылка будет реализована именно так. Единственный случай, когда в этом можно быть уверенным - это ссылка-параметр не инлайнового оператора (если такие бывают), или неинлайновой подпрограммы, так как в этом случае нет технической возможности реализовать ссылку как либо ещё, кроме синтаксической надстройки над указателем.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
04.01.2013, 17:25
Цитата Сообщение от taras atavin Посмотреть сообщение
для косвенной адресации
может и для прямой, тут как компилятору будет удобно.
0
 Аватар для ~B~
7 / 7 / 1
Регистрация: 12.06.2011
Сообщений: 80
04.01.2013, 17:26
Цитата Сообщение от gomodril Посмотреть сообщение
int si_1 = (int&) si;
так разве можно?
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.01.2013, 17:26
Как звёздочка в декларации, или операторе приведения типа говорит об указателе, или повышает его кратность, а в остальных местах становится операцией разыменования, так и амперсанд в декларации означает ссылку, а в любом другом месте операцию взятия адреса. Эта операция берёт адресе своего операнда, потом его можно присвоить указателю (ведь адрес - это значение указательного типа). Семантически эта операция обратна операции разыменования.
0
 Аватар для ~B~
7 / 7 / 1
Регистрация: 12.06.2011
Сообщений: 80
04.01.2013, 17:27
http://www.cplusplus.com/doc/tutorial/pointers/
вот тут отлично объясняется, если с инглишом проблем нет
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.01.2013, 17:27
Цитата Сообщение от Kastaneda Посмотреть сообщение
может и для прямой, тут как компилятору будет удобно.
Прямая - это адрес в коде, а в разыменовании он берётся из данного.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
04.01.2013, 17:29
Цитата Сообщение от taras atavin Посмотреть сообщение
Можно считать, что ссылка - это нечто, ведущее себя как указатель, неявно (то есть без прямого на то указания в исходном тексте) разыменуемый при каждом обращении к нему. Но стандарт не гарантирует,...
Да, если ссылка не используется как передаваемый параметр, то компилятор на этапе построения таблицы имен может просто связать имя ссылки с адресом переменной, т.е. получится просто синоним для переменной.

Добавлено через 1 минуту
Цитата Сообщение от taras atavin Посмотреть сообщение
Прямая - это адрес в коде, а в разыменовании он берётся из данного.
Цитата Сообщение от taras atavin Посмотреть сообщение
что на низком уровне указатель должен быть использован для косвенной адресации
Если говорить о низком уровне, то прямая - это использование адреса (того, что в указателе), а косвенная - это когда адрес предварительно кладется в регистр.
0
 Аватар для ~B~
7 / 7 / 1
Регистрация: 12.06.2011
Сообщений: 80
04.01.2013, 17:31
а не могли бы вы привести пример с использованием инкрементирования указателя для определенных задач, связанных с массивом?
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.01.2013, 17:35
Но ведь адрес то не в коде операции, он вообще вынесен за пределы кода и указатель текущей операции на него попасть ни как не может. Сначала надо загрузить данное, а потом уже использовать, как адрес. Но процессор не способен загрузить какое либо данное куда то кроме регистра.

Добавлено через 1 минуту
Цитата Сообщение от ~B~ Посмотреть сообщение
а не могли бы вы привести пример с использованием инкрементирования указателя для определенных задач, связанных с массивом?
Вывод массива в поток:
C++
1
2
3
4
5
6
int a[10]={431, 312, 42, 13, 431, 5531, 53, 5, 5, 131};
int *p;
for (p=a; p<=a+9; ++p)
{
 std::cout<<*p<<", ";
}
.
1
 Аватар для gomodril
6 / 6 / 0
Регистрация: 10.10.2012
Сообщений: 140
04.01.2013, 17:35  [ТС]
Цитата Сообщение от taras atavin Посмотреть сообщение
Как звёздочка в декларации, или операторе приведения типа говорит об указателе, или повышает его кратность, а в остальных местах становится операцией разыменования, так и амперсанд в декларации означает ссылку, а в любом другом месте операцию взятия адреса. Эта операция берёт адресе своего операнда, потом его можно присвоить указателю (ведь адрес - это значение указательного типа). Семантически эта операция обратна операции разыменования.
Т.е. это:

char si = 'H';
int si_1 = (int&) si;

То же самое что и:

char si = 'H';
int * si_1 = &si;

Я правильно понимаю?
0
04.01.2013, 17:36

Не по теме:

Цитата Сообщение от taras atavin Посмотреть сообщение
Но процессор не способен загрузить какое либо данное куда то кроме регистра.
Способен - может так же писать/читать в/из памяти. Например
Assembler
1
2
mov [0x12345678], еах; пишем значение из регистра ЕАХ в память по адресу DS:0x12345678
mov [0x12345678], 0х123; пишем значение 0х123 в память по адресу DS:0x12345678
точно так же можно производить арифметические операции с памятью/регистром.

0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.01.2013, 17:41
Цитата Сообщение от gomodril Посмотреть сообщение
int si_1 = (int&) si;
В операторе приведения типа разрешено использовать звёздочку при приведении к указательному типу, а оперсанд там не должен поддерживаться по логике своих значений: нельзя привести к ссылке и нельзя брать адрес в операторе приведения, а только отдельной операцией.

Добавлено через 1 минуту
Цитата Сообщение от Kastaneda Посмотреть сообщение
Способен - может так же писать/читать в/из памяти. Например
Читать куда? А писать в память - это, видимо, из регистра. Ну может какие то процессоры ещё могут из кода. Но надо то в процессор, а не в память, а кроме регистров в нём для этого места нет.

Добавлено через 53 секунды
Цитата Сообщение от Kastaneda Посмотреть сообщение
mov [0x12345678], 0x123; пишем значение 0x123 в память по адресу DS:0x12345678
Это сохранение в память, а я пишу о загрузке данных в процессор.

Добавлено через 51 секунду
Цитата Сообщение от gomodril Посмотреть сообщение
char si = 'H';
int * si_1 = &si;
нет.
C++
1
2
char si='H';
int *si_1=(int*)&si;
Добавлено через 25 секунд
Цитата Сообщение от gomodril Посмотреть сообщение
char si = 'H';
int si_1 = (int&) si;
А так нельзя.
0
погромист
 Аватар для coloc
415 / 251 / 30
Регистрация: 27.08.2012
Сообщений: 550
04.01.2013, 17:43
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>
 
using namespace std;
 
void displayArray (int array[], int size)
{
     cout << "Elements:\n";
     
     int* pArray = array;
     for (int i = 0; i < size; i++, pArray++)
     {
         cout << i << ": " << *pArray << "\n";
     }
     cout << "\n";
}
 
 
int main()
{
    int array [] = {5,546,4,6,1};
    displayArray (array,5);    
    system ("PAUSE");
    return 0;
}
Простенький пример операции вывода на экран массива с помощью указателя
1
04.01.2013, 17:46

Не по теме:

Цитата Сообщение от taras atavin Посмотреть сообщение
Это сохранение в память, а я пишу о загрузке данных в процессор.
Не совсем понимаю о чем ты. Есть указатель, в нем адрес. Задача - записать что-нибудь по этому адресу. Выглядеть это все будет где-то так
Assembler
1
2
mov edx, [0x123]; допустим 0x123 это адрес указателя
mov [edx], 0x123; пишем в память, на которую указывает указатель, значение 0х123
это как раз пример косвенной адресации. Но компилятор может знать, на какую переменную указывает данный указатель и сделать прямую адресацию (это в случае оптимизации). Т.е. выглядеть это будет так
Assembler
1
mov [0x123], 0x123; что либо грузить в процессор не обязательно

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
04.01.2013, 17:46
Помогаю со студенческими работами здесь

Подскажите хорошую статью про указатели и ссылки
Посоветуйте статью, видео или книгу по указателям и ссылкам в C++, где все доходчиво разъяснено с реальными примерами. Уже много чего...

Расскажите про new и delete в C++
Есть несколько вопросов: 1) Можно ли перегрузить несколько операторов new в разных пространствах имен, а потом просто писать int *t =...

Расскажите пожалуйста про флаги
Доброго времени суток. Помогите пожалуйста разобраться с фалагми. Вот код: #include &lt;iostream&gt; #define ID_F 1001 #define ID_D...

Расскажите на пальцах про классы
Доброе время суток! (сразу оговорюсь, можете кинуть ссылкой куда мне пойти почитать) Сижу разбираюсь в классах и собственно вопросы:...

Расскажите про IDE Intel Parallel Studio XE 2015
Реклама на сайте Intel Parallel Studio XE 2015 написано хорошо, а тех кто пользовался стоит ли установить себе? Добавлено через...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru