这个语法是什么意思?

muroachanf 2005-02-19 02:06:00
struct x
{
int m:1;
int n:2;
....
};
冒号后面的那个数字有什么用?
我刚开始以为是默认值,试了一下,不对。然后猜测是大小,也不对。到底有什么用?
...全文
576 42 打赏 收藏 转发到动态 举报
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
leogigi 2005-02-24
  • 打赏
  • 举报
回复
程序分配内存的单位是字节,但有的时候我只需要用一位!~~~
虽然一位位分配是没有什么价值的,但这种方法放在结构体里就很有用了~~~~~
ihsgnep 2005-02-24
  • 打赏
  • 举报
回复
本贴纯属对 错误 进行错误的讨论
引用:int m:1;// m占一位,只能表示-1,0活1

真的能表示3个数吗?

我们看另外一个举例: 假设 ,屏蔽对 byte(8位)类型进行范围检测, 给他赋值 300
那么 再把他的值输出,得到的输出肯定不是 300 ,而是另一个x(我不想去计算了)
你能说 byte 类型能表示 300 和 x 吗

位域里是 不进行 范围检测的 所以 你想对int x:2 赋什么值它都接受 但是只能输出 -2,-1
0 1
进而,上面所讨论的怎样区分是正数还是负数纯属陷入误区的讨论


structme 2005-02-24
  • 打赏
  • 举报
回复
看见楼主的汇编...我眼睛都花了...
不过一句好强..
lihuanzhong 2005-02-24
  • 打赏
  • 举报
回复
汇编也不到家
看不太懂
太打击我了吧
lihuanzhong 2005-02-24
  • 打赏
  • 举报
回复
又长见识了
看来我这C语言还没学到家呢
zhanghk 2005-02-24
  • 打赏
  • 举报
回复
其实这个问题就是我们都知道的二进制位所能表示的数的范围问题:
对于有符号数:-(2^(n-1)) ~ (2^(n-1))
对于无符号数:0 ~ (2^n-1)

至于不在这个范围内的数,进行溢出处理(上溢或者下溢),跟我们正常的32位,8位之间的转换本质是一样的,只不过是32位转2位,转成个不常见的位数而已。

呵呵,我也是刚想明白这个问题,讨论这个问题还是挺有意义的,在我们比较这里面的值的时候,有符号数就要注意了,或者是都采用无符号数。:)
Rudy_zhuang 2005-02-24
  • 打赏
  • 举报
回复
ihsgnep(石头)说的是正解。
zhanghk 2005-02-24
  • 打赏
  • 举报
回复
看了整个帖子,只有ihsgnep(石头)说的正确啊,而且这里面居然出现说1bit可以表示3个值,要是这样的话还有什么32位、64位操作系统之说啊!!!
zjyu88 2005-02-21
  • 打赏
  • 举报
回复
惭愧~~现在才知道:是干什么的..呵~~~
wuqian9 2005-02-21
  • 打赏
  • 举报
回复
等待~~~~~~~~~~~
关注~~~~~~~~~~~
Kelvin_Chen 2005-02-21
  • 打赏
  • 举报
回复
原来如此,猛!
ffb 2005-02-21
  • 打赏
  • 举报
回复
这个是设定内存布局的,一般用不到也不推荐使用
  • 打赏
  • 举报
回复
恩 头一次注意到 长见识了
muroachanf 2005-02-20
  • 打赏
  • 举报
回复
我的调试环境为vc6.0 + win2000 server sp4
以前俺还觉得我的c++还过得去的,实在是汗颜啊...

muroachanf 2005-02-20
  • 打赏
  • 举报
回复
$L9709:

; 21 : ts.x = -2;

and esi, -2 ; fffffffeH

; 22 : cout << ts.x << endl;

mov ecx, OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
or esi, 2
mov eax, esi
shl eax, 30 ; 0000001eH
sar eax, 30 ; 0000001eH
push eax
call ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
mov edi, eax
push 10 ; 0000000aH
mov ecx, edi
call ?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put
mov ecx, DWORD PTR [edi]
xor ebp, ebp
mov edx, DWORD PTR [ecx+4]
mov cl, BYTE PTR [edx+edi+4]
test cl, bl
lea eax, DWORD PTR [edx+edi]
jne SHORT $L9802
mov eax, DWORD PTR [eax+40]
mov ecx, eax
mov edx, DWORD PTR [eax]
call DWORD PTR [edx+44]
cmp eax, -1
jne SHORT $L9802
mov ebp, 4
$L9802:
mov eax, DWORD PTR [edi]
mov ecx, DWORD PTR [eax+4]
add ecx, edi
test ebp, ebp
je SHORT $L9799
mov edx, DWORD PTR [ecx+4]
push 0
or edx, ebp
push edx
call ?clear@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z ; std::basic_ios<char,std::char_traits<char> >::clear
$L9799:

; 23 : ts.x = -1;

or esi, 3

; 24 : cout << ts.x << endl;

mov ecx, OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
mov eax, esi
shl eax, 30 ; 0000001eH
sar eax, 30 ; 0000001eH
push eax
call ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
mov edi, eax
push 10 ; 0000000aH
mov ecx, edi
call ?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put
mov ecx, DWORD PTR [edi]
xor ebp, ebp
mov edx, DWORD PTR [ecx+4]
mov cl, BYTE PTR [edx+edi+4]
test cl, bl
lea eax, DWORD PTR [edx+edi]
jne SHORT $L9891
mov eax, DWORD PTR [eax+40]
mov ecx, eax
mov edx, DWORD PTR [eax]
call DWORD PTR [edx+44]
cmp eax, -1
jne SHORT $L9891
mov ebp, 4
$L9891:
mov eax, DWORD PTR [edi]
mov ecx, DWORD PTR [eax+4]
add ecx, edi
test ebp, ebp
je SHORT $L9888
mov edx, DWORD PTR [ecx+4]
push 0
or edx, ebp
push edx
call ?clear@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z ; std::basic_ios<char,std::char_traits<char> >::clear
$L9888:

; 25 : ts.x = 1;

and esi, -3 ; fffffffdH

; 26 : cout << ts.x << endl;

mov ecx, OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
or esi, 1
mov eax, esi
shl eax, 30 ; 0000001eH
sar eax, 30 ; 0000001eH
push eax
call ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
mov edi, eax
push 10 ; 0000000aH
mov ecx, edi
call ?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put
mov ecx, DWORD PTR [edi]
xor ebp, ebp
mov edx, DWORD PTR [ecx+4]
mov cl, BYTE PTR [edx+edi+4]
test cl, bl
lea eax, DWORD PTR [edx+edi]
jne SHORT $L9980
mov eax, DWORD PTR [eax+40]
mov ecx, eax
mov edx, DWORD PTR [eax]
call DWORD PTR [edx+44]
cmp eax, -1
jne SHORT $L9980
mov ebp, 4
$L9980:
mov eax, DWORD PTR [edi]
mov ecx, DWORD PTR [eax+4]
add ecx, edi
test ebp, ebp
je SHORT $L9977
mov edx, DWORD PTR [ecx+4]
push 0
or edx, ebp
push edx
call ?clear@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z ; std::basic_ios<char,std::char_traits<char> >::clear
$L9977:

; 27 : ts.x = 3;

or esi, 3

; 28 : cout << ts.x << endl;

mov ecx, OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
shl esi, 30 ; 0000001eH
sar esi, 30 ; 0000001eH
push esi
call ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
mov esi, eax
push 10 ; 0000000aH
mov ecx, esi
call ?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put
mov eax, DWORD PTR [esi]
xor edi, edi
mov ecx, DWORD PTR [eax+4]
lea eax, DWORD PTR [ecx+esi]
mov cl, BYTE PTR [ecx+esi+4]
test cl, bl
jne SHORT $L10055
mov eax, DWORD PTR [eax+40]
mov ecx, eax
mov edx, DWORD PTR [eax]
call DWORD PTR [edx+44]
cmp eax, -1
jne SHORT $L10055
mov edi, 4
$L10055:
mov eax, DWORD PTR [esi]
mov ecx, DWORD PTR [eax+4]
add ecx, esi
test edi, edi
je SHORT $L10066
mov edx, DWORD PTR [ecx+4]
push 0
or edx, edi
push edx
call ?clear@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z ; std::basic_ios<char,std::char_traits<char> >::clear
$L10066:
pop edi
pop esi
pop ebp
pop ebx
; 29 : }

ret 0
_main ENDP
muroachanf 2005-02-20
  • 打赏
  • 举报
回复
实验证明,楼上的兄弟完全正确。(半夜爬起来回贴,俺佩服,如果不是在国外的话)
其实本来我也这么想的,但是昨天我调试的时候发现输入2的时候输出也是2,当时我就懵了,觉得十分奇怪,原来我曾经嘲笑某些人说char型可以取到-255到+255,但昨天我调试的结果令我大感惊讶,以为以前我太无知而出了笑话?今天再调试发现一切都正常了,郁闷死。对于一个有符号的2位整数,3和-1的结果是一样的,都是-1。而-2和2也是一致的,从汇编代码可以看出,它们的代码都完全一致。现在我将测试代码以及测试结果和汇编代码一起贴出,谢谢这么多人的关注与帮忙。
#include <iostream>

using namespace std;

#pragma pack(push, 1)
typedef struct _tss
{
int x : 2;
}TSS;
#pragma pack(pop)

void main()
{

TSS ts;
memset(&ts, 0, sizeof(ts));

cout << sizeof(ts) << endl;
ts.x = 2;
cout << ts.x << endl;
ts.x = -2;
cout << ts.x << endl;
ts.x = -1;
cout << ts.x << endl;
ts.x = 1;
cout << ts.x << endl;
ts.x = 3;
cout << ts.x << endl;
}

结果为:4,-2,-2,-1,1,-1
汇编代码如下:
_main PROC NEAR ; COMDAT

; 13 : {

push ebx
push ebp
push esi
push edi

; 14 :
; 15 : TSS ts;
; 16 : memset(&ts, 0, sizeof(ts));
; 17 :
; 18 : cout << sizeof(ts) << endl;

push 4
mov ecx, OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
xor esi, esi
call ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@I@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
mov edi, eax
push 10 ; 0000000aH
mov ecx, edi
call ?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put
mov eax, DWORD PTR [edi]
mov bl, 6
xor ebp, ebp
mov ecx, DWORD PTR [eax+4]
lea eax, DWORD PTR [ecx+edi]
mov cl, BYTE PTR [ecx+edi+4]
test cl, bl
jne SHORT $L9623
mov eax, DWORD PTR [eax+40]
mov ecx, eax
mov edx, DWORD PTR [eax]
call DWORD PTR [edx+44]
cmp eax, -1
jne SHORT $L9623
mov ebp, 4
$L9623:
mov eax, DWORD PTR [edi]
mov ecx, DWORD PTR [eax+4]
add ecx, edi
test ebp, ebp
je SHORT $L9620
mov edx, DWORD PTR [ecx+4]
push 0
or edx, ebp
push edx
call ?clear@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z ; std::basic_ios<char,std::char_traits<char> >::clear
$L9620:

; 19 : ts.x = 2;

and esi, -2 ; fffffffeH

; 20 : cout << ts.x << endl;

mov ecx, OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
or esi, 2
mov eax, esi
shl eax, 30 ; 0000001eH
sar eax, 30 ; 0000001eH
push eax
call ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
mov edi, eax
push 10 ; 0000000aH
mov ecx, edi
call ?put@?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV12@D@Z ; std::basic_ostream<char,std::char_traits<char> >::put
mov ecx, DWORD PTR [edi]
xor ebp, ebp
mov edx, DWORD PTR [ecx+4]
mov cl, BYTE PTR [edx+edi+4]
test cl, bl
lea eax, DWORD PTR [edx+edi]
jne SHORT $L9712
mov eax, DWORD PTR [eax+40]
mov ecx, eax
mov edx, DWORD PTR [eax]
call DWORD PTR [edx+44]
cmp eax, -1
jne SHORT $L9712
mov ebp, 4
$L9712:
mov eax, DWORD PTR [edi]
mov ecx, DWORD PTR [eax+4]
add ecx, edi
test ebp, ebp
je SHORT $L9709
mov edx, DWORD PTR [ecx+4]
push 0
or edx, ebp
push edx
call ?clear@?$basic_ios@DU?$char_traits@D@std@@@std@@QAEXH_N@Z ; std::basic_ios<char,std::char_traits<char> >::clear
llmsn 2005-02-20
  • 打赏
  • 举报
回复
mark!
sweet_uestc 2005-02-20
  • 打赏
  • 举报
回复
mAr MDR,楼主的符号在SR里好象,我也还给老师了,楼主等等我一起汗颜
Zorror 2005-02-20
  • 打赏
  • 举报
回复
不懂-----
mov ecx, OFFSET FLAT:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A
xor esi, esi
call ??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@I@Z ; std::basic_ostream<char,std::char_traits<char> >::operator<<
-----是什么意思
Great_Bug 2005-02-20
  • 打赏
  • 举报
回复
应当是“如果是有符号的整数,”....
加载更多回复(22)

64,636

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧