栈字符串
分享一个小技术开始国泉的博客之旅。
————————————————————我是分割线——————————————————————
栈字符串是什么?
是利用栈空间做存储,和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 }

浙公网安备 33010602011771号