Форум программистов, компьютерный форум CyberForum.ru

Обязательно ли объявлять переменную для хранения адреса переменной как указатель? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 8, средняя оценка - 4.63
WLF
0 / 0 / 0
Регистрация: 06.12.2013
Сообщений: 14
09.05.2014, 09:12     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #1
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Указатели
#include <iostream>
 
using namespace std;
 
int Variable;
int *pVariable;
// int pVariable;
int main()
{
    setlocale(LC_ALL, "rus");
 
    Variable = 777;
    pVariable = &Variable;
 
    cout << "Переменная Variable\t = " << Variable << endl;
    cout << "Адрес Variable\t\t = " << &Variable << endl;
    cout << "Значение по этому адресу = " << *pVariable << endl;
    // cout << "Значение по этому адресу = " << pVariable << endl;
return 0;
}
Скажите, почему, если я объявляю переменную pVariable просто как int, а не как указатель (закомментированые строки), то компилятор ругается на типы? Разве, чтобы хранить в переменной какой-то адрес надо обязательно объявлять её как указатель?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.05.2014, 09:12     Обязательно ли объявлять переменную для хранения адреса переменной как указатель?
Посмотрите здесь:

C++ Описать класс,содержащий переменную для хранения текстовой строки.
Реализуйте класс для хранения ФИО и номера телефона человека, класс для хранения даты рождения человека, а также класс для хранения ФИО и почтового ад C++
Как вывести на экран переменную из функции, которой присваиваеться значение через указатель? C++
C++ Где объявлять переменную: перед циклом, или внутри класса
C++ Не обязательно разыменовывать указатель на функцию при вызове?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
09.05.2014, 09:25     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #2
Цитата Сообщение от WLF Посмотреть сообщение
Разве, чтобы хранить в переменной какой-то адрес надо обязательно объявлять её как указатель?
Как бы указатели для того и есть.
Можно, конечно, и в переменную типа int записать значение адреса, но вот конкретно Вам это зачем?
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
09.05.2014, 09:36     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #3
0x10, далеко не всегда можно запихнуть адрес в int. Взять хотя бы x64: адрес 64 бита, а int скорее всего 32.
WLF, компилятор ругается потому что типы не совместимы. Вы же едите суп ложкой, а не вилкой. Вот и здесь не надо путать сущности.
WLF
0 / 0 / 0
Регистрация: 06.12.2013
Сообщений: 14
09.05.2014, 09:51  [ТС]     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #4
Просто мне стало интересно, почему в строке 14 в переменную спокойно записывается адрес, а строка 19 не работает.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
09.05.2014, 09:57     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #5
WLF, как это не работает? Если раскомментировать 19 строку, то будет выведен адрес, так же как в 17 строке.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
09.05.2014, 09:58     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #6
Пруф: http://ideone.com/kwbHEN
WLF
0 / 0 / 0
Регистрация: 06.12.2013
Сообщений: 14
09.05.2014, 10:03  [ТС]     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #7
Цитата Сообщение от Tulosba Посмотреть сообщение
как это не работает? Если раскомментировать 19 строку, то будет выведен адрес, так же как в 17 строке.
А теперь раскомментируйте строку 8, а 7 и 18 закомментируйте.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
09.05.2014, 10:08     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #8
WLF, приведите пожалуйста полностью код, который Вас смутил. Без "расскоментируйте"/"закомментируйте". Так будет нагляднее и точнее. Чтобы не было недопонимания.
WLF
0 / 0 / 0
Регистрация: 06.12.2013
Сообщений: 14
09.05.2014, 10:16  [ТС]     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #9
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Указатели
#include <iostream>
 
using namespace std;
 
int Variable;
int pVariable;
 
int main()
{
    setlocale(LC_ALL, "rus");
 
    Variable = 777;
    pVariable = &Variable;
 
    cout << "Переменная Variable\t = " << Variable << endl;
    cout << "Адрес Variable\t\t = " << &Variable << endl;
    cout << "Значение по этому адресу = " << pVariable << endl;
 
return 0;
}
Code::Blocks ругается:
|14|error: invalid conversion from 'int*' to 'int' [-fpermissive]|

Может быть он ругается потому, что адрес сохраняется в hex-формате (т.е. с символом 'x')?
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
09.05.2014, 10:25     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #10
Нельзя так просто взять и привести указатель к целому числу. Типы разные.
Грубо говоря:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
using namespace std;
 
int Variable;
int pVariable;
 
int main()
{
    setlocale(LC_ALL, "rus");
 
    Variable = 777;
    pVariable = reinterpret_cast<int>(&Variable);
 
    cout << "Переменная Variable\t = " << Variable << endl;
    cout << "Адрес Variable\t\t = " << &Variable << endl;
    cout << "Значение по этому адресу = " << hex << pVariable << endl;
 
    return 0;
}
И не забывать о разрядности, что было сказано в 3 посте.
newbie666
Заблокирован
09.05.2014, 10:26     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #11
Цитата Сообщение от WLF Посмотреть сообщение
14|error: invalid conversion from 'int*' to 'int' [-fpermissive]|
ну конечно, ты ж пытаешься указатель присвоить обычной переменной
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
09.05.2014, 10:31     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #12
WLF, почему у Вас вообще возникла мысль, что указатель (а ведь адрес переменной это указатель) может быть так просто преобразован и сохранен в целочисленной переменной?

Hex - это всего лишь способ представления информации для человека. Так что в данном случае Вы сказали глупость.
WLF
0 / 0 / 0
Регистрация: 06.12.2013
Сообщений: 14
09.05.2014, 10:34  [ТС]     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #13
Ну так указатель, как я понял, это же обычная переменная в которой хранится адрес. Адрес - это просто число. Так почему я не могу поместить в обычную переменную (пусть даже это будет long int) какое-то число, которое я интерпретирую как адрес.
И вообще, почему вывод происходит в шестнадцатиричном формате, а не в десятичном?

Добавлено через 1 минуту
Цитата Сообщение от Tulosba Посмотреть сообщение
почему у Вас вообще возникла мысль, что указатель (а ведь адрес переменной это указатель) может быть так просто преобразован и сохранен в целочисленной переменной?
А почему нет? (см. выше)
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
09.05.2014, 10:36     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #14
Цитата Сообщение от WLF Посмотреть сообщение
Ну так указатель, как я понял, это же обычная переменная в которой хранится адрес.
Физически - да.
Цитата Сообщение от WLF Посмотреть сообщение
Так почему я не могу поместить в обычную переменную (пусть даже это будет long int) какое-то число, которое я интерпретирую как адрес.
В языке это разные типы данных.
Цитата Сообщение от WLF Посмотреть сообщение
И вообще, почему вывод происходит в шестнадцатиричном формате, а не в десятичном?
Потому что есть перегрузка operator<< для указателя http://www.cplusplus.com/reference/o...perator%3C%3C/, где и реализован вывод в hex-формате.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
09.05.2014, 10:41     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #15
Цитата Сообщение от WLF Посмотреть сообщение
Так почему я не могу поместить в обычную переменную (пусть даже это будет long int) какое-то число, которое я интерпретирую как адрес.
Во-первых откуда тебе известно, что это число туда влезет? Указатель же, объявленный с помощью звёздочки, гарантирует, что такое число туда поместится. Во вторых как инкрементить будешь? Типизированный указатель инкрементится оператором ++ сразу на размер ячейки, на которую указывает, а не к соседнему байту. И при вычитании двух указателей получается количество ячеек, которые межу этими адресами можно поместить. Например,
C++
1
2
3
4
5
int *p1;
int *p;
size_t n;
...
n=p1-p2;
поместит в n количество четырёхбайтных ячеек, а не количество байт, которые помещаются между двумя адресами. В-третьих ты как собираешься обращаться к данным, которые лежат по хранимому в long int адресу? Единственный возможный синтаксис такого обращения - это привести long int к указателю, а потом этот указатель разыменовать.
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
09.05.2014, 10:42     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #16
WLF, адрес это не просто число. Адреса например нельзя складывать в отличии от чисел. Т.к. результат этого действия не несет смысла. В некоторых случаях адрес можно преобразовывать в целое число и обратно, но это не делается автоматически.
Как будет выводится на экран то или иное значение через operator << зависит от типа, который ему будет передан. Целые по умолчанию выводятся в десятичном формате, а адреса в шестнадцатиричном. Задавая манипуляторы типа std::hex std::dec можно менять это поведение.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
09.05.2014, 10:44     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #17
Указатель есть целое специального вида, предназначенное только для хранения номера байта, с которого начинается некоторое данное, или функция. Адрес есть значение номера байта, с которого начинается некоторое данное, или функция. Значение указателя - это адрес, но адрес и указатель - разные сущности, соотносимые также, как число и переменная числового типа: адрес - значение указателя, указатель - данное, хранящее адрес.
WLF
0 / 0 / 0
Регистрация: 06.12.2013
Сообщений: 14
09.05.2014, 11:08  [ТС]     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #18
Да так-то понятно, что указатель это тип данных для адреса. Просто меня заинтересовало физика процесса можно ли обойтись без звездочек...

Цитата Сообщение от Tulosba Посмотреть сообщение
Задавая манипуляторы типа std::hex std::dec можно менять это поведение.
cout << "Адрес Variable\t\t = " << dec << &Variable << endl;
не работает. namespace задан (листинг в первом сообщении).

И пример отсюда не компилится.
|2|fatal error: iostream: No such file or directory|


Добавлено через 12 минут
Пример скомпилился, dec/hex работает, а у меня почему-то нет...
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
09.05.2014, 11:28     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #19
Цитата Сообщение от WLF Посмотреть сообщение
можно ли обойтись без звездочек
Нельзя, даже
C++
1
2
3
4
int x;
size_t p;
p=(size_t)(&x);
*((int*)p)=2;
требует вместо одной двух звёздочек при каждом разыменовании: одна для приведения к указателю, так как разыменовать можно только его, вторая для разыменования. А кроме как разыменованием ни как обратиться целиком к данному по его адресу нельзя. Функцию можно вызвать по адресу, не разыменуя, но и тогда одна звёздочка нужна будет при каждом вызове для приведения. Ещё можно по указателю и только по указателю получить доступ к члену, используя адрес всего объекта/структуры, но
C++
1
2
3
4
5
6
7
8
9
struct s
{
 int a;
 int b;
};
size_t p;
s d;
p=(size_t)(&x);
((s*)p)->b=2;
требует звёздочки для приведения при каждом доступе. Компилятор интерпретирует в качестве адресов только значения указателей и пока ты синтаксически не оформил указатель, использовать адрес не получится.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.05.2014, 13:23     Обязательно ли объявлять переменную для хранения адреса переменной как указатель?
Еще ссылки по теме:

C++ Можно ли как-то словить номер элемента используя указатель, а не переменную
Как использовать указатель на переменную во входящем параметре функции? C++
C++ Как правильно объявлять struct переменную?

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

Или воспользуйтесь поиском по форуму:
Tulosba
:)
Эксперт C++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
09.05.2014, 13:23     Обязательно ли объявлять переменную для хранения адреса переменной как указатель? #20
Цитата Сообщение от WLF Посмотреть сообщение
cout << "Адрес Variable\t\t = " << dec << &Variable << endl;
Для вывода адреса указателя манипуляторы не действуют. Я не совсем корректно выразился в предыдущем сообщении. Но если нужно вывести адрес в десятичном представлении, можно рассмотреть такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include <cstdint>
 
int main() {
    
    int i;
    int *p = &i;
    
    std::cout << std::dec << p << std::endl; // Указатель выводится всегда в hex
    std::cout << std::hex << p << std::endl; // т.к. манипулятор действует только на целые типы
 
    // Если преобразовать указатель в целое, то манипуляторы будут действовать
    // Значение (адрес) остаются прежними
    std::cout << std::dec << reinterpret_cast<uintptr_t>(p) << std::endl;
    std::cout << std::showbase << std::hex << reinterpret_cast<uintptr_t>(p) << std::endl;
    
    return 0;
}
http://ideone.com/CCe6XE

Кстати, если нужно преобразовывать значение указателя в целое и обратно, правильным будет именно использование типов uintptr_t/intptr_t, а не просто int, у которого может не хватить разрядности.
Integer types capable of holding object pointers

The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to a pointer to void, and the result will compare equal to the original pointer: intptr_t

The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to a pointer to void, and the result will compare equal to the original pointer: uintptr_t
отсюда

Цитата Сообщение от taras atavin Посмотреть сообщение
p=(size_t)(&x);
типа size_t может не хватить для представления адреса. См. первый комментарий к ответу тут.
Yandex
Объявления
09.05.2014, 13:23     Обязательно ли объявлять переменную для хранения адреса переменной как указатель?
Ответ Создать тему
Опции темы

Текущее время: 09:24. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru