WLF
1 / 2 / 0
Регистрация: 06.12.2013
Сообщений: 114
1

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

09.05.2014, 09:12. Показов 2921. Ответов 38
Метки нет (Все метки)

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, а не как указатель (закомментированые строки), то компилятор ругается на типы? Разве, чтобы хранить в переменной какой-то адрес надо обязательно объявлять её как указатель?
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.05.2014, 09:12
Ответы с готовыми решениями:

Как объявлять указатель на массив указателей?
Народ, поясните как объявлять указатель на массив указателей и как отправлять его как параметр в...

Как правильно объявлять указатель на массив указателей?
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;malloc.h&gt; int main(){ int a, b; int *a1,...

Как правильно объявлять struct переменную?
Как правильно объявлять? str one или struct str one; #include &lt;iostream&gt; using namespace std; ...

Объясните как в JSP объявлять и вызывать глобальную переменную???
С сервлетом всё понятно - ВСЁ работает а на JSP ругается и ругается. Пример с сервлетом ...

38
3254 / 2056 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
09.05.2014, 09:25 2
Цитата Сообщение от WLF Посмотреть сообщение
Разве, чтобы хранить в переменной какой-то адрес надо обязательно объявлять её как указатель?
Как бы указатели для того и есть.
Можно, конечно, и в переменную типа int записать значение адреса, но вот конкретно Вам это зачем?
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
09.05.2014, 09:36 3
0x10, далеко не всегда можно запихнуть адрес в int. Взять хотя бы x64: адрес 64 бита, а int скорее всего 32.
WLF, компилятор ругается потому что типы не совместимы. Вы же едите суп ложкой, а не вилкой. Вот и здесь не надо путать сущности.
0
WLF
1 / 2 / 0
Регистрация: 06.12.2013
Сообщений: 114
09.05.2014, 09:51  [ТС] 4
Просто мне стало интересно, почему в строке 14 в переменную спокойно записывается адрес, а строка 19 не работает.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
09.05.2014, 09:57 5
WLF, как это не работает? Если раскомментировать 19 строку, то будет выведен адрес, так же как в 17 строке.
0
3254 / 2056 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
09.05.2014, 09:58 6
Пруф: http://ideone.com/kwbHEN
0
WLF
1 / 2 / 0
Регистрация: 06.12.2013
Сообщений: 114
09.05.2014, 10:03  [ТС] 7
Цитата Сообщение от Tulosba Посмотреть сообщение
как это не работает? Если раскомментировать 19 строку, то будет выведен адрес, так же как в 17 строке.
А теперь раскомментируйте строку 8, а 7 и 18 закомментируйте.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
09.05.2014, 10:08 8
WLF, приведите пожалуйста полностью код, который Вас смутил. Без "расскоментируйте"/"закомментируйте". Так будет нагляднее и точнее. Чтобы не было недопонимания.
0
WLF
1 / 2 / 0
Регистрация: 06.12.2013
Сообщений: 114
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')?
0
3254 / 2056 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
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 посте.
0
Заблокирован
09.05.2014, 10:26 11
Цитата Сообщение от WLF Посмотреть сообщение
14|error: invalid conversion from 'int*' to 'int' [-fpermissive]|
ну конечно, ты ж пытаешься указатель присвоить обычной переменной
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
09.05.2014, 10:31 12
WLF, почему у Вас вообще возникла мысль, что указатель (а ведь адрес переменной это указатель) может быть так просто преобразован и сохранен в целочисленной переменной?

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

Добавлено через 1 минуту
Цитата Сообщение от Tulosba Посмотреть сообщение
почему у Вас вообще возникла мысль, что указатель (а ведь адрес переменной это указатель) может быть так просто преобразован и сохранен в целочисленной переменной?
А почему нет? (см. выше)
0
3254 / 2056 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
09.05.2014, 10:36 14
Цитата Сообщение от WLF Посмотреть сообщение
Ну так указатель, как я понял, это же обычная переменная в которой хранится адрес.
Физически - да.
Цитата Сообщение от WLF Посмотреть сообщение
Так почему я не могу поместить в обычную переменную (пусть даже это будет long int) какое-то число, которое я интерпретирую как адрес.
В языке это разные типы данных.
Цитата Сообщение от WLF Посмотреть сообщение
И вообще, почему вывод происходит в шестнадцатиричном формате, а не в десятичном?
Потому что есть перегрузка operator<< для указателя http://www.cplusplus.com/refer... tor%3C%3C/, где и реализован вывод в hex-формате.
0
4201 / 1793 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
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 к указателю, а потом этот указатель разыменовать.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
09.05.2014, 10:42 16
WLF, адрес это не просто число. Адреса например нельзя складывать в отличии от чисел. Т.к. результат этого действия не несет смысла. В некоторых случаях адрес можно преобразовывать в целое число и обратно, но это не делается автоматически.
Как будет выводится на экран то или иное значение через operator << зависит от типа, который ему будет передан. Целые по умолчанию выводятся в десятичном формате, а адреса в шестнадцатиричном. Задавая манипуляторы типа std::hex std::dec можно менять это поведение.
0
4201 / 1793 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
09.05.2014, 10:44 17
Указатель есть целое специального вида, предназначенное только для хранения номера байта, с которого начинается некоторое данное, или функция. Адрес есть значение номера байта, с которого начинается некоторое данное, или функция. Значение указателя - это адрес, но адрес и указатель - разные сущности, соотносимые также, как число и переменная числового типа: адрес - значение указателя, указатель - данное, хранящее адрес.
1
WLF
1 / 2 / 0
Регистрация: 06.12.2013
Сообщений: 114
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 работает, а у меня почему-то нет...
0
4201 / 1793 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
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;
требует звёздочки для приведения при каждом доступе. Компилятор интерпретирует в качестве адресов только значения указателей и пока ты синтаксически не оформил указатель, использовать адрес не получится.
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
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 может не хватить для представления адреса. См. первый комментарий к ответу тут.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.05.2014, 13:23
Помогаю со студенческими работами здесь

Сохранение адреса переменной пользовательского класса в переменную типа int или double
Здравствуйте. Подскажите, возможно ли это: есть переменная пользовательского класса. Я хочу...

Используя указатель на переменную типа string, удалить последний символ этой переменной
есть указатель на переменную string,нужно удалить последний символ этой переменной работая с...

Составьте описание типа данных для хранения фамилии, имени, отчества, адреса
Помогите составить на любом примере

Опишите переменную Tovar для хранения структуры данных
На картинке схема.


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru