最近做完了聊天室的项目(前两篇文章),C语言基础的学习阶段也算是告一段落了,但我对C语言还是只是一个入门,就像一个工具,我现在只是了解、会初步使用它了,但并没有达到如臂挥使的地步,今后还需要对C语言进行更深入的学习,今天我就讲一下我个人学到现在对C语言的认识,自己的理解,若有错误,还望指出,不甚感激。
首先是C语言整体的脉络,C语言包括哪些东西?哪些部分重要,哪些部分需要着重理解?这是我经常问自己的两个问题。
首先,C语言有哪些东西?C语言的东西其实并不是太多:
1、最基本的一些数据类型及其所占的内存大小、还有一些基础的计算机常识(进制转换等)。这些东西在对C语言有了一定的了解后都是比较容易的。
2、三种逻辑(顺序、选择和循环)
顺序语句就是从上到下没有判断,一步到底的语句。
选择语句就是if和switch语句,在特定的场合,switch语句使用会使程序看的简单明了,尤其是选择情况较多的时候。大多数时候if语句用的多一点。
循环语句就是while、do...while、和for语句,这三个do...while我用的不是太多,就不做评价了。while语句和for语句用的场合非常多,我说一下几个注意点:
a、在多层循环中,尽可能把最长的循环放在最外围,节省cpu的资源。
b、不能在循环体内修改循环变量,防止循环失控。
c、循环尽可能的短,太多行的循环代码会大大的影响阅读。解决方法:使用子函数处理
d、把循环嵌套控制在3层以内,超过三层,对代码的理解难度大大增加了。
e、for语句的控制表达式不能包含任何浮点类型的对象
还有就是break和continue语句,经常会有人问我,这两个关键字跳出的是什么,break是跳出离它最 近的一个循环(switch中的是跳出switch,不是跳出循环),continue也是一样。
3、数组和指针 数组我把它分为两个:普通数组和字符串,其中对字符串的操作就是C语言考核的最关键的一步,因为其涉及到了数组和指针,把字符串操作的很牛的人,他们对指针的理解一定很深。
普通数组:一维数组的内容不是太多,但是对算法的要求比较高,最基础的是一定要会冒泡和选择排序,这两种算法最基础,但也是在排序上用的最多的(如果会更好的算法的话另外谈),有兴趣的话可以对算法这一块深入研究(我还没有来得及研究算法,不是太懂)。二维数组的话,要理解其内存的分配情况,元素的存放顺序,会对二维数组进行输入输出,其他的,就是算法了,以后慢慢去研究去。
字符串:字符串这部分的话,因为C语言对字符串的操作不像c++那么容易,所以,要对指针和数组这块下一点功夫。最简单的就是将string.h库函数中的strlen,strcmp,strcpy,strcat,strncmp这几个函数自己实现一篇,使用指针的方式。
指针:当初老师讲指针的时候,说了一句,如果你把指针学会了,C语言你就掌握了70%。当初我还有些怀疑,现在的我十分赞同这句话。指针就是C语言的精华所在,C语言是一门软硬通吃的语言,归根到底就是这个指针的知识,他能直接操控底层。关于指针,我印象最深的是那个例子,*p 把p想象成小明家的门牌号,而*则是一把万能钥匙,*p代表的值就是小明本人,你可以把小明家的地址给别人,别人拿着*(万能钥匙)和p(小明家门牌号)就能去看小明本人,可以对小明本人进行操作。这个例子当时给我的印象非常深,那以后我感觉我对指针的理解顿时清楚了很多,非常感谢我的C语言启蒙老师,有了他的带领,我才能对C语言有深一步的理解。
4、函数 函数的话我感觉就是main函数的一个延伸,但它是可重复调用的,你可以把一些繁杂的步骤写到一个函数里面,这样main函数才不会显得太臃肿。函数最重要的就是它的格式,返回值+函数名+(形参)+函数体,其中有一个容易忽视的点就是,当形参是一个指针的时候,在函数开始时,要进行入口参数检查,就是对指针是否为空进行判断,要不然容易出现段错误。还有一个就是,如果一个函数在main函数下面,最好进行一下声明,虽说现在的编译器已经帮我们省略了这一步骤,但我们还是要养成良好的习惯,毕竟如果给你一个旧版本的编译器的话,就会报错。编译器的优化并不是我们偷懒的理由。不过我们也可以将函数写在main函数上方,这样的话就不需要考虑这个问题了。在函数这一部分,我在有些地方还是有很多不足之处,比如说递归函数和回调函数,递归函数涉及到一些算法,本人对算法还是不够了解,所以。。。还有回调函数接触的不多,到现在为止就接触到了一个sqlite3中的sqlite3_exec函数第三个参数为函数名的这种情况。
5、关键字
Static全局变量 作用范围局限于源文件,不可被源文件的其他文件使用
局部变量 局限于特定函数,出作用域不释放,函数结束后依然存在
函数 作用范围局限于源文件,不可被源文件的其他文件使用 函数名在其它文件不可见
const 这个关键字其实只要记住一局诗就行了,“近水楼台先得月”,最靠近const的那个就是不能变的。
extern 这个关键字一般用在.h头文件中,声明函数,不是本文件中的。
struct 结构体,包含多种数据类型的变量,在数据结构中经常用到,比如说:链表、栈和队列等
enum 枚举 和define的功能差不多,枚举和宏其实非常类似:宏在预处理阶段将名字替换成对应的值,枚举在编译阶段将名字替换成对应的值。
union 共用体,和结构体的结构差不多,但是结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员,一般用来测试系统的大小端。
到这边,C语言的内容其实就差不多了,除了其他一些零零碎碎的小知识点。但我学的是LinuxC,所以我还学了Linux进程和线程的管理,还有文件的操作以及Linux网络的编程。Linux网络的编程---搭建tcp协议的服务器 实际上就是那几个套路前两篇文章中的tcp_net_socket.c中已经整理好了。文件操作的话,Linux系统提供了一个文件描述符的机制,open之后对文件描述符进行read和write,而C语言则是fopen函数,返回一个指针,原理差不多,只不过C语言提供的fopen系列函数可以跨平台操作。线程和进程的话其实也没有多少内容(可能学的比较浅的缘故),太复杂的内容也没有接触到。线程中有一个东西要提一下,那就是同步和互斥的关系。其实也很好理解,打个比方,一扇门规定只能进一个人,这个时候来了10个人,如果没有秩序,一拥而上的话就是互斥,如果他们按照一定的规矩进行排队的话,那就是同步了,同步就是一种特殊的互斥。
想想应该差不多了,如果有漏掉了什么重要的东西的话,还希望读者能提示我一下,方便我改进改进。