【POJ】第一章 C/C++語言概述

前情提要:若是不涉及面向對象的部分,那麼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,&middot;&middot;&middot;);
#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結構的地址指針。因此可使用"->",而此時就不能使用 "."來操做。由於"." "至關於"對象的成員調用。

相關文章
相關標籤/搜索