c++ c

我可以将unsigned符号转换为符号,相反吗?

我想使用预期这些数据的功能:


void process/char *data_in, int data_len/;


所以这只是处理某些字节的处理。

但是我和我一起工作更方便 "unsigned char", 谈到未处理的字节 /这是出于某种原因 "feels" 更正确地处理积极的值 0 到 255/, 所以我的问题:

我可以总是安全通过
unsigned char *

在这个功能?

否则我会说:

它保证我可以安全地转换 /cast/ 之间 char 和 unsigned char 可选择,没有信息丢失?

我可以安全地转换 /cast/ 在指针B. char 和 unsigned char 可选择,没有信息丢失?

奖金:答案平等 C 和 C++?
已邀请:

奔跑吧少年

赞同来自:

简短答案 - 是的,如果使用明确的吸引力,但要详细解释它,您需要考虑三个方面:

1/ 转型的合法性

转型
signed T*


unsigned T*

/某些类型
T

/ 在任何方向上,通常可能是因为源类型可以首先转换为
void *

/这是标准转换, §4.10/, 和
void *

可以使用显式转换为目标类型
static_cast

/§5.2.9/13/:


static_cast<unsigned char*="">/static_cast<void *="">/data_in//


它可以减少 /§5.2.10/7/ 通过以下方式:


reinterpret_cast<unsigned *="" char="">/data_in/


因为
char

- 这种类型的标准布局 /§3.9.1/7,8 和 §3.9/9/, 并且签名不会改变对齐 /§3.9.1/1/. 它也可以被记录为风格的简报。 C:


/unsigned char *//data_in/


再次,它在两个方向上工作
unsigned*


signed*

然后回来。 还有一个保证如果您在一个方向上应用此过程,然后返回,则指针的值 /即他表明的地址/ 不会改变 /§5.2.10/7/.

所有这些不仅适用于之间的转换
signed char *


unsigned char *

, 但是K.
char *

/
unsigned char *


char *

/
signed char *

分别。 /
char

,
signed char


unsigned char

正式是三种不同的类型, §3.9.1/1./

要清楚,它还没有重要的三种方法,但你必须使用一个。 指针的简单传输将无法正常工作,因为转换虽然是合法的,但不是标准转换,所以它不会隐含地施加 /如果您尝试,编译器将给出错误/.

2/ 明确定义对值的访问

如果在函数内会发生什么,您将处理指针,即您执行
*data_in

, 获得 glvalue 对于基本符号; 它定义得很好吗? 以下是相关规则是严格平滑的规则 /§3.10/10/:

如果程序正试图通过保存的对象值

glvalue

除了以下的另一种类型之一,没有定义行为:

[...]

类型为与动态类型对象相对应的签名或无符号类型,

[...]

一种
char

或者
unsigned char

.

所以访问
signed char

/或者
char

/ 穿过
unsigned char*

/或者
char

/ 这条规则不会禁止反之亦然 – 你必须没有问题就可以这样做。

3/ 产生的值

检索转换类型的指针后,您可以使用所获得的值吗? 重要的是要记住,上述指针的转换和奉献相当于重新诠释 /不是变化!/ 存储在符号地址的位模式。 因此,当标志性符号的位模板被解释为未签名符号的模板时会发生什么 /或相反亦然/?

移动OT时。 unsigned 到 signed

典型效果

将包含在意义上 0 和 128 没有任何事情发生,值更高 128 变成消极。 同样,在相反的顺序:从符号移动到无符号负值时将显示为值 128.

但这是行为

案件不保证

标准。 标准保证的唯一方法是所有三种类型 ,
char

,
unsigned char


signed char

, 所有位 /没必要 8, 顺便一提/ 用于表示价值。 因此,如果您将一个解释为另一个,请制作多个副本,然后将它们保存回原始位置,您可以确定不会丢失信息 /你是如何要求的/, 但是你不必知道这些价值观实际上是指 /至少不是完全可容忍的方式/.
</unsigned></void></unsigned>

诸葛浮云

赞同来自:

unsigned char

或者
signed char

- 这只是一个解释:没有发生上诉。

由于您正在处理字节以显示意图,因此宣布为


void process/unsigned char *data_in, int data_len/;


[作为编辑注意到:通常的
char

它可以是签名或无符号类型。 标准 C 和 C++ 显然允许 /它总是一个单独的类型
unsigned char

或者
signed char

, 但是与其中一个相同的范围/]

小明明

赞同来自:

是的,您可以随时转换 char 在 unsigned char & 和

相反

没问题。 如果开始以下代码并将其与表格进行比较 ASCII /厘米。
http://www.asciitable.com/
/, 您可以自己看到证明,以及如何 C/C++ 冷却转化 - 他们以同样的方式工作:


#include "stdio.h"


int main/void/ {
//converting from char to unsigned char
char c = 0;
printf/"%d byte/s/\n", sizeof/char//; // result: 1byte, i.e. 8bits, so there are 2^8=256 values that a char can store.
for /int i=0; i<256; i++/{
printf/"int value: %d - from: %c\tto: %c\n", c, c, /unsigned char/ c/;
c++;
}

//converting from unsigned char to char
unsigned char uc = 0;
printf/"\n%d byte/s/\n", sizeof/unsigned char//;
for /int i=0; i<256; i++/{
printf/"int value: %d - from: %c\tto: %c\n", uc, uc, /char/ uc/;
uc++;
}
}


我不会发表一个结论,因为它有太多的行! 在结果中,可以注意到,在每个部分的前半部分,即,开始 i=0:127, 从字符转换为没有符号的符号和

相反

它运作良好,没有任何变化或损失。

但是,出来了 i=128:255 无法播放符号和无符号字符,或者您将具有不同的输出,因为 unsigned char 节省价值 [0:256], 和 char 在间隔中保存值 [-128:127]/. 尽管如此,这2岁的行为并不重要,因为 C/C++, 一般来说,你只带领符号 chars/unsigned chars 作为符号 ASCII, 这可能只采取 128 不同的价值观,其余的 128 价值 /积极的人物 chars 或消极的人物 unsigned/ 没用过。

如果您从未在不代表符号的符号中放置值,则切勿在未表示符号的未保存的符号中放置值,一切都将是 OK!

可选:即使您使用 UTF-8 或其他编码 /对于特殊字符/ 在你的行中 C/C++,, 这类带来的一切都将是 OK, 例如,使用编码 UTF-8 /ref.
http://lwp.interglacial.com/appf_01.htm
/:


char hearts[] = {0xe2, 0x99, 0xa5, 0x00};
char diamonds[] = {0xe2, 0x99, 0xa6, 0x00};
char clubs[] = {0xe2, 0x99, 0xa3, 0x00};
char spades[] = {0xe2, 0x99, 0xa0, 0x00};
printf/"hearts /%s/\ndiamonds /%s/\nclubs /%s/\nspades /%s/\n\n", hearts, diamonds, clubs, spades/;


此代码的输出将如下:

心中 /♥/

钻石 /♦/

tr /♣/

铲 /♠/





即使您将每个字符留成未签名的字符。

所以:

"can I always safely pass a unsigned char * into this function?"
是的!

"它保证我可以安全地转换 /扔/ 之间 char 和 unsigned char 可选择,没有信息丢失?"
是的!

"我可以安全地转换 /cast/ 在指针之间 char 和 unsigned char 可选择,没有信息丢失?"
是的!

"is the answer same in C and C++?"
是的!

小姐请别说爱

赞同来自:

您可以将指针传输到另一种类型
char

, 但你可能需要明确带来它。 指针保证具有相同的大小和相同的值。 转型期间不会丢失信息。

如果你想转换
char


unsigned char

在函数内,您只需分配一个值
char

多变的
unsigned char

或联络
char


unsigned char

.

如果您需要转换
unsigned char


char

没有数据丢失,它有点困难,但仍然可能:


#include <limits.h>

char uc2c/unsigned char c/
{
#if CHAR_MIN == 0
// char is unsigned
return c;
#else
// char is signed
if /c &lt;= CHAR_MAX/
return c;
else
// ASSUMPTION 1: int is larger than char
// ASSUMPTION 2: integers are 2's complement
return c - CHAR_MAX - 1 - CHAR_MAX - 1;
#endif
}


此功能转换
unsigned char


char

以这样的方式可以将返回值转换回相同的值
unsigned char

, 什么是参数。
</limits.h>

卫东

赞同来自:

从语义的角度来看,

过渡

之间
unsigned char *


char *

安全,甚至尽管他们之间带来它们,如此 c++.

但是,请考虑以下示例代码:


#include "stdio.h"

void process_unsigned/unsigned char *data_in, int data_len/ {
int i=data_len;
unsigned short product=1;

for/; i--; product*=data_in[i]/
;

for/i=sizeof/product/; i--; / {
data_in[i]=//unsigned char */&product/[i];
printf/"%d\r\n", data_in[i]/;
}
}

void process/char *data_in, int data_len/ {
int i=data_len;
unsigned short product=1;

for/; i--; product*=data_in[i]/
;

for/i=sizeof/product/; i--; / {
data_in[i]=//unsigned char */&product/[i];
printf/"%d\r\n", data_in[i]/;
}
}

void main// {
unsigned char
a[]={1, -1},
b[]={1, -1};

process_unsigned/a, sizeof/a//;
process/b, sizeof/b//;
getch//;
}


出口:

0
255
-1
-1
所有代码内部
process_unsigned


process

- 这很简单

IDENTICAL

. 唯一的区别是无符号和签名。 此示例显示了代码

黑盒子

真的很受影响

SIGN

, 和

没有

在被叫和造成用户之间不保证。

所以我会说它只适用于

通过

, 但没有其他可能性得到保证。

石油百科

赞同来自:

您真的需要查看代码
process//

, 要了解是否可以安全地传输不稳定性的字符。 如果函数使用字符作为阵列中的索引,则否,您无法使用无符号数据。

要回复问题请先登录注册