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);

サイズが int の場合、「%ld」ではなく「%d」を使用する必要があります。優れたコンパイラは、これについて警告します。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そうする必要があります。%lldunsigned long long

  2. %dの代わりにサイズを渡しています%ldsizeは とであるためint、 となるはずです%d

これらの引数が printf に渡されると、answerfor の最初%dの 32 ビットと 2 番目の 32 ビット (またはそれ以上、末尾を超えて!) がanswer出力されます%ld。これはあなたが望むものではありません。

コンパイラでコンパイルする場合-Wall、この種のことについて警告する必要があります。警告には細心の注意を払ってください。

于 2009-03-02T04:02:33.603 に答える
2

クレイジーに見える。サイズは「int サイズ」と宣言されているため、printf("...%d") は間違いなく正しいです。「サイズ」を int として明示的に宣言し、cout << ... size ... が正しく動作するため、size_t のサイズが「int」と異なることはあり得ません。

が含まれていることを確認しましたか? システムで適切な宣言がないと、printf が「間違って」動作する可能性があります。

于 2009-03-02T03:30:33.617 に答える
2

あなたの問題は、それanswerが として定義されており、long longそれを でのみ印刷すること%dです。

printf は varargs 関数であり、Cでは、関数に渡された引数をコンパイラが認識していないことを意味します。通常の型変換を行うことができず、ユーザーがフォーマット引数を正しく取得することを信頼する必要があります。そうしないと、引数がコール スタックから適切に取り出されません。

よくわかりませんでした。

于 2009-03-02T03:40:02.020 に答える
1

ベクトルのサイズはsize_tで、通常はlong...

ただし、なぜ機能しないprintfのかは言えません。

于 2009-03-02T03:24:18.907 に答える
1

実行しているハードウェアは何ですか? それsizeはあなたが思っているのとは違うタイプである可能性があります。印刷sizeof(size)して確認するか、試してみてください%ld。PPC のようなビッグ エンディアンのマシンを使用している場合、サイズは でありlong%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 に答える