如果在C语言中将一个int传递给一个byte参数,会发生什么?

3

C/C++中如果你将一个int类型的参数传递给一个接受byte(char)类型参数的方法时,它会怎么处理?是否会截断int类型变量?还是其他操作?

例如:

void method1()
{
    int i = //some int;
    method2(i);
}

void method2(byte b)
{
     //Do something
}

int如何被“强制转换”为byte(char)? 它会被截断吗?


什么是“字节”?它是“字符”吗? - bitmask
取决于 byte 是什么。在 C 和 C++ 中都没有这样的标准类型。那么,byte 是什么? - AnT stands with Russia
为什么不写几行代码来找出答案呢? - Sibster
在C语言中,它被视为赋值操作:byte x = intvalue; (参见C99标准的6.5.16节)。 - pmg
@Sibster:因为那将是逆向工程。标准可能不要求某种行为(在这种情况下它确实要求,但这就是问题所在),而某个编译器仍然可以实现它。 - bitmask
显示剩余2条评论
7个回答

8
如果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

4

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


1

引用C++ 2003标准:

第5.2.2条第4款:调用函数时,每个参数(8.3.5)都应使用其相应的参数进行初始化(8.5、12.8、12.1)。

所以,bi进行了初始化。这是什么意思?

8.5/14被初始化对象的初始值是初始化器表达式的(可能转换后的)值。如果需要,将使用标准转换(第4条)将初始化器表达式转换为目标类型;不考虑用户定义的转换。

哦,i转换了,使用了标准转换。这是什么意思?除了许多其他的标准转换之外,还有以下内容:

如果目标类型是无符号的,那么结果值就是与源整数同余的最小无符号整数(模2的n次方,其中n是用于表示无符号类型的位数)。
如果目标类型是有符号的,那么如果它可以在目标类型(和位域宽度)中表示,则该值不变;否则,该值是实现定义的。
哦,所以如果char是无符号的,那么该值将被截断为char中的位数(或计算模UCHAR_MAX+1,无论你想怎样考虑都可以)。
如果char是有符号的,那么如果它适合,则该值不变;否则,是实现定义的。
实际上,在您关心的计算机和编译器上,该值始终被截断为8位,无论char是有符号还是无符号。

0
这里有一个例子:
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)

希望这能对你的原问题以及相关问题有所帮助。

0

您没有说明byte是什么,但如果传递的参数可以转换为参数类型,则该值将被转换。

如果类型具有不同的值范围,则存在超出参数类型范围的风险,那么它就不能工作。 如果在范围内,则是安全的。


-1

有两种情况需要担心:

// Your input "int i" gets truncated
void method2(byte b)
{
  ...

// Your "method2()" stack gets overwritten
void method2(byte * b)
{
  ...

我不理解这个答案。问题中没有指针(byte *)。无论如何,为什么会覆盖堆栈? - Celada

-1

它将被转换为一个字节,就像你明确地将其转换为(byte)i一样。

然而,你上面的示例代码可能是不同的情况,除非你有一个未显示的method2的前向声明。因为在调用时method2还没有声明,编译器不知道它的第一个参数的类型。在C语言中,函数应该在调用之前声明(或定义)。在这种情况下会发生什么呢?编译器假定(作为隐式声明)method2的第一个参数是一个int,并且method2接收到一个int。虽然官方上来说这会导致未定义的行为,但在大多数架构中,intbyte都会以相同的大小寄存器传递,所以它会奇迹般地工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接