#include <vector>
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, const char *argv[])
{
vector<bool> a;
a.push_back(false);
int t=a[0];
printf("%d %d\n",a[0],t);
return 0;
}
此代码输出“5511088 1”。我以为它会是“0 0”。
任何人都知道为什么会这样?
答案 0 :(得分:9)
%d
格式说明符用于大小为整数的参数,因此printf
函数期望两个参数都是int
的大小。但是,您为它提供的参数不是int
,而是由vector<bool>
返回的可转换为bool
的特殊对象。
这基本上导致printf
函数将堆栈中的随机字节视为值的一部分,而事实上它们不是。
解决方案是将第一个参数转换为int
:
printf("%d %d\n", static_cast<int>(a[0]), t);
如果可能的话,更好的解决方案是优先选择printf
以上的流,因为与printf
不同,它们是类型安全的,这使得这种情况不可能发生:
cout << a[0] << " " << t << endl;
如果您正在寻找printf
的类型安全替代方案 - 例如格式化,请考虑使用Boost Format库。
答案 1 :(得分:3)
%d
格式说明符适用于int
类型。所以,试试 -
cout << a[0] << "\t" << t << endl;
答案 2 :(得分:2)
答案的关键是向量不是真正的bool向量。它实际上是一个代理对象的向量,可以转换为int和&amp;布尔变量。这允许每个bool作为单个位存储,以获得更大的空间效率(以速度效率为代价),但是会引起许多问题,如此处所见。这个要求在一个轻松的时刻被投票进入了C ++标准,我相信大多数委员会成员现在都认为这是一个错误,但它在标准中并且我们很顽固地坚持它。
答案 3 :(得分:0)
问题由the specialization for bool of vectors触发。
<块引用>标准库为 bool 定义了矢量模板的特殊化。这种特殊化的描述表明实现应该打包元素,以便每个 bool 只使用一位内存。 这被广泛认为是一个错误。
基本上std::bool
使用 1 位而不是 1 个字节,因此您面临有关 printf 的未定义行为。
如果你真的愿意使用printf
,你可以通过将std::bool
定义为char并打印为整数%d来解决这个问题(隐式转换,1表示true 和 0 表示 false)。
#include <vector>
#include <iostream>
#include <stdio.h>
#define bool char // solved
using namespace std;
int main(int argc, const char *argv[])
{
vector<bool> a;
a.push_back(false);
int t = a[0];
printf("%d %d\n", a[0], t);
return 0;
}