`
abruzzi
  • 浏览: 444441 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

C和指针(续)

阅读更多

前言

上一篇《C和指针》可能对关于C和指针的有些内容没有说透,下来写了一个链表的实现,当然,也是用C的函数指针来模拟OO的结构来做的。链表结构本身比较复杂(关于指针的使用方面),所以这个例子可能更清晰一些。之所以选List这个例子来说,是因为大家在学校里肯定接触过这个简单数据结构,从一个比较熟悉的例子入手可能比较容易理解一些。

接口定义

可以先看看接口的定义,与Java或者C#类似:

/* 
 * File:   IList.h
 * Author: juntao.qiu
 *
 * Created on May 22, 2009, 2:51 PM
 
*/
 

#ifndef _ILIST_H
#define    _ILIST_H 


typedef 
struct node{
    
void *
data;
    
struct node *
next;
}Node; //定义List中的元素类型,void * 相当于C中的泛型,可以支持任何结构的节点

typedef 
struct
 list{
    
struct list *
_this;
    Node 
*
head;
    
int
 size;
    
void (*insert)(void *
node);
    
void (*drop)(void *
node);
    
void (*
clear)();
    
int (*
getSize)();
    
void* (*get)(int
 index);
    
void (*
print)();
}List; //用head (Node)来维护链表的链!

void insert(void *
node);
void drop(void *
node);
void
 clear();
int
 getSize();
void* get(int
 index);
void
 print(); 

#endif    /* _ILIST_H */ 

 

接口中定义所有的公开的方法,正如所有的List结构一样,我们定义了

void insert(node);//插入一个新的节点到List
void drop(node);//删除一个指定的节点
void clear();//清空List
int getSize();//取到List的大小
void* get(int index);//取到指定位置的元素
void print();//打印整个List,用于调试

 

这样几个方法。

接口的实现

然后看看实现,同上篇一样,引入一个标记链表自身的_this指针,通过对这个指针的引用来修改真实对象中的状态。

 

#include <stdlib.h>
#include 
"IList.h" 

Node 
*node =
 NULL;
List 
*list =
 NULL; 

/* 函数声明块,作用已经在上边解释了*/
void insert(void *node);
void drop(void *
node);
void
 clear();
int
 getSize();
void
 print();
void* get(int
 index); 

/* 构造方法 */
List 
*
ListConstruction(){
    list 
= (List*)malloc(sizeof
(List));
    node 
= (Node*)malloc(sizeof
(Node));
    list
->head =
 node;
    list
->insert =
 insert;
    list
->drop =
 drop;
    list
->clear =
 clear;
    list
->size = 0
;
    list
->getSize =
 getSize;
    list
->get = get
;
    list
->print =
 print;
    list
->_this =
 list; 

    
return (List*
)list;


void
 ListDeconstruction(){

//插入节点,size增加1
void insert(void *
node){
    Node 
*current = (Node*)malloc(sizeof
(Node));
    current
->data =
 node;
    current
->next = list->_this->head->
next;
    list
->_this->head->next =
 current;
    (list
->_this->size)++
;

//删除一个节点,size减1
void drop(void *
node){
    Node 
*= list->_this->
head;
    Node 
*=
 NULL;
    
int i = 0
;
    
for(i;i < list->_this->size;i++
){
        d 
= list->_this->head->
next;
        
if(d->data == ((Node*)node)->
data){
            list
->_this->head->next = d->
next;
            free(d);
            (list
->_this->size)--
;
            
break
;
        }
else
{
            list
->_this->head = list->_this->head->
next;
        }
    }
    list
->_this->head =
 t;

//取到指定index的节点
void* get(int
 index){
    Node 
*node = list->_this->
head;
    
int i = 0


    
if(index > list->_this->
size){
        
return
 NULL;
    }
else
{
        
for(i;i < index;i++
){
            node 
= node->
next;
        }
        
if(node != (Node*)0
){
            
return node->
data;
        }
else
{
            
return
 NULL;
        }
    }


void
 clear(){
    Node 
*node =
 NULL;
    
int i = 0
;
    
for(i;i< list->_this->size;i++
){
        node 
= list->_this->
head;
        list
->_this->head = list->_this->head->
next;
        free(node);
    }
    list
->_this->size = 0
;
    list 
=
 NULL;


int
 getSize(){
    
return list->_this->
size;

//调试用,像这种getSize(), print()这种调用,需要注意的是在调用过程中不能对原始指针做任何修改,
//否则可能出现无法预测的错误。
void
 print(){
    Node 
*node = list->_this->
head;
    
int i = 0
;
    
for(i;i <= list->_this->size;i++
){
        
if(node != (Node*)0
){
            printf(
"[%p] = {%s}\n",&node->data, node->
data);
            node 
= node->
next;
        }
    }
}

 

测试

/* 
 * File:   Main.c
 * Author: juntao.qiu
 *
 * Created on May 21, 2009, 4:05 PM
 
*/
 

#include 
<stdio.h>

#include 
<stdlib.h> 

s#include "IList.h" 

int main(int argc, char** argv) {

    List 
*list = (List*)ListConstruction();//构造一个新的list
    list
->insert("Apple"
);
    list
->insert("Borland"
);
    list
->insert("Cisco"
);
    list
->insert("Dell"
);
    list
->insert("Electrolux"
);
    list
->insert("FireFox"
);
    list
->insert("Google"
);//插入一些节点
    list
->
print();//查看是否插入正确
    printf(
"list size = %d\n",list->
getSize());
   
  //删除两个节点,并打印结果查看。
    Node node;
    node.data 
= "Electrolux"
;
    node.next 
=
 NULL;  
    list
->drop(&
node);
    node.data 
= "Cisco"
;
    node.next 
=
 NULL;
    list
->drop(&
node);

    list
->
print();
    printf(
"list size = %d\n",list->
getSize());
    list
->
clear(); 

    
return 0
;

 

运行结果
$./ooc
[
00489760= {Google}
[
00489730= {FireFox}
[
00489700= {Electrolux}
[004896D0] 
= {Dell}
[004896A0] 
= {Cisco}
[
00489670= {Borland}
[
00489640= {Apple}
list size 
= 7
[
00489760= {Google}
[
00489730= {FireFox}
[004896D0] 
= {Dell}
[
00489670= {Borland}
[
00489640= {Apple}
list size 
= 5

 

可以看出,程序正如预期的那样运行(前一项为节点在内存中的地址,后一项为节点的值),如果大家有兴趣,可以将上一篇《C和指针》s中的Executor装入一个List实现一个Executor的管理器,加入get方法,同时考虑多线程的状态,即可自己完成一个线程池的实现。

 

分享到:
评论

相关推荐

    C语言学习课件

    C1-简介 C2-运算符、表达式 C3-运算符、表达式(续) C4-基本语句、顺序结构 C5-选择结构 C6-循环结构 C7-循环结构(续) C8-数组 C9-字符数组 C10-结构体 ...C12-函数(续1) C13-函数(续2) C14-指针 C15-指针(续)

    16*16点阵C语言程序

    本程序介绍了利用指针写点阵程序的范例,在此策划给你续中能过得到启发,从而对以后学习168*64液晶有很好的帮助

    C语言 酒店管理系统VC6.0编辑

    前台续订4. 网上已订的客户办理入住手续5前台查询到期房6. 前台结账7. 退出系统 这是我们专周的题目 全是自己写的(本人的第一个程序) 因为没有学指针、数组、文件读取,所以全用的简单语句 大家见笑了

    Windows应用程序捆绑核心编程光盘代码

    13.2.3 FTP协议多线程下载和断点续传的实现 295 13.2.4 实例 306 13.3 使用HTTP进行多线程下载和断点续传 307 13.3.1 HTTP协议简介 307 13.3.2 HTTP协议的内部操作过程 308 13.3.3 HTTP协议多线程下载和断点续...

    OpenGL 库函数汇总(中文分类)CHM

    参数: c 指向一个由单个元素组成的数组指针 ,该数组中包含新的当前颜色索引值。 glIndexPointer 定义颜色索引数组 void glIndexPointer(GLenum type ,GLsizei stride ,GLsizei count ,const GLvoid *pointer...

    Portfolio:对于潜在的雇主

    维亚切斯拉夫·沙利 Vyacheslav Shalygin)档案袋, 你好! 我目前正在寻找工作,如果您能花点时间考虑我的候选人资格并查看我的投资组合,将不胜感激。... 此外,我还提供在完成在线IT课程(用C ++编程(续),

    TCP_IP详解卷1

    14.5 指针查询 150 14.5.1 举例 151 14.5.2 主机名检查 151 14.6 资源记录 152 14.7 高速缓存 153 14.8 用UDP还是用TCP 156 14.9 另一个例子 156 14.10 小结 157 第15章 TFTP:简单文件传送协议 159 15.1 引言 159 ...

    Java面试宝典和大学生面试宝典

    国企会问到技术问题,我就曾被问到如何在 C++中调用 C 程序、索引的分类等技术问题,回答基本上要靠平时的积累和对知识的 掌控能力。电话面试的具体内容可参见第 18 章。 3.3 面试 一个比较好的面试是能够问出求职...

    C#5.0本质论第四版(因文件较大传的是百度网盘地址)

    3.7 控制流语句(续) 84 3.7.1 while和do while循环 84 3.7.2 for循环 86 3.7.3 foreach循环 88 3.7.4 switch语句 90 3.8 跳转语句 92 3.8.1 break语句 92 3.8.2 continue语句 94 ...

    电子系统设计题目.doc

    C、其他自拟的无线系统(可2人一组) (2)测试测量类 A、姿态测量系统 采用MPU6050传感器模块(或其他传感器模块),采集刚性物体姿态,并在nokia51 10 LCD上,以图案和指针形式,显示方向、倾斜角度等信息。...

    C#微软培训资料

    18.2 在 C #代码中调用 C++和 VB 编写的组件 .240 18.3 版 本 控 制 .249 18.4 代 码 优 化 .252 18.5 小 结 .254 第五部分 附 录 .255 附录 A 关 键 字.255 附录 B 错 误 码.256 附录 C .Net 名字空间...

    计算机应用基础IV备课笔记.doc

    3、鼠标操作: (1)单击:单击左键 快速按下并释放鼠标左键 (2)单击右键:右键单击 快速按下并释放鼠标右键 (3)双击:双击左键 边续两次快速单击鼠标左键 (4)拖动:按住左键不放拖动鼠标 (5)指针 4、桌面...

    TCPIP详解卷[1].part04

    14.5 指针查询 150 14.5.1 举例 151 14.5.2 主机名检查 151 14.6 资源记录 152 14.7 高速缓存 153 14.8 用UDP还是用TCP 156 14.9 另一个例子 156 14.10 小结 157 第15章 TFTP:简单文件传送协议 159 15.1 引言 159 ...

    TCPIP详解卷[1].part09

    14.5 指针查询 150 14.5.1 举例 151 14.5.2 主机名检查 151 14.6 资源记录 152 14.7 高速缓存 153 14.8 用UDP还是用TCP 156 14.9 另一个例子 156 14.10 小结 157 第15章 TFTP:简单文件传送协议 159 15.1 引言 159 ...

    TCPIP详解卷[1].part03

    14.5 指针查询 150 14.5.1 举例 151 14.5.2 主机名检查 151 14.6 资源记录 152 14.7 高速缓存 153 14.8 用UDP还是用TCP 156 14.9 另一个例子 156 14.10 小结 157 第15章 TFTP:简单文件传送协议 159 15.1 引言 159 ...

    TCPIP详解卷[1].part05

    14.5 指针查询 150 14.5.1 举例 151 14.5.2 主机名检查 151 14.6 资源记录 152 14.7 高速缓存 153 14.8 用UDP还是用TCP 156 14.9 另一个例子 156 14.10 小结 157 第15章 TFTP:简单文件传送协议 159 15.1 引言 159 ...

    TCPIP详解卷[1].part06

    14.5 指针查询 150 14.5.1 举例 151 14.5.2 主机名检查 151 14.6 资源记录 152 14.7 高速缓存 153 14.8 用UDP还是用TCP 156 14.9 另一个例子 156 14.10 小结 157 第15章 TFTP:简单文件传送协议 159 15.1 引言 159 ...

    TCP/IP详解part_2

    14.5 指针查询 150 14.5.1 举例 151 14.5.2 主机名检查 151 14.6 资源记录 152 14.7 高速缓存 153 14.8 用UDP还是用TCP 156 14.9 另一个例子 156 14.10 小结 157 第15章 TFTP:简单文件传送协议 159 15.1 引言 159 ...

    TCPIP详解卷[1].part08

    14.5 指针查询 150 14.5.1 举例 151 14.5.2 主机名检查 151 14.6 资源记录 152 14.7 高速缓存 153 14.8 用UDP还是用TCP 156 14.9 另一个例子 156 14.10 小结 157 第15章 TFTP:简单文件传送协议 159 15.1 引言 159 ...

    TCPIP详解卷[1].part11

    14.5 指针查询 150 14.5.1 举例 151 14.5.2 主机名检查 151 14.6 资源记录 152 14.7 高速缓存 153 14.8 用UDP还是用TCP 156 14.9 另一个例子 156 14.10 小结 157 第15章 TFTP:简单文件传送协议 159 15.1 引言 159 ...

Global site tag (gtag.js) - Google Analytics