C语言实现流水灯

思考:

①流水灯的实现是将控制该灯的另一端设置为低电平或者高电平(反着接入的情况下),以高电平为例;

②假如说有8个小灯,则需要将8个小灯对应的为一次设置为1,其他设置为0,因此需要循环,循环周期为8;

③将每个小灯对应位设置为1,则可以通过0x1的位置实现:0000 0001  、0000 0010 、 0000 0100.......每次多移动一位

④每个小灯点亮后需要持续一段时间,可以使用for循环的空语句,让程序在点亮一个小灯后持续一段时间,再进入下一个小灯点亮的代码之行

⑤需要将这8个小灯依次点亮后,继续这种操作,需要死循环。

代码:

#include
#include

/*
将整型数转化为二进制
*/
void intToBit(unsigned int n,char *arr){
    int totalBit = sizeof(n) * 8;
    int i = 0,j = 0;
    char ch;

    while(n / 2 != 0){
        arr[i] = '0'+ n % 2;
        n = n / 2;
        i++;
    }
    //最后一个余数处理
    arr[i] = '0'+ n % 2;

    //arr翻转
    for(j=0;j

遇到的问题及解决办法:

1、将数字转化为字符

使用'0'字符加上这个数,因为char型字符在ASCII码表中都对应于一个整数,而数字字符在ASCII码表中是按照顺序存储的,‘0’对应的是48,‘1’对应的是49,因此将49存入到char中就代表一个字符‘1’

使用这种方法的缺点:数字字符只有‘0’~‘9’,如果是>10的数需要使用itoa或者sprintf转化,该转化只涉及0、1,所以可以不用考虑这个缺点。

'0' + 2 == '2'

2、数组赋初值

原来写的是:char arr[33] = {'\0'}或者char arr[33] = {'0'}

但是会发现,结果只能从位置为1的地方开始打印,1,10,100......但是填充的0并不能打印,

 

原因:

字符串初始化为‘\0’或者‘0’,则从第二个字符开始都是‘\0’,如果将整型转1化为二进制字符存储,{''\0','\0'......,'1'},在打印时则结果什么也打印不出来。

赋值为 '\0' 和 0 是等价的,因为字符 '\0' 在内存中就是 0。
    char str1[] = {0,0,0,0,0,1};
    printf("%s\n",str1); //什么也不显示 犹如第一个字符是'\0'
    char str2[] = {'\0','\0','\0','\0','\0',1};
    printf("%s\n",str2); //什么也不显示
    char str3[] = {'0','0','0','0','1'};
    printf("%s\n",str3); //没有结束符会出现乱码
    char str4[] = "0000000001";
    printf("%s",str4);

 

解决办法:

需要循环给数组的每个元素赋初值‘0’,在每次循环while(1)中写:

  for(i=0;i<8;i++){
     arr[i] = '0';
  }

优化:借助stdlib.h中的memset将这个数组的置零操作进行优化。

memset 一般使用“0”初始化内存单元,而且通常是给数组或结构体进行初始化。

 memset 是对较大的数组或结构体进行清零初始化的最快方法,因为它是直接对内存进行操作的。

memset(arr,'0',32);

设置32个有效字符‘0’,最后一个为结束符‘\0',不然打印会出错。


 3、延迟

使用for循环空语句进行延迟,这种延迟属于非精确延迟,单片机有自己的定时器操作。

unsigned long i;
for(i=0;i<300000000;i++);

i的值可以自己设置,注意它的数据类型,不要超出这个数据类型的表示范围。

4、未解决的问题

如何让intToBit函数的参数无论串unsigned int 或者unsigned char都可以使用呢,因为有的时候不需要32位,8位操作就可以了。

你可能感兴趣的:(C语言,c语言,C语言练习,C语言位操作)