Смущен (char *) приведением

struct myStruct
{
int foo;
}

myStruct bar;
bar.foo = 123;
cout<<(char *) &bar<<endl;

Оператор cout выводит ‘{‘.
ASCII для 123 на самом деле равен «{» (bar.foo = 123. При изменении этого значения выводятся разные символы). Что я не понимаю, так это

cout<<(char *) &bar<<endl;

Технически следует напечатать адрес бара. Как я могу получить доступ к данным внутри структуры, используя (char *) приведение? Использование (int *) по-прежнему возвращает адрес. Я знаю, что (char *) заставляет данные располагаться побайтово, но разве это не должно влиять на адрес?

0

Решение

Существует перегрузка для << принятие const char *, который интерпретирует операнд как указатель на строку с нулем в конце в стиле C. Это перегрузка, используемая, например,

cout << "Hello\n";

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

4

Другие решения

<< на char* обрабатывает его как строку C, а не как указатель. Эта программа интерпретирует myStruct в качестве буфера sizeof(myStruct) байтов и полагается на порядковый номер, чтобы гарантировать, что он завершается NUL.

Чтобы распечатать адрес, просто передайте &bar без актерского состава.

2

Поскольку bar является объектом структуры myStruct, его начальный адрес и начальный адрес первого члена в myStruct, т.е. bar.foo, будут одинаковыми. Так &bar даст вам начальный адрес объекта bar, а char * предоставит вам значение первого байта в этом месте адреса.

1

В отличие от int *, char * это особый вид указателей, они также используются для указания на строки ASCII, например:

const char * s = "hello world";

Для выражения (char *) &bar результат char * указатель, cout поэтому напечатает строку, потому что она имеет специальный оператор для char * это выводит строки. за int * здесь нет оператора, есть только универсальный оператор для указателей, который печатает только адреса.

1

std::ostream как правило, имеет перегрузку для operator << с const char * к которому char * будет связан с.

Эта перегрузка обрабатывает свой аргумент как завершенную нулем строку символов ASCII.

1

Если вам нужно вывести содержимое myStruct в выходной поток, вам нужно определить ostream << Оператор для вашей структуры, как это:

std::ostream& operator <<(std::ostream& os, const myStruct& ms)
{
os << "myStruct { foo: " << ms.foo << "\n}";
return os;
}

(char *) ничего не меняет. Структура хранится в памяти как 4 байта = sizeof (int) или 8 байтов на 64-битном ЦП, в зависимости от архитектуры процессора в порядке с прямым порядком байтов или с прямым порядком байтов (см. http://en.wikipedia.org/wiki/Endianness).

Ваш код, вероятно, работает на процессоре архитектуры x86, поэтому младший байт хранится по младшему адресу. Например, число 123 в foo будет храниться как байты 7B 00 00 00. В памяти. Ваш оператор co char * скажет компилятору использовать оператор ostream для массива char *, который используется как строка в C. Каждый байт интерпретируется как один символ, оканчивающийся на 0 байт. Байт 123 соответствует символу ASCII ‘{‘, он заканчивается байтом 00, поэтому в этом случае ваш код не потерпит крах. Другие значения могут привести к сбою вашего кода или печати байтов в стеке за пределами хранилища вашей структуры (до тех пор, пока не встретится нулевой байт или не произойдет сбой).

Надеюсь это поможет.

1

На самом деле ваш код печатает адрес строки переменных структуры, а не значение foo. (Char *)&bar преобразует адрес типа структуры в (char *) означает c строкового типа.
Некоторые параметры функций c, c ++ действительно принимают тип struct в качестве аргументов, поэтому нам нужно преобразовать тип struct в (char *) или (void *) в соответствии с параметрами функции.

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector