前情提要:若是不涉及面向對象的部分,那麼C++語言和C語言的語法90%以上是同樣的,只不過略有擴充,用起來更爲方便而已。java
查看gcc版本:c++
E:\Program Files\MinGW\bin>gcc -v Reading specs from ./../lib/gcc/mingw32/3.4.5/specs Configured with: ../gcc-3.4.5-20060117-3/configure --with-gcc --with-gnu-ld --wi th-gnu-as --host=mingw32 --target=mingw32 --prefix=/mingw --enable-threads --dis able-nls --enable-languages=c,c++,f77,ada,objc,java --disable-win32-registry --d isable-shared --enable-sjlj-exceptions --enable-libgcj --disable-java-awt --with out-x --enable-java-gc=boehm --disable-libgcj-debug --enable-interpreter --enabl e-hash-synchronization --enable-libstdcxx-debug Thread model: win32 gcc version 3.4.5 (mingw vista special r3)
全部程序都在gcc 3.4.5下編譯運行。數組
//1.1程序的基本框架 //gcc warning:return type of 「main」 is not 「int」 #include "stdio.h" int main(){ printf("hello world\n"); return 0; } //1.3 C/C++語言的數據類型 //說明數據類型之間的自動轉換 int main(){ int n1=1378; short n2; char c='a'; double d1=7.809; double d2; n2=c;//n2 becaming 97 printf("c=%c,n2=%d\n",c,n2); c=n1; //char型變量只有一個字節,int型爲兩個字節 //1387十六進制爲562,char型的c只獲得了62,變成十進制即爲98 //故輸出c=b printf("c=%c,n1=%d\n",c,n1); n1=d1; //n1變爲7 printf("n1=%d\n",n1); d2 = n1; printf("d2=%f\n",d2); return 0; } //1.4常量 #define MAPLENGTH 100 #define MAPWIDTH 80 int main(){ int mapSize; mapSize=MAPLENGTH*MAPWIDTH; printf("the map size is %d\n",mapSize); } //1.5 運算符和表達式 //算術運算符之除法運算符 int main(){ int a=10; int b=3; double d=a/b; printf("%f\n",d); d=5/2; printf("%f\n",d); d=5/2.0; printf("%f\n",d); d=(double)a/b; printf("%f\n",d); return 0; } //1.5 運算符和表達式 //算術運算符之自增自減運算符 int main(){ int n1,n2=5; n2++; ++n2; n1=n2++; n1=++n2; printf("n1=%d,n2=%d\n",n1,n2); } //1.5 運算符和表達式 //位運算符之左移運算符 int main(){ int n1=15; short n2=15; unsigned short n3=15; unsigned char c=15; n1<<=15; n2<<=15; n3<<=15; c<<=6; printf("n1=%x,n2=%d,n3=%d,c=%x,c<<4=%d",n1,n2,n3,c,c<<4); return 0; } //1.5 運算符和表達式 //位運算符之右移運算符 #include "stdio.h" int main(){ int n1=15; short n2=-15; unsigned short n3=0xffe0; unsigned char c=15; n1=n1>>2; n2>>=3; n3>>=4; c>>=3; printf("n1=%x,n2=%d,n3=%x,c=%x",n1,n2,n3,c); return 0; } //1.9 函數 #include "stdio.h" int multiple(int x,int y); //函數聲明 int main(){ int a=0,b=0; scanf("%d%d",&a,&b); printf("%d\n",multiple(a,b)); return 0; } int multiple(int x,int y) return x*y; } //1.12 數組 //我擦,輸入100個參數,有沒有搞錯啊 #include "stdio.h" #define MAX_NUM 100 int main(){ int i,j; int an[MAX_NUM]; //下面輸入100個整數 for(i=0;i<MAX_NUM;i++){ scanf("%d",&an[i]); } //排序 for(i=0;i<MAX_NUM-1;i++){ int nTmpMin=i; for(j=i;j<MAX_NUM;j++){ if(an[j]<an[nTmpMin]) nTmpMin=j; } //置換 int temp=an[i]; an[i]=an[nTmpMin]; an[nTmpMin]=temp; } //輸出排序以後的元素 for(i=0;i<MAX_NUM;i++){ printf("%d\n",an[i]); } return 0; } //-------------------------------------- //1.13 字符串 //字符串常量&字符串變量,字符串變量包含\0結尾 #include "stdio.h" #include "string.h" int main(){ char szTitle[]="Prison Break"; char szHero[100]="Michael Scofield"; char szPrisonName[100]; char szResponse[100]; printf("what is the name of the Prison Break in %s\n",szTitle); //用scanf輸入字符串不能含有空格,可用gets取代之 scanf("%s",szPrisonName); //int strcmp(const char *s1,const char *s2) 比較字符串s1與s2的大小,並返回s1-s2 if(strcmp(szPrisonName,"Fox-River")==0){ printf("Yeah! Do you love %s?\n",szHero); } else{ strcpy(szResponse,"it seems you have't watched it!\n"); printf(szResponse); } szTitle[0]='t'; szTitle[3]=0;//等效於szTitle[3]='\0' printf(szTitle); return 0; }
指針通常規律:如有定義T *p;不論T是什麼類型,sizeof(T *)的值都是4.由於指針表示的是地址,而當前流行的cpu內存尋址範圍通常都是4GB即2^32,因此一個地址正好用32位,即4個字節表示。框架
tip1,不一樣類型的指針,若不通過強制類型轉換,是不能互相賦值的,ide
eg. pn=(int *)p;函數
tip2,兩個類型爲T的指針相減的意義:p1-p2=(地址p1-地址p2)/sizeof(T);工具
tip3,指針和整數相加的定義:n+p意爲,地址p+nXsizeof(T);oop
//1.14 指針 #include "stdio.h" int main(){ int *pn1,*pn2; char *pc1,*pc2; int n=4; pn1=(int *)100; pn2=(int *)200; printf("%d\n",pn2-pn1);//輸出25,由於(200-100)/sizeof(int)=100/4=25 pc1=(char *)pn1;//pc1地址爲100 pc2=(char *)pn2; printf("%d\n",pc1-pc2);//(100-200)/sizeof(char)=-100 printf("%d\n",(pn2+n)-pn1); int *pn3=pn2+n; printf("%d\n",pn3-pn1); printf("%d",(pc2-10)-pc1); return 0; } //1.14 指針 //指針和數組 #include "stdio.h" int main(){ int i,an[200]; int *p; p=an; *p=10; *(p+1)=20; p[0]=30; p[4]=40; for(i=0;i<10;i++)//循環賦值 *(p+i)=i; p++; printf("%d\n",p[0]); p=an+6; printf("%d\n",*p); return 0; } //1.14 指針 //bubble sort #include "stdio.h" void BubbleSort(int *pa,int nNum){ int i,j;//在for中定義i,j在gcc下會報錯:loop initial declaration used outside c99 mode for(i=nNum-1;i>0;i--){ for(j=0;j<i;j++){ if(pa[j]>pa[i]){ int temp=pa[j]; pa[j]=pa[i]; pa[i]=temp; } } } } #define NUM 5 int main(){ int an[NUM]={5,4,8,2,1}; BubbleSort(an,NUM); int i; for(i=0;i<NUM;i++){ printf("%d\n",an[i]); } return 0; } //1.14 指針 //字符串和指針 #include "stdio.h" #include "string.h" int main(){ char *p="Tom\n"; char szName[20]; char *pName=szName; scanf("%s",pName); printf(p); printf("Name is %s",pName); return 0; }
tip,void指針:主要用於內存複製,將內存中某一塊內容複製到另外一塊去,標準庫函數void *memcpy(void *dest,const void *src,unsigned int n);將地址src開始的n字節內容複製到地址dest,返回值是destspa
eg. memcpy(a2,a1,10*sizeof(int));線程
//1.14 指針 //1.14.8 函數指針定義形式:類型名(* 指針變量名)(參數類型1,參數類型2,···); #include "stdio.h" void PrintMin(int a,int b){ if(a<b) printf("%d",a); else printf("%d",b); } int main(){ void (*pf)(int ,int );//定義函數指針pf int x=4,y=5; pf=PrintMin; pf(x,y); return 0; } //1.14 指針 /* 1.14.8 C/C++中有一個快速排序的標準庫函數qsort,使用該函數可對任何類型一維數組排序 void qsort(void *base,int nele,unsigned int width, int (*pfCompare)(const void *,const void *)); qsort函數用法規定,「比較函數」原型應該是:int 函數名(const void *elem1,const void *elem2); 自主設置比較規則,*elem1要排在*elem2前面,則函數返回值必須爲負整數; 無所謂,則返回值爲0; 後面,則返回值必須爲正整數; */ #include "stdio.h" #include "stdlib.h" int MyCompare(const void *elem1,const void *elem2){ unsigned int *p1,*p2; p1=(unsigned int *) elem1; p2=(unsigned int *) elem2; return (*p1%10)-(*p2%10);//按個位數字大小來排序 } #define NUM 5 int main(){ unsigned int an[NUM]={8,123,11,10,4}; qsort(an,NUM,sizeof(unsigned int),MyCompare); int i; for(i=0;i<NUM;i++){ printf("%d, ",an[i]); } return 0; }
指針tip:1.14.9 指針和動態內存分配,1.14.10 誤用無效指針
//1.15 結構體 /* tip 結構體定義必定是以分號結束的, struct Student { ...}; Student stu1,stu2; 等價於: struct Student { ...} stu1,stu2; */ #include "stdio.h" #include "string.h" #include "stdlib.h" #define NUM 4 struct Student { unsigned ID; char szName[20]; float fGPA; }; Student MyClass[NUM]={ {1234,"Tom",3.78}, {1238,"Jack",3.25}, {1232,"Mary",4.00}, {1234,"Jone",2.78} }; int CompareID(const void *elem1,const void *elem2){ Student *p1=(Student *) elem1; Student *p2=(Student *) elem2; return ps1.ID-ps2.ID; } int CompareName(const void *elem1,const void *elem2){ Student *p1=(Student *) elem1; Student *p2=(Student *) elem2; return strcmp(ps1.szName,ps2.szName); } int main(){ int i; qsort(MyClass,NUM,sizeof(Student),CompareID); for(i=0;i<NUM;i++){ printf("%s",MyClass[i].szName); printf("\n"); } qsort(MyClass,NUM,sizeof(Student),CompareName); for(i=0;i<NUM;i++){ printf("%s",MyClass[i].szName); printf("\n"); } return 0; }
P62的代碼1.15結構體真是好奇怪,看不出爲何錯。。。
Mark:小工具,在線程序編譯器http://codepad.org調試結果以下:
Line 19: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'MyClass' 如下略
本地調錯信息以下
---------- gcc編譯並生成 ----------
sheldon.c:19: error: syntax error before "MyClass"
如下略
問題:明明定義了Student結構體,怎麼又說「Student」未聲明呢???
Answer:感謝@斯雷波 的關注和解答,以上代碼修改兩處後可在C++編譯環境調試經過。
2六、27行修改*p1 *p2爲*ps1 *ps2【打錯了】,28行修改點號爲箭頭;
31到33行作相似修改;
若不修改點號爲箭頭,codepad報錯以下
In function 'int CompareName(const void*, const void*)':
Line 33: error: request for member 'szName' in 'ps1', which is of non-class type 'Student*'
compilation terminated due to -Wfatal-errors.
在codepad設置爲C++語言或者使用VC++6.0均可以調試經過,本地gcc始終對19行報錯 error: syntax error before "MyClass";
Tip:28行的修改參考C中指針中點與箭頭區別
在c++中I若是是對象,就能夠經過"."來調用I中的成員變量。
若是I是指針的話,就不能經過"."來調用,而只能使用"->"來調用。
在C語言中不存在對象的概念。
這種狀況的出現是由於使用告終構,例如
struct CandyBar{
float weight;
int calorie;
};
在程序中
CandyBar snack={
2.3,
350
};
咱們就能夠用snack.weight來取得結構中的值。
這時是不能使用"->"來調用的,"->"符號指針對指針來講的。
以下狀況可使用"->"
CandyBar* bird;
bird->weight=2.33;
此時bird爲一個CandyBar結構的地址指針。因此可使用"->",而此時就不能使用 "."來操做。由於"." "至關於"對象的成員調用。