是时候创建新的智能指针了!


Pointer.h
SmartPointer.h




由于SharedPointer支持多个对象同时指向一片堆空间;因此,必须支持比较操作!
- #ifndef SHAREDPOINTER_H_
- #define SHAREDPOINTER_H_
- /*******************************************************************************
- * Include _Files *
- *******************************************************************************/
- #include <cstdlib>
- #include "Pointer.h"
- #include "Exception.h"
- /*******************************************************************************
- * Type Definition *
- *******************************************************************************/
- namespace DTLib
- {
-
- template < typename T >
- class SharedPointer : public Pointer<T>
- {
- protected:
- int* m_ref; // 计数机制成员指针
-
- // 获取当前的智能指针地址、计数变量地址、计数变量 +1
- void assign(const SharedPointer<T>& obj)
- {
- this->m_ref = obj.m_ref; // 获取共用的计数变量地址
- this->m_pointer = obj.m_pointer; // 获取共用的堆空间地址
-
- if( this->m_ref )
- {
- (*this->m_ref)++; // 计数变量 +1
- }
- }
-
- public:
- // 构造函数
- SharedPointer(T* p = NULL) : m_ref(NULL)
- {
- if( p )
- {
- this->m_ref = static_cast<int*>(std::malloc(sizeof(int))); // 申请计数变量堆空间
-
- if( this->m_ref )
- {
- *(this->m_ref) = 1; // 计数变量 +1
- this->m_pointer = p; // 获取p对应的堆空间
- }
- else
- {
- THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create SharedPointer object ...");
- }
- }
- }
-
- SharedPointer(const SharedPointer<T>& obj) : Pointer<T>(NULL)
- {
- assign(obj); // 获取当前的智能指针地址、计数变量地址、计数变量 +1
- }
-
- SharedPointer<T>& operator= (const SharedPointer<T>& obj)
- {
- if( this != &obj )
- {
- clear(); // 让当前的智能指针置空,计数变量 -1
- assign(obj); // 获取当前的智能指针地址、计数变量地址、计数变量 +1
- }
-
- return *this;
- }
-
- // 让当前的智能指针置空,计数变量 -1
- void clear()
- {
- T* toDel = this->m_pointer;
- int* ref = this->m_ref;
-
- this->m_pointer = NULL; // 智能指针指向的堆空间地址 置 NULL
- this->m_ref = NULL; // 智能指针指向的计数变量地址 置 NULL
-
- if( ref )
- {
- (*ref)--; // 计数变量 -1
-
- if( *ref == 0 ) // 计数变量为 0
- {
- free(ref); // 释放共用的计数变量的堆空间
-
- delete toDel; // 释放共用的堆空间
- }
- }
- }
-
- ~SharedPointer()
- {
- clear(); // 让当前的智能指针置空,计数变量 -1
- }
- };
-
- // 支持比较操作 智能指针地址 <==> 智能指针地址 <==> 类对象地址
- template < typename T >
- static bool operator == (const T* l, const SharedPointer<T>& r)
- {
- return (l == r.get());
- }
-
- template < typename T >
- static bool operator != (const T* l, const SharedPointer<T>& r)
- {
- return (l != r.get());
- }
-
- template < typename T >
- static bool operator == (const SharedPointer<T>& l, const T* r)
- {
- return (l.get() == r);
- }
-
- template < typename T >
- static bool operator != (const SharedPointer<T>& l, const T* r)
- {
- return (l.get() != r);
- }
-
- template < typename T >
- static bool operator == (const SharedPointer<T>& l, const SharedPointer<T>& r)
- {
- return (l.get() == r.get());
- }
-
- template < typename T >
- static bool operator != (const SharedPointer<T>& l, const SharedPointer<T>& r)
- {
- return !(l == r);
- }
- }
-
- #endif // SHAREDPOINTER_H_




- #ifndef CIRCLELIST_H_
- #define CIRCLELIST_H_
- /*******************************************************************************
- * Include _Files *
- *******************************************************************************/
- #include "LinkList.h"
- /*******************************************************************************
- * Type Definition *
- *******************************************************************************/
- namespace DTLib
- {
-
- template < typename T >
- class CircleList : public LinkList<T>
- {
- protected:
- typedef typename LinkList<T>::Node Node; // 使用typename的原因:编译器无法辨识标识符究竟是什么(是一个类型还是一个成员名称(静态数据成员或者静态函数))
-
- int mod(int i) const // 取余
- {
- return (this->m_length == 0) ? 0 : (i % this->m_length);
- }
-
- Node* last() const // 尾结点的指针
- {
- return this->position(this->m_length-1)->next;
- }
-
- void last_to_first() const // 将链表首尾相连
- {
- last()->next = this->m_header.next; // 尾结点指向首结点
- }
-
- public:
- /**********************************************************************
- * Function: insert()
- * Description: 插入新结点(函数重载)
- * Input: i 在位置i插入新结点(默认插在最后)
- * e 带插入结点的数据(value)
- * Output:
- * Return: bool 判断插入结点位置是否合法
- * Others: 异常 申请内存是否成功
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- bool insert(const T& e)
- {
- return insert(this->m_length, e);
- }
-
- bool insert(int i, const T& e)
- {
- bool ret = true;
-
- i = i % (this->m_length + 1); // 取余
-
- ret = LinkList<T>::insert(i, e); // 调用父类的插入函数
-
- if( ret && (i == 0) ) // 处理特殊情况(首结点)
- {
- last_to_first(); // 将链表首尾相连
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: remove()
- * Description: 删除结点
- * Input: i 在位置i删除结点
- * Output:
- * Return: bool 判断删除结点位置是否合法
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- bool remove(int i)
- {
- bool ret = true;
-
- i = mod(i); // 取余
-
- if( i == 0 ) // 处理特殊情况(首结点)
- {
- Node* toDel = this->m_header.next; // 获取首结点地址
-
- if( toDel != NULL )
- {
- this->m_header.next = toDel->next; // 头结点指向 1 结点
- this->m_length--; // 当前线性表长度 -1
-
- if( this->m_length > 0 ) // 当前结点不是最后一个结点
- {
- last_to_first(); // 将链表首尾相连
-
- if( this->m_current == toDel ) // 判断游标是否指向 待删除结点的地址
- {
- this->m_current = toDel->next; // 指向 待删除结点的下一个结点的地址
- }
- }
- else
- {
- this->m_header.next = NULL; // 头结点置 NULL
- this->m_current = NULL; // 当前结点置 NULL
- }
-
- this->destroy(toDel); // 为了异常安全,最后销毁结点
- }
- else
- {
- ret = false;
- }
- }
- else
- {
- ret = LinkList<T>::remove(i); // 若不是特殊情况,调用父类函数实现
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: set()
- * Description: 修改第i个结点的值
- * Input: i 待修改结点的位置
- * Output:
- * Return: bool 判断修改结点位置是否合法
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- bool set(int i, const T& e)
- {
- return LinkList<T>::set(mod(i), e);
- }
- /**********************************************************************
- * Function: get()
- * Description: 获取第i个结点的值(函数重载)
- * Input: i 待获取结点的位置
- * Output:
- * Return: bool 判断获取结点位置是否合法
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- T get(int i) const
- {
- return LinkList<T>::get(mod(i));
- }
-
- bool get(int i, T& e) const
- {
- return LinkList<T>::get(mod(i), e);
- }
-
- /**********************************************************************
- * Function: find()
- * Description: 查找指定元素的位置
- * Input: e 待查找结点的值(value)
- * Output:
- * Return: int 返回结点的位置
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- int find(const T& e) const
- {
- int ret = -1;
- Node* slider = this->m_header.next; // 获取 0 元素的地址
-
- for(int i=0; i<this->m_length; i++)
- {
- if( slider->value == e ) // 判断值是否相等
- {
- ret = i; // 获取位置
- break;
- }
-
- slider = slider->next; // 移动到下一个结点
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: clear()
- * Description: 清空线性表
- * Input:
- * Output:
- * Return:
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- void clear()
- {
- while( this->m_length > 1 )
- {
- remove(1); // 为了效率 remove(0)
- }
-
- if( this->m_length == 1 ) // 处理特殊情况(只剩首结点)
- {
- Node* toDel = this->m_header.next;
-
- this->m_header.next = NULL;
- this->m_length = 0;
- this->m_current = NULL;
-
- this->destroy(toDel);
- }
- }
-
- /**********************************************************************
- * Function: move()
- * Description: 将游标定位到目标位置(i)
- * Input: i 移动到第i个元素
- * step 步进默认为 1
- * Output:
- * Return: bool 判断i位置是否合法
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- bool move(int i, int step) // 遍历所有元素
- {
- return LinkList<T>::move(mod(i), step);
- }
-
- /**********************************************************************
- * Function: end()
- * Description: 游标是否到达尾部
- * Input:
- * Output:
- * Return: bool 游标是否到达尾部
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- bool end()
- {
- return (this->m_length == 0) || (this->m_current == NULL);
- }
-
- /**********************************************************************
- * Function: ~LinkList()
- * Description: 析构函数 - 清空线性表
- * Input:
- * Output:
- * Return:
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- ~CircleList()
- {
- clear();
- }
- };
-
- }
-
-
- #endif // CIRCLELIST_H_


- #include <iostream>
- #include "./DTLib/CircleList.h"
-
- using namespace std;
- using namespace DTLib;
-
- void josephus(int n, int s, int m)
- {
- CircleList<int> cl;
-
- for(int i=1; i<=n; i++)
- {
- cl.insert(i);
- }
-
- cl.move(s-1,m-1); //游标指向0处,步长2
-
- int i=0;
-
- while( cl.length() > 0 )
- {
- cl.next();
-
- cout << cl.current() <<endl; //当前要自杀的
-
- int index=cl.find(cl.current());
- cl.remove(index);
- }
- }
-
- int main()
- {
- josephus(41,1,3); //41个人,从1号开始数,数到第三个人开始自杀
-
- return 0;
- }




在“单链表”的结点中增加一个指针 pre ,用于指向当前结点的前驱结点。



- #ifndef DUALLINKLIST_H_
- #define DUALLINKLIST_H_
- /*******************************************************************************
- * Include Files *
- *******************************************************************************/
- #include "List.h"
- #include "Exception.h"
- /*******************************************************************************
- * Type Definition *
- *******************************************************************************/
- namespace DTLib
- {
-
- template < typename T >
- class DualLinkList : public List<T>
- {
- protected:
- struct Node : public Object
- {
- T value; // 数据域
- Node* next; // 后继指针
- Node* pre; // 前驱指针
- };
-
- mutable struct : public Object // mutable 突破const的限制而设置,永远处于可变的状态,即使在一个const函数中
- {
- char reserved[sizeof(T)]; // 为了与Node内存对齐,以便后续使用强制类型转换,继承于Object同理。
- Node* next; // 指向首结点
- Node* pre; // 内存对齐
- } m_header; // 创建头结点 不直接用 Node m_header,因为T有可能是类,在类运行构造函数时,可能会抛出异常
-
- int m_length; // 当前线性表的长度
-
- int m_step; // 步进次数 遍历元素的时候使用 move(); end(); next(); current()
- Node* m_current; // 游标 遍历元素的时候使用 move(); end(); next(); current()
-
- /**********************************************************************
- * Function: position()
- * Description: 移动i次,返回第i-1个结点的地址
- * Input: i 数组类地址
- * m_header 头结点地址
- * Output:
- * Return: Node 返回第i-1个结点的地址
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- Node* position(int i) const
- {
- Node* ret = reinterpret_cast<Node*>(&m_header); // 头结点地址 - 强制类型转换
-
- for(int p=0; p<i; p++) // 移动i次
- {
- ret = ret->next;
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: create()
- * Description: 创建新结点(堆空间)
- * Input:
- * Output:
- * Return: Node 返回新结点的地址
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- virtual Node* create()
- {
- return new Node();
- }
-
- /**********************************************************************
- * Function: destroy()
- * Description: 销毁结点(堆空间)
- * Input: pn 待销毁的结点
- * Output:
- * Return:
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- virtual void destroy(Node* pn)
- {
- delete pn;
- }
-
- public:
- /**********************************************************************
- * Function: DualLinkList()
- * Description: 构造函数 - 初始化参数
- * Input:
- * Output:
- * Return:
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- DualLinkList()
- {
- m_header.next = NULL;
- m_header.pre = NULL;
- m_length = 0;
- m_step = 1;
- m_current = NULL;
- }
-
- /**********************************************************************
- * Function: insert()
- * Description: 插入新结点(函数重载)
- * Input: i 在位置i插入新结点(默认插在最后)
- * e 带插入结点的数据(value)
- * Output:
- * Return: bool 判断插入结点位置是否合法
- * Others: 异常 申请内存是否成功
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- bool insert(const T& e)
- {
- return insert(m_length, e); // 新结点插在最后
- }
-
- bool insert(int i, const T& e)
- {
- bool ret = ((0 <= i) && (i <= m_length)); // 位置i合法性校验
-
- if( ret )
- {
- Node* node = create(); // 创建新结点 - 申请内存
-
- if( node != NULL )
- {
- Node* current = position(i); // 获取新结点前一个结点的地址
- Node* next = current->next; // 获取新结点后一个结点的地址
-
- node->value = e; // 新结点的数据域(value)赋值
-
- node->next = next; // 新结点后继指针赋值
- current->next = node; // 前一个结点后继指向新结点
-
- if( current != reinterpret_cast<Node*>(&m_header) ) // 前一个结点不为头结点
- {
- node->pre = current; // 新结点前继指针赋值
- }
- else
- {
- node->pre = NULL; // 新结点前继指针置 0
- }
-
- if( next != NULL ) // 后一个结点存在
- {
- next->pre = node; // 后一个结点的前继指针赋值
- }
-
- m_length++; // 当前线性表的长度 +1
- }
- else
- {
- THROW_EXCEPTION(NoEnoughMemoryException, "No memory to insert new element ...");
- }
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: remove()
- * Description: 删除结点
- * Input: i 在位置i删除结点
- * Output:
- * Return: bool 判断删除结点位置是否合法
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- bool remove(int i)
- {
- bool ret = ((0 <= i) && (i < m_length)); // 位置i合法性校验
-
- if( ret )
- {
- Node* current = position(i); // 获取待删除结点前一个结点的地址
- Node* toDel = current->next; // 临时保存 待删除结点的地址
- Node* next = toDel->next; // 获取待删除结点后一个结点的地址
-
- if( m_current == toDel ) // 判断游标是否指向 待删除结点的地址
- {
- m_current = next; // 指向 待删除结点的下一个结点的地址
- }
-
- current->next = next; // 待删除结点的下一个结点的地址,赋值给待删除结点的前一个结点的next
-
- if( next != NULL ) // 待删除结点后还有结点
- {
- next->pre = toDel->pre; // 待删除结点的前驱地址,赋值给下一个结点的前驱指针
- }
-
- m_length--; // 当前线性表的长度 -1 为了防止元素为类时,析构函数抛出异常,无法保证链表的安全性
-
- destroy(toDel); // 释放该结点所占得内存
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: set()
- * Description: 修改第i个结点的值
- * Input: i 待修改结点的位置
- * Output:
- * Return: bool 判断修改结点位置是否合法
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- bool set(int i, const T& e)
- {
- bool ret = ((0 <= i) && (i < m_length)); // 位置i合法性校验
-
- if( ret )
- {
- position(i)->next->value = e; // 待修改结点的前一个结点->next == 待修改的结点的地址
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: get()
- * Description: 获取第i个结点的值(函数重载)
- * Input: i 待获取结点的位置
- * Output:
- * Return: bool 判断获取结点位置是否合法
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- virtual T get(int i) const
- {
- T ret;
-
- if( get(i, ret) )
- {
- return ret;
- }
- else
- {
- THROW_EXCEPTION(IndexOutOfBoundsException, "Invalid parameter i to get element ...");
- }
-
- return ret;
- }
-
- bool get(int i, T& e) const
- {
- bool ret = ((0 <= i) && (i < m_length)); // 位置i合法性校验
-
- if( ret )
- {
- e = position(i)->next->value; // 待获取结点的前一个结点->next == 待获取的结点的地址
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: find()
- * Description: 查找指定元素的位置
- * Input: e 待查找结点的值(value)
- * Output:
- * Return: int 返回结点的位置
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- int find(const T& e) const
- {
- int ret = -1;
- int i = 0;
- Node* node = m_header.next; // 获取 0 元素的地址
-
- while( node )
- {
- if( node->value == e ) // 判断值是否相等
- {
- ret = i; // 获取位置
- break;
- }
- else
- {
- node = node->next; // 移动到下一个结点
- i++; // 位置 +1
- }
- }
-
- return ret;
- }
-
-
- /**********************************************************************
- * Function: length()
- * Description: 当前线性表的长度
- * Input:
- * Output:
- * Return: int 当前线性表的长度
- * Others: O(1)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- int length() const
- {
- return m_length;
- }
-
- /**********************************************************************
- * Function: clear()
- * Description: 清空线性表
- * Input:
- * Output:
- * Return:
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- void clear()
- {
- while( m_length > 0 ) // 循环删除首结点
- {
- remove(0);
- }
- }
-
- /*
- 遍历所有元素 推荐使用方法
- 移动到0号元素 判断是否到尾部 移动到下一个结点
- for (list.move(0); !list.end();list.next())
- {
- cout << list.current() << endl;
- }
- 移动到尾元素 判断是否到首部 移动到上一个结点
- for (list.move(list.length()-1); !list.end();list.pre())
- {
- cout << list.current() << endl;
- }
- */
- /**********************************************************************
- * Function: move()
- * Description: 将游标定位到目标位置(i)
- * Input: i 移动到第i个元素
- * step 步进默认为 1
- * Output:
- * Return: bool 判断i位置是否合法
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- virtual bool move(int i, int step = 1)
- {
- bool ret = (0 <= i) && (i < m_length) && (step > 0);
-
- if( ret )
- {
- m_current = position(i)->next; // 目标位置的地址
- m_step = step;
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: end()
- * Description: 游标是否到达尾部
- * Input:
- * Output:
- * Return: bool 游标是否到达尾部
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- virtual bool end()
- {
- return (m_current == NULL);
- }
-
- /**********************************************************************
- * Function: current()
- * Description: 获取游标所指向的数据元素
- * Input:
- * Output:
- * Return: T 游标所指向的数据元素
- * Others: 异常 游标已到尾部,无法获取到值
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- virtual T current()
- {
- if( !end() ) // 游标是否到达尾部
- {
- return m_current->value;
- }
- else
- {
- THROW_EXCEPTION(InvalidOperationException, "No value at current position ...");
- }
- }
-
- /**********************************************************************
- * Function: next()
- * Description: 向后移动游标 m_step次
- * Input:
- * Output:
- * Return: bool 是否成功移动游标 m_step次
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- virtual bool next()
- {
- int i = 0;
-
- while( (i < m_step) && !end() ) // 移动次数是否为m_step && 游标是否到达尾部
- {
- m_current = m_current->next; // 移动一次游标
- i++;
- }
-
- return (i == m_step);
- }
-
-
- /**********************************************************************
- * Function: pre()
- * Description: 向前移动游标 m_step次
- * Input:
- * Output:
- * Return: bool 是否成功移动游标 m_step次
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- virtual bool pre()
- {
- int i = 0;
-
- while( (i < m_step) && !end() ) // 移动次数是否为m_step && 游标是否到达尾部
- {
- m_current = m_current->pre; // 移动一次游标
- i++;
- }
-
- return (i == m_step);
- }
-
- /**********************************************************************
- * Function: ~DualLinkList()
- * Description: 析构函数 - 清空线性表
- * Input:
- * Output:
- * Return:
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- ~DualLinkList()
- {
- clear();
- }
- };
-
- }
-
- #endif // DUALLINKLIST_H_





- #include <stdio.h>
-
- #ifndef offsetof
- #define offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER)
- #endif
-
-
- struct ST
- {
- int i; // 0
- int j; // 4
- char c; // 8
- };
-
- void func(struct ST* pst)
- {
- int* pi = &(pst->i); // 0
- int* pj = &(pst->j); // 4
- char* pc = &(pst->c); // 8
-
- printf("pst = %p\n", pst);
- printf("pi = %p\n", pi);
- printf("pj = %p\n", pj);
- printf("pc = %p\n", pc);
- }
-
- int main()
- {
- struct ST s = {0};
-
- func(&s);
- func(NULL);
-
- printf("offset i: %ld\n", offsetof(struct ST, i));
- printf("offset j: %ld\n", offsetof(struct ST, j));
- printf("offset c: %ld\n", offsetof(struct ST, c));
-
- return 0;
- }



- #include <stdio.h>
-
- #ifndef offsetof
- #define offsetof(TYPE, MEMBER) ((size_t)&((TYPE*)0)->MEMBER)
- #endif
-
- #ifndef container_of
- #define container_of(ptr, type, member) ({ \
- const typeof(((type*)0)->member)* __mptr = (ptr); \
- (type*)((char*)__mptr - offsetof(type, member)); })
- #endif
-
- #ifndef container_of_new
- #define container_of_new(ptr, type, member) ((type*)((char*)(ptr) - offsetof(type, member)))
- #endif
-
-
- struct ST
- {
- int i; // 0
- int j; // 4
- char c; // 8
- };
-
- void method_1()
- {
- int a = 0;
- int b = 0;
-
- int r = (
- a = 1,
- b = 2,
- a + b
- );
-
- printf("r = %d\n", r);
- }
-
- void method_2()
- {
- int r = ( {
- int a = 1;
- int b = 2;
-
- a + b;
- } );
-
- printf("r = %d\n", r);
- }
-
- void type_of()
- {
- int i = 100;
- typeof(i) j = i;
- const typeof(j)* p = &j;
-
- printf("sizeof(j) = %d\n", sizeof(j));
- printf("j = %d\n", j);
- printf("*p = %d\n", *p);
- }
-
- int main()
- {
-
- // method_1();
- // method_2();
- // type_of();
-
- struct ST s = {0};
- char* pc = &s.c;
- int e = 0;
- int* pe = &e;
-
- struct ST* pst = container_of(pc, struct ST, c);
-
- printf("&s = %p\n", &s);
- printf("pst = %p\n", pst);
-
- return 0;
- }
list.h



main.c




main.c
- #include <stdio.h>
- #include "LinuxList.h"
-
- void list_demo_1()
- {
- struct Node
- {
- struct list_head head;
- int value;
- };
-
- struct Node l = {0};
- struct list_head* list = (struct list_head*)&l;
- struct list_head* slider = NULL;
- int i = 0;
-
- INIT_LIST_HEAD(list);
-
- printf("Insert begin ...\n");
-
- for(i=0; i<5; i++)
- {
- struct Node* n = (struct Node*)malloc(sizeof(struct Node));
-
- n->value = i;
-
- list_add_tail((struct list_head*)n, list);
- }
-
- list_for_each(slider, list)
- {
- printf("%d\n", ((struct Node*)slider)->value);
- }
-
- printf("Insert end ...\n");
-
- printf("Delete begin ...\n");
-
- list_for_each(slider, list)
- {
- if( ((struct Node*)slider)->value == 3 )
- {
- list_del(slider);
- free(slider);
- break;
- }
- }
-
- list_for_each(slider, list)
- {
- printf("%d\n", ((struct Node*)slider)->value);
- }
-
- printf("Delete end ...\n");
- }
-
- void list_demo_2()
- {
- struct Node
- {
- int value;
- struct list_head head;
- };
-
- struct Node l = {0};
- struct list_head* list = &l.head;
- struct list_head* slider = NULL;
- int i = 0;
-
- INIT_LIST_HEAD(list);
-
- printf("Insert begin ...\n");
-
- for(i=0; i<5; i++)
- {
- struct Node* n = (struct Node*)malloc(sizeof(struct Node));
-
- n->value = i;
-
- list_add(&n->head, list);
- }
-
- list_for_each(slider, list)
- {
- printf("%d\n", list_entry(slider, struct Node, head)->value);
- }
-
- printf("Insert end ...\n");
-
-
- printf("Delete begin ...\n");
-
- list_for_each(slider, list)
- {
- struct Node* n = list_entry(slider, struct Node, head);
-
- if( n->value == 3 )
- {
- list_del(slider);
- free(n);
- break;
- }
- }
-
- list_for_each(slider, list)
- {
- printf("%d\n", list_entry(slider, struct Node, head)->value);
- }
-
- printf("Delete end ...\n");
- }
-
- int main()
- {
- // list_demo_1();
- // list_demo_2();
-
- return 0;
- }

数据结点之间在逻辑上构成双向循环链表,头结点仅用于结点的定位。

DualCircleList.h
- #ifndef DUALCIRCLELIST_H
- #define DUALCIRCLELIST_H
-
- #include "LinuxList.h"
- #include "DualLinkList.h"
-
-
- namespace DTLib
- {
-
- template < typename T >
- class DualCircleList : public DualLinkList<T>
- {
- protected:
- struct Node : public Object // 结点类型
- {
- list_head head; // Linux内核链表结点的结构体成员
- T value; // 数据域
- };
-
- list_head m_header; // 头结点
- list_head* m_current; // 游标 - 用于遍历
-
- /**********************************************************************
- * Function: position()
- * Description: 移动i次,返回第i-1个结点的地址
- * Input: i 数组类地址
- * m_header 头结点地址
- * Output:
- * Return: Node 返回第i-1个结点的地址
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- list_head* position(int i) const
- {
- list_head* ret = const_cast<list_head*>(&m_header); // 头结点地址 - 强制类型转换
-
- for(int p=0; p<i; p++) // 移动i次游标
- {
- ret = ret->next;
- }
-
- return ret;
- }
- /**********************************************************************
- * Function: mod()
- * Description: 取余
- * Input: i 数组类地址
- * m_header 头结点地址
- * Output:
- * Return: Node 返回第i-1个结点的地址
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- int mod(int i) const
- {
- return (this->m_length == 0) ? 0 : (i % this->m_length);
- }
-
- public:
- /**********************************************************************
- * Function: DualCircleList()
- * Description: 构造函数 - 初始化参数
- * Input:
- * Output:
- * Return:
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/04/12 1.0 Create
- **********************************************************************/
- DualCircleList()
- {
- this->m_length = 0;
- this->m_step = 1;
-
- m_current = NULL;
-
- INIT_LIST_HEAD(&m_header); // Linux链表头结点初始化
- }
-
- /**********************************************************************
- * Function: insert()
- * Description: 插入新结点(函数重载)
- * Input: i 在位置i插入新结点(默认插在最后)
- * e 带插入结点的数据(value)
- * Output:
- * Return: bool 判断插入结点位置是否合法
- * Others: 异常 申请内存是否成功
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- bool insert(const T& e)
- {
- return insert(this->m_length, e);
- }
-
- bool insert(int i, const T& e)
- {
- bool ret = true;
- Node* node = new Node();
-
- i = i % (this->m_length + 1); // 取余
-
- if( node != NULL )
- {
- node->value = e;
-
- list_add_tail(&node->head, position(i)->next);
-
- this->m_length++;
- }
- else
- {
- THROW_EXCEPTION(NoEnoughMemoryException, "No memory to insert new element ...");
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: remove()
- * Description: 删除结点
- * Input: i 在位置i删除结点
- * Output:
- * Return: bool 判断删除结点位置是否合法
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- bool remove(int i)
- {
- bool ret = true;
-
- i = mod(i);
-
- ret = ((0 <= i) && (i < this->m_length));
-
- if( ret )
- {
- list_head* toDel = position(i)->next;
-
- if( m_current == toDel )
- {
- m_current = toDel->next;
- }
-
- list_del(toDel);
-
- this->m_length--;
-
- delete list_entry(toDel, Node, head);
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: set()
- * Description: 修改第i个结点的值
- * Input: i 待修改结点的位置
- * Output:
- * Return: bool 判断修改结点位置是否合法
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- bool set(int i, const T& e)
- {
- bool ret = true;
-
- i = mod(i);
-
- ret = ((0 <= i) && (i < this->m_length));
-
- if( ret )
- {
- list_entry(position(i)->next, Node, head)->value = e;
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: get()
- * Description: 获取第i个结点的值(函数重载)
- * Input: i 待获取结点的位置
- * Output:
- * Return: bool 判断获取结点位置是否合法
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- T get(int i) const
- {
- T ret;
-
- if( get(i, ret) )
- {
- return ret;
- }
- else
- {
- THROW_EXCEPTION(IndexOutOfBoundsException, "Invalid parameter i to get element ...");
- }
-
- return ret;
- }
-
- bool get(int i, T& e) const
- {
- bool ret = true;
-
- i = mod(i);
-
- ret = ((0 <= i) && (i < this->m_length));
-
- if( ret )
- {
- e = list_entry(position(i)->next, Node, head)->value;
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: find()
- * Description: 查找指定元素的位置
- * Input: e 待查找结点的值(value)
- * Output:
- * Return: int 返回结点的位置
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- int find(const T& e) const
- {
- int ret = -1;
- int i = 0;
- list_head* slider = NULL;
-
- list_for_each(slider, &m_header)
- {
- if( list_entry(slider, Node, head)->value == e )
- {
- ret = i;
- break;
- }
-
- i++;
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: length()
- * Description: 当前线性表的长度
- * Input:
- * Output:
- * Return: int 当前线性表的长度
- * Others: O(1)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- int length() const
- {
- return this->m_length;
- }
-
- /**********************************************************************
- * Function: clear()
- * Description: 清空线性表
- * Input:
- * Output:
- * Return:
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- void clear()
- {
- while( this->m_length > 0 )
- {
- remove(0);
- }
- }
-
- /*
- 遍历所有元素 推荐使用方法
- 移动到0号元素 判断是否到尾部 移动到下一个结点
- for (list.move(0); !list.end();list.next())
- {
- cout << list.current() << endl;
- }
- */
- /**********************************************************************
- * Function: move()
- * Description: 将游标定位到目标位置(i)
- * Input: i 移动到第i个元素
- * step 步进默认为 1
- * Output:
- * Return: bool 判断i位置是否合法
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- bool move(int i, int step = 1)
- {
- bool ret = (step > 0);
-
- i = mod(i);
-
- ret = ret && ((0 <= i) && (i < this->m_length));
-
- if( ret )
- {
- m_current = position(i)->next;
-
- this->m_step = step;
- }
-
- return ret;
- }
-
- /**********************************************************************
- * Function: end()
- * Description: 游标是否到达尾部
- * Input:
- * Output:
- * Return: bool 游标是否到达尾部
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- bool end()
- {
- return (m_current == NULL) || (this->m_length == 0);
- }
-
- /**********************************************************************
- * Function: current()
- * Description: 获取游标所指向的数据元素
- * Input:
- * Output:
- * Return: T 游标所指向的数据元素
- * Others: 异常 游标已到尾部,无法获取到值
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- T current()
- {
- if( !end() )
- {
- return list_entry(m_current, Node, head)->value;
- }
- else
- {
- THROW_EXCEPTION(InvalidOperationException, "No value at current position ...");
- }
- }
-
- /**********************************************************************
- * Function: next()
- * Description: 移动游标 m_step次
- * Input:
- * Output:
- * Return: bool 是否成功移动游标 m_step次
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/18 1.0 Create
- **********************************************************************/
- bool next()
- {
- int i = 0;
-
- while( (i < this->m_step) && !end() )
- {
- if( m_current != &m_header )
- {
- m_current = m_current->next;
- i++;
- }
- else
- {
- m_current = m_current->next;
- }
- }
-
- if( m_current == &m_header )
- {
- m_current = m_current->next;
- }
-
- return (i == this->m_step);
- }
-
- /**********************************************************************
- * Function: pre()
- * Description: 向前移动游标 m_step次
- * Input:
- * Output:
- * Return: bool 是否成功移动游标 m_step次
- * Others:
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- bool pre()
- {
- int i = 0;
-
- while( (i < this->m_step) && !end() )
- {
- if( m_current != &m_header )
- {
- m_current = m_current->prev;
- i++;
- }
- else
- {
- m_current = m_current->prev;
- }
- }
-
- if( m_current == &m_header )
- {
- m_current = m_current->prev;
- }
-
- return (i == this->m_step);
- }
-
- /**********************************************************************
- * Function: ~DualLinkList()
- * Description: 析构函数 - 清空线性表
- * Input:
- * Output:
- * Return:
- * Others: O(n)
- * Modify Date Version Author Modification
- * ------------------------------------------------------------
- * 2022/03/19 1.0 Create
- **********************************************************************/
- ~DualCircleList()
- {
- clear();
- }
-
- };
-
- }
-
- #endif // DUALCIRCLELIST_H
下面代码中的pn1和pn2是否相等?为什么?
