c=a&0xff 取出a的低字节,置于c中是怎样 *** 作的?

c=a&0xff 取出a的低字节,置于c中是怎样 *** 作的?,第1张

简单起见,在接下来的例子中,我们设a和c为unsigned short类型(大小为2 byte)。不妨设a的值为 0x1234(十进制为4660)。在计算机中,数据以2进制的方式存储,如下:

 a  = 0001 0010 0011 0100

0xff = 0000 0000 1111 1111

将两个数进行按位与(&) *** 作(每一位只有同时为1,才结果才为1),有:

a & 0xff = 0000 0000 0011 0100。

将结果赋值给变量c:

c = 0000 0000 0011 0100。

转换成十进制,为52;转换成十六进制为0x34。

总结一下:

0与一个数位(0或1)进行按位与,结果均为0;1与一个数位(0或1)按位与,结果与那个数位相同

根据我们刚才的 *** 作,不难发现:

无论a取何值,与0xff这个神奇的数进行按位与 *** 作后,最后的8位与a相同,剩下的位均为0,这就达到了我们取出a的最后一个字节(8 bit)的目的。

我想问这是哪的题
如果是计算机专业的考研题,或者是编译原理课的考试题,那么值得分析一下。
如果是 C 程序设计题,那么出题人的水平值得质疑
要回答这道题,需要 C 知识,更需要 *** 作系统的内存处理模式及 CPU 在处理内存地址方面的知识。
另外可以明确告诉你,这道题对不同的 *** 作系统或 CPU 答案是不确定的。
与 int 型存储高低字节以及具体平台下 int 型的字长有关(C 标准没有规定 int 必须是多少字节)。
现在只能说在 Intel X86 (高位高地址) 和 Win32 下答案是 D。其他平台有待考察
要分析过程也可以写,但仍然要说,实际中没人这么写代码,自己给自己找麻烦
首先看 union 里共有两个成员,一个 int 另一个 struct。一个一个来分析
对一个 int 型,32位系统下占用 4 字节空间。
我们来看下 *** 作系统内存是如何分配的:
低地址 <--------------------------------------------------> 高地址
| | 函数调用栈
|<-------------未使用---------------->| 栈顶 <-------------> 栈底
| <---
栈增长方向
假设按上图, *** 作系统分配给的一个 4 字节空间,从低地址到高地址由左向右排列,那么当给它赋值 0x1234 时,从低到高四个字节的内容有可能依次为
00 00 12 34 (都是16进制),也有可能依次为
34 12 00 00
前者是按高位放低地址的存储方式,后者是按高位放高地址的存储方式。对于 X86 CPU 和 Win32 系统,正对应了第二种存储方式。
下面再来看那个 struct ,它包含两个 char 型,一共只需占用 2 字节,要和上面的 int 型共用那 4 个字节,这就牵涉到如何分配的问题。简单来看,如果直接分配到低地址的2个字节,那么 实际的内存对应就像下面这样:
34 12 00 00 (int)
c1 c2 (struct)
在我的电脑上确实是这么分配的。但这并不是唯一的分配方法,有些平台下的编译器为了优化提高存取速度,会将单字节采用偶地址对齐的方式存放,如下也是一种可能性
34 12 00 00 (int)
c1 c2 (struct)
或者将 c1 c2 分配在高地址,像这样:
34 12 00 00 (int)
c1 c2 (struct)
这就是答案无法确定的原因。以上还没有考虑 int 型的长度为其他字节数的情况。
如果确定到 X86 CPU 和 Win32 平台下,那么对照上面第一种内存对应情况可知,当访问 abc1 时实际取出的是 0x34 这个内容,而 c1 是 char 类型,0x34 (十进制 52)对应的字符刚好是 '4' (查 ASCII 码表),所以猜测出题人可能是想让人选 D 。但不得不说这道题漏洞很大,出成一道分析题都足够。
下面是一道考研专业试题,以做参考:
union
{
int i;
char c1;
}a;
i=0x4321;
printf("%d",c1);
请问c1的值是43还是21;

"1234
"
首先定义了一个包含两个元素的数组,arrya[0]=0x12,arrya[1]=0x34,
然后把”arrya[0]=0x12“赋值给新建变量temp,
然后temp(0x12)左移8位,变为0x1200,注意:因为temp是short类型,所以有32位,如果是8位的话,左移8位就都变为0啦!
左移后再加arrya[1],也就是0x1234,然后再把0x1234赋值给temp
最后输出,再换行。

#include<stdioh>
void main()
{
char a;
int b;
a=0x1234;//a为字符型变量,只占2个字节,但是现在给了16进制数有四个字节,由于                    //是低位对齐,所以相当于执行的是a=Ox34
b=0x1234;//b是整型变量,占4个字节,所以原样赋值;
printf("a=%x,a=%d,b=%x,b=%d\n",a,a,b,b);//结果如截图所示:a十六进制数出34
}                                                //a十进制输出为52;
                                                  b同理;

辛苦打来,望~~!

#include "stdioh" //包含标准输入输出头文件stdioh
#include<stringh> //包含字符串处理函数头文件stringh
struct w //定义结构体类型为w
{
char low; //结构体内成员之一为low
char high; //结构体内成员之一为higth
};
union u //定义联合体u
{
 struct w byte; //联合体成员之一为结构体w类型定义的byte
 int word; //联合体成员之一为int类型定义的word
}uu; //命名联合体u的名称为uu
main()
{
 uuword=0x1234; //指向联合体uu中的word并赋值为十六进制数0x1234
 printf("Word value:%04x\n",uuword); //输出联合体uu中word的值
 printf("High value:%02x\n",uubytehigh); //输出联合体uu中结构体byte中high的值
    printf("Low value:%02x\n",uubytelow); //输出联合体uu中结构体byte中low的值
 uubytelow=0xff; //指向联合体uu中的结构体byte中的low并赋值为十六进制数0xff
    printf("Word value:%04x\n",uuword); //输出联合体uu中word的值
}

问题一:为什么16ms对应的是16000??
12MHz的晶振下,CPU得到的频率是1M,因为51单片机是内部十二分频的。那么对应的一个时钟的周期就是1us,16000us就是16ms,也就是16000个周期后将产生溢出,如果你的程序里全能了定时中断和全局中断,那么将会发生定时器中断。但你程序一里面的写法是有问题的。应该是
TH0 = (-16000/256);
TL0 = (-16000%256);
或者
TH0 = (65536-16000)/256;
TL0 = (65536-16000)%256;
问题二:为什么高八位要除256,低八位求余??
51单片机是八位的单片机的,里面的寄存器都是八位的(DPTR除外),所以一个十六位的数据需要用两个八位的的寄存器来存放。在定时器0工作方式1下,51单片机是十六位的定时器,所以要用TH0来存放定时数据的高八位,用TL0来存放数据的低八位。
一个十六位数除以256得到的就是这个数的高八位,再对256求余,得到的就是这个数的低八位。
问题三:为什么要加小括号??是多余的吗?我在另一个程序(如下)中看到的初值还加上个负号是怎么回事??-5000是指50ms么??
不加也是可以的,但并不是说多余的,这是编程风格的习惯,推荐这种习惯,不会容易出错。
使用负值的写法,其实是使用补码的方法写的,-5000的十六进制数也就是0xec78,刚好是等于65536-5000,所以在这个程序里,-5000/256=(65536-5000)/256,但是呢,不推荐这种写法,因为数据类型与编译器是有关的,应该并成记好的习惯,推荐用(65536-5000)/256的写法。
那么问题一一样-5000/256=(65536-5000)/256,可以看出定时是5ms,当然这个是有前的,就是你使用的晶振是12MHz的。
希望可以帮到你,对这三个问题还有什么疑问,可以扣我236376723

彩色图空间是三维空间(R,G,B)。灰度空间是一维空间(一条直线)。
每一种彩色图到灰度图的变换方法,实际上就是定义一种(R,G,B)空间到灰度空间的映射。一般来说它的反映射是一点对多点,不存在唯一性。
为了保证反映射的唯一性,就需要有彩色图空间各像素取值范围的限制条件。
比如你所说的单色图。假如它只是蓝色单色调图(R=0,G=0),那么只要把
蓝色值(B)简单地变换为灰度值(GRAY)就可以了。逆变换也是简单地把灰度值变换为蓝色值(B)而R和G为零。
如果是其它一些复杂的限制条件,我觉得最简单的就是把彩色图的样本图像(你的例子中的左边图像)各像素的(R,G,B)值和它变换到灰度图像(你的例子的右边图像)后对应点的灰度值(GRAY)做一个变换表,有些灰度图像中没有出现的灰度值,可能需要用插值的方法填满。如果它是一对一的,逆变换也同样是查这个表来计算就可以了。
根据楼主补充,我给个具体变换方法。
灰度0 --- 给定颜色(R0,G0,B0)
灰度255 -- 白色(255,255,255)
那么任意一个灰度值 M
变换到(R0+(255-R0)/255M,G0+(255-G0)/255M,B0+(255-B0)/255M)就可以了。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/13338605.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2025-08-31
下一篇2025-08-31

发表评论

登录后才能评论

评论列表(0条)

    保存