Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 32, средняя оценка - 4.84
gomodril
6 / 6 / 0
Регистрация: 10.10.2012
Сообщений: 132
#1

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

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

Помогите разобраться со ссылками и указателями на различные объекты. Запутался вообще в них полностью. Когда читаю книгу про них, то вроде все понятно написано, но примеров для меня видимо не достаточно, что бы как то их различать. В итоге начинаю решать задачи и ни чего не выходит.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.01.2013, 16:05
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Расскажите популярно про ссылки и указатели (C++):

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

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

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

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

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

Расскажите пожалуйста про флаги - C++
Доброго времени суток. Помогите пожалуйста разобраться с фалагми. Вот код: #include <iostream> #define ID_F 1001 #define ID_D 1002 ...

110
gomodril
6 / 6 / 0
Регистрация: 10.10.2012
Сообщений: 132
04.01.2013, 17:35  [ТС] #16
Цитата Сообщение от taras atavin Посмотреть сообщение
Как звёздочка в декларации, или операторе приведения типа говорит об указателе, или повышает его кратность, а в остальных местах становится операцией разыменования, так и амперсанд в декларации означает ссылку, а в любом другом месте операцию взятия адреса. Эта операция берёт адресе своего операнда, потом его можно присвоить указателю (ведь адрес - это значение указательного типа). Семантически эта операция обратна операции разыменования.
Т.е. это:

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

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

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

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

Не по теме:

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

0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
04.01.2013, 17:41 #18
Цитата Сообщение от 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
погромист
411 / 247 / 15
Регистрация: 27.08.2012
Сообщений: 550
Завершенные тесты: 1
04.01.2013, 17:43 #19
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
Kastaneda
04.01.2013, 17:46
  #20

Не по теме:

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

0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
04.01.2013, 17:54 #21
Цитата Сообщение от 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
Сообщений: 132
04.01.2013, 17:58  [ТС] #22
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~
6 / 6 / 0
Регистрация: 12.06.2011
Сообщений: 80
04.01.2013, 17:58 #23
Цитата Сообщение от 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
погромист
411 / 247 / 15
Регистрация: 27.08.2012
Сообщений: 550
Завершенные тесты: 1
04.01.2013, 18:04 #24
Потому что ,,а,, интерпретируется как адрес нулевого элемента массива
В С++ очень тесная связь между указателями и массивами. Массив array[n] интерпретируется как *(&array[0] + n) или проще *(array + n)
1
Kastaneda
Jesus loves me
Эксперт С++
4688 / 2892 / 236
Регистрация: 12.12.2009
Сообщений: 7,353
Записей в блоге: 2
Завершенные тесты: 1
04.01.2013, 18:09 #25

Не по теме:

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



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

Не по теме:

Intel manual

Код
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
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
04.01.2013, 18:20 #26
Цитата Сообщение от 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
Nixy
ComfyMobile
400 / 281 / 8
Регистрация: 24.07.2012
Сообщений: 916
04.01.2013, 18:24 #27
Цитата Сообщение от taras atavin Посмотреть сообщение
int a;
a=200;

Не по теме:

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



Добавлено через 31 секунду
а вообще
taras atavin, прав, прекратите уже оффтоп дискуссию)
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
04.01.2013, 18:25 #28
Цитата Сообщение от gomodril Посмотреть сообщение
char si = 'H';
char *si_1 = (char*) &si;
А здесь нафига приведение типа?
C++
1
2
char si='H';
char *si_1=&si;
0
Kastaneda
Jesus loves me
Эксперт С++
4688 / 2892 / 236
Регистрация: 12.12.2009
Сообщений: 7,353
Записей в блоге: 2
Завершенные тесты: 1
04.01.2013, 18:26 #29
Цитата Сообщение от taras atavin Посмотреть сообщение
А ну да эльф может адрес на рельсе выбить, спрятать в го на дубе в центре континента, а дельфин в океане его использует.
Я привел цитату из мануала Intel с описанием инструкции mov. Судя по нему операция
Assembler
1
mov [0x123], 0x123
абсолютно валидная. Т.е. запись по адресу определенного значения это вполне нормально и это не зависит от того, в каком сегменте (хотя "сегмент" это уже условность) расположена адресуемая память.
Цитата Сообщение от taras atavin Посмотреть сообщение
Указатель у тебя тоже среди данных. Как процессор узнает его значение и адрес, по которому надо писать?
линковщик подставит нужные адреса в нужные места.
Цитата Сообщение от taras atavin Посмотреть сообщение
Если же указатель используется однократно и хранит адрес только именованной переменной, то в таких случаях можно разделить то, что имел ввиду кривопрограммист и то, как в действительности будет выглядеть программа. Кривопрограммист имел ввиду, что надо грузить адрес в регистр.
Дело не в "кривопрограммисте". Компилятор умеет оптимизировать подобные вещи.
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
04.01.2013, 18:31 #30
Цитата Сообщение от gomodril Посмотреть сообщение
Это из-за разных типов данных как я понимаю - в первом случае символьный тип и там адрес преобразуется в символьный тип?
Адрес нельзя преобразовывать в неуказательный тип, а символьный указательным не является. Только не говори индусам, для них это крамола.

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

Добавлено через 2 минуты
Цитата Сообщение от Kastaneda Посмотреть сообщение
Т.е. запись по адресу определенного значения это вполне нормально и это не зависит от того, в каком сегменте (хотя "сегмент" это уже условность) расположена адресуемая память.
Дело не в сегменте, можно и в сегменте кода отвести область для данных. Но это будет именно область данных, процессор в неё не переходит. И не из-за линковщика, это разруливается уже при компиляции.
0
04.01.2013, 18:31
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.01.2013, 18:31
Привет! Вот еще темы с ответами:

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

Расскажите про "тру" метод парсинга строки - C++
Опять Добрый день!))) Ой как я ошибался говоря что с парсингом не будет проблем((( Код void GetDirList(const char *Target) { ...

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

Указатели и Ссылки - C++
извеняюсь,но никак не могу понять. int sum(int* inLeft, int* inRight) { if(inLeft == inRight) return *inLeft; ...


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru