1

当我使用 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;
}
4

8 回答 8

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 已知类型的丑陋转换。

于 2009-03-02T03:40:06.887 回答
5

这搞砸了,因为你有:

unsigned long long answer = 0;
int size;

你打电话printf给:

std::printf("current last: %d sieve size: %ld\n", answer, size);

您的两个格式字符串都是错误的:

  1. 您正在传递answerprintf格式化它%d,但它应该是%lld,因为它已声明unsigned long long

  2. 您使用%d而不是传递大小%ld。既然size是和int,它应该是%d

当这些 args 被传递给 printf 时,answer%danswer%ld. 这不是你想要的。

如果你用-Wall你的编译器编译应该警告你这种事情。请密切注意警告!

于 2009-03-02T04:02:33.603 回答
2

看起来很疯狂。因为 size 被声明为“int size”,所以 printf("...%d") 绝对正确。它不可能是 size_t 与“int”的大小不同,因为您明确地将“size”声明为 int,并且 cout << ... size ... 可以正常工作。

您是否检查过您是否已包含 ? 可能是在您的系统上没有正确声明 printf 工作“错误”。

于 2009-03-02T03:30:33.617 回答
2

你的问题是它answer被定义为 along long并且你只用 a 打印它%d

printf 是一个可变参数函数,在 C 中这意味着编译器不知道您传递给函数的参数是什么。它不能进行正常的类型转换,它必须信任它的用户才能正确获取格式参数,否则参数将无法正确地从调用堆栈中拉出。

你没看对。

于 2009-03-02T03:40:02.020 回答
1

矢量大小是size_t,我相信这通常是long...

不过,不能说为什么printf不起作用。

于 2009-03-02T03:24:18.907 回答
1

你运行的硬件是什么?奇怪的是,这size与您想象的类型不同。打印sizeof(size)并检查,或尝试%ld. 如果你有一台像 PPC 这样的大端机器,大小是 a long,并且你打印 a %d,你会得到 long 的全零结尾。

更新

好的,这就是我使用 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
$ 

您可能应该开始将代码分解成更小的部分并尝试它们;这里有一些奇怪的东西。

于 2009-03-02T03:25:58.777 回答
1

size()方法返回size_t,这取决于您的 c++ 实现。当您尝试 时printf("%d"),您是在告诉图书馆期待一个int,但不一定如此;然后它int从调用堆栈中获取一个,它只获取size_t.

您需要做的是通过强制转换将返回值强制size()为已知数据类型: printf("%d", (int) size)

于 2009-03-02T03:29:50.610 回答
0

这将起作用:

std::printf("current last: %**lld** sieve size: %ld\n", answer, size);

问题是答案是一个 long long (一个 64 位整数)并且 %d 需要一个 32 位整数。所以尺寸不会被打印出来。您将需要使用 %lld。

有关 printf 格式字符串的更多信息,请查看: http ://en.wikipedia.org/wiki/Printf

于 2009-03-02T04:19:42.737 回答