为什么 int8 像 char (C++) 一样工作(Visual Studio 2015)
Why int8 works like char (C++) (Visual Studio 2015)
我试图在 C++ 中找到最小的 int 类型。我读到没有使用少于一个字节的类型,because is the minimum addressable size。我找到的最小的是int8_t,或者_int8visual studio类型。我尝试同时使用两者,但程序将值存储为字符。有一种方法可以将这种类型用作整数吗?或者甚至,如果有办法使用更小的类型(2 位(有符号)将是完美的 XD,我只需要存储 -1、0 和 1)或任何其他数字字节类型。
提前致谢
标准为您提供以下类型:
signed char
unsigned char
(char
相当于其中之一)
而您在 8 位系统上的固定宽度 int8_t
、uint8_t
只是这些的 别名 。
都已经是整数了
您的陈述 "but the program stores the values as chars" 表明人们误解了这些类型的基本价值 。这可能是由于以下原因。
您可能遇到的唯一 "problem" 是 IOStreams 子库中这些类型的特殊格式:
const char c = 40;
std::cout << c << '\n';
// Output: "("
因为 int8_t
is/may 是 signed char
,这在字面上是一样的:
const int8_t c = 40;
std::cout << c << '\n';
// Output: "("
但这很容易 "fixable" 一点积分提升:
const char c = 40;
std::cout << +c << '\n';
// Output: 40
现在流得到一个 int
,并将其作为其格式化例程的一部分进行词法转换。
这与标准库提供的类型系统和函数重载有关;它与 "how the values are stored" 无关。都是整数。
您可以使用带两位的 bit field。
I tried to use both, but the program stores the values as chars.
它不会(将值存储为字符)。在 C++ 中,char 值 是 整数值。与其他整数类型的不同之处在于两个地方:
编译器透明地将字符文字转换为整数
标准库将 char 类型与其他整数类型分开处理(也就是说,它认为 char 代表 字母 文本字符,而不是数字)。
就编译器而言,代码:
char x = 'A';
相当于:
char x = 65; // set value to 65 (ASCII code for letter "A")
如果您在调试器中查看 x
的第二个定义,debugger/IDE 可能会告诉您 x 是 'A'。
Or even, if there are a way to use smaller types (2 bits (signed) would be perfect XD, I need to store only -1, 0 and 1), or any other numeric byte type.
没有小于 8 位表示的整数类型。
也就是说,您可以(并且可能应该)为其创建自定义类型:
enum class your_type: std::uint8_t
{
negative = -1,
neutral = 0,
positive = 1
};
选择在您的程序上下文中有意义的值(即不是 "negative, neutral and positive")。
对于 MSVC,您可以使用 #pragma pack(1)
和结构来获得它。
#pragma pack(1)
struct int2 {
int value:2;
};
#pragma pack()
int main()
{
int2 a;
for (int i = 0; i < 10; i++)
{
a.value = i;
std::cout << a.value << std::endl;
}
return 0;
}
输出:
0
1
-2
-1
0
1
-2
-1
0
1
我想构建构造函数和运算符函数来间接访问值应该不是问题。
编辑:带有运算符的改进版本:
#pragma pack(1)
template <typename INT_TYPE, int BYTE_SIZE>
class int_x {
INT_TYPE value: BYTE_SIZE;
public:
int_x() :value(0) {}
int_x(INT_TYPE v) :value(v) {}
operator INT_TYPE() const {
return value;
}
int_x& operator=(INT_TYPE v) {
value = v; return *this;
}
int_x& operator+=(INT_TYPE v) {
value += v; return *this;
}
int_x& operator-=(INT_TYPE v) {
value -= v; return *this;
}
int_x& operator/=(INT_TYPE v) {
value /= v; return *this;
}
int_x& operator*=(INT_TYPE v) {
value *= v; return *this;
}
};
typedef int_x<int, 1> int1; //Range [-1;0]
typedef int_x<unsigned int, 1> uint1; //Range [0;1]
typedef int_x<int, 2> int2; //Range [-2;1]
typedef int_x<unsigned int, 2> uint2; //Range [0;3]
typedef int_x<int, 3> int3; //Range [-4;3]
typedef int_x<unsigned int, 3> uint3; //Range [0;8]
#pragma pack()
我试图在 C++ 中找到最小的 int 类型。我读到没有使用少于一个字节的类型,because is the minimum addressable size。我找到的最小的是int8_t,或者_int8visual studio类型。我尝试同时使用两者,但程序将值存储为字符。有一种方法可以将这种类型用作整数吗?或者甚至,如果有办法使用更小的类型(2 位(有符号)将是完美的 XD,我只需要存储 -1、0 和 1)或任何其他数字字节类型。
提前致谢
标准为您提供以下类型:
signed char
unsigned char
(char
相当于其中之一)
而您在 8 位系统上的固定宽度 int8_t
、uint8_t
只是这些的 别名 。
都已经是整数了
您的陈述 "but the program stores the values as chars" 表明人们误解了这些类型的基本价值 。这可能是由于以下原因。
您可能遇到的唯一 "problem" 是 IOStreams 子库中这些类型的特殊格式:
const char c = 40;
std::cout << c << '\n';
// Output: "("
因为 int8_t
is/may 是 signed char
,这在字面上是一样的:
const int8_t c = 40;
std::cout << c << '\n';
// Output: "("
但这很容易 "fixable" 一点积分提升:
const char c = 40;
std::cout << +c << '\n';
// Output: 40
现在流得到一个 int
,并将其作为其格式化例程的一部分进行词法转换。
这与标准库提供的类型系统和函数重载有关;它与 "how the values are stored" 无关。都是整数。
您可以使用带两位的 bit field。
I tried to use both, but the program stores the values as chars.
它不会(将值存储为字符)。在 C++ 中,char 值 是 整数值。与其他整数类型的不同之处在于两个地方:
编译器透明地将字符文字转换为整数
标准库将 char 类型与其他整数类型分开处理(也就是说,它认为 char 代表
字母文本字符,而不是数字)。
就编译器而言,代码:
char x = 'A';
相当于:
char x = 65; // set value to 65 (ASCII code for letter "A")
如果您在调试器中查看 x
的第二个定义,debugger/IDE 可能会告诉您 x 是 'A'。
Or even, if there are a way to use smaller types (2 bits (signed) would be perfect XD, I need to store only -1, 0 and 1), or any other numeric byte type.
没有小于 8 位表示的整数类型。
也就是说,您可以(并且可能应该)为其创建自定义类型:
enum class your_type: std::uint8_t
{
negative = -1,
neutral = 0,
positive = 1
};
选择在您的程序上下文中有意义的值(即不是 "negative, neutral and positive")。
对于 MSVC,您可以使用 #pragma pack(1)
和结构来获得它。
#pragma pack(1)
struct int2 {
int value:2;
};
#pragma pack()
int main()
{
int2 a;
for (int i = 0; i < 10; i++)
{
a.value = i;
std::cout << a.value << std::endl;
}
return 0;
}
输出:
0
1
-2
-1
0
1
-2
-1
0
1
我想构建构造函数和运算符函数来间接访问值应该不是问题。
编辑:带有运算符的改进版本:
#pragma pack(1)
template <typename INT_TYPE, int BYTE_SIZE>
class int_x {
INT_TYPE value: BYTE_SIZE;
public:
int_x() :value(0) {}
int_x(INT_TYPE v) :value(v) {}
operator INT_TYPE() const {
return value;
}
int_x& operator=(INT_TYPE v) {
value = v; return *this;
}
int_x& operator+=(INT_TYPE v) {
value += v; return *this;
}
int_x& operator-=(INT_TYPE v) {
value -= v; return *this;
}
int_x& operator/=(INT_TYPE v) {
value /= v; return *this;
}
int_x& operator*=(INT_TYPE v) {
value *= v; return *this;
}
};
typedef int_x<int, 1> int1; //Range [-1;0]
typedef int_x<unsigned int, 1> uint1; //Range [0;1]
typedef int_x<int, 2> int2; //Range [-2;1]
typedef int_x<unsigned int, 2> uint2; //Range [0;3]
typedef int_x<int, 3> int3; //Range [-4;3]
typedef int_x<unsigned int, 3> uint3; //Range [0;8]
#pragma pack()