知識(shí)結(jié)構(gòu): 1、if,for,switch,goto 2、#define,const 3、文件拷貝的代碼,動(dòng)態(tài)生成內(nèi)存,復(fù)合表達(dá)式,strcpy,memcpy,sizeof 4、函數(shù)參數(shù)傳遞,內(nèi)存分配方式,內(nèi)存錯(cuò)誤表現(xiàn),malloc與new區(qū)別 5、類(lèi)重載、隱藏與覆蓋區(qū)別,extern問(wèn)題,函數(shù)參數(shù)的缺省值問(wèn)題,宏代碼與內(nèi)聯(lián)函數(shù)區(qū)別 6、構(gòu)造和析構(gòu)的次序,String函數(shù)定義
具體實(shí)現(xiàn): 1、if,for,switch,goto if: bool int float pointer char 變量的使用方法 bool bParam; int iParam; float fParam; int* pParam; char cParam; if(bParam) ,if(!bParam); if(iParam == 0 ),if(iParam != 0 ); if(fParam>= -0.00001 && fParam <= 0.00001); if(pParam == NULL),if(pParam != NULL); if(cParam == '\0'),if(cParam != '\0');
if/else/return 的使用方法 if(condition) 可以等價(jià)為 return (condition?x:y); { return x; } else { return y; }
for: 執(zhí)行效率問(wèn)題: int row,col,sum; int a[100][5]; for(row=0;row <100;row++) 效率低于 for(col=0;col <5;col++) { { for(col=0;col <5;col++) for(row=0;row <100;row++) { { sum = sum+a[row][col]; sum = sum+a[row][col]; } } } }
int i; for(i=0;i <N;i++) 效率低于 if(condition) { { if(condition) for(i=0;i <N;i++) DoSomething(); DoSomething(); else } DoOtherthing(); else } { for(i=0;i <N;i++) DoOtherthing(); }
for (int x=0;x <=N-1;x++) 直觀性差于 for (int x=0;x <N;x++)
switch: switch(variable) { case value1: ... break; case value2: ... break; default: ... break; } switch(c)中的c的數(shù)據(jù)類(lèi)型可以是int,char,long,unsigned int,bool. variable必須是整數(shù)或者強(qiáng)制為整數(shù),由于char實(shí)際上是ASCII碼,所以也可以. c不可以是double,float,char*.
goto: goto主要用于 {... {... {.... goto error; } } }
error: ...
2、#define,const #define和const區(qū)別 1、#define C語(yǔ)言 const C語(yǔ)言 C++語(yǔ)言 const常量有數(shù)據(jù)類(lèi)型,編譯器會(huì)進(jìn)行類(lèi)型安全檢查,而#define沒(méi)有數(shù)據(jù)類(lèi)型, const的常量可以進(jìn)行調(diào)試,但宏常量不能進(jìn)行調(diào)試. 2、const的使用方法 在全局定義 const float PI=3.1415926 在類(lèi)中定義 class A {... A(int size); const int SIZE; }; A::A(int size):SIZE(size) { ... } 對(duì)參數(shù)和函數(shù)的定義(const只能修飾輸入?yún)?shù),不能修飾輸出參數(shù)) const int x=1; 表示x的值是1,在程序中不能改變; const int* x; 表示x代表的地址所指向的內(nèi)容是不能改變得; int const* x; 與const int* x;的表示的意思一樣; int * const x; 表示x代表的地址是不能改變的;
當(dāng)是輸入?yún)?shù)時(shí),不需要是void Func(const int i),void Func(const int& i),可以是void Func(int i) 因?yàn)檩斎雲(yún)?shù)采用"值傳遞"(const int i),由于函數(shù)將自動(dòng)產(chǎn)生臨時(shí)變量用于復(fù)制該參數(shù),該輸入?yún)?shù)本來(lái)就無(wú)需保護(hù),所以不要加const修飾; 不用const int& i的原因在于內(nèi)部數(shù)據(jù)類(lèi)型的參數(shù)不存在構(gòu)造、析構(gòu)的過(guò)程,而復(fù)制也非常快,"值傳遞"和"引用傳遞"的效率幾乎相當(dāng).
當(dāng)是輸入?yún)?shù)時(shí),不需要是void Func(const A a),void Func(A a),可以是void Func(A& a)或void Func(const A& a) 不用const A a,A a的原因是函數(shù)的效率比較低,因?yàn)楹瘮?shù)體內(nèi)將產(chǎn)生A類(lèi)型的臨時(shí)對(duì)象用于復(fù)制參數(shù)a,而臨時(shí)對(duì)象的構(gòu)造、復(fù)制和析構(gòu)過(guò)程都需要消耗時(shí)間 最好用const A&a的原因是A&a中的a可以被改變,A&a和const A&a的好處在于都不會(huì)產(chǎn)生臨時(shí)對(duì)象,效率高;
const A Func(const A&a )const的好處 第一個(gè)const表示返回的是個(gè)內(nèi)部產(chǎn)生的對(duì)象,它不能被修改 const A Func(...) {...} const A a=Func(...);//不能是A a=Func(...); 第二個(gè)const表示輸入的參數(shù)是引用傳遞,函數(shù)內(nèi)部不會(huì)產(chǎn)生臨時(shí)對(duì)象,而且這個(gè)對(duì)象不能被內(nèi)部修改 第三個(gè)const表示此函數(shù)內(nèi)部的所涉及的數(shù)據(jù)成員不能修改 class Stack { int m_num; int GetCount(void) const; int Pop(void); } int Stack::GetCount(void) const { m_num++;//編譯錯(cuò)誤,企圖修改數(shù)據(jù)成員m_num; Pop();//編譯錯(cuò)誤,企圖調(diào)用非const函數(shù) }
3、文件拷貝的代碼 #include <stdio.h> int main(int argc, char* argv[]) { printf("Hello World!\n"); FILE* in; FILE* out; in=fopen("d:\\1.txt","rb"); out=fopen("d:\\2.txt","wb"); char ch=fgetc(in); while(!feof(in)) { fputc(ch,out); ch=fgetc(in); } fclose(in); fclose(out); return 0; }
動(dòng)態(tài)生成內(nèi)存的代碼 ------------------------------------------ 正確代碼: void GetMemory(char **p, int num) { *p = (char *)malloc(sizeof(char) * num); } char* GetMemory2(int num) { char* p = (char *)malloc(sizeof(char) * num); return p; } ------------------------------------------ 錯(cuò)誤的代碼: void GetMemory3(char *p, int num) { p = (char *)malloc(sizeof(char) * num); }
------------------------------------------ void Test(void) { char *str = NULL; GetMemory(&str, 100); // 注意參數(shù)是&str,而不是str strcpy(str, "hello"); cout < < str < < endl; free(str);
str=NULL; str=GetMemory2(100); strcpy(str, "hello"); cout < < str < < endl; free(str);
str=NULL; GetMemory3(str, 100); // str 仍然為NULL strcpy(str, "hello"); // 運(yùn)行錯(cuò)誤 cout < < str < < endl;//運(yùn)行錯(cuò)誤 free(str);//運(yùn)行錯(cuò)誤 }
strcpy代碼 char* strcpy(char* strDest,const char* strSrc) { if(strDest==NULL||strSrc==NULL) return NULL; char* pStr=strDest; while((*strDest++=*strSrc++)!='\0) NULL; return pStr; }
復(fù)合表達(dá)式 d = (a = b + c) + r ; 該表達(dá)式既求a 值又求d 值.應(yīng)該拆分為兩個(gè)獨(dú)立的語(yǔ)句: a = b + c; d = a + r;
if (a < b < c) // a < b < c 是數(shù)學(xué)表達(dá)式而不是程序表達(dá)式 并不表示 if ((a <b) && (b <c)) 而是成了令人費(fèi)解的 if ( (a <b) <c )
memcpy代碼 void* memcpy(char* strDest,const char* strSrc,size_t size) { if(strDest==NULL||strSrc==NULL) return NULL; if(size <=0) return NULL; char* pStr=strDest; while(size-->0) *strDest++=*strSrc++; return pStr; }
sizeof: i.在32位操作系統(tǒng)中,基本數(shù)據(jù)類(lèi)型 類(lèi)型 字節(jié)長(zhǎng)度 char 1 short 2 short int 2 signed short 2 unsigned short 2 int 4 long int 4 signed int 4 unsigned int(unsigned) 4 long 4 unsigned long 4 float 4 double 8 void* 4 (所有指針類(lèi)型長(zhǎng)度都一樣)(char*,int*,float*,double*) enum 4
ii.在32位操作系統(tǒng)中,定義或函數(shù)中的大小 char a[]="hello"; char b[100]; char *p=a; 類(lèi)型 字節(jié)長(zhǎng)度 sizeof(a) 6 sizeof(b) 100 sizeof(p) 4
void Func(char a[100]) { sizeof(a); //4 }
#pragma pack(1) struct A { int i; char j; }; sizeof(A) //5
#pragma pack(1) struct A { int o; int j; union { int i[10],j,k; };
}; sizeof(A) //48
#pragma pack(1) struct A { enum day{monring, moon, aftermoon}; }; sizeof(A) //1 sizeof(A::day) //4
|