首先看一个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("\n"); } } 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.........................................\n"); dump16(iarray,30); printf("output data.........................................\n"); dump16(oarray,30); audio_stereo2mono_16bits_check(0,oarray,iarray,BUFF_SIZEA); //audio_mono2stereo_16bits(oarray,iarray,30); printf("output data2.........................................\n"); dump16(oarray,30); return 0; }
运行结果:
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("\n"); 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.........................................\n"); 59 dump16(iarray,30); 60 printf("output data.........................................\n"); 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.........................................\n"); 65 dump16(oarray,30); 66 67 return 0; 68 }
运行结果:
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内核源码.并写一个专题.