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

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

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

Author24 — интернет-сервис помощи студентам
Добрый вечер.
Можно ли создать шаблон, что бы не приводить явно универсальный указатель к определенному типу при разыменовании?
Или по крайней мене узнать тип (размер) данных которые хранятся по указанному адресу?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.02.2013, 22:46
Ответы с готовыми решениями:

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

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

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

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

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

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

Решение

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

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

Но вот использовать qsort() в плюсовом коде — это как прийти на автозавод и обнаружить, что всё собирается на конвейере, но дырку под лобое стекло самолично выпиливает безопилой дядя Вася. Это работает, Вася виртуозен и делает всё правильно, вовремя и не отрезает себе ноги, но у инспектора по технике безопасности глаза на лоб полезут и он сразу побежит спрашивать инженеров: "На кой хрен, если у вас тут безопасных механизмов с автоматическим контролем хоть ложкой ешь?" И ведь действительно, на кой хрен? Только потому, что кто-то хорошо знает дядю Васю и поленился настроить ещё один автомат?
4
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
26.02.2013, 15:26  [ТС] 24
Что бы не создавать новую тему дополню вопрос тут, тем более что он связан с темой топика...
Архитектура машины (разрядность), определяет не только общий объем памяти, но и размер ячейки памяти?
К примеру long long доступно только на 64 разрядной платформе (не зависимо от системы)?
Если для хранения переменной нам достаточно, к примеру, 1-2 байта, как выставлены остальные?
0
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
26.02.2013, 23:48 25
Цитата Сообщение от fuelcs Посмотреть сообщение
Архитектура машины (разрядность), определяет не только общий объем памяти, но и размер ячейки памяти?
Память всегда разбита на минимальные адресуемые ячейки — байты. От разрядности зависят размеры регистров (а от них косвенно быстродействие), размеры адресного пространства. Размеры конкретных типов данных зависят от языка, компилятора и рантайма.
Цитата Сообщение от fuelcs Посмотреть сообщение
К примеру long long доступно только на 64 разрядной платформе (не зависимо от системы)?
На любой. Просто на 32-битных платформах он точно не влезет в один регистр, так что работа с такими числами будет выполняться несколько медленнее.
Цитата Сообщение от fuelcs Посмотреть сообщение
Если для хранения переменной нам достаточно, к примеру, 1-2 байта, как выставлены остальные?
Зависит от типа данных. От него же зависит понятие "достаточности" и "лишнего места". С точки зрения языка лишних байтов вообще нет. Для целых чисел при кодировании дополнительным кодом незначащие биты установлены в нули для положительных и в единицы для отрицательных чисел.
1
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
27.02.2013, 01:38  [ТС] 26
Цитата Сообщение от ~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 (1111111111111111111111111111111111001100110011000000000000000001)
-858993663 (1111111111111111111111111111111111001100110011001100110000000001)

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

Вот и решил что так и хранится переменная в памяти...
0
4064 / 3318 / 924
Регистрация: 25.03.2012
Сообщений: 12,495
Записей в блоге: 1
27.02.2013, 02:05 27
ты уже вообще перемудрил чего-то. Не воспринимай это дело так серьёзно. При чём здесь вообще указатели в твоём примере?
char занимает 1 байт, int - 4
ты присвоил значение 1 байту по адресу &a
а вывел значение 4х байт по этому адресу.
естесственно, все они кроме младшего - случайно оказавшиеся в памяти числа (ну, может не совсем случайно, но к твоим переменным отношение не имеют, они просто за ними стояли.)
0
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
27.02.2013, 02:44 28
Цитата Сообщение от 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  [ТС] 29
Цитата Сообщение от 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 (111111111111111111111111111111111111111111111111 1100 1100 1100 1100)
-858993460 (11111111111111111111111111111111 1100 1100 1100 1100 1100 1100 1100 1100)

Добавлено через 21 минуту
К чему это все я? Получается что из за наличия "мусора" в памяти, можно программно определить тип переменных которые находятся в ячейке, на которую указывает указатель типа void*?
По крайней мере для без знаковых переменных...
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
27.02.2013, 13:40 30
Цитата Сообщение от fuelcs Посмотреть сообщение
К чему это все я? Получается что из за наличия "мусора" в памяти, можно программно определить тип переменных которые находятся в ячейке, на которую указывает указатель типа void*?
бред полнейший, что курил!?
0
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
27.02.2013, 14:14  [ТС] 31
И вот что еще у меня получилось:
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
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
27.02.2013, 14:18 32
Цитата Сообщение от fuelcs Посмотреть сообщение
По идеи переменные должны лежать рядом в стеке, а разница между адресами 12. То есть получается, что на хранение одной переменной выделяется 12 байт (96 бит)?
выставь release
0
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
27.02.2013, 14:25  [ТС] 33
Цитата Сообщение от Jupiter Посмотреть сообщение
бред полнейший, что курил!?
Почему бред? При разыменовании указателя мы всегда будем получать отрицательное число если тип не сходится...
Причем в двоичной форме старшие биты будут иметь одинаковый вид...
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
27.02.2013, 14:30 34
Цитата Сообщение от fuelcs Посмотреть сообщение
Почему бред?
потому что указатель на воид на то и воид, чтоб хранить адрес и не знать что лежит по этому адресу.
если это ваша программа - то вы знаете что там лежит.
0
4064 / 3318 / 924
Регистрация: 25.03.2012
Сообщений: 12,495
Записей в блоге: 1
27.02.2013, 21:39 35
Цитата Сообщение от fuelcs Посмотреть сообщение
При разыменовании указателя мы всегда будем получать отрицательное число если тип не сходится...
И что? И зачем тебе это? Я потерял нить разговора. А завтра ты откроешь для себя union и будешь без всяких операций с адресами преобразовывать 1 байт в 4 байта... или чего ты там хотел?
В чём суть вопроса то?
0
419 / 418 / 167
Регистрация: 28.11.2010
Сообщений: 1,183
27.02.2013, 23:39 36
Вообще-то внутренний формат хранения данных зависит от архитектуры, и здесь правильно указали, что для большинства минимальной единицей является 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  [ТС] 37
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
В чём суть вопроса то?
суть вопроса изложил в первом посте... И лучше поздно чем никогда, все таки признать свою ошибку... По содержимому ячейки памяти узнать тип переменной которая там хранится невозможно, что мне сразу же написали...
Но все же всем спасибо за ответы, по ходу прояснил себе некоторые моменты...
0
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
02.03.2013, 00:56 38
Ну почему сразу нельзя. Можно. Если вы сами рядом с ячейкой положите этот тип. И будете его обновлять при присваиваниях. Но да, конечно, всё это под честное слово, что там будет действительно лежать тип, а не мусор.
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
02.03.2013, 02:18 39
Это как брать черные коробки и подписывать что в них есть, а потом в одной из них будет лежать бомба, а написано "любимой маме на 8 марта"
0
02.03.2013, 02:18
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.03.2013, 02:18
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
39
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru