C++笔记

 

-------------------------查找代码和相关主题

http://www.oschina.net/code/snippet_12_1001

 

1:指针引用区别。
2:将构造函数或者析构函数声明为protect会阻止该类被使用非new或者delete的方式调用。构造函数省名public,析构函数声明private,即可防止
外部使用delete的方式删除对象。如果使用private会组织该类被继承。
3:const_cast:去掉const属性:
const int uu=10;
const int &cu=uu;
int *pax= const_cast<int*>(&cu);
4:dynamic_cast:继承关系的上下转换,基类必须含有虚函数。
a * p= dynamic_cast<a*>(pa);
base * pbase=dynamic_cast<base*>(pp);
5:不能对数组传递多态类型。因为数组是顺序访问的i*size(obj),而此obj是父类的大小不是子类的大小。这样就可能转换出界。
6:函数数组参数是传址,如果需要固定数组长度限制可使用数组引用:
void ff2(int arr[]){}//数据传址
void ff2(int (&arr)[10]){}//数据引用
7:使父类的析构函数成为虚函数,可以在delete父类指针的时候一并调用子类的析构函数(父类指针指向的是子类对象):
a * p1= new a();
base *p2=p1;
delete p2;//会调用~a(),然后调用~base();  如果析构函数不是虚函数,则是调用~a(),这样的话会有内存泄露;
8:stl的remove_if算法只能用于非关联容器,且不会真正删除关联容器的数据,只会做一个分界,将不满足if的放在界限的前面,
满足if的放到界限的后头。所以要删除最好使用erase+remove_if
class Fun
{
public:
bool operator () (const int & v){return (v%5)==0;}
//Functor的对象就是函数符
};
void main()
{
vector<int> arr;
for (int i=0;i<10;i++)
  arr.push_back(i);
vector<int>::iterator ss =remove_if(arr.begin(), arr.end(), Fun());
arr.erase(ss,arr.end());
}
9:stl仿函数的适配器(即绑定)分为两种bind2nd和bind1st。一般使用bind2nd多一点:
class Fun2: std::binary_function<string, char *, bool>  
{  
        bool operator() (string & a, char* b) const  
        {  
                if (!a.compare(b))  
                        return true;  
                else  
                        return false;  
        }  
};
bind2nd(Fun2,val):意思是将仿函数Fun和变量val绑定在一起。如果val值发生变化,与之相关绑定的仿函数的第二个参数(也就上面是重载
operator()的参数char* b)的值也会发生改变。
bind1st(Fun2,val):意思是将仿函数Fun和变量val绑定在一起。如果val值发生变化,与之相关绑定的仿函数的第一个参数(也就上面是重载
operator()的参数char* a)的值也会发生改变。
10:stl迭代器适配器:
流适配器:istream_iterater,ostream_iterater,istreambuf_iterater,ostreambuf_iterater
插入适配器:back_insert_iterator,front_insert_iterator,insert_iterator
顺序容器适配器:stack,queue
11:stl的unique算法可以查找相邻重复(可以是>=2个,但都需相邻)元素,unique实质上没有删掉重复数据,
顺序容器的长度不变,跟remove的算法是一样的,只会做一个分界,
把相邻重复元素之外的其他元素复制到一个较小的区间中,并返回指向该区间末尾的迭代器:
vector<int> v;
v.push_back(2);
v.push_back(6);
v.push_back(6);
v.push_back(6);
v.push_back(9);
v.push_back(4);
v.push_back(4);
v.push_back(6);
v.push_back(3);
v.push_back(3);
v;//(2,6,6,6,9,4,4,6,3,3)
vector<int>::iterator result, xx;
result=unique(v.begin(),v.end());
v;//(2,6,9,4,6,3,4,6,3,3)
cout<<*(--v.end())<<endl;//3
此刻:(result)到(--v.end())就是那重复的数据,即4,6,3
12:stl的adjacent_find算法是产找一堆相邻的重复元素,并只返回第一次查找到的迭代器:
vector<int> v;
v.push_back(2);
v.push_back(6);
v.push_back(6);
v.push_back(6);
v.push_back(9);
v.push_back(4);
v.push_back(4);
vector<int>::iterator result;
result= adjacent_find(v.begin(),v.end());//6
13:stl的copy算法:
vector<string> vv,vv2,vv3;
vv.push_back("aaa");
vv.push_back("bbb");
ifstream f("d:\\1.txt");
ofstream f2("d:\\2.txt",ios::app);
copy(istream_iterator<string>(f),istream_iterator<string>(),back_inserter(vv2));//将流拷贝到vect中
copy(vv.begin(),vv.end(),ostream_iterator<string>(f2));//将vect写入流中
//copy(vv.begin(),vv.end(),vv3.begin());//error
copy(vv.begin(),vv.end(),back_inserter(vv3));//succ
14:merge和set_union的都是合并容器。两个容器必须先都得有序,否则会报错。区别是但前者不排重,后者排重:
vector<string> vec1, vec2, vec3,vec;  
vec1.push_back("aa");  
vec1.push_back("bb");  
vec1.push_back("cc");  
vec2.push_back("ff"); 
vec2.push_back("bb");  
vec2.push_back("ff");
sort(vec1.begin(),vec1.end());
sort(vec2.begin(),vec2.end());
set_union(vec1.begin(),vec1.end(),vec2.begin(),vec2.end(),back_inserter(vec3));//("aa","bb","cc","ff","ff")
merge(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), back_inserter(vec));//("aa","bb","bb","cc","ff","ff")
unique_copy(vec.begin(),vec.end(),back_inserter(vec4));//vec4==>("aa","bb","cc","ff")
vector<string>::iterator iter= unique(vec.begin(),vec.end());//("aa","bb","cc","ff","ff","ff")
vec.erase(iter,vec.end());//("aa","bb","cc","ff")
15:unique_copy和unique类似只是会将不连续重复的数据放到另一个容器中。参见14。
16:partial_sort获取前多少名的排序方法,获取所有数据中最大/小的前n名:
bool fun4(string s1,string s2)
{
return atoi(s1.c_str())<atoi(s2.c_str());
}
class Fun5
{
public:
bool operator () (const string & v1,const string & v2)
{
return atoi(v1.c_str())<atoi(v2.c_str());
}
};
vector<string> vec;
vec.push_back("11");
vec.push_back("16");
vec.push_back("88");
vec.push_back("13");
vec.push_back("9");
partial_sort(vec.begin(),vec.begin()+3,vec.end(),fun4);//("9","11","13","88","16")只排序top n,比如获取全班前3名最高分数的学生成绩
partial_sort(vec.begin(),vec.begin()+3,vec.end(),Fun5());//("9","11","13","88","16")只排序top n,比如获取全班前3名最高分数的学生成
绩。
17:nth_element算法是获取第n个数据,比如班上有10个学生,我想知道分数排在倒数第4名的学生:
vector<int> vect;
vect.push_back(133);
vect.push_back(1);
vect.push_back(23);
vect.push_back(9);
vect.push_back(13);
nth_element(vect.begin(), vect.begin()+3, vect.end(),less<int>());
vect[3];//即到时第4那个学生的分数
18:rotate算法是将容器一部分区间段放置到容器的尾端:
vector<int> vec;
vec.push_back(74);
vec.push_back(56);
vec.push_back(92);
vec.push_back(85);
vec.push_back(56);
rotate(vec.begin(),vec.begin()+3,vec.end());//(85,56,74,56,92)
19:equal算法是判断两个容器是否相等,但首先得保证两个容器长度一样,排好序,否则没意义,且报错:
vector<int> vec,vec2;
vec.push_back(74);
vec.push_back(56);
vec.push_back(92);
vec.push_back(85);
vec.push_back(85);
vec2.push_back(92);
vec2.push_back(156);
vec2.push_back(1526);
//bool a= equal(vec.begin(),vec.end(),vec2.begin());//error
bool a= equal(vec2.begin(),vec2.end(),vec.begin());//error
20:find_if算法,找到满足条件的第一个:
bool fun6(int ii)
{
return ii==3;
}
class Fun5  : public binary_function<int, int, bool>
{
public:
bool operator () (const int & v1,const int & v2) const 
{
return v1==v2;
}
//Functor的对象就是函数符
};
vector<int> vec,vec2;
vector<int>::iterator iter;
vec.push_back(74);
vec.push_back(56);
vec.push_back(92);
vec.push_back(85);
vec.push_back(85);
vec2.push_back(92);
vec2.push_back(156);
vec2.push_back(1526);
iter= find(vec.begin(),vec.end(),85);
int g=92;
iter= find_if(vec.begin(),vec.end(),fun6);
iter= find_if(vec.begin(),vec.end(),bind2nd(Fun5(),g));
21:find_end算法是在一个区间中查找等于(需要连续相等)另一个区间所有元素,然后取出最后一个连续相等的最后一次的手元素的迭代器,
find_first_of跟find_end返回的结果刚好相反:
vector<int> vec,vec2;
vector<int>::iterator iter;
vec.push_back(74);
vec.push_back(56);
vec.push_back(92);
vec.push_back(156);
vec.push_back(85);
vec.push_back(92);
vec.push_back(156);
vec.push_back(9911);
vec2.push_back(92);
vec2.push_back(156);
vec2.push_back(1526);
iter= find_end(vec.begin(),vec.end(),vec2.begin(),vec2.begin()+2);//92
iter=iter+2;//9911
iter= find_first_of(vec.begin(),vec.end(),vec2.begin(),vec2.begin()+2);//92
iter=iter+2;//85
22:equal_range=lower_bound+upper_bound,获取某个数据可插入的前后位置,且此位置在插入后不影响容器的大小排序:
vector<int> vec,vec2;
vector<int>::iterator iter;
vec.push_back(74);
vec.push_back(56);
vec.push_back(92);
vec.push_back(156);
vec.push_back(85);
vec.push_back(92);
vec.push_back(156);
vec.push_back(9911);
sort(vec.begin(),vec.end());
iter= lower_bound(vec.begin(),vec.end(),92);//92
iter= upper_bound(vec.begin(),vec.end(),92);//156
pair<vector<int>::iterator,vector<int>::iterator> pa= equal_range(vec.begin(),vec.end(),92);//<92,156>
23:next_permutation,prev_permutation算法分别是后去下一个和上一个全排列的组合,最好先sort排次序,再用。比如(a,b,c)的全排列为
{a, b, c}、{a, c, b}、{b, a, c}、{b, c, a}、{c, a, b}、{c, b, a}而(a,c,b)的上一个全排序就为(a, b, c),
(a,c,b)的下一个全排序就为(b, a, c):
vector<string> vec,vec2;
vector<string>::iterator iter;
vec.push_back("c");
vec.push_back("a");
vec.push_back("b");
sort(vec.begin(),vec.end());
while (next_permutation(vec.begin(),vec.end()))
  cout<<vec<<endl;
24:search,search_n算法是分别指返回某个数据连续出现1次和连续出现n次的第一次出现迭代器:
vector<string> vec,vec2;
vector<string>::iterator iter;
vec.push_back("c");
vec.push_back(",");
vec.push_back("a");
vec.push_back(",");
vec.push_back(",");
vec.push_back("b");
iter= search_n(vec.begin(),vec.end(),2,",");//,
iter=(iter+1);//,
iter=(iter+1);//b
25:includes算法是指一个区间是否包含另一个区间的值,前提是这两个区间需要有序:
vector<string> vec,vec2;
vector<string>::iterator iter;
vec.push_back("c");
vec.push_back(",");
vec.push_back("a");
vec.push_back(",");
vec.push_back(",");
vec.push_back("b");
vec2.push_back("a");
vec2.push_back("c");
sort(vec.begin(),vec.end());
sort(vec2.begin(),vec2.end());
bool bol= includes(vec.begin(),vec.end(),vec2.begin(),vec2.end());//true
26:accumulate“求和”算法

 

accumulate(A.begin(),A.end(),10);    //可以理解为10+A[1]+A[2]+…

accumulate(A.begin(),A.end(),10,minus<int>());    //可以理解为10-A[1]-A[2]-…

int myfunction (int x, int y) 
{
int z= x+2*y;
return z;
}

int init = 100;
int numbers[] = {10,20,30};

int c=std::accumulate (numbers, numbers+3, init, myfunction);//可以理解为myfunction(myfunction(100, numbers[0]), numbers[1])......

27:set_intersection求交集

vector<string> intersect(vector<string>vec1, vector<string> vec2)
{
vector<string> vec;
sort(vec1.begin(), vec1.end());
sort(vec2.begin(), vec2.end());
set_intersection(vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), back_inserter(vec));
return vec;
}

 



------------------volatile 关键字的使用(搞嵌入式的行业会经常遇到这个关键字)

http://blog.csdn.net/wwang196988/article/details/6623387

1:cpu寄存器放一个从内存拷贝的版本,内存一个版本,共两个版本,如果两个线程同时使用此变量的时候难保证会使用的都是cpu寄存器版本的变量或者是内存的那个版本的变量。

2:编译器可能会优化访问此volatile变量的代码,即可能从寄存器中获取,或者从内存中获取此volatile变量,如果没加volatile关键字的话这是由编译器决定的,如果加了volatile关键字则每次都会从内存中获取此变量。


----------------可变参数:

http://bbs.chinaunix.net/thread-4058976-1-1.html

http://blog.csdn.net/llg521208/article/details/6128744

string sprintfs(const char * fmt, ...){
char szBuffer[1024]={0};
va_list ap;
va_start(ap, fmt);
vsnprintf_s(szBuffer, 1024, fmt, ap);
va_end(ap);

return string(szBuffer);
}

-------------------stl 仿函数适配器 (即绑定)bind2nd和bind1st绑定

http://larrytang.iteye.com/blog/850260

http://blog.csdn.net/xuqing1980/article/details/1269424

http://blog.csdn.net/simahao/article/details/405455

http://blog.csdn.net/garfier/article/details/8062141

-----------------remove_if的用法:

http://blog.sina.com.cn/s/blog_68c02fb90100xhoi.html

-----------------stl迭代器:

http://www.cnblogs.com/L-hq815/archive/2012/08/28/2660714.html

http://blog.csdn.net/fall221/article/details/8233606

http://blog.csdn.net/fdl19881/article/details/6685744------istream_iterater的使用

http://blog.csdn.net/bichenggui/article/details/4710996    ---------可以使用istreambuf_iterater读取字符,而istream_iterater不行,因为会忽略空格。

http://www.cnblogs.com/HappyAngel/archive/2011/05/03/2035636.html

http://zhidao.baidu.com/link?url=0epEJwCKfpmtuomAfpbh433WC-XCQn5yedicQmXgecb0eOxsKr3iyKDUShx20lvp4236Zgsaw3IFG5_QFEF8Ha  ----容器适配器

----------------stl算法

http://www.cplusplus.com/reference/algorithm/equal/?kw=equal  ------------算法查找demo

http://www.cppblog.com/mzty/archive/2005/12/15/1770.html  ----------排序算法

http://wenku.baidu.com/view/f1855128cfc789eb172dc88d.html

http://www.cnblogs.com/yuehui/archive/2012/06/19/2554300.html


------------------------------stl缺少正则:

可以使用pcre来进行正则使用:

 

[plain]  view plain  copy
  1. C++中使用Regex一直是个麻烦事,为了小小的Regex安装boost库实在不是什么能让人感觉到兴奋的事情。http://iregex.org/的老大推荐了http://www.pcre.org/,感觉非常非常的不错。有兴趣的朋友绝对值得去研究一下。  
  2.          Win下的版本可以从http://www.psyon.org/projects/pcre-win32/index.php, 或http://gnuwin32.sourceforge.net/packages/pcre.htm获取。  


下载pcre-----http://dearymz.blog.163.com/blog/static/20565742008724104826358/

 

安装pcre---------cmd==>cd 下载的文件夹中==>nmake -f makefile

示例----------------http://www.wuzesheng.com/?p=994                     http://www.oschina.net/code/snippet_203297_7559


---------------------------在window下给某个窗体发送wm_command命令

 

[cpp]  view plain  copy
  1. HWND pHwnd= FindWindow(NULL, sDataCheckPlatformName.c_str());//"数据检查平台 5.0.0.0 版"  
  2.     ::SendMessage( pHwnd, WM_COMMAND, IDM_ANNDM_EXE, NULL);  

-------获取当前时间

 

 

[cpp]  view plain  copy
  1. string GetNowTime()  
  2. {  
  3.     struct tm *newtime;  
  4.     char tmpbuf[128];  
  5.     time_t lt1;  
  6.     time( <1 );  
  7.     newtime=localtime(<1);  
  8.     strftime( tmpbuf, 128, "%m-%d,%H:%M:%S", newtime);  
  9.     return tmpbuf;  
  10. }  


---------------------字符串split切割

 

 

[cpp]  view plain  copy
  1. std::vector<std::string> split(std::string str,std::string pattern)  
  2. {  
  3.     std::string::size_type pos;  
  4.     std::vector<std::string> result;  
  5.     str+=pattern;//扩展字符串以方便操作  
  6.     int size=str.size();  
  7.       
  8.     for(int i=0; i<size; i++)  
  9.     {  
  10.         pos=str.find(pattern,i);  
  11.         if(pos<size)  
  12.         {  
  13.             std::string s=str.substr(i,pos-i);  
  14.             result.push_back(s);  
  15.             i=pos+pattern.size()-1;  
  16.         }  
  17.     }  
  18.     return result;  
  19. }  


------------------字符串trim

 

 

[cpp]  view plain  copy
  1. inline static string& left(string& str)   
  2. {   
  3.     string::size_type index = str.find_first_not_of(" \n\r\t,");  
  4.     if (index != string::npos){str = str.substr(index);}  
  5.     return  str;  
  6. }  
  7.   
  8. inline static string& right(string& str)   
  9. {   
  10.     string::size_type index = str.find_last_not_of(" \n\r\t,");  
  11.     if (index != string::npos){str = str.substr(0, index + 1);}  
  12.     return str;  
  13. }  
  14.   
  15. inline static string& trim(string& str)   
  16. {   
  17.     return left(right(str));   
  18. }  

 

---------------------------------类似shell命令,执行exe

 

[cpp]  view plain  copy
  1. long ShellExe(const string& strcmdline, string sDataCheckPlatformLogPath, string sDataCheckPlatformName)  
  2. {  
  3.     PROCESS_INFORMATION piprocinfo;  
  4.     STARTUPINFO sistartinfo;  
  5.     memset(&sistartinfo, 0, sizeof(sistartinfo)); // Set up memory block,这个很重要  
  6.     // set up members of startupinfo structure.  
  7.     sistartinfo.cb = sizeof(STARTUPINFO);  
  8.     sistartinfo.lpReserved = NULL;  
  9.     sistartinfo.lpReserved2 = NULL;  
  10.     sistartinfo.cbReserved2 = 0;  
  11.     sistartinfo.lpDesktop = NULL;  
  12.     sistartinfo.dwFlags = 0;  
  13.     char strcmd[1000]={0};  
  14.     strcpy(strcmd, strcmdline.c_str());  
  15.     CreateProcess (  
  16.         NULL,  
  17.         strcmd,  
  18.         NULL, // process security attributes  
  19.         NULL, // primary thread security attributes  
  20.         0, // handles are inherited  
  21.         0, // creation flags  
  22.         NULL, // use parent\'s environment  
  23.         NULL, // use parent\'s current directory  
  24.         &sistartinfo, // startupinfo pointer  
  25.         &piprocinfo); // receives process_information  
  26.       
  27.     Sleep(5000);//为了启动界面  
  28.       
  29.     LARGE_INTEGER BegainTime ;   
  30.     LARGE_INTEGER EndTime ;   
  31.     LARGE_INTEGER Frequency ;  
  32.     QueryPerformanceFrequency(&Frequency);  
  33.     QueryPerformanceCounter(&BegainTime);  
  34.       
  35.     //功能性代码放在这里  begin----------------------------------------------------  
  36.     HWND pHwnd= FindWindow(NULL, sDataCheckPlatformName.c_str());//"数据检查平台 5.0.0.0 版"  
  37.     ::SendMessage( pHwnd, WM_COMMAND, IDM_ANNDM_EXE, NULL);  
  38.     //功能性代码放在这里  end ----------------------------------------------------  
  39.       
  40.     long lWaitTime=500;//每隔0.5s检测一次  
  41.     string sStartProcessTime= GetNowTime();  
  42.     do  
  43.     {  
  44.         WaitForSingleObject(piprocinfo.hProcess, lWaitTime);  
  45.     } while (!IsProcessOver(sDataCheckPlatformLogPath, sStartProcessTime));//数据检查平台运行日志  
  46.   
  47.     QueryPerformanceCounter(&EndTime) ;  
  48.     long lCostTime=( EndTime.QuadPart - BegainTime.QuadPart )*1000 / Frequency.QuadPart ;  
  49.       
  50.     TerminateProcess(piprocinfo.hProcess, 0);  
  51.     return lCostTime;  
  52. }  


--------------------------处理xml的时候可以使用tinyxml

http://qaohao.iteye.com/blog/496237


--------------------------安装vs2010的时候编译的时候可能会碰到 "LNK1123: 转换到 COFF 期间失败: 文件无效或损坏" 错误

解决方案:http://blog.chinaunix.net/uid-20385936-id-3506149.html

下载cvtres.exe然后覆盖“C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\cvtres.exe”(如果vs2010安装的c盘的话)


----------------------------磁盘操作

 

[cpp]  view plain  copy
  1. vector<string> GetLogicalDriveStrings()  //获取所有磁盘  
  2. {    
  3.     vector<string> vectDrive;  
  4.     DWORD dwDiskCount= 0;  
  5.       
  6.     DWORD dwBitMask = GetLogicalDrives();  
  7.       
  8.     for (DWORD dw = 0 ;dw<26;dw++)  
  9.     {         
  10.         if (dwBitMask&1)  
  11.         {             
  12.             dwDiskCount++;  
  13.         }  
  14.         dwBitMask=dwBitMask>>1;  
  15.     }  
  16.     printf("Logical Disk Count %d\n",dwDiskCount);    
  17.     DWORD dwDriveStrLen = 0;      
  18.     dwDriveStrLen= GetLogicalDriveStrings(0,NULL);    
  19.     TCHAR *szDriveName = new char[dwDriveStrLen];     
  20.     TCHAR *pDriveName=NULL;   
  21.     if (GetLogicalDriveStrings(dwDriveStrLen,szDriveName))        
  22.     {         
  23.         pDriveName = szDriveName;         
  24.         while (*pDriveName!=NULL)             
  25.         {             
  26.             printf("%s\n",pDriveName);    
  27.             long lDriveType =GetDriveType(pDriveName);  
  28.             switch (lDriveType)               
  29.             {                 
  30.             case DRIVE_UNKNOWN :                  
  31.                 break;                
  32.             case DRIVE_NO_ROOT_DIR:                   
  33.                 break;                
  34.             case DRIVE_REMOVABLE :                
  35.                 break;                
  36.             case DRIVE_FIXED :    
  37.                 vectDrive.push_back(pDriveName);  
  38.                 break;                
  39.             case DRIVE_REMOTE:                
  40.                 break;                
  41.             case DRIVE_CDROM:                 
  42.                 break;                
  43.             case DRIVE_RAMDISK:                   
  44.                 break;                
  45.             default:                  
  46.                 break;                
  47.             }                         
  48.             pDriveName+=lstrlen(pDriveName)+1;            
  49.         }         
  50.     }     
  51.     else          
  52.     {         
  53.         printf("GetLogicalDriveStrings Failed,%d",GetLastError());        
  54.     }  
  55.     return vectDrive;  
  56. }    
  57.   
  58. long GetFreeG(string sDirectoryName)  //获取磁盘空间大小  
  59. {    
  60.     long lG= 0;  
  61.     ULARGE_INTEGER nFreeBytesAvailable;  
  62.     ULARGE_INTEGER nTotalNumberOfBytes;  
  63.     ULARGE_INTEGER nTotalNumberOfFreeBytes;  
  64.     if (GetDiskFreeSpaceEx(sDirectoryName.c_str(),  
  65.         &nFreeBytesAvailable,  
  66.         &nTotalNumberOfBytes,  
  67.         &nTotalNumberOfFreeBytes))  
  68.     {  
  69.         lG= nTotalNumberOfFreeBytes.QuadPart/1024/1024/1024;  
  70.     }  
  71.     return lG;  
  72. }  

 

---------------------------讲一个数组平均分配成M份

 

[cpp]  view plain  copy
  1. double array_sum(string *arr, int length)  
  2. {  
  3.     double sum = 0;  
  4.     for (long i=0; i<length; i++)  
  5.     {  
  6.         string sline= arr[i];  
  7.         vector<string> vectkv= split(sline, ",");  
  8.         sum += atof(vectkv[1].c_str());  
  9.     }  
  10.     return sum;  
  11. }  
  12.   
  13. //将vectSrc平均分配成m组  
  14. map<long, vector<string> > AvgAlloc(vector<string> vectSrc, long m)  
  15. {  
  16.     map<long, vector<string> > mapassign;  
  17.     vector<string> vectEnable;  
  18.     string ** pgroup= NULL;  
  19.     long n= vectSrc.size();  
  20.     pgroup= new string* [m];  
  21.     for (long i=0;i<m;i++)  
  22.         pgroup[i]= new string[n];  
  23.     for (long i=0;i<m;i++)  
  24.         for (long j=0;j<n;j++)  
  25.             pgroup[i][j]= ZERO;  
  26.     int *g =new int[m];  
  27.     for (long i=0;i<m;i++)  
  28.         g[i]= 0;  
  29.     //升序  
  30.     sort(vectSrc.begin(), vectSrc.end(), cmp);  
  31.     long x=0, y=0;  
  32.     for (long i=n-1;i>=0;i--)  
  33.     {  
  34.         long k=0;  
  35.         double dminM= MAXLONG;  
  36.         for (long j=0;j<m;j++)  
  37.         {  
  38.             if (dminM > array_sum(pgroup[j], n))  
  39.             {  
  40.                 dminM = array_sum(pgroup[j], n); /* 找出最小的 */  
  41.                 k = j; /* 记住是哪一组 */  
  42.             }  
  43.         }  
  44.         pgroup[k][g[k]] = vectSrc[i];  
  45.         g[k]= g[k]+1;  
  46.     }  
  47.   
  48.     for (long i=0;i<m;i++)  
  49.     {  
  50.         vector<string> vectline;  
  51.         for (long j=0;j<n;j++)  
  52.         {  
  53.             string sline= pgroup[i][j];  
  54.             if (sline==ZERO)  
  55.                 continue;  
  56.             vectline.push_back(sline);  
  57.         }  
  58.         if (vectline.size()>0)  
  59.             mapassign[i]= vectline;  
  60.     }  
  61.   
  62.     for (long i=0;i<m;i++)  
  63.         delete[] pgroup[i];  
  64.     delete[] pgroup;  
  65.     delete[] g;  
  66.     return mapassign;  
  67. }  
  68.   
  69. //test  将vectstats的字符串用逗号隔开的后面那个double作为对比值  
  70. vector<string> vectstats;  
  71. vectstats.push_back("24523542,75.6");  
  72. vectstats.push_back("23223542,15.6");  
  73. vectstats.push_back("33523542,125.3");  
  74. vectstats.push_back("84523542,5.3");  
  75. vectstats.push_back("94523542,35.3");  
  76. vectstats.push_back("74523542,56.9");  
  77. map<long, vector<string> > mapgroup= AvgAlloc(vectstats, vectmachine.size());  


----------------------在使用MFC的CString的时候不能如下使用,使用次数多了就会报错。

CString sErr;

sErr.Format("{%s}%s", sRoadLine, sErr);//会引起错误,崩溃。

stl::string ss="asdfsd";

sErr.Format("{%s}%s", sRoadLine, ss);//会引起错误,崩溃。需要将ss==>ss.c_str()


---------------------指针的注意:

 

[cpp]  view plain  copy
  1. #define DELETE_PTR(ptr) if(NULL!=ptr){delete(ptr);ptr=NULL;}   
  2. CNode *pWFTNode= NULL;//不用释放  
  3. CNode *pFNode= pRoad->GetFNodeEx();  
  4. pWFTNode=pFNode;  
  5. DELETE_PTR(pFNode);  
  6. DELETE_PTR(pWFTNode);//崩溃  


--------------------

CMD可以使用CreateProcess的方式来调用。

CreateProcess的第二个参数需要写成这样即可:“cmd.exe /c rd /s /q d:\aa”

/c 会自动退出, /k 则不会

引用
CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]
[[/S] [/C | /K] string]

/C 执行字符串指定的命令然后终断
/K 执行字符串指定的命令但保留

 

----------------字符串替换函数

 

[cpp]  view plain  copy
  1. void string_replace(std::string& strBig, const std::string & strsrc, const std::string &strdst)  
  2.   
  3. {  
  4.      std::string::size_type pos = 0;  
  5.      while( (pos = strBig.find(strsrc, pos)) != string::npos)  
  6.   
  7.      {  
  8.          strBig.replace(pos, strsrc.length(), strdst);  
  9.          pos += strdst.length();  
  10.      }  
  11. }  


----------得到路径的上N级目录

 

 

[cpp]  view plain  copy
  1. string getuplevel(string spath, long llevel)  
  2. {  
  3.     string senable;  
  4.     vector<string> vectpart= split(spath, "\\");  
  5.     long lsize= vectpart.size();  
  6.     for (long i=0;i<lsize-llevel;i++)  
  7.     {  
  8.         senable= senable+ vectpart[i]+ "\\";  
  9.     }  
  10.     return trim(senable);  
  11. }  

 

---------------------------异常捕获

对于C++的结构化异常 一般的try catch很难捕获,可以使用第三方的一个库"dbghelp"

当然,这一切都依赖于VC产生的程序数据库文件(pdb),以及提供以上API函数的dbghelp.dll。

http://download.csdn.net/download/ydsoft/4140786(dbghelp下载地址和使用方式)

在VC6中使用dbghelp的时候可能会报错"error C2146: syntax error : missing ';' before identifier 'ReqOffsets'",解决办法是在调用dbghelp.h文件的文件中加入一句:

typedef  unsigned long ULONG_PTR, *PULONG_PTR;

http://blog.csdn.net/mergerly/article/details/6288358(dbghelp使用方式)

http://blog.csdn.net/vblittleboy/article/details/6561868(解决Cannot use __try in functions that require object unwinding)

http://m.blog.csdn.net/blog/hlfkyo/6645369

http://www.debugease.com/vc/863098.html(对于vector的下标越界问题,vc6的stl库没有捕获而是交给了调用方,而vs2008以上版本的stl捕获了,不会再抛出给调用方。所以再vs2008中使用dbghelp的话还是捕获不到vector的数组越界异常。)

vs2010中尝试过,vs2010是可以的。



-----------------release模式下调试程序,可以如下设置:

 

vs2010中设置在Release模式下调试的方法:
1.工程项目上右键 -> 属性
2.c++ -> 常规 -〉调试信息格式    选  程序数据库(/Zi)或(/ZI), 注意:如果是库的话,只能(Zi)
3.c++ -> 优化 -〉优化            选  禁止(/Od)
4.连接器 -〉调试 -〉生成调试信息 选  是 (/DEBUG
vc6中<span data-mce-style="font-family: Arial, Helvetica, sans-serif;" style="font-family: Arial, Helvetica, sans-serif;">设置在Release模式下调试的方法:</span>
1、在Project Settings里选Settings For为All Configurations。
2、在C/C++标签中,Debug info 选 Program Database。
3、在Link 标签中,Category选 Debug,选中Debug info 复选框和Microsoft format。

 

---------------------PathFileExists的使用需要加入如下内容才可。

#include "Shlwapi.h"

#pragma comment(lib,"Shlwapi.lib")

---------------------获取文件夹大小:http://www.cppblog.com/humanchao/archive/2012/09/28/55154.html

----------数据对齐

对于C++中的结构体对齐可以按照以下规则进行计算:

http://www.cnblogs.com/graphics/archive/2010/08/12/1797953.html

 

// rarf.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

struct Node_X
{
    short a;//2
    int c;//4
    double b;//8
    char d;//1
};//24

struct Node
{
    double b;//8
    short a;//2
    int c;//4
    char d;//1
};//24

struct Node2
{
    char a;//1
    int b;//4
    double c;//8
    Node d;//24
};//40

struct Node3
{
    int b;//4
    Node2 a;//40    
};//48

struct Node4
{
    Node2 a;//40    
    int b;//4
};//48

struct C
{
    char a;//1
    int b;//4
    short c;//2
};//12

struct D
{
    char b;//1
};//1

//对sizeof(E)=对sizeof(C)+size(D)求int(4字节)的倍数(此处的8字节是因为结构体C和D中最大的类型是int)
struct E
{
    C c1;//12
    D d1;//1
};//16

int _tmain(int argc, _TCHAR* argv[])
{
    int xx_x= sizeof(Node_X);//24
    int xx= sizeof(Node);//24
    int xx2= sizeof(Node2);//40
    int xx3= sizeof(Node3);//48
    int xx4= sizeof(Node4);//48

    int xx5= sizeof(C);//12
    int xx6= sizeof(D);//1
    int xx7= sizeof(E);//16
    return 0;
}

 ------------------左右移

左移一位相当于乘以2。

右移一位相当于除以2。

cout<<(4<<1)<<endl;//4*2
cout<<(4>>1)<<endl;//4/2

----------------无法定位程序输入点 _except_handler4_common 于动态链接库 msvcrt.dll上。

删除exe统计目录下所有以“ms”开头的dll,只留下msvcp100.dll和msvcr100.dll即可。

如果这样还是报出此错误,则需要将xp下的c:\window\system32下的所有dll拷贝到自己的软件中,然后就没问题了。

---------半角转全角

View Code

---------全角转半角

View Code

---------c++写入,修改ini配置文件

GetPrivateProfileString:得到ini下某个group下的一个key-value
GetPrivateProfileSection:得到ini下group下的全部key-values
WritePrivateProfileString:向ini下一个group中写一个key-value

--------使用c++的时候有时候会出现中文乱码,解决方法如下:

View Code

 -----------------类中const方法和普通方法:

1:普通对象能调用const方法和普通方法。

2:const对象只能调用const方法。

-----------------const 指针引用

1:const 修改的永远只有左边的内容。

2:引用(&)永远只是引用,不会将等号右边的变量clone一个临时变量赋给等号左边。

分析这种情况的方法:

先分析指针,什么样类型的指针才能赋值给什么样类型的指针。完了在分析引用,引用只是一个引用而已(不是赋值)。

const int * p=NULL;这种写法等同于int const * p= NULL;//const永远修饰的是其左边的内容。

的含义是p指针所指的值(int的内容)不能改变(即类似可以修改*p=137),但是可以改变p指针本身(即类似可以修改p=0XF78AC07)。//0XF78AC07指的是一个地址。

再次需要注意的是:const int *p=......和const int *&p=......的区别,“=”号都是将等号右边的值clone一份赋值给左边,但是如果等号左边有了“&”则等号右边的值不需要clone,而是直接赋值给等号左边。

需要指明一点的是:“&a”其实获取到的是一个整数(常量)。类似地举个例子如下:

[cpp]  view plain  copy
  1. int k=234;  
  2. int & v= k;  
是没有问题的。但是

[cpp]  view plain  copy
  1. int & v= 123;//error C2440: 'initializing' : cannot convert from 'int' to 'int &'  
是有问题的。


情况1:这种写法没有问题:

[cpp]  view plain  copy
  1. int a=123;  
  2. const int *b= &a;  
  3. const int * &p =b;  
情况2: 这种写法有问题,因为b不是const char *:error C2440: 'initializing' : cannot convert from 'int *' to 'const int *&'

[cpp]  view plain  copy
  1. int a=123;  
  2. int *b= &a;  
  3. const int * &p =b;  

情况3: 这种写法也有问题,

[cpp]  view plain  copy
  1. int a=123;  
  2. const int * &p =&a;//error: initial value of reference to non-const must be an lvalue  
[cpp]  view plain  copy
  1. int * &p =&a;//error C2440: 'initializing' : cannot convert from 'int *' to 'int *&'  

情况4:这种情况就没问题:

[cpp]  view plain  copy
  1. int a=123;  
  2. int * b= &a;  
  3. int   * &p =b;//在情况3的时候会报错,在此处没报错的原因是“&a”是临时指针(这个临时指针本身不允许改变),临时指针不能在初始化时使用引用(&)给等号左边,需要变量化。  

情况5:这种情况就没问题:

[cpp]  view plain  copy
  1. int a=123;  
  2. const int * p =&a;  

情况6:换成这种写法,没问题了:=====一个指向常量对象的常量指针

[cpp]  view plain  copy
  1. int a=123;  
  2. const int * const &p =&a;//将临时指针(&a)已引用方式赋值给等号左边,如果非要这么用则需要等号左边将此指针本身设为const才可。  

-------------------------------------------指针的指针:

[cpp]  view plain  copy
  1. int a=123;  
  2. int * b= &a;  
  3. int * * c= &b;    
  4. const int  *  *  p=  c;//error C2440: 'initializing' : cannot convert from 'int **' to 'const int **'  
  5. const int  *  *  p=  (const int **)c;//没问题,需要强转才可。可能是vs编译器这样规定的吧。gcc不知道会不会不用强转。  


-------------------------------------IDE模板定义的区别

vs2008以上的IDE需要如下的写法:

typedef typename map<T_Key, T_Value* >::iterator   map_It;

而vc6这样既可:

typedef /*typename*/ map<T_Key, T_Value* >::iterator   map_It;


-------------------------------------vc控制台使用MFC的CString,两部完成:

1:在“stdafx.h”中加入 #include <afx.h>

3:将工程的“属性”-->“常规”-->“MFC使用”改为“在共享 DLL 中使用 MFC”既可。

-------------------------static和extern的注意

在".h"头文件中static允许其他地方有重复,而extern不可以。

 在头文件中最好使用extern而少用static。

-------------------------debug下和release下对于有些区别:

1:对于const char * pszCHN和"dfdsgfsfge"的比较不能直接用“==”号。debug下回没问题但是release下会比较的是指针本身。

2:对于int类型的变量在debug下如果没有初始化会是一个负值,但是在release下会是一个正值。

------------------virtual

http://www.cnblogs.com/fanzhidongyzby/archive/2013/01/14/2859064.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值