C/C++中如果你将一个int类型的参数传递给一个接受byte(char)类型参数的方法时,它会怎么处理?是否会截断int类型变量?还是其他操作?
例如:
void method1()
{
int i = //some int;
method2(i);
}
void method2(byte b)
{
//Do something
}
int如何被“强制转换”为byte(char)? 它会被截断吗?
byte
代表char
类型,则行为取决于您平台上的char
是有符号还是无符号。char
是无符号的,则原始int
值将被减少到模UCHAR_MAX+1
下的unsigned char
范围内。在[0,UCHAR_MAX]
范围内的值将被保留。C语言规范描述了这个过程:
如果...该值通过反复加或减一个比新类型中可以表示的最大值多一的值来转换,直到该值在新类型的范围内。
char
类型是有符号的,则在[SCHAR_MIN,SCHAR_MAX]
范围内的值将被保留,而任何超出此范围的值都将以某种实现定义的方式转换。(C语言还明确允许在这种情况下引发实现定义的信号。)也就是说,没有通用答案。请查阅您平台的文档。或者更好地编写不依赖于任何特定转换行为的代码。char
为无符号时,规则是将int
值截断为二进制补码表示的较低log_2(UCHAR_MAX+1)
位。 - caf将AS位模式截断(字节通常是无符号字符,但必须检查)
int i = -1;
变成
当byte = unsigned char时,byte b = 255;
当byte = signed char时,byte 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
被转换了,使用了标准转换。这是什么意思?除了许多其他的标准转换之外,还有以下内容:
#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)
您没有说明byte
是什么,但如果传递的参数可以转换为参数类型,则该值将被转换。
如果类型具有不同的值范围,则存在超出参数类型范围的风险,那么它就不能工作。 如果在范围内,则是安全的。
有两种情况需要担心:
// Your input "int i" gets truncated
void method2(byte b)
{
...
// Your "method2()" stack gets overwritten
void method2(byte * b)
{
...
byte *
)。无论如何,为什么会覆盖堆栈? - Celada它将被转换为一个字节,就像你明确地将其转换为(byte)i
一样。
然而,你上面的示例代码可能是不同的情况,除非你有一个未显示的method2
的前向声明。因为在调用时method2
还没有声明,编译器不知道它的第一个参数的类型。在C语言中,函数应该在调用之前声明(或定义)。在这种情况下会发生什么呢?编译器假定(作为隐式声明)method2
的第一个参数是一个int
,并且method2
接收到一个int
。虽然官方上来说这会导致未定义的行为,但在大多数架构中,int
和byte
都会以相同的大小寄存器传递,所以它会奇迹般地工作。
byte
是什么。在 C 和 C++ 中都没有这样的标准类型。那么,byte
是什么? - AnT stands with Russiabyte x = intvalue;
(参见C99标准的6.5.16节)。 - pmg