zoukankan      html  css  js  c++  java
  • 一个强制转换引发的血案及反思

      首先看一个C语言的例子:

    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    
    
    typedef short uint16_t;
    typedef int uint32_t;
    
    void audio_mono2stereo_16bits(uint16_t *dst_buf, uint16_t *src_buf, uint32_t src_len)
    {
        uint32_t i = 0;
        for (i = 0; i < src_len; ++i) {
            dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = src_buf[i]>>1;
        }
    }
    
    void audio_stereo2mono_16bits(unsigned char channel, uint16_t *dst_buf, uint16_t *src_buf, uint32_t src_len)
    {
        uint32_t i = 0;
        for (i = 0; i < src_len; i+=2) {
            dst_buf[i/2] = src_buf[i + channel];
        }
    }
    
    void audio_stereo2mono_16bits_check(unsigned char channel, int *dst_buf, int *src_buf, uint32_t src_len)
    {
        uint32_t i = 0;
        for (i = 0; i < src_len; i+=2) {
            dst_buf[i/2] = src_buf[i + channel];
        }
    }
    
    #define BUFF_SIZEA 160
    
    static int iarray[BUFF_SIZEA];
    static int oarray[2*BUFF_SIZEA];
    
    void dump16(short *ibuf, int length)
    {
      int j = 0;
    
      for (j=0; j<length; j++) {
       //if (!(j%20)) printf("%d == ",j);
       printf(" %d, ", ibuf[j]);
       if (!((j+1)%10)) printf("
    ");
     }
    }
    int main()
    {
            int ibuff[160],outbuf[160];
            int ilen = BUFF_SIZEA;
            for(int icnt = 0; icnt < BUFF_SIZEA; icnt++)
            {
                    iarray[icnt] = -icnt;
            }
    
            audio_stereo2mono_16bits(0,oarray,iarray,BUFF_SIZEA);
            printf("input data.........................................
    ");
            dump16(iarray,30);
            printf("output data.........................................
    ");
            dump16(oarray,30);
            audio_stereo2mono_16bits_check(0,oarray,iarray,BUFF_SIZEA);
            //audio_mono2stereo_16bits(oarray,iarray,30);
            printf("output data2.........................................
    ");
            dump16(oarray,30);
    
            return 0;
    }
    View Code

      运行结果:

    input data.........................................
     0,  0,  -1,  -1,  -2,  -1,  -3,  -1,  -4,  -1, 
     -5,  -1,  -6,  -1,  -7,  -1,  -8,  -1,  -9,  -1, 
     -10,  -1,  -11,  -1,  -12,  -1,  -13,  -1,  -14,  -1, 
    output data.........................................
     0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9, 
     -10,  -11,  -12,  -13,  -14,  -15,  -16,  -17,  -18,  -19, 
     -20,  -21,  -22,  -23,  -24,  -25,  -26,  -27,  -28,  -29, 
    output data2.........................................
     0,  0,  -2,  -1,  -4,  -1,  -6,  -1,  -8,  -1, 
     -10,  -1,  -12,  -1,  -14,  -1,  -16,  -1,  -18,  -1, 
     -20,  -1,  -22,  -1,  -24,  -1,  -26,  -1,  -28,  -1,

      是不是运行结果很乱?是哪儿出问题了呢?

      接下来再看另外一个例子:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <assert.h>
     4 
     5 
     6 typedef short uint16_t;
     7 typedef int uint32_t;
     8 
     9 void audio_mono2stereo_16bits(uint16_t *dst_buf, uint16_t *src_buf, uint32_t src_len)
    10 {
    11     uint32_t i = 0;
    12     for (i = 0; i < src_len; ++i) {
    13         dst_buf[i*2 + 0] = dst_buf[i*2 + 1] = src_buf[i]>>1;
    14     }
    15 }
    16 
    17 void audio_stereo2mono_16bits(unsigned char channel, uint16_t *dst_buf, uint16_t *src_buf, uint32_t src_len)
    18 {
    19     uint32_t i = 0;
    20     for (i = 0; i < src_len; i+=2) {
    21         dst_buf[i/2] = src_buf[i + channel];
    22     }
    23 }
    24 
    25 void audio_stereo2mono_16bits_check(unsigned char channel, int *dst_buf, int *src_buf, uint32_t src_len)
    26 {
    27     uint32_t i = 0;
    28     for (i = 0; i < src_len; i+=2) {
    29         dst_buf[i/2] = src_buf[i + channel];
    30     }
    31 }
    32 
    33 #define BUFF_SIZEA 160
    34 
    35 static short iarray[BUFF_SIZEA];
    36 static short oarray[2*BUFF_SIZEA];
    37 
    38 void dump16(short *ibuf, int length)
    39 {
    40   int j = 0;
    41 
    42   for (j=0; j<length; j++) {
    43    //if (!(j%20)) printf("%d == ",j);
    44    printf(" %d, ", ibuf[j]);
    45    if (!((j+1)%10)) printf("
    ");
    46  }
    47 }
    48 int main()
    49 {
    50         int ibuff[160],outbuf[160];
    51         int ilen = BUFF_SIZEA;
    52         for(int icnt = 0; icnt < BUFF_SIZEA; icnt++)
    53         {
    54                 iarray[icnt] = -icnt;
    55         }
    56 
    57         audio_stereo2mono_16bits(0,oarray,iarray,BUFF_SIZEA);
    58         printf("input data.........................................
    ");
    59         dump16(iarray,30);
    60         printf("output data.........................................
    ");
    61         dump16(oarray,30);
    62         audio_stereo2mono_16bits_check(0,oarray,iarray,BUFF_SIZEA);
    63         //audio_mono2stereo_16bits(oarray,iarray,30);
    64         printf("output data2.........................................
    ");
    65         dump16(oarray,30);
    66 
    67         return 0;
    68 }
    View Code

      运行结果:

    input data.........................................
     0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,  -8,  -9, 
     -10,  -11,  -12,  -13,  -14,  -15,  -16,  -17,  -18,  -19, 
     -20,  -21,  -22,  -23,  -24,  -25,  -26,  -27,  -28,  -29, 
    output data.........................................
     0,  -2,  -4,  -6,  -8,  -10,  -12,  -14,  -16,  -18, 
     -20,  -22,  -24,  -26,  -28,  -30,  -32,  -34,  -36,  -38, 
     -40,  -42,  -44,  -46,  -48,  -50,  -52,  -54,  -56,  -58, 
    output data2.........................................
     0,  -1,  -4,  -5,  -8,  -9,  -12,  -13,  -16,  -17, 
     -20,  -21,  -24,  -25,  -28,  -29,  -32,  -33,  -36,  -37, 
     -40,  -41,  -44,  -45,  -48,  -49,  -52,  -53,  -56,  -57, 

      其实,这两个例子说明了很多问题,也让我在一个很大型的程序中,花费了不少时间去定位这个输出的数据一直不正确的问题.其实,核心的问题,就是我把short类型和int类型之间强制转换的过程中出现了问题.

    不同类型之间的强制转换,在这个知识点掌握不够透彻的情况下,就一头栽倒在这个深坑中出不去了.当我花费很大力气去解决这个bug,必须要应该回头反思一下了.

      用了那么多年的C语言,我真的掌握了吗?

      像很多初级程序员一样,在我拿出去的简历上,经常会用黑体标出来---熟练掌握C语言.在一般的面试中,也能够应付面试官,在日常的工作中,绝大多数的代码也能够看懂,也能够实现所需的功能.这样,我就飘飘然了,以为自己已经掌握了C语言,当到了实战中,才发现很多东西远远还没有达到理解的境界.

      每天都是用的东西,为什么还犯这种低级的错误?

      就像每天见到的同事,假如你没有和他有很深业务上的往来或者利益冲突,是根本无法看清楚这个人的.工作中用的语言也是同样的情况,很多时候,我们都喜欢使用熟悉的套路去写程序,自己不熟悉还有不了解的东西一般是不会使用的,这样就出现了,熟的愈加熟练,陌生的依旧是陌生.这,也许就是人性吧.

      今后的应对策略.  

      其实,这个是有解决方法的.根据经验,以后要针对这些情况,做以下功课吧.

      定期总结,针对不熟悉的模块和知识,要定期的去总结.

      经典的书籍要反复看,特别是相关的经典书籍,千万不能看一遍就丢了.

      多看优秀的源码,特别是内核的源码,经典的一定要反复去看,今后,要找个时间熟悉和分析一下linux内核源码.并写一个专题.

  • 相关阅读:
    重写保存按钮save事件
    隐藏列获取不到值,表格选中行提示未选中
    前后台获取上下文context
    editGrid分录表格
    通用查询-高级查询
    js保留位和取整
    在Visual Studio中使用C++创建和使用DLL
    Lua中的一些库(1)
    Lua中的面向对象编程
    Lua中的模块与包
  • 原文地址:https://www.cnblogs.com/dylancao/p/9878019.html
Copyright © 2011-2022 走看看