上个月积累的代码如下,由于在同一文件中测试多个代码段,因此只好用#if 0 ……#endif的形式来控制了。这次的代码包括:

1、测试函数入栈顺序,入栈顺序依据语言的不同而不同,C语言是从右到左的。从代码的运行结果也可以看出,因为栈帧是往下增长的。

2、从字符串中去除指定字符,这里在csdn帖子中抄来的,原问题是说出现了段错误,因为他使用的不是字符数组。详见代码。

3、移位操作,从http://aggregate.ee.engr.uky.edu/MAGIC/抄来的,上面有许多位运算的技巧。那个大小端转换是我自己临时加上去的,因为以前雄心勃勃想研究SD卡时候曾经写过,一时心血来潮也写一下,没想到还没忘记。

4、计算一个数的二进制中包含1的个数,比如7的二进制为0111,则1的个数为3。最后结果和3f相与,一开始不太理解,后来想通了,因为32位的二进制中1的个数最多是32个(似乎是废话)。那个求msb(搞过单片机的应该很熟悉这个东西)的函数中,结果是这样的:比如0x64,二进制为0x0110 0100,最高有效位为0x0100 0000,则结果为0x40。本文所有代码片段可任意使用而不用告诉作者,当然,作者修改了也不必要告知阁下,而且,由于代码的错误而造成的损失亦与作者无关,不过一起讨论、学习还是可以的。

/*************************************************

没有main函数
$ gcc rock.c -Wall
/usr/lib/gcc/i386-redhat-linux/4.3.0/../../../crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld 返回 1
**************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#if 0
/**************************************************
* 参数入栈测试
编译过程中出现警告:
$ gcc rock.c -Wall
rock.c: 在函数‘main’中:
rock.c:55: 警告:‘t’上的运算结果可能是未定义的
rock.c:57: 警告:‘t’上的运算结果可能是未定义的
rock.c:61: 警告:‘j’上的运算结果可能是未定义的
rock.c:61: 警告:‘j’上的运算结果可能是未定义的
rock.c:51: 警告:未使用的变量‘i’

测试结果:
$ ./a.out 
6 6
6 6
a=6[0xbfaeca30] b=7[0xbfaeca34] c=7[0xbfaeca38]
20
了解过堆栈帧的话,应该知道参数入栈的顺序
**************************************************/

int foo(int a, int b, int c)
{
        printf("a=%d[%p] ",a, &a);
        printf("b=%d[%p] ",b, &b);
        printf("c=%d[%p]/n",c, &c);
        return a+b+c;
}
int main(void)
{
        int i = 3;
        int j = 5;
        int ret;
        int t = 5;
        printf("%d %d/n", ++t, t);
        t = 5;
        printf("%d %d/n", t, ++t);
        //printf("%d %d %d/n", i++, ++i, i);
        //printf("%d %d %d/n", j, ++j, j++);
        //ret = foo(i++, ++i, i);
        ret = foo(j++, ++j, j);
        printf("%d/n", ret);
        return 0;
}
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
* 参数入栈测试 结束
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
#endif

/*************************************************
* 字符串去除特定字符
* 段错误
运行结果:
$ ./a.out 
Before: abcdabcdabcdefgabcd
After:  abdabdabdefgabd
*************************************************/
#if 0
#include <string.h>
void SqueezeChar(char s[],int c)
{
        int i,j;
        for(i=j=0;i<strlen(s);i++)
                if(s[i]!=c)
                        s[j++]=s[i]; s[j]='/0';
}
int main(void)
{
        //char * org="abcdabcdabcdefgabcd"; // 此处造成段错误
        char org[] = "abcdabcdabcdefgabcd";
        printf("Before:/t%s/n",org);
        SqueezeChar(org,'c');
        printf("After:/t%s/n",org);

return 0;
}
/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
* 字符串去除特定字符 结束
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
#endif

#if 0
/************************************************
8位、16位、32位平台无符号位反转,如0000ffff --> ffff0000
注:实际中需要注意位数需要一致。比如,不能将unsigned int版本的反转用于unsigned char中。
来自 http://aggregate.ee.engr.uky.edu/MAGIC/
运行结果:
$ ./a.out 
fffe 7fff0000
7f fe00
fe 7f
55aa8977 7789aa55
55aa aa55
*************************************************/
#include <stdio.h>

/* fe --> 7f */
unsigned char reverse8(register unsigned char x)
{
        x = (((x & 0xaa) >> 1) | ((x & 0x5555) << 1));
        x = (((x & 0xcc) >> 2) | ((x & 0x3333) << 2));

return((x >> 4) | (x << 4));
}

/* 007f --> fe00 */
unsigned short reverse16(register unsigned short x)
{
        x = (((x & 0xaaaa) >> 1) | ((x & 0x5555) << 1));
        x = (((x & 0xcccc) >> 2) | ((x & 0x3333) << 2));
        x = (((x & 0xf0f0) >> 4) | ((x & 0x0f0f) << 4));

return((x >> 8) | (x << 8));
}

/* fffe --> 7fff0000 */
unsigned int reverse32(register unsigned int x)
{
        x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
        x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
        x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
        x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));

return((x >> 16) | (x << 16));
}

/* 大小端转换,如 55aa6788 --> 8867aa55 */
unsigned int endian_reverse32(register unsigned int x)
{
        return ((x & 0xff) << 24) | ((x & 0xff00) << 8) | ((x & 0xff0000) >> 8) | ((x & 0xff000000) >> 24);
}

/* 大小端转换, 如55aa --> aa55 */
unsigned short endian_reverse16(register unsigned short x)
{
        return ((x & 0xff) << 8) | ((x & 0xff00) >> 8);
}

int main(void)
{
        unsigned int i = 65534;
        unsigned int tmp = reverse32(i);
        unsigned short j = 127;
        unsigned short tmp1 = reverse16(j);
        unsigned char k = 254;
        unsigned char tmp2 = reverse8(k);
        
        unsigned int tmp3 = 0x55aa8977;
        unsigned int tmp4 = endian_reverse32(tmp3);
        
        unsigned short tmp5 = 0x55aa;
        unsigned short tmp6 = endian_reverse16(tmp5);
        
        printf("%x %x/n", i, tmp);
        printf("%x %x/n", j, tmp1);
        printf("%x %x/n", k, tmp2);
        printf("%x %x/n", tmp3, tmp4);
        printf("%x %x/n", tmp5, tmp6);
        return 0;
}

/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
* 位反转 结束
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
#endif

#if 0
/*************************************************
计算二进制中1的个数
运行结果:
$ ./a.out 
64 3 3 40
0x64 = 0110 0100 (共3个1)
0x40 = 0100 0000
*************************************************/

/* 计算一个数(32位无符号)的二进制中1的个数
 * 以x = 999测试,34条指令,占4个字节栈空间
 */
unsigned int binary_count(unsigned int x)
{
        unsigned int count = 0;
        while (x)
        {
                count++;
                //x = x&(x-1); /* 与 */
                x &= x-1;         /* 与 */
                #ifdef DEBUG
                printf("%x ", x);  /* debug */
                #endif
        }
        return count;
}

/* 另一个版本
 * 以x = 999测试,30条指令,不占栈空间
 * 最后一语句x & 0x0000003f, 因为32位1的个数最多只能是32位。
 */
unsigned int ones32(register unsigned int x)
{
         /* 32-bit recursive reduction using SWAR...
           but first step is mapping 2-bit values
           into sum of 2 1-bit values in sneaky way
        */
        x -= ((x >> 1) & 0x55555555);
        x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
        x = (((x >> 4) + x) & 0x0f0f0f0f);
        x += (x >> 8);
        x += (x >> 16);
        return(x & 0x0000003f);
}

/* 求一个数中的MSB */
unsigned int msb32(register unsigned int x)
{
        x |= (x >> 1);
        x |= (x >> 2);
        x |= (x >> 4);
        x |= (x >> 8);
        x |= (x >> 16);
        return(x & ~(x >> 1));
}

/* ?? */
unsigned int tzc(register int x)
{
        return(ones32((x & -x) - 1));
}

int main(void)
{
        unsigned int x = 100;
        unsigned int y = ones32(x);
        unsigned int tmp = binary_count(x);
        unsigned int tmp1 = msb32(x);
        printf("%x %x %x %x/n", x, y, tmp, tmp1);

return 0;
}

/*xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
* 二进制中1的个数 结束
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
#endif

李迟2011年3月代码积累相关推荐

  1. 李迟2011年4月知识积累

    我从来不觉得写代码只是写代码的事,也不是整天拿数据结构和算法来研究,拿C.C++大头书来看.我对自己的要求是:坚持融会贯通,坚持多层次联系,坚持学习,坚持积累. 非代码知识 主要关于linux日常使用 ...

  2. 李迟2021年12月知识总结

    本文为 2021 年 12 月知识总结. 研发编码 测试发现,不同语言对浮点数的存储和处理不太相同,比如1.5,有的语言存储的可能是1.49999999999,有的可能是1.500000001.这样四 ...

  3. 李迟2021年11月知识总结

    本文为 2021 年 11 月知识总结. 研发编码 C / C++ 无. golang 保留小数点后2位,假定在原数值基础上上浮10%(即1.1倍),但不进位. // 使用Sprintf有些情况会导致 ...

  4. 李迟2021年10月知识总结

    本文为 2021 年 10 月知识总结. 研发编码 C / C++ 无. golang 写了数字签名.数字信封的测试示例,了解了 RSA .AES 加解密,知道 AES 的密钥长度必须大于16字节. ...

  5. 李迟2022年1月知识总结

    本文为 2022 年 1 月知识总结. 研发编码 Golang golang中中文字符长度为3,如下示例中,判断某字段中文开头是否为"广西"二字,如是则舍去,只保留后面的字符串,如 ...

  6. 李迟2022年10月工作生活总结

    本文为 2022 年 10 月工作生活总结. 研发编码 Go 判断interface{}是否为空 判断interface{}类型是否为空,不能直接使用==nil来判断(用之无效),需先用reflect ...

  7. 李迟2021年8月知识总结

    本文为 2021 年 8 月知识总结. 编码总结 C / C++ 产生随机数示例二则. 产生给出范围,并指定数量的随机数.即给定数组(实为向量),其内可预先定义有数值,也可以为空,产生随机数时,需保留 ...

  8. 李迟2021年6月知识总结

    本文为 2021 年 6 月知识总结. 编码总结 C / C++ 使用sscanf检查不确定的输入参数: char name[8] = {0};int type = 0;int threadnum = ...

  9. 李迟2022年8月工作生活总结

    本文为 2022 年 8 月工作生活总结. 研发编码 Java 接手了一个 Java 工程事务(注:不是接手工程),在其中添加一个模块.不知为何领导会找到我,或者是没有负责项目的原故,作为十分珍惜工作 ...

最新文章

  1. (曲率系列2:)Paper6:Curvature Estimation of 3D Point Cloud Surfaces Through the Fitting of Normal
  2. Selenium提取数据之标签对象提取文本内容和属性值
  3. oracle创建定时任务
  4. Tomcat源码分析--转
  5. MySql 里的IFNULL、NULLIF和ISNULL用法
  6. 使用Rancher搭建K8S测试环境
  7. 新增成功到编制为空bug_36 个JS 面试题为你助力,让面试更有力(面试必读)
  8. 同样版本的jstl,都是jstl1.2版本,有个有问题,另一个没有问题
  9. 阿里云Centos镜像源和EPEL源
  10. androidx86安装pc后无法联网_Ubuntu 16.04 安装显卡驱动后循环登录和无法设置分辨率的一种解决方案
  11. [Java] 蓝桥杯ADV-205 算法提高 拿糖果
  12. 浴血凤凰DNF自动辅助开发教程
  13. BarTender制作圆形标签的方法
  14. python中base函数_详细的python basemap中各函数的所有参量注释
  15. 以Crotex M3为例讲解stm32芯片内部原理
  16. 产品引流的方式有哪些?适合引流推广的平台有哪些?
  17. 关于联合体union的详细解释
  18. 【论文阅读】Adaptive Clustering-based Malicious Traffic Classification at the Network Edge
  19. 下一代安全管理平台NextSOC
  20. php中的网页漂浮代码,网页中上下漂浮的按钮JS代码-DEDE

热门文章

  1. 7年赚出两个阿里加两个腾讯,他是地表最强打工人!
  2. 这个“十一”长假,你是背“锅”出行吗?
  3. “腾讯持股比例提升”系误读!美团对外定增后腾讯持股比例降低
  4. 网红奶茶雪糕高价背后,到底是真好吃还是智商税
  5. 快手封禁网红殷世航:涉及炒作卖货、低俗表演等违规行为
  6. 男子拒绝春节带电脑回家工作被开除,最后结果十分舒适...
  7. 网易有道词典2019年度十大热词:Vlog、PUA等上榜
  8. 相机翻转设计的华硕旗舰ZenFone 6固件更新:新增“超级夜间模式”
  9. 自如回应南京租客事件:未对该房源进行过装修 配置的家具符合规定
  10. 元年·潮湃 首届搜狐5G峰会倒计时 参会大咖揭晓