文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>C和指针(续)

C和指针(续)

时间:2010-07-19  来源:wangmanlivsli

                             草根编程http://www.caogenbiancheng.com

上一篇《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 *t = list->_this->head;
    Node *d = 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;
        }
    }
}

                                  草根编程http://www.caogenbiancheng.com

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载