0

Есть некая переменная int a = 10; для вывода на экран её адреса мы используем printf("%p\n", &a);. А как записать адрес в char*? Разумеется, что под char* выделена память.

Да, и, видимо, стоит уточнить, что функциями семейства принтф пользоваться нельзя. Из доступных функций вывода на экран есть write(2).

Мне же нужно каким-то образом с помощью этой функции из библиотеки unistd.h вывести на экран адрес. Я думал, что можно как-то адрес записать в строку, и потом уже выводить.Бол

  • 2
    Непонятно, что вы спрашиваете. – Vlad from Moscow Jan 04 '19 at 13:41
  • 1
    если умеете выводить через printf, то смотрите в сторону sprintf/snprintf - они получают буфер и данные туда выведут. А char* - это и есть буффер. – KoVadim Jan 04 '19 at 13:51
  • Записать адрес чего в char *? – AnT stands with Russia Jan 04 '19 at 16:06
  • @VladfromMoscow Я спрашиваю как записать адрес ака "007bf92t4f" в строку char*. – Laughing_Man Jan 04 '19 at 16:58
  • В каком формате хотите адрес записать? Для удобства программинга можно записать как восемь байт, или в hex режиме будет двенадцать или в восьмеричном или в десятичном или как '1' '0' ? – AlexGlebe Jan 04 '19 at 17:26
  • @AlexGlebe, как выводит стандартный принтф в 16 системе. Возможно вы знаете, как можно сразу выводить адрес с помощью функции write(2) (без записи в char*)? – Laughing_Man Jan 04 '19 at 17:32
  • С буфером понятнее и быстрее. – AlexGlebe Jan 04 '19 at 17:44
  • @AlexGlebe , тогда остается открытый вопрос как адрес записать в буфер. – Laughing_Man Jan 04 '19 at 17:54
  • в ответе весь цикл – AlexGlebe Jan 04 '19 at 17:56
  • 1
    @Laughing_Man: Строкой может быть char [10], char [20], char [100500] и т.п. char * никак не может быть строкой и записать в него строку никак нельзя. – AnT stands with Russia Jan 04 '19 at 19:31

4 Answers4

2

Если я правильно понял, вам интересен вывод адреса функцией write() в 16-ричном формате без лидирующих нулей.

Например, вот так:

#include <unistd.h>
#include <limits.h>  // CHAR_BIT определен здесь


// значение `x` должно быть < 16
static inline void 
print_hb (int fd, unsigned char x)
{
  write(fd, "0123456789abcdef" + x, 1);
}

// для CНAR_BIT > 8 изменения вносить в эту функцию
// для CНAR_BIT == 8 -- поскольку делим байт пополам, требования к аргументам `print_hb()` удовлетворены
void
print_byte (int fd, unsigned char b)
{
  print_hb(fd, b >> 4);
  print_hb(fd, b & 0xf);
}

void
print_addr (int fd, void *a)
{
  if (a) {
    size_t x = (size_t)a;
    int i, n = sizeof(x);

    for (i = 0; i < n - 1; i++) // пропустим лидирующие нулевые байты
      if ((x >> ((n - i - 1) * CHAR_BIT)))
        break;

    for (; i < n; i++)
      print_byte(fd, (unsigned char)(x >> ((n - i - 1) * CHAR_BIT)));
  } else
    print_hb(fd, 0);
}

Окружающее форматирование -- "0x" перед выводом (если адрес не 0) и \n в конце (если требуется) добавляйте сами по мере надобности.

P.S.
справедливости ради, программа правильна только для CHAR_BIT == 8

avp
  • 46,098
  • 6
  • 48
  • 116
1

Думаю вы хотели этого?

#include <stdio.h>
#include <string.h>

int main(void) {

    int b = 20;

    char string[20];

    memset(string, 0, 20);

    sprintf(string, "%p", &b);

    printf("address of variable string: %p\n", string);
    printf("address of variable b: %s\n", string);

    return 0;
}

Тест здесь.

1

Придумал только собственный printf.

# include <stdio.h>
int main(){
  int x ;
  int * p = & x ;
  char buf [ 15 ] = "0x000000000000";
  for ( int * j = p , k = 13 ; j ; j = (void*)(((size_t)j) >> 4) , -- k ) {
    unsigned int dig = ((size_t)j) % 0x10 ;
    if ( dig < 10 ) buf [ k ] = '0'+dig;
    else buf [ k ] = 'a' + ( dig - 10 ) ; }
  printf ("buf    = %s\n" , buf);
  printf ("printf = %p\n" ,(void *)p);
  fputs  ("no buf = 0x",stdout);
  for ( int * j = p , k = sizeof(void*) * 2 ; k > 0 ; j = (void*)(((size_t)j) << 4)) {
    -- k ;
    unsigned int dig = ((size_t)j) >> (sizeof(void*) * 8 - 4) ;
    if ( dig < 10 ) putc('0'+dig,stdout);
    else putc('a' + ( dig - 10 ) ,stdout); }
  putc('\n',stdout);

  return 0;}

выводит так :

> ./a.out 
buf    = 0x7ffe43921b40
printf = 0x7ffe43921b40
no buf = 0x00007ffe43921b40
AlexGlebe
  • 17,227
0
  int x ;
  int * p = & x ;
  char buf [ 15 ] = "0x000000000000";
  for ( int * j = p , k = 13 ; j ; j = (void*)(((size_t)j) >> 4) , -- k ) {
    unsigned int dig = ((size_t)j) % 0x10 ;
    if ( dig < 10 ) buf [ k ] = '0'+dig;
    else buf [ k ] = 'a' + ( dig - 10 ) ; }
  printf ("buf    = %s\n" , buf);
  printf ("printf = %p\n" ,(void *)p);
  fputs  ("no buf = 0x",stdout);
  for ( int * j = p , k = sizeof(void*) * 2 ; k > 0 ; j = (void*)(((size_t)j) << 4)) {
    -- k ;
    unsigned int dig = ((size_t)j) >> (sizeof(void*) * 8 - 4) ;
    if ( dig < 10 ) putc('0'+dig,stdout);
    else putc('a' + ( dig - 10 ) ,stdout); }
  putc('\n',stdout);

  return 0;
0x77dev
  • 101