1

私は与えられたコードを持っています。私の意見では、そのコードには何か問題があります。私は XINU でコンパイルしています。

次の変数が関連しています:

unsigned long ularray[];
int num;
char str[100];

intを返す関数があります:

int func(int i)
{
    return ularray[i];
}

コードは次のようになります。

num = func(i);
sprintf(str, "number = %lu\n", num);
printf(str);

問題は、%lu で印刷しているときに大きな数字が表示されることです。これは正しくありません。

%lu%dに変更すると、正しい番号が得られます。例: %lu では 27654342 を取得しますが、%di では 26 を取得します。後者は正しいです。

変数が与えられ、関数の宣言が与えられます。本体を書きますが、int を返す必要があります。

私の質問は次のとおりです。

  1. 私は「sprintf」に慣れていません。おそらく問題がありますか?

  2. unsigned long を int に代入し、int を %lu で出力しましたが、正しいですか?

  3. どうすれば問題を解決できますか?

前もって感謝します。

答えてくれてありがとう。私は XINU の下で作業していることに言及したいと思います。ファイルのコンパイルの順序とあなたが知っていることを変更しました...その作業と %lu と %d で同じ番号が表示されます。

'unsigned long' を int に代入してから %lu で出力すると、コーディングが正しくなく、データが失われる可能性があることは十分承知しています。しかし、私が言ったように、コードは与えられていますが、変数と印刷コマンドを変更できませんでした。

エラーや警告はありませんでした。コンパイルの順序を変更することで問題が解決した理由がわかりません。誰かがアイデアを持っている場合は、共有してください。

私を助けようとしてくれた皆さんに感謝します。

4

4 に答える 4

2

1) 誤解は、フォーマット指定子全般です。

2) num は int です。したがって、 anを印刷したい%d場合は正しいです。int

3) 理想的には

  • int func(int i)だろうunsigned long func(size_t i)
  • そしてint numなるだろうunsigned long num
  • そしてsprintf(str, "number = %d\n", num);なるだろうsprintf(str, "number = %lu\n", num);

そうすれば、縮小も変換も行われず、型/値は実行中に正しく保持されます。

そして衒学的であることは、printfあるべきですprintf("%s", str);

警告レベルを上げると、コンパイラはこれらのいくつかについて警告します。私は長い間プログラミングを行ってきましたが、まだ警告レベルを不快なほど高くしています (一部の人々の基準によると)。

于 2012-08-25T07:28:52.133 に答える
2

unsigned long を int に代入し、int を %lu で出力しましたが、正しいですか?

いいえ、それはまったく正しくありません。少し考えてみてください!Printf は、渡された変数によって表されるメモリにアクセスしようとします。あなたの場合、unsigned long は int よりも多くのビットで表されます。したがって、printf が unsigned int を出力するように指示されると、実際の int を超えて読み取られ、いくつかが読み取られます。おそらくガベージである他のメモリ、したがって乱数。printf のプロトタイプが unsigned long を正確に記述している場合、コンパイラは暗黙的なキャストを実行し、残りの不要なメモリをゼロで埋めることができますが、そうではないため、次のいずれかの解決策を実行する必要があります。

1 つ、変数を明示的にキャストします。

printf("%lu", (unsigned long)i);

2 つ目は、正しい書式指定子を使用することです。

printf("%d", i);

また、unsigned long を int に代入する際にも問題があります。long に含まれる数値が大きすぎると、int に収まらず、切り捨てられます。

于 2012-08-25T07:32:54.923 に答える
0

がある場合は、 (またはunsigned int の場合) をint使用します。long がある場合は、(またはunsigned long の場合) を使用します。 long を指定して int のみを渡すと伝えると、ランダムなガベージが出力されます。(技術的には、未定義の動作になります。)%d%u%ld%lu
printf

それがintどういうわけか「から来た」かどうかは問題ではありません。より短いものに割り当てると、余分なバイトは失われます。int しか残っていません。

于 2012-08-25T07:28:44.370 に答える
0

unsigned long を int に代入し、int を %lu で出力しましたが、正しいですか?

いいえ、最初に int にキャストしないか、単に int を配列型として使用することをお勧めします。はるかに大きな表現を保存し、小さな表現だけを使用するのは無意味に思えます。いずれにせよ、変数の型 (技術的にはencoding ) と形式の変換指定子を適切に組み合わせるまで、スプリントの結果は常にオフになります。これは、unsigned long を渡す場合は を使用%ulし、int の場合は または のいずれかを使用する%iことを意味します%d(違いは、%d常に基数10 であり、他の基数で出力%iするために追加の指定子を使用できることです。

どうすれば問題を解決できますか?

関数の戻り値とエンコーディングをに変更しnumますunsigned long

unsigned long ularray[];
unsigned long num;
char str[100];

unsigned long func(int i)
{
    return ularray[i];
}
于 2012-08-25T07:39:06.507 に答える