Для чего используются «BYTE» и «PBYTE»? Я не смог найти никакой информации в Интернете.
#include <iostream>
#include <Windows.h>
using namespace std;
BYTE by='a';
PBYTE pby= &by;
int main(){
cout<<"by : "<<by<<endl;
cout<<"&by : "<<&by<<endl; // Why doesn't it return the memory address?
cout<<"pby : "<<pby<<endl;
cout<<"&pby: "<<&pby;
return 0;
}
The console shows:
by : a
&by : a
pby : a
&pby: 00007FF6CC10A008
Я просто хочу знать, для чего используются BYTE и PBYTE. Я не понимаю. Спасибо
Если вы используете любую визуальную студийную среду (сообщество, профессионал, предприятие, код и т. д.), просто выделите перспективу в коде, нажмите F12 и следуйте инструкциям. Странный результат, который вы видите, связан с определенными перегрузками operator <<
по сравнению с типами под BYTE
и PBYTE
, которые я бы поставил на большие деньги, это unsigned char
и unsigned char*
соответственно.
Вы сказали, что я не могу найти никакой информации в Интернете, смотрите здесь для получения дополнительной информации. Вы не должны использовать BYTE
, если вы не занимаетесь программированием для Windows, и даже в этом случае я бы не рекомендовал его, если вы хотите использовать байтовый тип данных uint8_t
, который является стандартным C++, а не специфичным для WIndows.
Забудьте о типе PBYTE
. Не используйте его, а вместо этого используйте BYTE *
, это то же самое. И если вы видите PBYTE
в существующем коде или в документации MS, думайте об этом как BYTE*
.
Для чего используются «BYTE» и «PBYTE»?
BYTE
— это псевдоним типа для unsigned char
, а PBYTE
— это псевдоним для BYTE *
, также известный как unsigned char *
. Они используются в WINAPI как их «настоящий» тип — unsigned char
и указатель на unsigned char
В вашем коде:
cout << "&by : ";
cout << "&phy : ";
возьмет указатель этого строкового литерала в памяти и распечатает все последующие символы, пока не достигнет \0
(так работает строка с нулевым завершением). Затем он возвращает basic_ostream<char, _Traits>&
, что позволяет объединить несколько вызовов в цепочку.
Когда вы вызываете cout << &by
, вы вызываете перегруженный оператор для basic_ostream << const unsigned char *__s
. Если копнуть глубже в код,
template<typename _Traits> inline basic_ostream<char, _Traits>&
operator<<(basic_ostream<char, _Traits>& ___out, const unsigned char* __s)
{
return (___out << reinterpret_cast<const char*>(__s));
}
Вы обнаружите, что это просто приведение const unsigned char*
к const char*
(обратите внимание, что unsigned char*
является const
, потому что это глобальная переменная). Другими словами, он работает точно так же, как cout << reinterpret_cast<const char*>(&by)
, где программа обрабатывает ваш &by
как строку с завершающим нулем. Поскольку выделенное в стеке сбрасывается до \0
s, by
такое же, как односимвольная длинная строка с нулем в конце ("a\0"
).
С другой стороны, когда вы вызываете cout << &pby
, вы вызываете перегруженный оператор для __ostream_type& << const void*
. Программа приводит PBYTE *
к пустому указателю, поскольку для PBYTE *
(BYTE **
) нет перегрузки. В этом случае он просто распечатывает адрес pby
.
__ostream_type& operator<<(const void* __p) {
return _M_insert(__p);
}
Этот вопрос не о том, как работает <<
. Этот вопрос кратко сформулирован в первом предложении. Вы видимо невнимательно прочитали вопрос.
@SamVarshavchik Я не согласен. ОП написал // Why doesn't it return the memory address?
вместе с выводом консоли в своем коде. PBYTE
и BYTE
объявлены в windows.h
, и достаточно очевидно, что они используются в WINAPI. Вопрос «Я просто хочу знать, для чего используются BYTE и PBYTE», по-видимому, возникает из-за того, что cout << &by
не печатает адрес by
.
Я хочу научиться пользоваться Winapi. Я изучаю типы данных, используемые этим API. Итак, я делаю тесты. Небольшие программы, которые показывают мне значение переменных в консоли. Вот почему я сослался на то, что показывала консоль. Но мой настоящий вопрос: для чего используются эти типы данных?
Есть два вопроса - один для их использования и один для "почему вызов cout не распечатывает память". BYTE
— это псевдоним типа для unsigned char
, а PBYTE
— это псевдоним для BYTE *
, также известный как unsigned char *
. Это отвечает на ваш вопрос?
BYTE, PBYTE — это очень старый стиль программирования для Windows. Если вы хотите выделить память кучи, например, для загрузчика изображений, вы можете написать
unsigned char* img = new unsigned char[1024 * 1024];
load_image(img, ....);
conv_image(img, ....);
Но твой палец устанет, так что ты можешь писать
PBYTE img = new BYTE[1024 * 1024];
Да, Microsoft изобрела эти определенные типы более 20 лет назад. Но он не переносим, не соответствует стандартам и вызывает утечку памяти, поэтому в 21 веке вы должны писать так, как описано ниже.
auto img = make_shared<uint8_t>(1024 * 1024);
or
vector<uint8_t> v(1024 * 1024);
or
array<uint8_t, 1024 * 1024> a; // need enough stack memory
Использование вектора вместо нового не имеет ничего общего с использованием BYTE против uint8_t.
Для чего используются «BYTE» и «PBYTE»? Я не смог найти никакой информации в Интернете.
Пожалуйста, смотрите здесь.
BYTE A byte (8 bits).
This type is declared in WinDef.h as follows:
typedef unsigned char BYTE;
PBYTE
A pointer to a BYTE.
This type is declared in WinDef.h as follows:
typedef BYTE *PBYTE;
Также есть std::byte, который документирует:
std::byte — это отдельный тип, реализующий концепцию байта, указанную в определении языка C++. Подобно char и unsigned char, его можно использовать для доступа к необработанной памяти, занятой другими объектами (объектное представление), но в отличие от этих типов, это не символьный тип и не арифметический тип. Байт — это всего лишь набор битов, и для него определены только побитовые операторы.
Пока кто-нибудь не найдет дубликат:
BYTE
— псевдоним типа дляunsigned char
(см. эту ссылку). Тип&by
— этоunsigned char*
. Существует перегруженный оператор<<
, который принимает любой тип указателя наchar
(char*
,signed char*
иunsigned char*
) и обрабатывает его как указатель на первый символ строки с завершающим нулем. Поскольку&by
не является таким указателем, у вас фактически есть неопределенное поведение. Вам нужно навести указатель наvoid*
, чтобы получить адрес. У вас такая же проблема сpby
.