バイト(char)を受け取るメソッドにパラメーターとしてintを渡す場合、C / C ++はどのように処理しますか?intは切り捨てられますか?または、他の何か?
例えば:
void method1()
{
int i = //some int;
method2(i);
}
void method2(byte b)
{
//Do something
}
intはどのようにしてバイト(char)に「キャスト」されますか?切り捨てられますか?
byte
タイプを表す場合、動作はプラットフォームで署名されているか署名されていchar
ないかによって異なります。char
char
が符号なしの場合、元のint
値はunsigned char
モジュロの範囲に縮小されますUCHAR_MAX+1
。範囲内の値[0, UCHAR_MAX]
は保持されます。C言語仕様では、このプロセスを次のように説明しています。
...値は、値が新しいタイプの範囲内になるまで、新しいタイプで表すことができる最大値より1つ多い値を繰り返し加算または減算することによって変換されます。
char
タイプが署名されている場合、範囲内の値は[SCHAR_MIN, SCHAR_MAX]
保持されますが、この範囲外の値は実装で定義された方法で変換されます。(C言語では、このような状況で実装定義のシグナルを明示的に発生させることができます。)つまり、普遍的な答えはありません。プラットフォームのドキュメントを参照してください。または、特定の変換動作に依存しないコードを作成することをお勧めします。
ASビットパターンを切り捨てただけです(バイトは一般にunsigned charですが、確認する必要があります)
int i = -1;
になります
バイトb=255; バイト=unsignedcharの場合
バイトb=-1; バイト=符号付き文字の場合
i = 0; b = 0;
i = 1024; b = 0;
i = 1040; b = 16;
C ++ 2003標準の引用:
5.2.2項パラグラフ4:関数が呼び出されると、各パラメーター(8.3.5)は、対応する引数で初期化されます(8.5、12.8、12.1)。
したがって、b
はで初期化されi
ます。どういう意味ですか?
8.5 / 14初期化されるオブジェクトの初期値は、初期化式の(変換される可能性のある)値です。必要に応じて、標準変換(4節)を使用して、初期化子式を…宛先タイプに変換します。ユーザー定義の変換は考慮されません
ああ、標準の変換i
を使用して変換されます。どういう意味ですか?他の多くの標準変換には、次のものがあります。
4.7 / 2宛先タイプが符号なしの場合、結果の値はソース整数と一致する最小の符号なし整数です(モジュロ2 n、nは符号なしタイプを表すために使用されるビット数)。
4.7 / 3宛先タイプが署名されている場合、宛先タイプ(およびビットフィールド幅)で表すことができれば、値は変更されません。それ以外の場合、値は実装定義です。
ああ、char
符号なしの場合、値は文字のビット数に切り捨てられます(または、UCHAR_MAX + 1を法として計算されます。どちらの方法でもかまいません)。
また、char
が署名されている場合、値が適合する場合、値は変更されません。実装-それ以外の場合は定義されます。
char
実際には、関心のあるコンピューターとコンパイラーでは、 sが符号付きか符号なしかに関係なく、値は常に8ビットに収まるように切り捨てられます。
aが何であるかはわかりませんbyte
が、パラメータタイプに変換可能なパラメータを渡すと、値が変換されます。
タイプの値の範囲が異なる場合、値がパラメータータイプの範囲外である可能性があり、その場合は機能しません。範囲内であれば安全です。
次に例を示します。
1)コード:
#include <stdio.h>
void
method1 (unsigned char b)
{
int a = 10;
printf ("a=%d, b=%d...\n", a, b);
}
void
method2 (unsigned char * b)
{
int a = 10;
printf ("a=%d, b=%d...\n", a, *b);
}
int
main (int argc, char *argv[])
{
int i=3;
method1 (i);
method2 (i);
return 0;
}
2)コンパイル(警告付き):
$ gcc -o x -Wall -pedantic x.c
x.c: In function `main':
x.c:22: warning: passing arg 1 of `method2' makes pointer from integer without a cast
3)実行(クラッシュあり):
$ ./x
a=10, b=3...
Segmentation fault (core dumped)
「お役に立てば幸いです。元の質問と関連する問題の両方で。
心配する2つのケースがあります:
// Your input "int i" gets truncated
void method2(byte b)
{
...
// Your "method2()" stack gets overwritten
void method2(byte * b)
{
...
明示的にとしてキャストした場合と同じように、バイトにキャストされます(byte)i
。
ただし、上記のサンプルコードは、前方宣言が表示されていない場合を除いて、別のケースである可能性がありますmethod2
。method2
呼び出された時点ではまだ宣言されていないため、コンパイラーは最初のパラメーターのタイプを認識していません。Cでは、関数を呼び出す前に、関数を宣言(または定義)する必要があります。この場合に起こることは、コンパイラーが(暗黙の宣言として)method2
の最初のパラメーターがであるint
と想定し、をmethod2
受け取ることint
です。公式には、これは未定義の動作になりますが、ほとんどのアーキテクチャでは、両方ともint
同じbyte
サイズのレジスタで渡され、動作します。