【问题标题】:How can I merge two ASCII characters? [closed]如何合并两个 ASCII 字符? [关闭]
【发布时间】:2020-07-08 14:47:47
【问题描述】:

我想合并两个字符并使用 ASCII 通过单个变量打印它们(参考下图):

[1]:https://i.stack.imgur.com/TWodP.jpg

【问题讨论】:

  • 一个足够宽的整数和两个字符的结构的联合可能是你想要的。但这不被认为是干净的。您是否考虑过强制转换为 int、移位和位或运算?
  • 注意C初始化后int C = 'AB';的值为implementation-defined
  • 试试int C; C= (((int)a)<<8)|((int)b); 如果这行得通并且得到你想要的,我会回答并解释。
  • 当普通的char 是有符号类型并且变量中的值为负时,转换应该是(unsigned char)A 以避免符号扩展问题。
  • @Yunnosch:如果你有(unsigned char)A << 8作为术语,那么unsigned char的值在移位发生之前被扩展为int,结果是int,值即使普通的char 类型是有符号类型并且A 中的值是负的char 值,A 中的 in 也不会被符号扩展。如果将负的(隐式带符号的)char 值直接转换为int,那么它将进行符号扩展,结果的高位将全部为 1 位。

标签: c binary char ascii bit


【解决方案1】:

如果你的机器是小端的,试试这个

unsigned int C = (b << 8) | a;
printf("%s",&C);

否则如果你的机器是大端试试

unsigned int C = (a << 24) | (b<<16);
printf("%s",&C);

【讨论】:

  • 第一个工作正常!你能解释一下你的代码吗?我是新手,我知道 bitshift
  • 字节在内存中通过字节序的概念进行排序,字节序有两种类型(i)小和(ii)大。所以例如:0x12345678 是一个 8 字节的数字,存储在地址 0x100 处。通常你会认为 0x12 存储在 0x100 , 0x34 存储在 0x101 ......这是在主要是太阳机器的大端机器中完成的。来到小端机器时,0x78 存储在 0x100,0x56 存储在 0x101,0x34 存储在 0x102,0x12 存储在 0x103,因此字节在小端机器中被反转。
  • 所以 C = (b
  • 不匹配的参数和转换说明符会导致 C 中未定义的行为。%s 需要一个指向字符类型的指针,但 &amp;C 是指向 unsigned int 的指针,因此是未定义的行为。这个解决方案充其量是脆弱的。
【解决方案2】:

根据我的评论,但乔纳森的意见有所改进,我建议这样做:

int C;
C= (((unsigned char)a)<<8)|((unsigned char)b);

您已经尝试了注释版本以提供帮助,这个版本基本相同,只是对 ab 的潜在负值具有鲁棒性(我认为这超出了范围,但乔纳森是对的尽可能安全)。

至于解释:

&lt;&lt; 8 部分,即所谓的左移,将值向 MSB 移动 8 位。
IE。 00000000010000001 变为 01000000100000000

为了避免负值(见下文为什么这很重要),该值首先被类型转换为unsigned char。那是((unsigned char)a) 的部分。请注意,在使用() 时,我倾向于大方,有些人不喜欢这样。对这两个值都执行此操作。

使用值 'A''B' 我们最终得到

01000001000000000000000001000010.

下一部分使用按位 OR (|),而不是逻辑 OR (||)。
结果是

0100000101000010,这是我理解的你的目标。

防止负面输入的重要性是这样的。任何负 8 位值都设置了 MSB,当转换为更广泛的数据类型时,最终会设置所有 8 个新的高位。这是因为负值在 2-compliment 中以整数表示。

正如 Jonathan 解释的那样,最终转换为所需的更广泛的数据类型:

如果您有(unsigned char)A &lt;&lt; 8 作为术语,则在移位发生之前将 unsigned char 值扩展为 int,结果为 int。

【讨论】:

  • @JonathanLeffler 因为我不想歪曲你,所以我邀请你指出任何你不喜欢的地方。
猜你喜欢
  • 2015-02-08
  • 1970-01-01
  • 1970-01-01
  • 2013-11-11
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-14
相关资源
最近更新 更多