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

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

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

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

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

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

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

110
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.01.2013, 17:54
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Kastaneda Посмотреть сообщение
Не совсем понимаю о чем ты. Есть указатель, в нем адрес. Задача - записать что-нибудь по этому адресу. Выглядеть это все будет где-
Assembler
1
2
mov edx, [0x123]; допустим 0x123 это адрес указателя
mov [edx], 0x123; пишем в память, на которую указывает указатель, значение 0х123
Вот именно. Обрати внимание, откуда во второй строке берётся адрес.
Цитата Сообщение от Kastaneda Посмотреть сообщение
Если говорить о низком уровне, то прямая - это использование адреса (того, что в указателе), а косвенная - это когда адрес предварительно кладется в регистр.
Адрес должен быть в процессоре, когда его используешь, загрузить его с кодом операции нельзя, так как это данное и пеходить на него процессор не должен. Альтернативы здесь просто нет, в первой строке его больше некуда загрузить.

Добавлено через 1 минуту
Цитата Сообщение от Kastaneda Посмотреть сообщение
Но компилятор может знать, на какую переменную указывает данный указатель
Не может. Компилятор работает до того, как указатель получит значение.

Добавлено через 1 минуту
Цитата Сообщение от Kastaneda Посмотреть сообщение
mov [0x123], 0x123; что либо грузить в процессор не обязательно
Можно, но так адрес должен быть в коде, а он у нас в данном.
0
 Аватар для gomodril
6 / 6 / 0
Регистрация: 10.10.2012
Сообщений: 140
04.01.2013, 17:58  [ТС]
taras atavin,

А почему тогда результат вывода получается разный?

char si = 'H';
char *si_1 = (char*) &si;
int *si_2 = (int*) &si;
std::cout << "==========" << "\n";
std::cout << " Указатель на символ 'si' = " << si_1 << " * " << si_2 << endl;

Это из-за разных типов данных как я понимаю - в первом случае символьный тип и там адрес преобразуется в символьный тип?
0
 Аватар для ~B~
7 / 7 / 1
Регистрация: 12.06.2011
Сообщений: 80
04.01.2013, 17:58
Цитата Сообщение от taras atavin Посмотреть сообщение
Сообщение от ~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<<", ";
}
.
а почему p=a? разве не p=&a?
0
погромист
 Аватар для coloc
415 / 251 / 30
Регистрация: 27.08.2012
Сообщений: 550
04.01.2013, 18:04
Потому что ,,а,, интерпретируется как адрес нулевого элемента массива
В С++ очень тесная связь между указателями и массивами. Массив array[n] интерпретируется как *(&array[0] + n) или проще *(array + n)
1
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
04.01.2013, 18:09

Не по теме:

Цитата Сообщение от taras atavin Посмотреть сообщение
Адрес должен быть в процессоре, когда его используешь,
нет, не обязательно.
Цитата Сообщение от taras atavin Посмотреть сообщение
загрузить его с кодом операции нельзя, так как это данное и пеходить на него процессор не должен
первую фразу не понял. Так прцессор же не переходит по адресу, в который производится запись, он просто туда пищет.
Цитата Сообщение от taras atavin Посмотреть сообщение
Можно, но так адрес должен быть в коде, а он у нас в данном.
без разницы, это не зависит от местоположения памяти. Главное, чтоб в адресуемую память была разрешена запись, а в участок данных она разрешена.
Цитата Сообщение от taras atavin Посмотреть сообщение
Не может. Компилятор работает до того, как указатель получит значение.
C++
1
2
int a;
int *p = &a
компилятор может увидеть, что p указывает на a. Но да, тут нельзя утверждать, что указатель, как сущность, будет вообще выброшен из кода. Но такое может быть.



Добавлено через 4 минуты

Не по теме:

Intel manual

Code
1
2
Opcode   Instruction                   Description
C7 / 0   MOV r/m32, imm32              Move imm32 to r/m32
это значит - опкод операции 0xC7, при этом в байте ModRM на месте регистра всегда записан 0.
r/m32 - это значит регистр либо память размером 32 бита
imm32 - это immediate(непосредственный) операнд размером 32 бита.

0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.01.2013, 18:20
Цитата Сообщение от Kastaneda Посмотреть сообщение
нет, не обязательно.
А ну да эльф может адрес на рельсе выбить, спрятать в го на дубе в центре континента, а дельфин в океане его использует.

Добавлено через 1 минуту
Цитата Сообщение от Kastaneda Посмотреть сообщение
Так прцессор же не переходит по адресу, в который производится запись, он просто туда пищет.
Имеется ввиду адрес, по которому находится сам указатель, данные должны храниться где то.

Добавлено через 52 секунды
Цитата Сообщение от Kastaneda Посмотреть сообщение
без разницы, это не зависит от местоположения памяти. Главное, чтоб в адресуемую память была разрешена запись, а в участок данных она разрешена.
Указатель у тебя тоже среди данных. Как процессор узнает его значение и адрес, по которому надо писать?

Добавлено через 2 минуты
Цитата Сообщение от Kastaneda Посмотреть сообщение
Не может. Компилятор работает до того, как указатель получит значение.
C++
1
2
int a;
int *p = &a;
Эйси. К моменту использования он может поменяться.
C++
1
2
3
4
5
6
7
int a;
int *p = &a;
int *e=p+200;
for (; p<=e; ++p)
{
 *p*=2;
}
Добавлено через 3 минуты
Если же указатель используется однократно и хранит адрес только именованной переменной, то в таких случаях можно разделить то, что имел ввиду кривопрограммист и то, как в действительности будет выглядеть программа. Кривопрограммист имел ввиду, что надо грузить адрес в регистр, прогу же можно оптимизировать и на высоком уровне, превратив
C++
1
2
3
int a;
int *p=&a;
*p=200;
в
C++
1
2
int a;
a=200;
.
0
ComfyMobile
 Аватар для Nixy
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
04.01.2013, 18:24
Цитата Сообщение от taras atavin Посмотреть сообщение
int a;
a=200;

Не по теме:

взял и испортил индийский код :D



Добавлено через 31 секунду
а вообще
taras atavin, прав, прекратите уже оффтоп дискуссию)
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.01.2013, 18:25
Цитата Сообщение от gomodril Посмотреть сообщение
char si = 'H';
char *si_1 = (char*) &si;
А здесь нафига приведение типа?
C++
1
2
char si='H';
char *si_1=&si;
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
04.01.2013, 18:26
Цитата Сообщение от taras atavin Посмотреть сообщение
А ну да эльф может адрес на рельсе выбить, спрятать в го на дубе в центре континента, а дельфин в океане его использует.
Я привел цитату из мануала Intel с описанием инструкции mov. Судя по нему операция
Assembler
1
mov [0x123], 0x123
абсолютно валидная. Т.е. запись по адресу определенного значения это вполне нормально и это не зависит от того, в каком сегменте (хотя "сегмент" это уже условность) расположена адресуемая память.
Цитата Сообщение от taras atavin Посмотреть сообщение
Указатель у тебя тоже среди данных. Как процессор узнает его значение и адрес, по которому надо писать?
линковщик подставит нужные адреса в нужные места.
Цитата Сообщение от taras atavin Посмотреть сообщение
Если же указатель используется однократно и хранит адрес только именованной переменной, то в таких случаях можно разделить то, что имел ввиду кривопрограммист и то, как в действительности будет выглядеть программа. Кривопрограммист имел ввиду, что надо грузить адрес в регистр.
Дело не в "кривопрограммисте". Компилятор умеет оптимизировать подобные вещи.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
04.01.2013, 18:31
Цитата Сообщение от gomodril Посмотреть сообщение
Это из-за разных типов данных как я понимаю - в первом случае символьный тип и там адрес преобразуется в символьный тип?
Адрес нельзя преобразовывать в неуказательный тип, а символьный указательным не является. Только не говори индусам, для них это крамола.

Добавлено через 2 минуты
Цитата Сообщение от Kastaneda Посмотреть сообщение
Я привел цитату из мануала Intel с описанием инструкции mov. Судя по нему операция
Код ASM
1
mov [0x123], 0x123
Операция
Assembler
1
mov [0x123], 0x123;
содержит адрес в своём коде, ну так он и грузится в то же месте в процессоре, куда грузится код операции.

Добавлено через 2 минуты
Цитата Сообщение от Kastaneda Посмотреть сообщение
Т.е. запись по адресу определенного значения это вполне нормально и это не зависит от того, в каком сегменте (хотя "сегмент" это уже условность) расположена адресуемая память.
Дело не в сегменте, можно и в сегменте кода отвести область для данных. Но это будет именно область данных, процессор в неё не переходит. И не из-за линковщика, это разруливается уже при компиляции.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
04.01.2013, 18:39
Цитата Сообщение от taras atavin Посмотреть сообщение
содержит адрес в своём коде, ну так он и грузится в то же месте в процессоре, куда грузится код операции.
не понял, ты про конвейер говоришь? Или что? Так это уже дело "железяки", т.е. это уже не низкий уровень, а уровень железа. Это вообще к программирования отношения не имеет.
Цитата Сообщение от taras atavin Посмотреть сообщение
Дело не в сегменте, можно и в сегменте кода отвести область для данных. Но это будет именно область данных, процессор в неё не переходит.
то, что это область данных - это условность, о которой будет знать только программист, у дескриптора сегмента кода все равно стоит флаг "execute", поэтому область данных все равно будет в сегменте кода. А управление туда не передается, потому что программист его туда не передает. А на практике ни что не мешает исполнится данным, как коду.
0
 Аватар для gomodril
6 / 6 / 0
Регистрация: 10.10.2012
Сообщений: 140
05.01.2013, 10:03  [ТС]
taras atavin,

А что тогда будет являться указателем на символ:
C++
1
2
char si = 'H';
char *si_1 = &si;
или
C++
1
2
char si = 'H';
int *si_2 = (int*) &si
Добавлено через 15 часов 23 минуты
taras atavin,

Если я правильно понимаю идеологию C++, то оба кода будут являться указателем на символ и написаны они правильно.
C++
1
2
char si = 'H';
char *si_1 = &si;
C++
1
2
char si = 'H';
int *si_2 = (int*) &si;
0
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
05.01.2013, 10:54
Указатель содержит адрес, и ему самому абсолютно всё равно, адрес чего именно. Чтобы избежать путаницы, компилятор ведёт типы указателей, которые и говорят ему о том, что по данному адресу содержится. И есть возможность сказать компилятору что-то вроде: "Хотя это адрес переменной типа char, считай, что по этому адресу лежит значение типа int. Поверьте, я знаю, что я делаю!". Что и делается во втором примере. Заметим, что char у нас занимает 1 байт, а int - 4. И если мы попытаемся прочитать значение, на которое указывает si_2, то он вытянет и первый байт, который 'H', и 3 следующих за ним, в которых неизвестно что, так что в результате мы получим не пойми какое число.
0
 Аватар для gomodril
6 / 6 / 0
Регистрация: 10.10.2012
Сообщений: 140
05.01.2013, 13:37  [ТС]
Цитата Сообщение от Nick Alte Посмотреть сообщение
Указатель содержит адрес, и ему самому абсолютно всё равно, адрес чего именно. Чтобы избежать путаницы, компилятор ведёт типы указателей, которые и говорят ему о том, что по данному адресу содержится. И есть возможность сказать компилятору что-то вроде: "Хотя это адрес переменной типа char, считай, что по этому адресу лежит значение типа int. Поверьте, я знаю, что я делаю!". Что и делается во втором примере. Заметим, что char у нас занимает 1 байт, а int - 4. И если мы попытаемся прочитать значение, на которое указывает si_2, то он вытянет и первый байт, который 'H', и 3 следующих за ним, в которых неизвестно что, так что в результате мы получим не пойми какое число.
Странно, у меня получается наоборот почему то, si_1 вытаскивает непонятно чего, а si_2 вытаскивает адрес где находится переменная si. Вот код:
C++
1
2
3
4
5
6
7
char si = 'H';
char* si_1 = &si;
int* si_2 = (int*) &si;
 
std::cout << "Символьная переменная 'si' = " << si << endl;
std::cout << "Указатель на адрес в char = " << si_1 << endl;
std::cout << "Указатель на адрес в int = " << si_2 << endl;
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
05.01.2013, 13:46
Цитата Сообщение от gomodril Посмотреть сообщение
А что тогда будет являться указателем на символ:
C++
1
2
char si = 'H';
char *si_1 = &si;
C++
1
2
char si = 'H';
int *si_2 = (int*) &si
валидны оба, но на символ указывает только первый вариант, второй - это указатель на целое, содержащее символ в одном из своих байтов.
1
ComfyMobile
 Аватар для Nixy
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
05.01.2013, 13:49
Цитата Сообщение от gomodril Посмотреть сообщение
si_1 вытаскивает непонятно чего, а si_2 вытаскивает адрес где находится переменная s
если внимательно подебажить то в si_1 записывается, 4 символа, которые si_2 переводятся в число, число же потом переводится в 16 ричную систему и выводится на экран, это не адрес как вам кажется а представление того мустора коим заполнена переменная
1
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
05.01.2013, 13:50
Цитата Сообщение от gomodril Посмотреть сообщение
Странно, у меня получается наоборот почему то, si_1 вытаскивает непонятно чего, а si_2 вытаскивает адрес где находится переменная si.
Адрес char при выводе в поток интерпретируется как адрес строки, поэтому выводится содержимое памяти по этому адресу вплоть до первого нулевого байта. Начинаться такая строка будет с 'H', а дальше - что получится. Указатели других типов выводятся по своему значению, именно как адрес.
2
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
05.01.2013, 13:51
Цитата Сообщение от gomodril Посмотреть сообщение
у меня получается наоборот почему то, si_1 вытаскивает непонятно чего
оператор << для char* перегружен таким образом, что он будет выводить данные по указателю, воспринимая их как символы, до тех пор, пока не встретит символ 0. Попробуй так
C++
1
2
std::cout << *si_1 << std::endl;
std::cout << *si_2 << std::endl;
1
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
05.01.2013, 13:57
Цитата Сообщение от gomodril Посмотреть сообщение
Странно, у меня получается наоборот почему то, si_1 вытаскивает непонятно чего, а si_2 вытаскивает адрес где находится переменная si. Вот код:
C++
1
2
3
4
5
6
char si = 'H';
char* si_1 = &si;
int* si_2 = (int*) &si;
std::cout << "Символьная переменная 'si' = " << si << endl;
std::cout << "Указатель на адрес в char = " << si_1 << endl;
std::cout << "Указатель на адрес в int = " << si_2 << endl;
Функции и операторы ввода/вывода не догадываются об указателях на отдельные символы и принимают их за указатели на нуль-терминальные строки. И почему наоборот? По адресу валяется не известное число, а не сам указатель не понятен.
1
ComfyMobile
 Аватар для Nixy
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
05.01.2013, 13:57
Цитата Сообщение от Kastaneda Посмотреть сообщение
std::cout << *si_1 << std::endl;
std::cout << *si_2 << std::endl;
так выведет содержимое адреса в первом случае это Н а во втором, int число всего муссора
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
05.01.2013, 13:57
Помогаю со студенческими работами здесь

Подскажите хорошую статью про указатели и ссылки
Посоветуйте статью, видео или книгу по указателям и ссылкам в 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 написано хорошо, а тех кто пользовался стоит ли установить себе? Добавлено через...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение Это мой обзор планшета X220 с точки зрения школьника. Недавно я решила попытаться уменьшить свой. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru