发 帖  
原厂入驻New

[经验] 朱兆祺教你如何攻破C语言学习、笔试与机试的难点(连载)

2013-7-31 08:47:54  184411 C语言 C语言 C语言 C语言 C语言
分享
341
本帖最后由 zzq宁静致远 于 2014-2-27 19:42 编辑

    再过1个月又是一年应届毕业生应聘的高峰期了,为了方便应届毕业生应聘,笔者将大学四年C语言知识及去年本人C语言笔试难点进行梳理,希望能对今年应届毕业生的应聘有所帮助。

2013年10月18日更新-->    攻破C语言这个帖子更新到这里,我不仅仅是为了补充大学学生遗漏的知识,我更重要的是希望通过我的经验,你们实际项目中的C语言写得漂亮,写出属于你的风格。“朱兆祺STM32手记”(http://bbs.elecfans.com/jishu_385613_1_1.html)一帖中我就多次强调过编程的模块化,要考虑到可移植性和别人的可阅读性。我在某公司实习的时候,拿到一个程序,我当时就想吐槽,我想除了这个程序的当时写作者能够看懂之外,其他人有谁还能看懂,程序构架、可移植性性就更是一塌糊涂。结果我全部推到重写。因此明志电子科技工作室从承接第一个项目做开始,我便和搭档说,我们必须制定我们工作室的编程规范和编程风格,这样就算给谁,换成谁,拿到项目都能马上接下去做。
    朱兆祺在这个帖子将会不断更新,明志电子工作室的项目经验也将在电子发烧友论坛不断贴出,我希望能用我们仅有的力量,将我们的经验毫不保留传授给大家。我只希望在未来某一天,有那么几个人会竖着大拇指说:明志电子科技工作室的经验受益匪浅就够了。我相信,在深圳,明志电子科技工作室的影响力会日益增长,因为我们已经规划好了未来脚步。
    C语言是一门技术,但更是一门艺术。写一个c语言代码不难,写一个高水平、漂亮的代码很难。朱兆祺将在此帖不断为大家攻破C语言。

<--朱兆祺于2013年10月18日

-->朱兆祺更新于2014年2月21日:
    深圳市馒头科技有限公司于2014年2月注册成立,当初命名为馒头科技,不管是吴坚鸿所说亲切还是谢贤斌所说草根。馒头科技永远以用户满意为我们的追求,馒头科技不追求锦上添花,但是我们很愿意为每一位客户雪中送炭。因为锦上添花每一个人都会做,但是雪中送炭却不是每一个人愿意去做。
    馒头科技往后将为每一位读者送上更为精美的学习资料。敬请期待。



第一节  C语言编程中的几个基本概念
http://bbs.elecfans.com/jishu_354666_1_1.html

第二节  数据存储与变量
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088253&fromuid=222350

第三节  数学算法解决C语言问题
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088283&fromuid=222350

第四节  关键字、运算符与语句
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088352&fromuid=222350

第五节    C语言中的细节
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088375&fromuid=222350

第六节  数组与指针
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088417&fromuid=222350

第七节  结构体与联合体
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088582&fromuid=222350

第八节  内存分配与内存释放
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088596&fromuid=222350

第九节   笔试中的几个常考题
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2088606&fromuid=222350

第十节  数据结构之冒泡排序、选择排序
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2092632&fromuid=222350

第十一节   机试题之数据编码
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2096393&fromuid=222350

第十二节  机试题之十进制1~N的所有整数中出现“1”的个数
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2097513&fromuid=222350

第十三节  机试题之  遍历单链表一次,找出链表中间元素
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2103563&fromuid=222350

第十四节  机试题之全排序
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2105648&fromuid=222350


第十五节 机试题之大整数运算
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2109737&fromuid=222350


第十六节  机试题之大整数减法与乘法
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2115675&fromuid=222350

第十七节  算法之二分查找
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2128027&fromuid=222350

第十八节  数据结构之单向链表(颠覆你手中数据结构的三观)
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2139670&fromuid=222350

第十九节  数据结构之双向链表(接着颠覆你手中的数据结构三观)
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2156978&fromuid=222350

第二十节 数据结构之栈
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2193337&fromuid=222350


C语言技术公开课第一讲——编译环境给C语言带来的困扰,网络课程讲义
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2230571&fromuid=222350

第二十一节  通过加减法高效的求出两个无符号整数的商和余数
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2252461&fromuid=222350

第二十二节  表达式计算器(1)
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2280837&fromuid=222350

第二十三节  表达式计算器(2)
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2325485&fromuid=222350

第二十四节  表达式计算器(3)
http://bbs.elecfans.com/forum.ph ... 4547&fromuid=222350

第二十五节  表达式计算器(4)
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2395966&fromuid=222350

C语言技术公开课第三讲  const问题
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2434706&fromuid=222350

第二十六节  序列差最小
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2466868&fromuid=222350

第二十七节  sizeof与strlen的深入
http://bbs.elecfans.com/forum.php?mod=redirect&goto=findpost&ptid=354666&pid=2676569&fromuid=222350

第二十八节  C与C++中的const

第二十九节 do、while
第三十节 变量的生命周期

第一节  C语言编程中的几个基本概念
1.1      include< >与#include" "


1.   #include< >和#include" "有什么区别
这个题目考查大家的基础能力,#include< >用来包含开发环境提供的库,
#include" "用来包含.c/.cpp文件所在目录下的头文件。注意:有些开发环境可以在当前目录下面自动收索(包含子目录),有些开发环境需要指定明确的文件路径名。
1.2      switch()
1.   switch(c) 语句中 c 可以是 int, long, char, float, unsigned int 类型?
其实这个题目很基础,c应该是整型或者可以隐式转换为整型的数据,很明显不能是实型(float、double)。所以这个命题是错误的。
1.3      const
1.   const有什么用途?
虽然const很常用,但是我相信有很多人仍然答不上来。
(1) 欲阻止一个变量被改变,可以使用const 关键字。在定义该 const 变量时,通常需要对它进行初 始化,因为以后就没有机会再去改变它了;
(2) 对指针来说,可以指定指针本身为 const,也可以指定指针所指的数据为 const,或二者同时指定为 const;
(3) 在一个函数声明中,const 可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4) 对于类的成员函数,若指定其为 const 类型,则表明其是一个常函数,不能修改类的成员变量;
(5) 对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。
1.4      #IFndef/#define/#endif
1.   头文件中的 #ifndef/#define/#endif 干什么用?
其实#ifndef、#define、#endif这些在u-boot、linux内核文件中经常见到,在这么大型的程序中大量使用,可见它的作用不可小觑。
这些条件预编译多用于对代码的编译控制,增加代码的可裁剪性,通过宏定义可以轻松的对代码进行裁剪。
#ifndef/#define/#endif最主要的作用是防止头文件被重复定义。
1.5      全局变量和局部变量
1.         全局变量和局部变量在内存中是否有区别?如果有,是什么区别?
全局变量储存在静态数据库,局部变量在堆栈。 其实,由于计算机没有通用数据寄存器,则函数的参数、局部变量和返回值只能保存在堆栈中。提示:局部变量太大可能导致栈溢出,所以建议把较大数组放在main函数外,防止产生栈溢出。
思考:如程序清单1. 1所示。会出现怎样的情况?
程序清单1. 1  大数组放在main函数中导致堆栈溢出
int main(int argc, char *argv[])
{
    int iArray[1024 * 1024];
    return 0;
}






评分

参与人数 3威望 +7 +7 积分 +10 收起 理由
eminjie + 2 + 2
A670521546 + 5 + 5 很精彩,期待您更多的分享
冰葑世纪 + 5 + 5 您的付出是论坛的动力,感谢您一直支持!.

查看全部评分

zzq宁静致远 2013-8-16 15:25:20

学长二字承担不起
回复

举报

zzq宁静致远 2013-8-16 15:27:09
Naga1991 发表于 2013-8-15 08:35
确实不错啊看了一下   有基础  都是单片机所用的基础知识 很不错

你若能吃透我所写,单片机C语言编程绝对没有问题
回复

举报

zzq宁静致远 2013-8-16 15:28:46

有问题可以QQ联系我,每个人这样叫我发实在难以操作,抱歉
回复

举报

zzq宁静致远 2013-8-16 15:29:52
mikeboy 发表于 2013-8-15 15:42
谢谢楼主,很好的讲解,麻烦发一份给我好吗?

有问题可以QQ联系我,每个人这样叫我发实在难以操作,抱歉
回复

举报

TTki_gavinkk 2013-8-16 16:12:09
感谢分享。。顶一个。。
回复

举报

唯一很无敌 2013-8-16 17:24:23
还是没有过呀{:16:}
回复

举报

szlaosong 2013-8-16 17:50:36
看看,学习一下,谢谢楼主分享
回复

举报

Desire伪装 2013-8-17 09:06:32
{:12:}{:12:}顶起来
回复

举报

caicxz 2013-8-17 09:21:30
不错, 学习一下, 谢谢不错, 学习一下, 谢谢{:3:}{:3:}{:3:}{:3:}
回复

举报

andyyau 2013-8-17 09:59:27
楼主人才,期望楼主能多多提携指点我们这些菜鸟。
回复

举报

士多啤梨 2013-8-17 13:58:45
好好啊,多谢楼主
回复

举报

Leslie〜 2013-8-17 19:39:05
赞一个,非常感谢
回复

举报

liuxxiangfei 2013-8-17 21:34:52
收藏,很好
回复

举报

xxin@mao 2013-8-17 23:25:17
谢谢分享,先收藏,备用。
回复

举报

雨萱 2013-8-18 22:45:15
学习交流-------------------------------------------------------------------很不错
回复

举报

Leslie〜 2013-8-19 07:58:52
很好。收藏啦。
回复

举报

Leslie〜 2013-8-19 08:32:21
很好。收藏啦。
PCB打样找华强 http://www.hqpcb.com 样板2天出货
回复

举报

zzq宁静致远 2013-8-19 09:23:47
第十九节  数据结构之双向链表
在单向链表中,获取当前节点的下一个节点,即可使用ptr = ptr->next,但是如果要获取当前节点的上一个节点,则需要重新遍历一次链表。但是如果有指向上一个节点的指针,ptr = ptr->befor ,这样即可获取当前节点的上一个节点。虽然增加了空间上的执行,但是时间效率却提高了,这也算是以空间换时间的一种方法吧。其实老子在《道德经》中就多次提到时间和空间的置换,两者在一定条件下是要互相变通。
每一个节点应该保存的数据,有数据指针、指向下一个节点的指针、指针上一个节点的指针。
/* 双向链表节点数据结构 */
typedef struct _DoubleListNode {
         void                   *pData ;            //数据指针,用于保存链表元素的个数
         struct _DoubleListNode   *pNext ;            //指向下一个节点的指针
         struct _DoubleListNode   *pPrev ;            //指向前一个节点的指针
} DoubleListNode , *POSITION;
相对于总个链表,肯定需要一个头节点,让头节点的pNext指向第一个节点,而头节点的pPrev指向最后一个节点,而第一个节点的pPrev和最后一个节点的pNext都是指向头节点,这样就形成了循环链表。如果将头节点的的数据域空间用来存储链表节点的个数,这样我们就能明了链表的长度。

1.1      创建链表
/******************************************************************************
** 函数名称: ListCreate
** 函数功能: 创建链表函数
                             该函数虽然有一个参数,为函数指针,但是在创建函数中并不调用它,
                             而仅仅是保存它。这种保存而不调用回调函数的方法也叫注册回调函数。
                             如果不需要销毁元素,则只需要传入NULL即可。
** 入口参数: DestroyFunc
** 出口参数: 如果创建失败,则返回NULL;成功则返回一个双向链表结构体的指针
******************************************************************************/
LIST *ListCreate(DESTROYFUNC DestroyFunc)
先开辟一个链表结构体空间,同时为头节点的所有成员初始化,初始状态下,pNextpPrev都是指向本身,头节点的数据域用来保存节点个数。
LIST  *pList ;
         pList = (LIST *)malloc(sizeof(LIST)) ;       //申请存储空间,建立头结点
         if (pList) {
                   /* 初始时,头结点两个指针都指向头结点本身 */
                   pList->nodeHead.pNext  =  &(pList->nodeHead) ;
                   pList->nodeHead.pPrev  =  &(pList->nodeHead) ;
                   pList->nodeHead.pData  =  0 ;              //初始时节点个数为0
                   pList->DestroyFunc     =  DestroyFunc ;    //注册销毁函数
         }
return pList ;                                   //返回链表结构体的指针

1.1.1   获取链表第一个节点位置
/******************************************************************************
** 函数名称: ListGetBegin
** 函数功能: 获取链表第一个节点的位置
** 入口参数: pList:要操作的双向链表指针
** 出口参数: pList->nodeHead.pNext:返回头结点指针
******************************************************************************/
POSITION ListGetBegin( PLIST pList )
{
         assert(pList) ;
         return (pList->nodeHead.pNext) ;
}
1.1.2   获取链表最后一个节点的下一个节点位置
/******************************************************************************
** 函数名称: ListGetEnd
** 函数功能: 获取链表最后一个节点的下一个节点的位置
** 入口参数: pList:要操作的双向链表指针
** 出口参数: &(pList->nodeHead):返回最后一个节点的下一个节点地址
******************************************************************************/
POSITION ListGetEnd( PLIST pList )
{
         assert(pList) ;
         return (&(pList->nodeHead)) ;
}
1.1.3   获取链表的元素个数
/******************************************************************************
** 函数名称: ListGetSize
** 函数功能: 获取链表元素的个数
** 入口参数: pList:要操作的双向链表指针
** 出口参数: (unsigned int)(pList->nodeHead.pData):返回链表个数
******************************************************************************/
unsigned int ListGetSize( PLIST pList )
{
         assert(pList) ;
         return ( (unsigned int)(pList->nodeHead.pData) ) ;
}
1.1.4   由位置获取数据的值
/******************************************************************************
** 函数名称: ListGetData
** 函数功能: 由位置获取数据的值
** 入口参数: pList:要操作的双向链表指针
              pos  :待插入节点的位置指针
** 出口参数:
******************************************************************************/
DATATYPE ListGetData( PLIST pList , POSITION pos )
{
         assert(pList) ;
         assert(pos)   ;
         return (pos->pData) ;
}

1.1      插入节点1.1.1   将数据插入到指定位置
要想将数据data插入到双向链表中,则必须先为待插入数据data的节点申请存储空间,并且建立指向该节点的指针pNewNode,用于 存储新节点的地址。
/******************************************************************************
** 函数名称: ListInsert
** 函数功能: 将数据插入到链表的指定位置函数
** 入口参数: pList:要操作的双向链表指针
              pos  :为待插入节点的位置指针
                            data :为待插入节点的数据指针
** 出口参数: 如果失败,则返回FALSE;如果成功则返回TRUE
******************************************************************************/
BOOL ListInsert( PLIST pList , POSITION pos , DATATYPE data )
插入节点第一步,为待插入数据data的节点申请存储空间;并将data数据存储在新建节点的数据域。
DoubleListNode *pNewNode ;
         unsigned int uiTemp = 0 ;
         assert(pList) ;
         assert(pos)   ;
         pNewNode = (DoubleListNode *)malloc(sizeof(DoubleListNode)) ;
pNewNode->pData   = data ;  

插入节点第二步,将待插入节点的前向指针指向pos所指向的节点。
pNewNode->pPrev   = pos  ;
插入节点第三步,将待插入节点的后向指针指向pos指向的下一个节点。
pNewNode->pNext   = pos->pNext ;
插入节点第四步,pos指向节点的下一节点的前向指针指向pNewNode。
pos->pNext->pPrev = pNewNode ;
插入节点第五步,pos指向节点的后向指针pNewNode。
pos->pNext        = pNewNode ;

uiTemp = ((unsigned int)(pList->nodeHead.pData)) ;
         uiTemp++ ;
         (pList->nodeHead.pData) = ( void * ) uiTemp ;
    return TRUE ;
成功插入节点后,链表的节点数要加1,返回成功插入的标志。

1.1.1   将数据插入到链表头成为第一个节点
也就是说吃插入在头结点后面,成为第一个节点。那么同样要知道头节点的地址,即为&pList->nodeHead。
/******************************************************************************
** 函数名称: ListPushFront
** 函数功能: 将数据插入到链表头函数
** 入口参数: pList:要操作的双向链表指针
                            data :为待插入节点的数据指针
** 出口参数: 如果失败,则返回FALSE;如果成功则返回TRUE
******************************************************************************/
BOOL ListPushFront( PLIST pList , DATATYPE data )
{
         return (ListInsert(pList , &(pList->nodeHead) ,data)) ;
}
1.1.2   将数据插入到链表尾成为最后一个节点
这里我们可以调用上面函数实现,只要我们知道链表尾的地址和待插入的数据,我们就能将数据插入到链表尾。链表最后一个节点的地址即为头结点的前向指针pList->nodeHead.pPrev。由于上面返回值只有TRUE和FALSE。则函数类型可以定义为BOOL型。
/******************************************************************************
** 函数名称: ListPushBack
** 函数功能: 将数据插入到链表尾函数
** 入口参数: pList:要操作的双向链表指针
                            data :为待插入节点的数据指针
** 出口参数: 如果失败,则返回FALSE;如果成功则返回TRUE
******************************************************************************/
BOOL ListPushBack( PLIST pList , DATATYPE data )
{
         return (ListInsert(pList , (pList->nodeHead.pPrev) , data)) ;
}
1.2      删除节点1.2.1   删除指定位置的节点
/******************************************************************************
** 函数名称: ListErase
** 函数功能: 删除指定位置节点函数
** 入口参数: pList:要操作的双向链表指针
                            data :为待插入节点的数据指针
** 出口参数: 如果失败,则返回FALSE;如果成功则返回TRUE
******************************************************************************/
BOOL ListDelete( PLIST pList , POSITION pos )
将指向待删除节点的两个指针重新指向即可,先判断待删除节点是否为头节点。
unsigned int   uiTemp = 0 ;
         assert(pList) ;
         /* 不允许删除头节点 */
         assert( pos && (pos != &(pList->nodeHead)) ) ;

让(pos指向节点的前一个节点的后向指针)指向(pos指向节点的下一个节点)。
pos->pPrev->pNext = pos->pNext ;
让(pos指向节点的后一个节点的前向指针)指向(pos指向节点的前一个节点)。
pos->pNext->pPrev = pos->pPrev ;
如果用户定义了销毁函数,则执行调用销毁函数。然后释放待删除节点所占的空间。
if (pList->DestroyFunc) {
                   pList->DestroyFunc(pos->pData) ;         
         }
3. 11  free(pos)
         free(pos) ;
成功删除节点后,链表节点数要减1,并且返回TRUE。
uiTemp = ((unsigned int)(pList->nodeHead.pData)) ;
         uiTemp++ ;
         (pList->nodeHead.pData) = (void *)uiTemp ;
         return TRUE ;
1.1.1   删除链表头节点后的节点(即第一个节点)
只要知道第一个节点的地址即可调用上面函数删除第一个节点。而第一个节点的地址为:pList->nodeHead.pNext。
/******************************************************************************
** 函数名称: ListPopFront
** 函数功能: 删除链表头节点函数
** 入口参数: pList:要操作的双向链表指针
** 出口参数: 如果失败,则返回FALSE;如果成功则返回TRUE
******************************************************************************/
BOOL ListPopFront( PLIST pList )
{
         return ( ListDelete(pList , (pList->nodeHead.pNext)) ) ;
}
1.1.2   删除链表的尾节点
尾节点地址为:pList->nodeHead.pPrev。
/******************************************************************************
** 函数名称: ListPopBack
** 函数功能: 删除链表尾节点函数
** 入口参数: pList:要操作的双向链表指针
** 出口参数: 如果失败,则返回FALSE;如果成功则返回TRUE
******************************************************************************/
BOOL ListPopBack( PLIST pList )
{
         return ( ListDelete(pList , (pList->nodeHead.pPrev)) ) ;
}
1.2      按值搜索位置算法
从第一个节点开始搜索,直到搜索到数据域为data的节点为止;如果从第一个节点搜索到最后一个节点都没有搜索到数据域为data的节点,则返回NULL。
/******************************************************************************
** 函数名称: ListFind
** 函数功能: 搜索算法函数
** 入口参数: pList:要操作的双向链表指针
              data :要查找的匹配数据
                            CompareFunc:数据匹配比较函数
** 出口参数:
******************************************************************************/
POSITION ListFind( PLIST pList , DATATYPE data , COMPAREFUNC CompareFunc )
{
         DoubleListNode *pNode , *pEndNode ;
         assert(pList) ;
         pNode    = ListGetBegin(pList) ;                //获取第一个节点位置
          pEndNode = ListGetEnd(pList)   ;                //获取最后一个节点的下一个节点位置
         /* 从头到尾开始找 */
         while (pNode != pEndNode) {
                   /* 如果找到则返回 */
                   if ( 0 == CompareFunc((pNode->pData),data) ) {
                       return pNode ;
                   }
        pNode = pNode->pNext ;
         }
         return (NULL) ;
}


1.1      遍历算法
这个函数主要是在遍历双向链表的同时要对每一个节点进行怎么样的操作,这个操作由用户自己决定,入口参数只是给定了一个函数指针TRAVERSEFUNC,由用户自己调用。
/******************************************************************************
** 函数名称: ListTraverse
** 函数功能: 遍历算法函数
** 入口参数: pList:要操作的双向链表指针
              TraverseFunc:节点数据的遍历操作函数
** 出口参数: 如果失败,则返回 0 ;如果成功则返回 1
******************************************************************************/
void ListTraverse( PLIST pList , TRAVERSEFUNC TraverseFunc )
{
         DoubleListNode *pNode , *pEndNode ;
         assert(pList) ;
         pNode    = ListGetBegin(pList) ;             //获取第一个节点的位置
         pEndNode = ListGetEnd(pList) ;               //获取最后一个节点的下一个节点位置
         /* 从头到尾开始遍历 */
         while (pNode != pEndNode) {
                   TraverseFunc(pNode->pData) ;             //访问数据
         }
}
1.2      销毁链表
从最后一个节点开始逐个删除节点,一直到头结点为止。最后再释放掉链表所占空间。
/******************************************************************************
** 函数名称: ListDestroy
** 函数功能: 销毁链表函数
** 入口参数: pList:要释放的双链表指针
** 出口参数: void
******************************************************************************/
void ListDestroy( PLIST pList )
{
         assert(pList) ;
         while( 0 != ListGetSize(pList) ) {
                   ListPopBack(pList) ;                     //删除链表尾节点
         }
         free(pList) ;                                //释放节点所占的空间
}
回复

举报

wangxiang8889 2013-8-19 09:56:16
很好。收藏ll了
回复

举报

zzq宁静致远 2013-8-19 10:17:37
andyyau 发表于 2013-8-17 09:59
楼主人才,期望楼主能多多提携指点我们这些菜鸟。

不是每个人生下来就是老鸟,都是从菜鸟走过来的,关键在于你是否抓住机会,将菜鸟变成老鸟这个阶段压缩到尽可能短。有问题可以QQ向我提出。
回复

举报

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

发经验
关闭

站长推荐 上一条 /10 下一条

快速回复 返回顶部 返回列表