栈字符串

分享一个小技术开始国泉的博客之旅。

————————————————————我是分割线——————————————————————

栈字符串是什么?

  是利用栈空间做存储,和c++ STL::string的区别在于前者的数据存储在栈上面后者在堆上面,替换std::string。

栈字符串的优势是什么?国泉认为比较最重要的是

  1、栈是系统提供的数据结构(而堆是C++库提供),栈有专门的寄存器来操作压栈和出栈效率更高。

  2、访问栈内存只需要一次,而访问堆需要两次(第一次取得指针,第二次取得数据)。

  3、在申请堆空间时需要去寻址一块够大的连续内存,会耗费更多的时间,原因是频繁使用new delete造成的内存空洞。

  其他还有很多机制上的不同这里就不在详细介绍。

 

那怎么设计一个栈字符串呢?直接上干货

  1 template<int SIZE>
  2 class stackString
  3 {
  4 public:
  5     stackString();
  6     stackString(const char* pszStr);
  7     stackString(stackString& rhs);
  8     ~stackString() {};
  9 
 10     void copyString(const char* pszStr, int nLen);
 11 
 12     inline stackString& operator=(const char* pszStr);
 13     inline stackString& operator=(const stackString& rhs);
 14 
 15     inline const char* getStr() { return m_szString; }
 16     inline size_t getLen() { return m_nLen; }
 17     inline void reset() { m_nLen = 0; m_szString[0] = 0; }
 18 
 19     int append(const char* pszAdd);
 20     int appendFormat(const char* fmt, ...);
 21 
 22     inline int deleteBack(int nLen)
 23     {
 24         if (nLen >= m_nLen)
 25         {
 26             m_szString[0] = 0;
 27             m_nLen = 0;
 28             return false;
 29         }
 30 
 31         m_nLen -= nLen;
 32         m_szString[m_nLen] = 0;
 33         return true;
 34     }
 35 
 36 private:
 37     int     m_nLen;
 38     char    m_szString[SIZE];
 39 };
 40 
 41 template<int SIZE>
 42 stackString<SIZE>::stackString() : m_nLen(0)
 43 {
 44     m_szString[0] = 0;
 45 }
 46 
 47 template<int SIZE>
 48 void stackString<SIZE>::copyString(const char* pszStr, int nLen)
 49 {
 50     if (!pszStr)
 51         return;
 52 
 53     m_nLen = nLen;
 54     if (m_nLen > SIZE)
 55         m_nLen = SIZE - 1;
 56     strncpy(m_szString, pszStr, m_nLen);
 57     m_szString[m_nLen] = 0;
 58     m_szString[sizeof(m_szString) - 1] = 0;
 59 }
 60 
 61 template<int SIZE>
 62 inline stackString<SIZE>& stackString<SIZE>::operator=(const char* pszStr)
 63 {
 64     copyString(pszStr, (int)strlen(pszStr));
 65 
 66     return *this;
 67 }
 68 
 69 template<int SIZE>
 70 inline stackString<SIZE>& stackString<SIZE>::operator=(const stackString& rhs)
 71 {
 72     if (&rhs == this)
 73         return *this;
 74 
 75     copyString(rhs.getStr(), rhs.getLen());
 76     return *this;
 77 }
 78 
 79 template<int SIZE>
 80 stackString<SIZE>::stackString(const char* pszStr)
 81 {
 82     copyString(pszStr, strlen(pszStr));
 83 }
 84 
 85 template<int SIZE>
 86 stackString<SIZE>::stackString(stackString& rhs)
 87 {
 88     copyString(rhs.getStr(), rhs.getLen());
 89 }
 90 
 91 template<int SIZE>
 92 int stackString<SIZE>::append(const char* pszAdd)
 93 {
 94     if (m_nLen >= (SIZE - 1))
 95         return false;
 96 
 97     int nlen = (int)strlen(pszAdd);  
 98 
 99     strncpy(m_szString + m_nLen, pszAdd, sizeof(m_szString) - m_nLen);
100     if ((nlen + m_nLen) > (SIZE - 1))
101         m_nLen = SIZE - 1;
102     else
103         m_nLen += nlen;
104     m_szString[sizeof(m_szString) - 1] = 0;
105 
106     return true;
107 }
108 
109 // 格式化字符串
110 template<int SIZE>
111 int stackString<SIZE>::appendFormat(const char* fmt, ...)
112 {
113     va_list arg;
114     va_start(arg, fmt);
115 
116     int nLen = _vsnprintf(m_szString + m_nLen, SIZE - m_nLen, fmt, arg);
117     m_szString[SIZE - 1] = 0;
118 
119     va_end(arg);
120 
121     if (nLen == -1)
122     {
123         m_nLen = SIZE - 1;
124     }
125     else if (nLen < 0)
126     {
127         m_nLen = SIZE - 1;
128         return false;
129     }
130     else
131     {
132         m_nLen += nLen;
133     }
134 
135     return true;
136 }

 

使用上和std::string唯一的区别在于需要评估并预设一个大小,会有一定量的资源浪费。

1 #include<iostream>
2 int main()
3 {
4     stackString<32> str("my name");
5     str.append(" is");
6     str.appendFormat(" %s", "GuoQuan");
7 }

 

posted @ 2018-08-11 12:00  GuoQuanLiu  阅读(900)  评论(0)    收藏  举报