问题描述
嗨!
我想将数字129(二进制10000001)分配给4字节长的MSB(大多数
有效字节)并留下其他较低的字节 -
圆滑!
-正常奔腾的工作(... endian)
我想用不使用shift的代码(<<<<<<<<<<<<<<<<<<<<<<<<<<"编译器必须完成工作,我将介绍
适当的结构和联合。
#include< stdio.h>
struct each_of_four {
unsigned char byte0;
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
}
/ * __ attribute __((打包))* /
;
union align_long_and_each_of_four {
long dummy; / * 4字节* /
struct each_of_four四;
}
/ * __ attribute __((打包))* /
;
int main(无效)
{
long val; // 4个字节
/ ******************测试A:编译器错误 - 为什么?
********************* /
((union align_long_and_each_of_four)val).four.byte3 =(未签名
char)129;
#define FUNNY_NUMBER((union align_long_and_each_of_four)\
(const long)((129<< ; 24)|(val& 16777215)))。four.byte3
// 16777215 = 2 ^ 24-1
printf(" test FUNNY_NUMBER:%d \ n",FUNNY_NUMBER);
/ ******************测试B:编译器错误 - 为什么?
********************* /
((union align_long_and_each_of_four)val).four.byte3 = FUNNY_NUMBER;
返回0;
}
编译器错误报告--->
test_align.c:25:错误:赋值时左值无效
test_align.c:39:错误:赋值时左值无效
如何修复??
谢谢
anon.asdf
Hi!
I want to assign the number 129 (binary 10000001) to the MSB (most
significant byte) of a 4-byte long and leave the other lower bytes in-
tact!
-working on normal pentium (...endian)
I want to do it with code that does NOT use shifts (<<) , bit-
operations (| &) !!
So the compiler will have to do the work and I''ll introduce
appropriate structs and unions.
#include <stdio.h>
struct each_of_four {
unsigned char byte0;
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
}
/*__attribute__ ((packed))*/
;
union align_long_and_each_of_four {
long dummy; /* 4 bytes */
struct each_of_four four;
}
/*__attribute__ ((packed))*/
;
int main(void)
{
long val; // 4 bytes
/****************** TEST A: COMPILER ERROR - WHY?
*********************/
((union align_long_and_each_of_four) val).four.byte3 = (unsigned
char) 129;
#define FUNNY_NUMBER ((union align_long_and_each_of_four) \
(const long) ((129<<24) | (val & 16777215))).four.byte3
// 16777215 = 2^24-1
printf("test FUNNY_NUMBER: %d\n", FUNNY_NUMBER);
/****************** TEST B: COMPILER ERROR - WHY?
*********************/
((union align_long_and_each_of_four) val).four.byte3 = FUNNY_NUMBER;
return 0;
}
Compiler error report--->
test_align.c:25: error: invalid lvalue in assignment
test_align.c:39: error: invalid lvalue in assignment
How can this be fixed??
Thanks
anon.asdf
这里非常有趣的是,以下代码可以正常工作!
{
union align_long_and_each_of_four tmp;
tmp.four.byte3 =(unsigned char)129;
}
但是仍然 - 如何修复测试A中的编译器错误?
The really interesting here, is that the following code DOES work!
{
union align_long_and_each_of_four tmp;
tmp.four.byte3 = (unsigned char) 129;
}
But still - how can the compiler error in TEST A be fixed??
因为你不能转换为联盟(或结构)或来自联盟(或结构)
类型:它们不是标量类型 (6.5.4p2)。请记住
一个演员是一个转换一个值的运算符,而不是一个神奇的让'假装构造。在任何情况下,由演员操作员产生的
值与由(例如)一元减号运算符产生的
a值相同:
你不能写`-x = 42''。
Because you cannot cast to or from a union (or struct)
type: They are not "scalar types" (6.5.4p2). Keep in mind
that a cast is an operator that converts a value, not a
magical "let''s pretend" construct. And in any case, the
value produced by a cast operator has the same status as
a value produced by (for example) a unary minus operator:
You cannot write `-x = 42'', either.
单程是
((unsigned char *)& val)[3] = 129;
当然,如果'val''不是四个字节
长,MSB处于第四位,这就失败了。更好的方法是
val =(val& 0xffffffUL)| (129UL<< 24);
(是的,我知道你说你不想使用班次或
按位运算符。艰难:无论如何,这是更好的方式。)
最后的想法:*每个*解决方案都存在问题
它对于什么做出了不可移植的假设当你到达并敲定其中一个
字节时,就会发生'val''的价值。当你这样做时,你已经离开了
C语言的保证,并且需要在没有他们保护的情况下进入未知领域。 unsigned long会让事情好一些,但是......
-
l%= 0x01000000;
l + = 129 * 0x01000000;
无论字节顺序如何,这都有效。
l %= 0x01000000;
l += 129 * 0x01000000;
This works regardless of endianness.
unsigned char bytes [4]出了什么问题,导致你注释掉的东西会在某个地方发生同样的事情,但是在
标准C?
What was wrong with unsigned char bytes[4], which causes the same
thing that the stuff you commented out would do somewhere, but in
standard C?
{long dummy; unsigned char four [4]; }?
What was wrong with { long dummy; unsigned char four[4]; }?
因为演员的结果不是左值。
尝试
((unsigned char * )& val)[3] = 129;
不需要工会,也不需要结构。
Because the result of a cast isn''t a lvalue.
Try
((unsigned char *)&val)[3] = 129;
No unions and no struct needed.
Didn''你说你不想使用按位操作吗?
-
Army1987(用电子邮件替换NOSPAM)
没有人通过辞职来赢得比赛。 - S. Tartakower
Didn''t you say you didn''t want to use bitwise operations?
--
Army1987 (Replace "NOSPAM" with "email")
No-one ever won a game by resigning. -- S. Tartakower
这篇关于结构和联合中的字节对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!