关于C语言的一道题目 关于strcpy,memcpy,求高手解,万分感激
发布网友
发布时间:2022-05-12 08:21
我来回答
共3个回答
热心网友
时间:2024-02-20 08:50
这个问题出的有点*,有点类似于中国小学生天天学英语“this is a desk”一样,老外的孩子要是天天指着桌子对他的妈妈说 “这是一个桌子”,我估计他母亲会觉得他的孩子得病了。。
言归正转,说正题! 首先这个问题在不同的机器上会有不同的运行结果,原因向下看。
1、首先明确aa是个位域,b1占了5个二进制位 ,b2占了2个二进制bit位。
2、明确哪些数据复制到aa了
strcpy,是复制字符串,cc里面包含了0---------------z那一串字符串
memcpy 要复制 cc到aa,那到底复制哪些内容呢? 你看过memcpy()的源码就知道了,它是以char类型的一个字节一个字节复制数据的,换句话说,sizeof(aa)就决定了从0 ----------------z那串字符串复制多少到aa中。 sizeof(aa)这个值是多少呢? 这决定于位域的压缩规则,细说起来很多,自己可以搜索,但是关键的一点是位域也是个结构体,它有一个对齐原则,在glibc中是2^n,即它占的大小要么是1 2 4 8 这样的字节数,在vc6.0中我运行的结果是 4。
从这点就可以看出两个问题,其一,不同的编译器,如果对齐不一样,则结果不一样。所以这是一个和实践编译环境密切相关的问题,其二,我们按4字节来看。也就是说,aa中的内容要复制4个字节,即 0 1 2 3 这4个字符。注意是字符哦,
所以aa的机器码(机器码)
33 32 31 30
3、那如何判断5个二进制位的b1和2个二进制位的b1
这里面牵涉到存储顺序的问题,存储顺序有两种一种是big endian一种是little endian,一般来说intel的cpu都是little endian。
到底这个存储顺序是什么呢? 比如 一个数值,0x12345678,它需要4个字节来存储,起始的地址是0x100
0x100 0x101 0x102 0x103 ->这是地址
0x12 0x34 0x56 0x78 ->这是存储的内容,如果说存储的内容和我们书写的顺序一致,这叫做顺序存储也就是big endian
相反 如果是这样的
0x100 0x101 0x102 0x103 ->这是地址
0x78 0x56 0x34 0x12 -->这是存储的内容,存储的顺序和我们书写的顺序正好相反,这叫做little endian .
所以,如果是intel的cpu的话。。那
33323130的机器码是
0011 0011 0011 0010 0011 0001 0 01 1 0000
================ b2 b1
这时候因为是little endian存储,所以b1的值是最右侧的5位二进制,即10000 = 16,最高位是符号位,当5位的二进制位,转换成整数的时候,要进行最高位的扩展,即movsx 于是便会出现结果-16 同样 b2就是右侧的01,所以它的值是1。
如果是power pc或者其它的cpu,则相反了,b1 = 00110 b2 = 01
所以这个问题,有点"this is a desk "的教条啊
热心网友
时间:2024-02-20 08:51
-16
1
Press any key to continue
这道题比较难解释,这又字节对齐,还与操作系统的字长相关,32位系统下答案如上:
typedef struct AA{
int b1:5;
int b2:2;
}AA;
int main()
{
AA aa;
char cc[100];
strcpy(cc,"0123456789");
memcpy(&aa, cc, sizeof(AA));
cout<<aa.b1<<endl;
cout<<aa.b2<<endl;
return 0;
}
热心网友
时间:2024-02-20 08:51
好好琢磨,不会问老师