2010-10-15 2 views
2

Я пытаюсь напечатать значение, на которое указывает адрес, но проблема в том, что мне нужно разыменовать этот указатель на основе размера, который передается мне. Так что-то в этом роде:Как разыменовывать по размеру?

void print(Address addr, Int size) { 
... 
} 

Я немного смущен о том, как этого достичь. Может ли кто-нибудь указать мне в правильном направлении?

EDIT: Хорошо, так что я имею в виду:

char p[80]; 
memset(p, '\0', 80); 
memcpy(p, addr, size); 

А затем разыменования как * р. Если есть лучший способ или правильный способ, пожалуйста, дайте мне знать

+0

Можете ли вы подробно рассказать о том, что иногда вы хотите разыменовать указатель как 32-битный int (скажем, если size == 4), а иногда и как 64-битный int (if size == 8)? Или вы что-то еще? –

+0

@ Майкл: Правильно. Я пытаюсь напечатать шестнадцатеричное представление этих чисел. – Legend

ответ

3

Ваш вопрос очень неясен. Если вы имеете в виду вы хотите сбросить произвольные двоичные данные из адреса прошло, вы хотите что-то вроде:

void print(const unsigned char *addr, size_t size) 
{ 
    while (size--) printf("%.2x", *addr++); 
} 

Или, если вы имеете в виду вы хотите печатать данные символов, не оканчивается нулем, попробуйте:

void print(const char *addr, int size) 
{ 
    printf("%.*s", size, addr); 
} 
+1

Я добавил атрибуты const в аргументы 'char *'. Поскольку функции не (и не должны) изменять цели аргументов указателя, мы можем позволить оптимизатору компилятора и проверке ошибок узнать немного больше о том, что происходит внутри. –

+0

Спасибо за исправление. –

0

Если это число, которое я предполагаю, что это, вам нужно что-то вроде этого:

int n=0; 
if (size>sizeof(int)) { return; //int is too small }; 
for (int i=0;i<size;i++) { 
    ((char*)(&n))[sizeof(int)-(i+1)] = ((char*)addr)[size-(i+1)]; 
} 
printf("%d",n); 
+0

Этот код в лучшем случае имеет поведение, определяемое реализацией, и, скорее, неопределенное поведение ... –

+0

действительно ли это, почему? –

+1

Если 'size' меньше' sizeof (int) ', часть представления' n' остается неинициализированной. Кроме того, следует ли вам копировать в начало или конец, это определяется реализацией (зависит от конца). –

0

вы можете использовать переключатель заявление в рутина:

switch (size) { 
    case 1: print(*(char*)pointer); break; 
    case 2: print(*(short*)pointer); break; 
    case 4: print(*(long *)pointer); break; 
    case 8: print(*(__int64*)pointer); break; 
    default: puts("unsupported); 
} 

(«печать» является обычной для печати целых чисел различных размеров, возможно, с использованием C++ полиморфизма)

Сложное решение заключается в использовании С ++, например, шаблоном используя тип параметра Integer, который после вызова заменяется фактическим типом переменной. Затем эта процедура может действовать на размер этой переменной Integer (которая может варьироваться от 1 до 8 или более, если вы сами реализуете более длинные целые числа). Этот недостаток этого подхода заключается в том, что компилятор генерирует обычный экземпляр для каждого типа аргументов, а логика, зависящая от размера, приведет к «всегда истинным» условиям для некоторых тестов. Легкий выход - использовать всегда самый длинный тип целого числа, которого вы ожидаете.

+0

OP отметил это как C не C++, поэтому я предполагаю, что это исключает полиморфизм или перегружает печать, но основная причина вашего ответа в порядке. – Andrew

Смежные вопросы