Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.94/16: Рейтинг темы: голосов - 16, средняя оценка - 4.94
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143

универсальный указатель

24.02.2013, 22:46. Показов 3918. Ответов 38
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый вечер.
Можно ли создать шаблон, что бы не приводить явно универсальный указатель к определенному типу при разыменовании?
Или по крайней мене узнать тип (размер) данных которые хранятся по указанному адресу?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
24.02.2013, 22:46
Ответы с готовыми решениями:

Универсальный указатель или универсальный скалярный тип
Здравствуйте! Помогите, пожалуйста написать программу: требуется написать универсальный скалярный тип данных без использования шаблонов....

Указатель типа void. Использование косвенного связывания через универсальный указатель
Необходимо использовать косвенного связывания через универсальный указатель, примерный вид: struct обобщение{ключ; void* на что угодно}...

универсальный указатель
Возможно ли сделать универсальный указатель, который будет указывать на переменную любого типа? Ведь указатель по сути - адрес.

38
В астрале
Эксперт С++
 Аватар для ForEveR
8049 / 4806 / 655
Регистрация: 24.06.2010
Сообщений: 10,562
25.02.2013, 02:59
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
а как же qsort, memset memcpy и прочий stdlib.h???
А они не являются С++ функциями и использовать их в С++ стоит только в уникальных случаях (ровно как и void*).
0
 Аватар для Kuzia domovenok
4268 / 3328 / 926
Регистрация: 25.03.2012
Сообщений: 12,545
Записей в блоге: 1
25.02.2013, 04:33
Цитата Сообщение от ForEveR Посмотреть сообщение
А они не являются С++ функциями и использовать их в С++ стоит только в уникальных случаях (ровно как и void*).
С++ мультипарадигменый язык, на нём можно успешно программировать и без ООП и шаблонов. То, что их добавили в С++, не значит, что Си-стиль хуже. Он просто другой.

Вот стоит перед тобой задача заполнить N байт по адресу 0x00ABCDEF значениями 0x01
Разве memset для такой задачи не подходит лучше всего?
1
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
25.02.2013, 10:35
Лучший ответ Сообщение было отмечено как решение

Решение

Мультипарадигменность — не разрешение делать что угодно. Любой язык общего назначения при должном возрасте становится мультипарадигменным.

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

Но вот использовать qsort() в плюсовом коде — это как прийти на автозавод и обнаружить, что всё собирается на конвейере, но дырку под лобое стекло самолично выпиливает безопилой дядя Вася. Это работает, Вася виртуозен и делает всё правильно, вовремя и не отрезает себе ноги, но у инспектора по технике безопасности глаза на лоб полезут и он сразу побежит спрашивать инженеров: "На кой хрен, если у вас тут безопасных механизмов с автоматическим контролем хоть ложкой ешь?" И ведь действительно, на кой хрен? Только потому, что кто-то хорошо знает дядю Васю и поленился настроить ещё один автомат?
4
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
26.02.2013, 15:26  [ТС]
Что бы не создавать новую тему дополню вопрос тут, тем более что он связан с темой топика...
Архитектура машины (разрядность), определяет не только общий объем памяти, но и размер ячейки памяти?
К примеру long long доступно только на 64 разрядной платформе (не зависимо от системы)?
Если для хранения переменной нам достаточно, к примеру, 1-2 байта, как выставлены остальные?
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
26.02.2013, 23:48
Цитата Сообщение от fuelcs Посмотреть сообщение
Архитектура машины (разрядность), определяет не только общий объем памяти, но и размер ячейки памяти?
Память всегда разбита на минимальные адресуемые ячейки — байты. От разрядности зависят размеры регистров (а от них косвенно быстродействие), размеры адресного пространства. Размеры конкретных типов данных зависят от языка, компилятора и рантайма.
Цитата Сообщение от fuelcs Посмотреть сообщение
К примеру long long доступно только на 64 разрядной платформе (не зависимо от системы)?
На любой. Просто на 32-битных платформах он точно не влезет в один регистр, так что работа с такими числами будет выполняться несколько медленнее.
Цитата Сообщение от fuelcs Посмотреть сообщение
Если для хранения переменной нам достаточно, к примеру, 1-2 байта, как выставлены остальные?
Зависит от типа данных. От него же зависит понятие "достаточности" и "лишнего места". С точки зрения языка лишних байтов вообще нет. Для целых чисел при кодировании дополнительным кодом незначащие биты установлены в нули для положительных и в единицы для отрицательных чисел.
1
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
27.02.2013, 01:38  [ТС]
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Память всегда разбита на минимальные адресуемые ячейки — байты
Не совсем понятен принцип работы... К примеру, указатель (int *) указывает на что? Первый-последний байт? В процессе работы программы осуществляется "сборка" числа? Вот пример кода с другого топика Стек и куча: как все это работает?:
Assembler
1
2
3
4
5
6
7
8
9
    movl    $0, -4(%rbp)
    jmp .L2
.L3:
    addl    $1, -4(%rbp)
.L2:
    cmpl    $4, -4(%rbp)
    setle   %al
    testb   %al, %al
    jne .L3
-4(%rbp) - обращение в стек к переменной, $4 - это ее размер в байтах?
Возможно вопросы примитивные, но нагуглить что-то стоящее тяжело...

Добавлено через 30 минут
Работу с память, в следующем примере, рассматриваю как "черный ящик":
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;
int main ()
{
    unsigned short a=1;
    void *p1=&a;
    cout << *(int*)p1 << "\n";//
    char b=(char)1;
    void *p2=&b;
    cout <<  *(int*)p2 << "\n";
    return 0;
}
Вывод:
-859045887 (111111111111111111111111111111111100110 0110011000000000000000001)
-858993663 (111111111111111111111111111111111100110 0110011001100110000000001)

Вывод программы в двоичной системе отличается в один байт...

Вот и решил что так и хранится переменная в памяти...
0
 Аватар для Kuzia domovenok
4268 / 3328 / 926
Регистрация: 25.03.2012
Сообщений: 12,545
Записей в блоге: 1
27.02.2013, 02:05
ты уже вообще перемудрил чего-то. Не воспринимай это дело так серьёзно. При чём здесь вообще указатели в твоём примере?
char занимает 1 байт, int - 4
ты присвоил значение 1 байту по адресу &a
а вывел значение 4х байт по этому адресу.
естесственно, все они кроме младшего - случайно оказавшиеся в памяти числа (ну, может не совсем случайно, но к твоим переменным отношение не имеют, они просто за ними стояли.)
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
27.02.2013, 02:44
Цитата Сообщение от fuelcs Посмотреть сообщение
К примеру, указатель (int *) указывает на что? Первый-последний байт?
На первый байт. На тот, у которого адрес меньше.
Цитата Сообщение от fuelcs Посмотреть сообщение
В процессе работы программы осуществляется "сборка" числа?
При чтении из памяти куска из четырёх байт они автоматически собираются из четырёх отдельных байтов в 32-битное число в регистре. Хитрость в том, что число 0x12345678 в памяти может храниться и как 0x78, 0x56, 0x34, 0x12, так и в виде 0x12, 0x34, 0x56, 0x78 (int* указывает на левый байт в этих последовательностях). Гуглите endianness.
Цитата Сообщение от fuelcs Посмотреть сообщение
Вот пример кода с другого топика
-4(%rbp) - обращение в стек к переменной, $4 - это ее размер в байтах?
-4(%rbp) — ага, это обращение к переменной из стека.
$4 — а вот это просто число 4.
0
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
27.02.2013, 13:13  [ТС]
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
все они кроме младшего - случайно оказавшиеся в памяти числа
Не согласен насчет "случайных" чисел, "мусор" - да, но не случайный...
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <conio.h>
using namespace std;
int main ()
{
    short a;
    int b;
    cout << a << "\n";
    cout << b << "\n";
    return 0;
}
Вывод:
-13108 (111111111111111111111111111111111111111 111111111 1100 1100 1100 1100)
-858993460 (11111111111111111111111111111111 1100 1100 1100 1100 1100 1100 1100 1100)

Добавлено через 21 минуту
К чему это все я? Получается что из за наличия "мусора" в памяти, можно программно определить тип переменных которые находятся в ячейке, на которую указывает указатель типа void*?
По крайней мере для без знаковых переменных...
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
27.02.2013, 13:40
Цитата Сообщение от fuelcs Посмотреть сообщение
К чему это все я? Получается что из за наличия "мусора" в памяти, можно программно определить тип переменных которые находятся в ячейке, на которую указывает указатель типа void*?
бред полнейший, что курил!?
0
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
27.02.2013, 14:14  [ТС]
И вот что еще у меня получилось:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <conio.h>
using namespace std;
int main ()
{
    short a;
    int b;
    cout << (int)&a - (int)&b;
    return 0;
}
По идеи переменные должны лежать рядом в стеке, а разница между адресами 12. То есть получается, что на хранение одной переменной выделяется 12 байт (96 бит)?
Интересно было бы увидеть еще машинный код...
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
27.02.2013, 14:18
Цитата Сообщение от fuelcs Посмотреть сообщение
По идеи переменные должны лежать рядом в стеке, а разница между адресами 12. То есть получается, что на хранение одной переменной выделяется 12 байт (96 бит)?
выставь release
0
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
27.02.2013, 14:25  [ТС]
Цитата Сообщение от Jupiter Посмотреть сообщение
бред полнейший, что курил!?
Почему бред? При разыменовании указателя мы всегда будем получать отрицательное число если тип не сходится...
Причем в двоичной форме старшие биты будут иметь одинаковый вид...
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
27.02.2013, 14:30
Цитата Сообщение от fuelcs Посмотреть сообщение
Почему бред?
потому что указатель на воид на то и воид, чтоб хранить адрес и не знать что лежит по этому адресу.
если это ваша программа - то вы знаете что там лежит.
0
 Аватар для Kuzia domovenok
4268 / 3328 / 926
Регистрация: 25.03.2012
Сообщений: 12,545
Записей в блоге: 1
27.02.2013, 21:39
Цитата Сообщение от fuelcs Посмотреть сообщение
При разыменовании указателя мы всегда будем получать отрицательное число если тип не сходится...
И что? И зачем тебе это? Я потерял нить разговора. А завтра ты откроешь для себя union и будешь без всяких операций с адресами преобразовывать 1 байт в 4 байта... или чего ты там хотел?
В чём суть вопроса то?
0
419 / 418 / 167
Регистрация: 28.11.2010
Сообщений: 1,183
27.02.2013, 23:39
Вообще-то внутренний формат хранения данных зависит от архитектуры, и здесь правильно указали, что для большинства минимальной единицей является 1 байт + порядок байт (little или big endian) + размер переменных зависит от архитектуры и оси тоже. И вывод вашей программы у меня
./a.out
вывод:
0
0
и что мы тут будем ловить?

Добавлено через 2 минуты
ну и ошибка к последнему коду
trashh_cpp/main.cpp:7:29: error: cast from ‘int*’ to ‘int’ loses precision [-fpermissive]
0
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
02.03.2013, 00:09  [ТС]
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
В чём суть вопроса то?
суть вопроса изложил в первом посте... И лучше поздно чем никогда, все таки признать свою ошибку... По содержимому ячейки памяти узнать тип переменной которая там хранится невозможно, что мне сразу же написали...
Но все же всем спасибо за ответы, по ходу прояснил себе некоторые моменты...
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
02.03.2013, 00:56
Ну почему сразу нельзя. Можно. Если вы сами рядом с ячейкой положите этот тип. И будете его обновлять при присваиваниях. Но да, конечно, всё это под честное слово, что там будет действительно лежать тип, а не мусор.
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8217 / 5048 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
02.03.2013, 02:18
Это как брать черные коробки и подписывать что в них есть, а потом в одной из них будет лежать бомба, а написано "любимой маме на 8 марта"
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.03.2013, 02:18

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

Универсальный вызов метода через указатель на объект
Никак не могу найти универсальную конструкцию, которая позволяла бы вызывать любой метод класс, с любыми параметрами через указатель на...

Как получить ссылку на указатель или указатель на указатель в массиве?
В процессе реализации сортировки пузырьком натолкнулся на такую проблему: как поменять значения указателей, передаваемых в функцию. Если...

А почему нельзя передавать в ф-ю добавления элемента в стек один указатель? Почему нужен именно указатель на указатель?
Вот код ф-ии добавления элемента в стек: void push1(Node **top, int d) { // top – указатель начала стека Node *pv;...

Функция, принимающая указатель и число байт и выделяющая память под указатель
Здравствуйте. Задача легкая, но почему-то завис Нужно написать функцию, принимающую указатель и число байт и выделяющую память под...


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

Или воспользуйтесь поиском по форуму:
39
Ответ Создать тему
Новые блоги и статьи
Книги по геймдизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru