类类型:
class CMyString{
public:
CMyString(char* pdata = NULL);
CMyString(const CMyString & str);
~CMyString(void);
private:
char* m_pData;
}
定义一个赋值运算符重载–改进四点
CMyString& CMyString::operator = (const CMyString &str){
if(this == &str)
return *this;
delete [] m_pData;
m_pData = NULL;
m_pData = new char[strlen(str.m_pData) + 1];
strcpy(m_pData, str.m_pData);
return this;
}
高级版
–考虑异常安全性( Exception safety )
(当内存分配失败时, 能确保CMyString不会被修改)
(先创建一个临时实例,后交换到原实例)
CMyString& CMyString::operator = (const CMyString &str){
if(this != &str){
CMyString strTemp(str);
char* pTemp = strTemp.m_pData;
strTemp.m_pData = m_pData;
m_pData = pTemp;
}
return *this;
}
数组与指针的区别
int GetSize(int data[]){
return sizeof(data);
}
int _tmain(int argc, _TCHAR* argv[]){
int data1[] = {1, 2, 3, 4, 5};
int size1 = sizeof(data1);
int* data2 = data1;
int size2 = sizeof(data2);
int size3 = GetSize(data1);
printf("%d, %d, %d", size1, size2, size3);
}
二维数组中的查找
bool Find(int* matrix, int rows, int columns, int number){
bool found = false;
if(matrix != NULL && rows > 0 && columns > 0){
int row = 0;
int column = columns - 1;
while(row < rows && columns >= 0){
if(matrix[row * columns + column] == number){
found = true;
break;
}
else if(matrix[row * columns + column] > number)
column--;
else
row++;
}
}
return found;
}
内存地址是否相同
int _tmain(int argc, _TCHAR* argv[]){
char str1[] = "hello world";
char str2[] = "hello world";
char* str3 = "hello world";
char* str4 = "hello world";
if(str1 == str2)
printf("aaa");
else
printf("bbb");
if(str3 == str4)
printf("ccc");
else
printf("ddd");
替换空格
将URL中特殊字符转换成服务器可以识别的字符
" " 的ASCII码是32,即十六进制的0x20, 因此空格替换为“%20”
- 覆盖修改在该字符串后面的内存
- 创建新的字符串,在此基础上替换
- a. 把第一个指针指向字符串末尾,第二个指针指向替换后的字符串的末尾,
- b. 依次复制字符串的内容,直到第一个指针碰到第一个空格
- c. 把第一个空格替换成 ‘%20’ ,把第一个指针向前移动一格,第二个指针向前移动3格,
- d. 依次向前复制字符串的字符,直到碰到空格,
- e. 重复
// length 为字符串总容量
void ReplaceBlank(char string[], int length){
if(string == NULL && length <= 0)
return;
// originalLength 为字符串 string 的实际长度
int originalLength = 0;
int numberOfBlank = 0;
int i = 0;
while(string[i] != '\0'){
++ originalLength;
if((string[i] == ' ')
numberOfBlank ++;
i++;
}
// newLength 为把空格替换成 ’%20‘ 之后的长度
int newLength = originalLength + numberOfBlank * 2;
if(newLength > length)
return;
int indexOfOriginal = originalLength;
int indexOfNew = newLength;
while(indexOfOriginal >= 0 && indexOfNew > indexOfOriginal){
if(string[indexOfOriginal] == ' '){
string[indexOfNew-- ] = '0';
string[indexOfNew-- ] = '2';
string[indexOfNew-- ] = '%';
}
else
string[indexOfNew-- ] = string[indexOfOriginal];
indexOfOriginal--;
}
}
链表
当插入一个结点,为新节点分配内存,内存分配不是在创建链表时一次性完成,而是每添加一个结点,分配一次内存,无闲置内存,所以空间效率高
struct ListNode{
int m_nValue;
ListNode * m_pNext;
};
末尾添加结点
向链表的末尾添加一个结点(pHead是指向指针的指针)
(避免结束了这个函数后,pHead 仍然是空指针)
void AddToTail(ListNode** pHead, int value){
ListNode* pNew = new ListNode();
pNew->m_nValue = value;
pNew->m_pNext = NULL;
if(*pHead == NULL)
*pHead = pNew;
else{
ListNode* pNode = *pHead;
while(pNode->m_pNext != NULL)
pNode = pNode->m_pNext;
pNode->m_pNext = pNew;
}
}
删除结点
void RemoveNode(ListNode** pHead, int value){
if(pHead == NULL || *pHead == NULL)
return;
ListNode* pToBeDeleted = NULL;
if((*pHead)->m_nValue == value){
pToBeDeleted = *pHead;
*pHead = (*pHead)->m_pNext;
}
else{
ListNode* pNode = *pHead;
while(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue != value)
pNode = pNode->m_pNext;
if(pNode->m_pNext != NULL && pNode->m_pNext->m_nValue == value){
pToBeDeleted = pNode->m_pNext;
pNode->m_pNext = pNode->m_pNext->m_pNext;
}
if(pToBeDeleted != NULL){
delete pToBeDeleted;
pToBeDeleted = NULL
}
}
}
从尾到头打印链表
void PrintListReversely_Iteratively(ListNode* pHead){
stack<ListNode* > nodes;
ListNode* pNode = pHead;
while(pNode != NULL){
nodes.push(pNode);
pNode = pNode->m_pNext;
}
while(!nodes.empty()){
pNode = nodes.top();
printf("%d\t", pNode->m_nValue);
nodes.pop();
}
}
// 用递归来实现
void PrintListReversingly_Reversively(ListNode* pHead){
if(pHead != NULL){
if(pHead->m_pNext != NULL)
PrintListReversingly_Reversively(pHead->m_pNext);
printf("%d\t", pHead->m_nValue);
}
}
//可能导致函数调用栈溢出