3

如果将 int 作为参数传递给接收字节(char)的方法,C/C++ 将如何处理?int 会被截断吗?或者是其他东西?

例如:

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

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

int 如何“转换”为字节(字符)?它会被截断吗?

4

7 回答 7

8

如果byte代表char类型,则行为将取决于char您的平台上是签名还是未签名。

如果char是无符号的,则原始int值减少到取unsigned char模范围内UCHAR_MAX+1。范围内的值[0, UCHAR_MAX]被保留。C 语言规范将此过程描述为

... 通过反复加减新类型可以表示的最大值多一的方式转换该值,直到该值在新类型的范围内。

如果chartype 有符号,则[SCHAR_MIN, SCHAR_MAX]保留范围内的值,而此范围外的任何值都以某种实现定义的方式进行转换。(C 语言还明确允许在这种情况下引发实现定义的信号。)即没有通用的答案。请查阅您平台的文档。或者,更好的是,编写不依赖于任何特定转换行为的代码。

于 2012-04-06T19:19:04.670 回答
4

只是截断了 AS 位模式(字节通常是无符号字符,但是,您必须检查)

诠释 i = -1;

变成

字节 b = 255; 当字节 = 无符号字符

字节 b = -1; 当字节 = 有符号字符

我 = 0; b = 0;

我 = 1024; b = 0;

我 = 1040; b = 16;

于 2012-04-06T19:16:45.463 回答
1

引用 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是无符号的,则该值将被截断为 char 中的位数(或计算的模 UCHAR_MAX+1,无论您想以哪种方式考虑它。)

如果char是有符号的,那么值不变,如果合适的话;否则实现定义。

实际上,在您关心的计算机和编译器上,无论chars 是有符号还是无符号,该值总是被截断以适合 8 位。

于 2012-04-06T19:28:50.107 回答
0

你不知道 abyte是什么,但是如果你传递一个可转换为参数类型的参数,则值将被转换。

如果类型具有不同的取值范围,则存在该值超出参数类型范围的风险,然后它将无法工作。如果在范围内,那就是安全的。

于 2012-04-06T19:19:20.787 回答
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)

'希望对您的原始问题和相关问题有所帮助。

于 2012-04-06T19:26:49.907 回答
-1

有两种情况需要担心:

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

// Your "method2()" stack gets overwritten
void method2(byte * b)
{
  ...
于 2012-04-06T19:19:03.417 回答
-1

它将被转换为一个字节,就像您将它显式转换为(byte)i.

不过,您上面的示例代码可能是不同的情况,除非您有method2未显示的前向声明。因为method2在调用它的时候还没有声明,所以编译器不知道它的第一个参数的类型。在 C 中,函数应该在调用之前声明(或定义)。在这种情况下发生的情况是编译器假设(作为隐式声明)method2的第一个参数是 anintmethod2接收一个int。正式地说,这会导致未定义的行为,但在大多数架构上,两者intbyte无论如何都会在相同大小的寄存器中传递,并且它会碰巧起作用。

于 2012-04-06T19:19:37.700 回答