あなたが得ている答えが問題に答えているのはわかりますが、説明はしません。見た目からすると、適切な説明を使用できるので、何が起こっているのですか:
C の型
int
異なる型 ( 、char
、float
、double
) が異なるサイズのメモリを使用することを理解する必要があります。C では、achar
は常に 1 バイトを占めると見なされ、-127 から 128 の範囲です。 (unsigned char
は 0 から 255 になります。) int
s は 4 バイトを占め、その範囲は -2M から 2M - 1 です。 . float
そしてdouble
、それぞれ 4 バイトと 8 バイトを取り、巨大な範囲を持ちますが、精度は限られています。(詳細については、「c 型の範囲」を検索するだけで、Stack Overflow のこれらのリンクを含む多くの情報が見つかります。これらのリンクからも適切な説明が得られます:データ型の範囲の定義、保証された最小サイズ/範囲C データ型の)。
また、char バージョンを取得するために桁に 48 を追加することを知るのに十分な ascii を知っていますが、近くに ascii テーブルがあることを確認してください。便利なことに、 http://www.asciitable.comで見つけることができます。
また、コンパイラが 1 から別の変換に最善を尽くすことも理解する必要がありますが、 afloat
を anにキャストするなど、場合によってint
は、明示的に変換しない場合、コンパイラは少なくとも警告を発行する必要があります。
文字列は C の型として存在しません。代わりに、配列に出力します。他の答えは、それを行う方法を教えてくれます。彼らのコードが行っていることは、必要な値を文字配列に出力することです。必要なのはこれだけです。
あなたのコードが何をしているか
それでは、現在のコードが何をしているか見てみましょう。
まず、簡単なサイドバー: ループを実行しているときはfor
、ループ自体にインクリメントを配置するのが最善です。
for(count=1.5;count<=2.5;count=count+0.5)
{
for(i=0;i<=15;i=i+5)
より標準化されます。
さて、最初の行はsendBuffer[0]=count+48;
. 何が起こるかは次のとおりです。
- 1.5 から始まるカウントに 48 を足すと、最初の数は 49.5 になります。
- コンパイラは自動的に a
float
を anint
に変更しますが、警告が表示されるはずです。これは、値を切り捨てて 49.5 を 45 に変更することによって行われます。
(int)49
その後、同じ値に変わります(char)49
が、4 ではなく 1 バイトを使用します。Ascii 49 は '1' であるため、これがたまたま必要な数値になります。
- コンパイラは残りの float に対して何もしません。この値に sendBuffer[1] または [2] を設定することはありません。
次の 3 行では、文字列の 2 番目、3 番目、4 番目の文字をabc
. 最初の行で完全な float 値を に設定したとしても、sendBuffer
上書きされてしまいます。
最後の行は、0、5、10、15 になる i を取り、それを 48 に追加しfloat
ます。最初に ascii 48 ('0') を検索し、次に ascii 53 ('5') を検索します。が 10 の場合i
、int 58 を受け取り、それを文字に変換します (再び、4 バイトから 1 バイトに変更します)。ascii 58 を印刷すると「:」になり、ascii 63 を印刷すると「?」になります。そして、それがあなたの出力がそのようになった方法です。
可能な解決策
最後に、与えられた解決策について一言:
結果を出力するだけなので、 no は必要ありsendBuffer
ませんsnprintf
。単に使用する
printf("%.1fabc%d\n", count, i);
で十分だったでしょう。
ただし、関数の printf ファミリーが何をするかを考えるのは有益です。効率は劣りますが、いくつかsnprintf
の s を使用して、何をしているかを見てみましょう。
int index = 0;
index = snprintf(&sendbuf[index], sizeof(sendbuf) - index, "%.1f", count);
index += snprintf(&sendbuf[index], sizeof(sendbuf) - index, "abc");
index += snprintf(&sendbuf[index], sizeof(sendbuf) - index, "%d", i);
sendbuf[index++] = '\n';
sendbuf[index] = '\0';
これが何をするか*printf
は、複数の引数を渡した場合と同じです: 書いた量を追跡し、それを使用して次の部分をどこに書いているかを伝えます。
ご存じない方のために説明すると、a += b
構文は の省略形ですa = a + b
。 a++
は、「a の値を指定してから、それをインクリメントする」という意味です。
したがって、私のコードの 2 行目は、0 の位置から始まる float 値を sendbuf に出力します。 *printf
は常に印刷された文字数を返すため、この例では常に 3 文字を印刷し、3 に設定index
します。
次の行は文字列 abc を sendbuf に書き込み、位置 3 から開始し、その次の行は値をi
位置 6 に出力します。最後に、新しい行に \n を追加し、最後の行はヌル ターミネータです。index++
インデックスはもう気にしないので入れません。わざわざインクリメントする必要はありません。整数配列ではなく char 配列を扱っていることをプログラマーに思い出させるため\0
です。\0
繰り返しますが、これらすべての行が必要というわけではありませんが、問題の一部が何を理解しているように見えたのでprintf
、役立つと思いました.