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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 5.00
Owyn
0 / 0 / 0
Регистрация: 28.05.2009
Сообщений: 64
#1

Дереференс указателей - C++

30.07.2010, 01:16. Просмотров 1570. Ответов 20
Метки нет (Все метки)

после прочтения мануала появилась необходимость использовать beth = *ted; но оно выдает еррор C2100 =\

надо:

есть size_t arg = 0x12345

нужно прочитать int по адресу из arg, можно ли это сделать поинтерами * или & ? или только кастом можно?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.07.2010, 01:16
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Дереференс указателей (C++):

по поводу указателей. Как правильно задавать массив указателей и его удалять? - C++
Т.е., например создаю указатель: TPoint *p_Point=NULL; а если массив? TPoint *p_MassPoint; //=?; как массив обнулить не ясно ...

Почему в сортировке указателей на объекты в вызове функции используются адреса объектов, а не указателей? - C++
Доброго времени суток! Рассматриваю пример (из Лафоре) сортировки массива указателей на объекты, для чего используются указатели на...

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

Объяснить различия в работе указателей на целое число и указателей на const char (строки в стиле Си) - C++
Уважаемые программисты, возникло несколько вопросов касательно указателей. Почему при выводе указателя на int нужна звёздочка (*), а...

Создать специализацию для шаблона, которая принимает массив указателей на строки и количество этих указателей - C++
Нужно создать специализацию для шаблона, которая принимает массив указателей на строки и количество этих указателей. Эта специализация...

Как обойтись без указателей и указателей на указатель? - C++
Ибо не совсем выходит понять,что на что тут указывает #include "stdafx.h" #include <iostream> #include <stdlib.h> using namespace...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
easybudda
Модератор
Эксперт CЭксперт С++
9530 / 5523 / 932
Регистрация: 25.07.2009
Сообщений: 10,608
30.07.2010, 01:56 #2
кто хоть что-нибудь понял - отзовитесь!
ForEveR
В астрале
Эксперт С++
7970 / 4732 / 321
Регистрация: 24.06.2010
Сообщений: 10,541
Завершенные тесты: 3
30.07.2010, 01:57 #3
& для получения адреса вообщем-то... Хотя я хз что вам надо...
CyBOSSeR
Эксперт C++
2300 / 1670 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
30.07.2010, 02:03 #4
Owyn, попробуй:
C++
1
int* p = reinterpret_cast<int*>(arg);
Owyn
0 / 0 / 0
Регистрация: 28.05.2009
Сообщений: 64
30.07.2010, 11:30  [ТС] #5
cast
ну так вообще я и делал я спрашивал можно ли поинтеры потыкать и получить тож самое
easybudda
Модератор
Эксперт CЭксперт С++
9530 / 5523 / 932
Регистрация: 25.07.2009
Сообщений: 10,608
30.07.2010, 11:44 #6
Цитата Сообщение от Owyn Посмотреть сообщение
поинтеры потыкать
C
1
2
size_t arg = 0x12345;
int i = *(int*)arg;
Evg
Эксперт CАвтор FAQ
17625 / 5849 / 376
Регистрация: 30.03.2009
Сообщений: 16,133
Записей в блоге: 26
30.07.2010, 11:50 #7
Цитата Сообщение от Owyn Посмотреть сообщение
или только кастом можно?
Только кастом. Операция дереференса может применяться только к значению типа указатель
easybudda
Модератор
Эксперт CЭксперт С++
9530 / 5523 / 932
Регистрация: 25.07.2009
Сообщений: 10,608
30.07.2010, 15:21 #8
Цитата Сообщение от Evg Посмотреть сообщение
Операция дереференса может применяться только к значению типа указатель
то есть вот такой фортель работать не должен?
C
1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main(void){
    int a = 13;
    int * pA = &a;
    size_t arg = (size_t)pA;
    printf("A = %d\n", *(int*)arg);
    return 0;
}
А работает. Хотя кому и зачем такое может понадобиться - не понятно...
Evg
Эксперт CАвтор FAQ
17625 / 5849 / 376
Регистрация: 30.03.2009
Сообщений: 16,133
Записей в блоге: 26
30.07.2010, 18:19 #9
Цитата Сообщение от easybudda Посмотреть сообщение
то есть вот такой фортель работать не должен?
Ёлы-палы. Ты ж поставил операцию преобразования к указателю. И дереференс работает над значением типа указатель. А над типом int не будет работать (а точнее не может работать, потому как смысла у такой операции нет)
easybudda
Модератор
Эксперт CЭксперт С++
9530 / 5523 / 932
Регистрация: 25.07.2009
Сообщений: 10,608
30.07.2010, 19:49 #10
Цитата Сообщение от Evg Посмотреть сообщение
А над типом int не будет работать (а точнее не может работать, потому как смысла у такой операции нет)
Ну да... Меня вот это суровое заключение смутило:
Цитата Сообщение от Evg Посмотреть сообщение
Только кастом.
Но тем не менее всё равно стрёмная затея. Есть переменные разных типов для хранения данных и переменные-указатели для хранения их адресов. И незачем их между собой путать.
Evg
Эксперт CАвтор FAQ
17625 / 5849 / 376
Регистрация: 30.03.2009
Сообщений: 16,133
Записей в блоге: 26
30.07.2010, 21:09 #11
Цитата Сообщение от easybudda Посмотреть сообщение
и переменные-указатели для хранения их адресов
Чем по твоему адрес отличается от целого числа? На уровне машины - ничем. Различие есть только на уровне языка, да и то выражается лишь в типе выражения

Цитата Сообщение от easybudda Посмотреть сообщение
И незачем их между собой путать
Да вроде как никто их пока тут и не путает. Что касается топикстартера - у меня есть смутные подозрения, что человек работал с ассемблером, но не имеет навыков работы на си. Он ничего не путает а просто спрашивает

Да, забыл ещё упомянуть. Дереференс можно делать только над поинтером по следующей причине. Если есть указатель типа int*, то дереференс означает чтение (или запись) фрагмента памяти размером в 4 байта (размер int'а), если есть указатель типа double*, то фрагмент памяти имеет размер 8 байт и т.п. Имея на руках лишь адрес в виде int'а (но не поинтера) мы такой информацией не обладаем, а потому по языку невозможно физически строить подобную операцию. Это принципиальное отличие между понятиями "адрес" и "указатель": указатель как сущность описывает не только адрес, но и размер
easybudda
Модератор
Эксперт CЭксперт С++
9530 / 5523 / 932
Регистрация: 25.07.2009
Сообщений: 10,608
30.07.2010, 22:29 #12
Цитата Сообщение от Evg Посмотреть сообщение
Чем по твоему адрес отличается от целого числа? На уровне машины - ничем. Различие есть только на уровне языка, да и то выражается лишь в типе выражения
Само собой, ничем не отличается. Но такой подход - прямой путь к куче трудноуловимых ошибок.

вот, кстати, ещё для разнообразия
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
 
int main(void){
    int a = 13;
    union {
        size_t num;
        int * ptr;
    } un;
    
    un.ptr = &a;
    
    printf("a = %d, &a = %#x\n", *(un.ptr), un.num);
    
    return 0;
}
Evg
Эксперт CАвтор FAQ
17625 / 5849 / 376
Регистрация: 30.03.2009
Сообщений: 16,133
Записей в блоге: 26
31.07.2010, 13:36 #13
Цитата Сообщение от easybudda Посмотреть сообщение
вот, кстати, ещё для разнообразия
Подход с преобразованием int'а НИКОГДА не приведёт к ошибке. В разумном предположении, что нужный нам адрес (но не режим адресации на машине) укалывается в размер int'а.

Твой подход приведёт к ошибке, если размер size_t не совпадает с размером int* (чего не будет при использовании cast'а). Твой подход заведомо не будет работать на архитектурах, где преобразование целого в указатель требует дополнительных действий (например, навешивание тэгов на число на защищённых архитектурах или специфические пляски с бубнами на сигнальных процессорах), потому что в твоём случае преобразования типов нет, хотя по логике постановки задачи оно должно быть.

Ну и твой способ неверен чисто с концептуальной точки зрения: преобразование типа (cast) НЕ является операцией наложения битового представления. Преобразование от int'а к float'у - это cast. При наложении битов получится неправильный результат. float от указателя принципиально ничем не отличается - происходит преобразование значения (а не его битового представления) из одного типа в другой. Наверняка есть сигнальные процессоры, в которых твой способ ошибочно отработает даже при преобразовании int'а к unsigned'у, потому что для представления целых чисел используется кодировка не в обратном коде, а в прямом (я не силён в терминологии и не помню точно, как это называется)

Ну и краткий итог. При работе через cast выполняется преобразование типа для значения. При работе через union происходит копирование битового образа (которое ещё и неправильно отработает, если битовые размеры типов не совпадают). Если твой пример работает на i386, то это вовсе не означает, что этот пример будет корректно работать на всех архитектурах

Добавлено через 1 минуту
Цитата Сообщение от easybudda Посмотреть сообщение
Но такой подход - прямой путь к куче трудноуловимых ошибок
К слову говоря, это твой подход является путём к созданию кучи ошибок
easybudda
Модератор
Эксперт CЭксперт С++
9530 / 5523 / 932
Регистрация: 25.07.2009
Сообщений: 10,608
31.07.2010, 15:38 #14
Цитата Сообщение от Evg Посмотреть сообщение
Твой подход приведёт к ошибке, если...
Твой подход заведомо не будет работать на архитектурах, где...
твой способ неверен чисто с концептуальной точки зрения...
твой подход является путём к созданию кучи ошибок...
Ну и краткий итог. При работе через cast выполняется преобразование типа для значения. При работе через union происходит копирование битового образа (которое ещё и неправильно отработает, если битовые размеры типов не совпадают). Если твой пример работает на i386, то это вовсе не означает, что этот пример будет корректно работать на всех архитектурах
Ага... И ещё с десяток причин можно назвать, почему оно не правильно. А где я говорил, что нужно так делать? Просто частный случай.
Раз уж так серьёзно к вопросу подходите, покажите мне малограмотному, как хранить адреса в переменных целочисленного типа так, чтобы это работало везде от майнфреймов до тетрисов. И главный вопрос, который я уже в третий раз задаю - зачем и кому это вообще нужно?!
Evg
Эксперт CАвтор FAQ
17625 / 5849 / 376
Регистрация: 30.03.2009
Сообщений: 16,133
Записей в блоге: 26
31.07.2010, 16:00 #15
Цитата Сообщение от easybudda Посмотреть сообщение
И ещё с десяток причин можно назвать, почему оно не правильно.
Если тебе не интересно - не читай. На форуме ты не один, есть люди, кому это будет интересно, есть начинающие, кому это будет полезно для самообразования

Цитата Сообщение от easybudda Посмотреть сообщение
А где я говорил, что нужно так делать?
Андрей, может не стоит уподобляться товарищу DenQ?

Цитата Сообщение от easybudda Посмотреть сообщение
Просто частный случай.
Частный случай, который не является правильным с концептуальной точки зрения. Я понимаю, что данный аспект вопроса тебя мало интересует, но начинающим, на мой взгляд, очень важно этот момент понимать. Так или иначе подавляющему большинству людей за всю программистскую карьеру приходится работать только с одной платформой или только с одним процессором, а потому попросту не удаётся понять на практике большинство из проблем переносимости. Но, опять-таки на мой взгляд, это не должно являться поводом к тому, чтобы не уметь писать программы "правильно"

Цитата Сообщение от easybudda Посмотреть сообщение
Раз уж так серьёзно к вопросу подходите, покажите мне малограмотному, как хранить адреса в переменных целочисленного типа так, чтобы это работало везде от майнфреймов до тетрисов.
При чём тут мэйнфрэймы и тетрисы я не особо понял, но ответ на вопрос: никак. Целое и указатель являются разными типами, которые в общем случае нельзя тождественно привести один в другое и обратно (так же, как нельзя тождественно перевести плавающее в целое и обратно)

Цитата Сообщение от easybudda Посмотреть сообщение
И главный вопрос, который я уже в третий раз задаю
Не стану уподобляться вышеобозначенному товарищу и не стану с пеной у рта доказывать, что вопрос ты задаёшь только в первый раз

Цитата Сообщение от easybudda Посмотреть сообщение
зачем и кому это вообще нужно?!
"Это" - это что? Если знания и понимания, то ответ очевиден: тот, кто сочтёт эти знания полезными, тот их усвоит, тот, кто сочтёт эти знания бесполезными - молча пройдёт мимо.

Если "это" - хранение адреса в целом, то в качестве реального примера загляни в файл /usr/include/elf.h на юниксах. Структуры, описывающие внутренний формат файла содержат данные, которые по своей сути являются указателями, но хранятся в виде адресов в целочисленных типах

Или под "это" имелось в виду что-то другое?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.07.2010, 16:00
Привет! Вот еще темы с ответами:

Различия указателей char* от указателей других типов - C++
Помогите пожалуйста разобраться! Прочитал раздел про указатели и даже вроде бы понял. Что касается указателей на тип int. Но что...

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

Добавление нового указателя в конец массива указателей, удаление указанного элемента, добавление указателей - C++
Здравствуйте. Помогите, пожалуйста, разобраться с одним большим заданием. Задание пока в процессе написания, но уже наверное есть ошибки....

Массив указателей на массив строк и сортировка массива указателей - C++
Добрый день. Поступил вопрос. Есть задача. У нас встроенный массив char mass;.Мы вводим строки до тех пор, пока не будет заполнен массив...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
31.07.2010, 16:00
Ответ Создать тему
Опции темы

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