C语言C51单片机花样流水灯程序分析注释

C语言C51单片机花样流水灯程序分析注释,第1张

和你说一句关键的(别告我你整个程序一句都看不懂):

P1=0xfe;

0xfe是十六进制表示的数,二进制就是1111 1110,通过你的程序和相关注释可以看出,硬件上你有8个led灯连接P1口,且这些led是低电平亮。P1=0xfe(1111 1110)也就是表示七个灯灭,一个灯亮。接下来的代码就是让P1数据0xfe左移且低位补1,移一次就是1111 1101,、两次就是1111 1011,三次是1111 0111。。。以此类推,可以看出它是0由最低位到最高位依次移过去的,而刚说了0表示led亮,这也就是led从一边到另一边依次点亮的效果。

后面的代码按我上面说的自己理解,完全对你解释太麻烦,对你也没多大好处,只有你自己理解了才能学好单片机

#include <stdioh>

#include <stringh>

int main()

{

char data[33];

int dota[33];

int i, j, num, len;

gets(data);

len = strlen(data);

for (i = 0; i <= len; i++)

{

dota[i] = (int)data[i] -'0';

}

num = dota[0];

for (j = 1; j < len; j++)

{

num = num 2 + (int)dota[j];

}

printf("%d\n", num);

}

//改了一下,自己看吧!不明可以问的!

下面是三种方式:

①通过模2除2(%2、/2)的方法

num%2——取出二进制的最后一位

num/2——右移去掉二进制的最后一位

通过while循环,依次取出二进制的最后一位数字判断是否为1,若为1则count++,while(num)只有当num变为0时循环结束。

问题:在测试-1出现bug,-1的二进制中应该有32个1,输出却为0。我们将-1带入代码中发现-1%2=0,count不增,然后-1/2=0,循环结束,故输出count的值为0。

解决方案:将变量num的数据类型改为unsigned int (无符号整型),此时表示的是正的整型的最大值,所以当num=-1时,表示二进制为32个1的正数,通过循环可以输出正确的个数。

②通过右移 *** 作符(>>)、按位与 *** 作符(&)实现

Example:当num=10(1010),通过右移 *** 作num>>i,二进制向右移动i位。

//i=0,num>>0,右移0位,此时(1010)&(0001)=0

//i=1,num>>1,右移1位,此时(0101)&(0001)=1,count++

//i=2,num>>2,右移2位,此时(0010)&(0001)=0

//i=3,num>>3,右移3位,此时(0001)&(0001)=1,count++

……

因为二进制共32位,所以循环要执行32次后结束,得到count为2。

缺点:不够高效,必须循环32次。

③通过按位与 *** 作符(&)巧妙运算实现

Example:  当num=15时,

1//num&(num-1)=(1111)&(1110)=(1110)  

2//num&(num-1)=(1110)&(1101)=(1100)

3//num&(num-1)=(1100)&(1011)=(1000)

4//num&(num-1)=(1000)&(0111)=0  ,循环停止。共执行4次while循环。

扩展资料

一、指定的某一位数置1

宏 #define setbit(x,y)  x|=(1<<y)

二、指定的某一位数置0

宏  #define clrbit(x,y)  x&=~(1<<y)

三、指定的某一位数取反

宏  #define reversebit(x,y)  x^=(1<<y)

四、获取的某一位的值

宏 #define getbit(x,y)   ((x) >> (y)&1)

是按2进制代码的同位进行运算。例如1010和1101这2个2进制数:

按位与为:

1010

1101

=

1000对应为同为1时是1,否则为0

按位或为:

1010

1101

=

1111只要同位的两个全为零时得零,否则为1

1、电脑中存放的数(二进制)都是用补码表示的。

先说说原码。

把一个数的绝对值用二进制表示,然后在最高位添上一个符号位(正数添0,负数添1),得到的就是原码。

比如对于int型整数来说,字长16位,表示十进制数123和-234。

123表示为二进制为111

1011,补至16位即0000

0000

0111

1011,因为是正数,所以最高位(从左数第一位)写0。

所以123原码就是0000

0000

0111

1011

234表示为二进制为1110

1010,补至16位即0000

0000

1110

1010,因为是负数,所以最高位改为1

所以-234的原码就是1000

0000

0111

1011

整数X(二进制)补码的表示规则如下

若X大于等于0,则补码与源码相同;

若X小于0,则补码为-X的原码各位取反,然后再加1。

比如上面的-234,234的原码是0000

0000

0111

1011,欲求它的补码

先各位取反,得1111

1111

1000

0100,

再加1得1111

1111

1000

0101

同理,-1在计算机中的表示形式,首先1的原码为0000

0000

0000

0001

各位取反得1111

1111

1111

1110

再加1得1111

1111

1111

1111。

八进制和十六进制其实就是二进制的简略形式,因为一大堆的0和1很容易看错。

八进制就是把二进制数从低位(右边)开始,每3个数字一组对应到这三个数所对应的十进制数。因为是每三个数字一组,所以只有0-7这些数字有对于,8和9不会出现。

把1111

1111

1111

1111按每3个数一组分组,得到

1

111

111

111

111

111,最高位的1补上两个0

001

111

111

111

111

111

写成八进制就是177777。

同样十六进制也是,不过是4个数字一组。因为4个数字有16种组合,大于9的部分如下表示

二进制数

-

十进制数

-

十六进制数

1010

-

10

-

A

1011

-

11

-

B

1100

-

12

-

C

1101

-

13

-

D

1110

-

14

-

E

1111

-

15

-

F

所以1111

1111

1111

1111写成十六进制数就是FFFF。

至于那个字符代码,没有什么背的必要。都是查表。用到的时候看两眼就记得了,用完了就忘了。

输出结果是由两条printf()语句得出的:

printf("%d→%u\n",b,a);

其中%d是十进制,所以%d就输出-1,然后→照写,最后%u是无符号数,把-1写成二进制形式:1000 0000 0000 0001(最高位为符号位,因为是负数,所以最高位为1),因为在计算机里数字都是用补码表示的,所以把以上的二进制(原码)写成补码为:(1111 1111 1111 1111)2=(65535)10(补码=反码+1)

所以最后输出结果为:-1→65535

printf("%d→%u\n",b,a);

因为b=a,而a=65534u,当我们用二进制表示时可以发现最高位为1,说明此数为负数,表示为:1111 1111 1111 1110此时为补码,反码=补码-1,为:1111 1111 1111 1101,再把反码变成原码(符号位不变)为:1000 0000 0000 0010,这个二进制数表示-2

所以第二个输出语句的结果为:-2→65534

如果n为13,二进制为1101

那么程序执行是这样的:

dtob(13)

{

13的二进制为1101,去掉最后一位后变成110,即13/2=6,进行dtob(6)

输出最后一位1,即13%2=1

}

dtob(6)

{

13的二进制为110,去掉最后一位后变成11,即6/2=3,进行dtob(3)

输出最后一位0,即6%2=0

}

dtob(3)

{

13的二进制为11,去掉最后一位后变成1,即3/2=1,进行dtob(1)

输出最后一位1,即3%2=1

}

dtob(1)

{

13的二进制为1,去掉最后一位后没有了

输出最后一位1,即3%2=1

}

最后就是

dtob(13)

{

    dtob(6)

    {

        dtob(3)

        {

            dtob(1)printf 1  -------1

            printf 1  --------------1

        }

        printf 0 -------------------0

    }

    printf 1 -----------------------1

}

以上就是关于C语言C51单片机花样流水灯程序分析注释全部的内容,包括:C语言C51单片机花样流水灯程序分析注释、C语言。编写一个程序,输入一个二进制的字符串(长度不超过32),然后计算出相应的十进制整数,并打印。、c语言中如何提取二进制数中的某一位等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址: http://outofmemory.cn/zz/10026082.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-04
下一篇 2023-05-04

发表评论

登录后才能评论

评论列表(0条)

保存