头文件1.h

#pragma once
#include <windows.h>
class CSimpleList
{
public:CSimpleList(int nNextOffset = 0);void Construct(int nNextOffset);// 提供给用户的接口函数(Operations),用于添加、删除和遍历节点BOOL IsEmpty() const;void AddHead(void* p);void RemoveAll();void* GetHead() const;void* GetNext(void* p) const;BOOL Remove(void* p);// 为实现接口函数所需的成员(Implementation)void* m_pHead;         // 链表中第一个元素的地址size_t m_nNextOffset; // 数据结构中pNext成员的偏移量void** GetNextPtr(void* p) const;
};// 类的内联函数
inline      CSimpleList::CSimpleList(int nNextOffset){ m_pHead = NULL; m_nNextOffset = nNextOffset; }
inline void CSimpleList::Construct(int nNextOffset){ m_nNextOffset = nNextOffset; }
inline BOOL CSimpleList::IsEmpty() const{ return m_pHead == NULL; }
inline void CSimpleList::RemoveAll(){ m_pHead = NULL; }
inline void* CSimpleList::GetHead() const{ return m_pHead; }
inline void* CSimpleList::GetNext(void* preElement) const{ return *GetNextPtr(preElement); }
inline void** CSimpleList::GetNextPtr(void* p) const{ return (void**)((BYTE*)p + m_nNextOffset); }void CSimpleList::AddHead(void* p)
{*GetNextPtr(p) = m_pHead;m_pHead = p;
}BOOL CSimpleList::Remove(void* p)
{if(p == NULL)    // 检查参数return FALSE;BOOL bResult = FALSE; // 假设移除失败if(p == m_pHead){// 要移除头元素m_pHead = *GetNextPtr(p);bResult = TRUE;}else{// 试图在表中查找要移除的元素void* pTest = m_pHead;while(pTest != NULL && *GetNextPtr(pTest) != p)pTest = *GetNextPtr(pTest);// 如果找到,就将元素移除if(pTest != NULL){*GetNextPtr(pTest) = *GetNextPtr(p);bResult = TRUE;}}return bResult;
}template<class TYPE>
class CTypedSimpleList : public CSimpleList
{
public:CTypedSimpleList(int nNextOffset = 0) : CSimpleList(nNextOffset){}void AddHead(TYPE p)  { CSimpleList::AddHead((void*)p);       }TYPE GetHead()         { return (TYPE)CSimpleList::GetHead();  }TYPE GetNext(TYPE p)   { return (TYPE)CSimpleList::GetNext(p); }BOOL Remove(TYPE p)        { return       CSimpleList::Remove(p);  }operator TYPE()            { return (TYPE)CSimpleList::GetHead();  }
};

实现文件1.cpp

#include <stdio.h>
#include <STDDEF.H>
#include "Demo01.h"struct CThreadData
{CThreadData* pNext; // CSimpleList类要使用此成员int nCount;           // 数组元素的个数LPVOID* pData;      // 数组的首地址CThreadData(){}
};void main()
{CTypedSimpleList<CThreadData*> m_list;   // CThreadData结构的列表m_list.Construct(offsetof(CThreadData, pNext));//    int x=0x40001111;//    int *y=&x;CThreadData* pData = NULL;for(int i=0;i<10;i++)       {pData=new CThreadData;//      pData->pNext=NULL;//        pData->nCount=15;//         pData->pData=(void**)&y;m_list.AddHead(pData);}m_list.Remove(pData);}

指针的指针的实际使用例子相关推荐

  1. 指针数组下标JAVA_C语言中下标与指针的转换以及指向指针的指针的例子

    下标到指针之间和转换以下的程序做了什么. #include int main() { int a[3][3] = {{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}; int i = ...

  2. 关于C语言中的数组指针、指针数组以及二级指针

    概念解释 数组指针:首先它是一个指针,它指向一个数组,即指向数组的指针:在32 位系统下永远是占4 个字节,至于它指向的数组占多少字节,不知道.数组指针指向的是数组中的一个具体元素,而不是整个数组,所 ...

  3. 函数指针与指针函数的区别

    原文:http://yliangliang.blog.sohu.com/86320000.html 一.函数指针 首先它是一个指针,只是这个指针指向的是一个函数.指针变量可以指向变量的地址.数组.字符 ...

  4. 初论函数指针、指针函数、指针的指针

    一.指针函数 1.定义 指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某一类型的指针 函数返回值类型 函数名(参数表) int * f(int x,int y); //函数返回值类型是in ...

  5. (转)数组指针和指针数组的区别

    数组指针(也称行指针) 定义 int (*p)[n]; ()优先级高,首先说明p是一个指针,指向一个整型的一维数组,这个一维数组的长度是n,也可以说是p的步长.也就是说执行p+1时,p要跨过n个整型数 ...

  6. 指针数组,数组指针,指针函数,函数指针,二级指针详解

    先看个简单的:char *p,这定义了一个指针,指针指向的数据类型是字符型,char  *(p)定义了一个指针P: char *p[4], 为指针数组,由于[]的优先级高于*,所以p先和[]结合,p[ ...

  7. 【C 语言】指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读)

    相关文章链接 : 1.[嵌入式开发]C语言 指针数组 多维数组 2.[嵌入式开发]C语言 命令行参数 函数指针 gdb调试 3.[嵌入式开发]C语言 结构体相关 的 函数 指针 数组 4.[嵌入式开发 ...

  8. (C/C++学习)6.数组指针和指针数组

    说明:int (*p)[4] 和 int *p[4](数组指针和指针数组),如果你是一个初学者,也许当你看到这两个名词的时候,已经懵了.其实,只要你理解了其中的含义.这两个名词对你来说会相当简单并且很 ...

  9. C语言什么时候必须用到二级指针?(需要调用函数为一维空指针确定值的情况下,需要传入二维指针,也就是那个一维指针的指针)

    结论:需要调用函数为一维空指针确定值的情况下,需要传入二维指针,也就是那个一维指针的指针 例子:为空指针p开辟内存空间 1.不用二级指针(无法实现) #include <stdio.h> ...

  10. 关于“指针的指针”的认识(值传递、指针传递区分)

    [摘要]对于C语言的参数传递通常都是值传递,当传传递一个指针给函数的时,其实质上还是值传递.我们可以看以下常见的面试题: #include <stdio.h> #include <s ...

最新文章

  1. 分布式之elk日志架构的演进
  2. XML序列化以及新增节点XMLHelper
  3. 一个毕业生初入社会的历程 (四)一次简单的面试...
  4. malloc()之后free报错的原因[详细解析]
  5. mysql 符_mysql命令操作符
  6. python扫雷的代码及原理_基于Python实现的扫雷游戏实例代码
  7. java 万年历_非常实用的java万年历制作方法
  8. 自动论文生成器 python_Python生成器常见问题及解决方案
  9. 数据结构之图的应用:最短路径(Dijkstra、Floyd)
  10. 使用ASP.NET核心应用程序实现存储库模式和工作单元的指南
  11. 抽象工厂模式_设计模式3之抽象工厂模式
  12. 数学四大思想八大方法_高中数学八种思维方法如何训练数学思维,高中数学的四大思想是什么?...
  13. 使用虚拟机镜像文件导入部署openGauss
  14. mapabc 国人推荐
  15. c语言爬楼梯不用递归,[leetcode]爬楼梯的递归和非递归方法
  16. asp网站如何设置默认页_IIS 7.5 在 Windows Server(R) 2008 R2
  17. python:判断3个数不相等
  18. Windows桌面图片打开慢的原因 wyz_csdn
  19. Android LBS
  20. APR协议及RARP协议

热门文章

  1. 软件测试bug文档模板,国家标准测试计划文档模板
  2. 我php第一个页面,您的第一个 PHP 页面
  3. android 百叶窗动画,android 幻灯片效果之百叶窗
  4. mysql 数据约束条件_mysql基本数据类型和约束条件
  5. ARM处理器与架构对应关系
  6. Vue.js 条件与循环
  7. 网络编程---tcp/udp协议
  8. PHPer 面试指南-扩展阅读资源整理
  9. 超融合带来的IT人员问题 企业是否看到?
  10. AndroidAnnotations说明—AndroidAnnotations它是如何工作的?