当我使用printf和%d来获取向量的大小时,我不明白为什么我得到0:
vector<long long> sieve;
int size;
...
//add stuff to vector
...
size = sieve.size();
printf("printf sieve size: %d \n", size); //prints "printf sieve size: 0"
std::cout << "cout sieve size: ";
std::cout << size;
std::cout << " \n ";
//prints "cout sieve size: 5 (or whatever the correct sieve size is)"
如果我通过
遍历向量if(i=0;i<sieve.size();i++)
我得到正确的迭代次数。
我做错了什么或者什么是printf? size()返回一个int对吗??
这是我的整个小脚本:
#include <iostream>
#include <vector>
#include <stack>
#include <math.h>
int main (int argc, char * const argv[]) {
unsigned long long answer = 0;
unsigned long long cur = 2;
std::vector<long long> sieve;
unsigned long long limit;
unsigned long long value;
unsigned int i;
int size;
bool isPrime;
std::cout << "Provide a value to find its largest prime factor: ";
std::cin >> value;
limit = ceil(sqrt(value));
sieve.push_back(2);
while(cur++ < limit){
isPrime = true;
sieve.begin();
for(i=0; i<sieve.size();i++){
if(!(cur % sieve[i])){
isPrime = false;
break;
}
}
if(isPrime){
if(!(value % cur)){
std::printf("Is prime factor: %d\n", cur);
sieve.push_back(cur);
answer = sieve[sieve.size() - 1];
size = sieve.size();
std::printf("current last: %d sieve size: %ld\n", answer, size);
for(i=0; i<sieve.size();i++){
std::printf("sieve iter: %d sieve val: %d\n", i, sieve[i]);
std::cout << size;
std::cout << " wtf\n";
}
}
}
}
answer = sieve[sieve.size() - 1];
size = sieve.size();
std::printf("Limit: %d Answer: %d sieve size: %ld\n", limit, answer, size);
return 0;
}
答案 0 :(得分:6)
现在,有了完整的消息来源,很明显。
你宣布:
int size;
然后你用过:
std::printf("current last: %d sieve size: %ld\n", answer, size);
std::printf("Limit: %d Answer: %d sieve size: %ld\n", limit, answer, size);
如果size为int,则应使用“%d”,而不是“%ld”。一个好的编译器会警告你这件事。 GCC为您的原始版本提供了这些警告:
test.cpp: In function ‘int main(int, char* const*)’:
test.cpp:17: warning: converting to ‘long long unsigned int’ from ‘double’
test.cpp:30: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long long unsigned int’
test.cpp:34: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long long unsigned int’
test.cpp:34: warning: format ‘%ld’ expects type ‘long int’, but argument 3 has type ‘int’
test.cpp:36: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘long long int’
test.cpp:45: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long long unsigned int’
test.cpp:45: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘long long unsigned int’
test.cpp:45: warning: format ‘%ld’ expects type ‘long int’, but argument 4 has type ‘int’
这说明了很多。
您应将尺寸声明为:
std::vector<long long>::size_type size;
然后你应该用它作为:
std::printf("current last: %llu sieve size: %llu\n", (unsigned long long) answer, (unsigned long long) size);
std::printf("Limit: %llu Answer: %llu sieve size: %llu\n", (unsigned long long) limit, (unsigned long long) answer, (unsigned long long) size);
当然,使用iostream可以避免这些问题,尤其是printf()中的丑陋转换,可以将大小转换为printf已知的类型。
答案 1 :(得分:5)
这搞砸了,因为你有:
unsigned long long answer = 0;
int size;
然后使用以下代码致电printf
std::printf("current last: %d sieve size: %ld\n", answer, size);
你的两个格式字符串都是错误的:
您已将answer
传递给printf
并将其格式化%d
,但它应为%lld
,因为它已声明为unsigned long long
。< / p>
您使用%d
代替%ld
传递尺寸。由于size
为int
,因此应为%d
。
当这些args传递给printf时,它会为answer
的第一个%d
和第二个32位(或更多,超过结束!)打印answer
的前32位} %ld
。这不你想要的。
如果使用-Wall
进行编译,编译器应该警告您这类事情。密切关注警告!
答案 2 :(得分:2)
看起来很疯狂。因为size被声明为“int size”,所以printf(“...%d”)肯定是正确的。它的大小不能与size_t不同,因为你明确地将“size”声明为int,而cout&lt;&lt; ......大小......工作正常。
你检查过你有没有?可能是因为没有在你的系统上正确声明printf工作“错误”。
答案 3 :(得分:2)
您的问题是,answer
被定义为long long
,您只能使用%d
进行打印。
printf是一个varargs函数,在C中表示编译器不知道你传递给函数的参数。它无法进行正常的类型转换,并且必须信任其用户才能正确获取格式参数,否则参数将无法正确地从调用堆栈中拉出。
你做得不对。
答案 4 :(得分:1)
矢量大小为size_t
,我认为通常是long
...
但不能说为什么printf
无效。
答案 5 :(得分:1)
您正在运行的硬件是什么?可能性size
与您的想法不同。打印sizeof(size)
并检查或尝试%ld
。如果您有像PPC这样的大端机器,大小为long
,并且您打印%d
,则会获得长尾的全零结束。
好的,这就是我使用Intel Mac mini,10.5:
$ cat trySize.C
#include <iostream>
#include <vector>
int main(){
std::cout << "sizeof(size_t): "
<< sizeof(size_t)
<< std::endl ;
std::vector<long long> sieve ;
std::cout << "sizeof(sieve.size()): "
<< sizeof(sieve.size())
<< std::endl;
printf("sizeof(sieve.size()) (printf): %d\n", sizeof(sieve.size()));
return 0;
}
$ g++ trySize.C
$ ./a.out
sizeof(size_t): 4
sizeof(sieve.size()): 4
sizeof(sieve.size()) (printf): 4
$
您可能应该开始将代码分解成更小的部分并尝试它们;这里有些东西。
答案 6 :(得分:1)
size()
方法返回size_t
,这取决于您的c ++实现。当您尝试printf("%d")
时,您告诉图书馆期待int
,但情况并非如此;然后它从调用堆栈中获取int
,它只占用size_t
的高位字节。
您需要做的是使用强制转换将返回值size()
强制为已知数据类型:
printf("%d", (int) size)
答案 7 :(得分:0)
这将有效:
std::printf("current last: %**lld** sieve size: %ld\n", answer, size);
问题是答案是长的(64位整数),%d期望32位整数。因此尺寸不会被打印出来。您需要使用%lld。
有关printf签出的格式字符串的更多信息: http://en.wikipedia.org/wiki/Printf