编程真的不简单

2014-04-17 by muzi

前言

以前觉得编程嘛,不就是写代码嘛。谁不会啊!后来,和大男哥聊天的过程中,他说到一句话:大家都说我会c编程,然后我也觉得我会用c。就像我会打篮球,科比也会打篮球一样。

当时真的笑翻了!不过说来也是!编程真的不简单!

编程真的不简单

下面是上个周我做的c语言培训题收获的感想。编程真的不简单啊!

之前都是用python写程序,很少会注意到一些方面,比如头文件之类的,指针之类的。这次的c题培训,让我对编程的认识上升到了另一个阶段。

编码

编程并不是仅仅把功能实现而已。还有许多重要的东西,比如:

  • 逻辑的严谨性:一些边界条件,可能的逻辑分支等,都需要考虑到。

  • 模块化思想:将相对独立的功能写在一个文件中,有利于解耦和移植。提高代码的复用性,同时也为单元测试提供了可能。

  • 头文件的重要性:在C语言中通过include 头文件的方式把某一些模块添加进来。同时一个头文件所包含的的内容应该是静态的声明,而不应该有实现。所有的实现都应该出现在同名的.c文件中。同时,在运行的时候我们必须保证.C的实现与.h的声明一致,某种程度上是对代码的保护。

  • 可读性:可读性的重点是对编程者而言。一个好的代码,应该可读性很高。我们可以从函数明直观的明白函数的功能,同时可以从变量名清楚地知道其作用。从文本的角度提高可读性。一段苦涩难懂的代码,也许机器容易度,但是其可读性过低,对于后期维护,成本过高。

  • 追求高效:在保证可读性的同时,应该追求代码的高效性,如多重循环中,上层计算结果应该用变量去保存,用于底层的循环,而不应该在底层进行多次计算重复值。 如:

    函数foo(int num)是一个计算庞大的函数。
    For(int i=0; i<100;i++)
    {   
        For(int j =0;j <foo(i);j++)
        {
            j++;//do anything.
        }
    }
    

    这样每一次循环内循环的时候,在判断j是否小于foo(i)的时候都需要花大量的时间去计算foo(i)的结果。正确的方式应该是:

    For(int i=0; i<100;i++)
    {   int tmp =foo(i);
        For(int j =0;j <tmp; j++)
        {
            j++;//do anything.
        }
    }
    

    如此一来仅仅计算了一次,就可以将值使用多次,减少了没有必要的循环。 虽然写起来可能不太好看。但是花费一个变量可以省去许多计算是很值得的。

  • 设计的重要性:能实现功能的方式有很多种,如何采用高效的算法,设计优雅的数据结构,定义正确的函数功能,参数。这些是我这些天学到的宝贵的一点。

  • 算法:一个程序的灵魂是算法。宁可花掉时间想算法,也不可以退而求其次采用低效的算法解决问题。

  • 数据结构的重要性:在写代码的过程中好多时候我的数据结构都设计得不好,男哥给我很多的帮助。首先要清楚要做什么,需要什么,然后再去设计。后来的数据结构好与坏,我基本能有一些感觉了。好的数据结构能让算法更简单。
  • 函数定义:函数定义涉及到函数的名称,参数,返回值这三大要素。好的名称可以提高可读性,正确的参数,能让整个程序运行得更合理,为算法提供正确的数据。返回值的重要性体现在函数调用的情况下。比如一个pop()函数,它不应该是在函数体里面打印pop出来的数值,而返回void,而是将pop的数值返回。打印的任务应该是打印返回值。这样的函数定义才是正确的,因为更多的场景需要得到这个数值,而不是在控制台下面打印一个值。

  • 代码的优雅度:渐渐觉得,其实写代码不是一件简单的事情。他需要一个人拥有足够的背景知识,如英文的熟练程度,逻辑思维严谨度,设计思想等等。能把一个功能成功拆分成许多的相对独立的模块,然后有机的组合在一起,而且可读性很高,鲁棒性(稳定性)很强,可移植性很强,这就是代码的优雅度。

  • 语言的熟练度非常重要:刚开始的时候举步维艰,一个指针就能搞疯掉。但是慢慢的就习惯了,速度也就上来了,遇到的问题多了,也就知道怎么解决了。写的多了,也就快了。所以语言的熟练程度也是我在这次培训中得到的提升。

  • 知识广度:除了基础的语法以外,比较成熟的接口,架构是我需要大大补充的。比如通用线程编程中很多知识还没有摸透。还需要多练习,多看书,多理解。有其事在线程池一题,pthread_cond_t 的一些操作我还不是特别清晰。

  • 指针: 从python这种不需要接触指针的语言转到c这种一直使用指针的语言,还是需要一个过渡的。幸亏大一的时候学C++,还算认真。基本上已经捡起来以前的东西了。只是始终没有使用完调用free的习惯,看来还需要培养。 因为指针出现的问题是这次训练中遇到的最多的问题。

调试

以上的都是在编码的过程中的一些总结。但是这显然不是最重要的,最重要的是:调试

如何定位错误是一个很重要的能力!

我目前使用打印信息调试,慢慢定位到错误断点。

调试方式有很多种:

  • 打印调试信息
  • gcc --debug + gdb
  • 使用eclipse等集成环境会让你调试爽一点哦。起码不需要一直面对黑框子。
  • 更多的我就不知道了。

我觉得我应该学习一下如何在bash中使用 gdb 进行调试。这是我以后要学习的知识之一,写代码不难,调试才难!因为出错是正常的。

总结

写一个程序其实就是在做一个产品

需要考虑到产品的功能,是否能够为用户创造价值。如何从无到有设计,实现一个功能,这个过程本身就是在做一个产品,只不过范围上比较小而已。在设计的时候不仅仅要考虑到产品的功能性,还要考虑到许多方面,比如与其他产品配合工作等等。我觉得这8道题给我的提升是非常大的!不仅仅是c语言方面,而是编码设计方面。更大的范围内,这次培训改变了我的思维模式。


Comments