[英]What happens if you pass an int to a byte parameter in C?
如果将 int 作为参数传递给接受字节(char)的方法,C/C++ 将如何处理? int 会被截断吗? 或者是其他东西?
例如:
void method1()
{
int i = //some int;
method2(i);
}
void method2(byte b)
{
//Do something
}
int 如何“转换”为一个字节(一个字符)? 它会被截断吗?
如果byte
代表char
类型,则行为将取决于char
在您的平台上是有符号的还是无符号的。
如果char
是无符号的,则原始int
值将减少到unsigned char
范围模UCHAR_MAX+1
。 [0, UCHAR_MAX]
范围内的值被保留。 C 语言规范将此过程描述为
...通过比新类型可以表示的最大值重复加或减1来转换值,直到该值在新类型的范围内。
如果char
类型是有符号的,则[SCHAR_MIN, SCHAR_MAX]
范围内的值将被保留,而该范围外的任何值将以某种实现定义的方式进行转换。 (C 语言另外明确允许在这种情况下引发实现定义的信号。)即没有通用的答案。 请查阅您平台的文档。 或者,更好的做法是编写不依赖于任何特定转换行为的代码。
Just truncated AS bit pattern(byte一般是unsigned char,不过你要核对一下)
诠释我= -1;
成为
字节 b = 255; 当 byte = unsigned char
字节 b = -1; 当 byte = signed char
我 = 0; b = 0;
我 = 1024; b = 0;
我 = 1040; b = 16;
引用 C++ 2003 标准:
条款 5.2.2 第 4 段:当调用 function 时,每个参数 (8.3.5) 应使用其相应的参数初始化 (8.5、12.8、12.1)。
因此, b
是用i
初始化的。 那是什么意思?
8.5/14 正在初始化的 object 的初始值是初始化表达式的(可能转换的)值。 如有必要,将使用标准转换(第 4 条)将初始化表达式转换为……目标类型; 不考虑用户定义的转换
哦, i
是转换的,使用标准转换。 那是什么意思? 许多其他标准转换包括:
4.7/2 如果目标类型是无符号的,则结果值是与源 integer 一致的最小无符号 integer(模 2 n ,其中 n 是用于表示无符号类型的位数)。
4.7/3 如果目标类型是有符号的,并且可以在目标类型(和位域宽度)中表示,则值不变; 否则,该值是实现定义的。
哦,所以如果char
是无符号的,则该值将被截断为 char 中的位数(或计算模 UCHAR_MAX+1,无论您以何种方式考虑。)
如果char
是有符号的,则值不变,如果适合; 实现定义的,否则。
实际上,在您关心的计算机和编译器上,该值总是被截断以适合 8 位,无论char
是有符号的还是无符号的。
你不知道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)
'希望对您的原始问题和相关问题有所帮助。
有两种情况需要担心:
// 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
无论如何都会在相同大小的寄存器中传递,并且它会碰巧起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.