c語言經典編程282例,c語言編程200例

本文目錄一覽:

C語言經典編程282例,求這本書的PDF或是其他文檔的文件,在線等,高分獎勵!!!

找到了的話,在給我也發一份:

caochunhb@sina.com

謝謝!!!

============================================================Mr_Computer

求C語言經典編程282例,求這本書的PDF或是其他文檔的文件,我郵箱zhouqg_2008@126.com

【程序1】

題目:有1、2、3、4個數字,能組成多少個互不相同且無重複數字的三位數?都是多少?

1.程序分析:可填在百位、十位、個位的數字都是1、2、3、4。組成所有的排列後再去

掉不滿足條件的排列。

2.程序源代碼:

main()

{

int i,j,k;

printf(“\n”);

for(i=1;i5;i++)

 for(j=1;j5;j++)

for (k=1;k5;k++)

 {

if (i!=ki!=jj!=k)

printf(“%d,%d,%d\n”,i,j,k);

 }

}

【程序2】

題目:企業發放的獎金根據利潤提成。利潤(I)低於或等於10萬元時,獎金可提10%;利潤高

 於10萬元,低於20萬元時,低於10萬元的部分按10%提成,高於10萬元的部分,可可提

 成7.5%;20萬到40萬之間時,高於20萬元的部分,可提成5%;40萬到60萬之間時高於

 40萬元的部分,可提成3%;60萬到100萬之間時,高於60萬元的部分,可提成1.5%,高於

 100萬元時,超過100萬元的部分按1%提成,從鍵盤輸入當月利潤I,求應發放獎金總數?

1.程序分析:請利用數軸來分界,定位。注意定義時需把獎金定義成長整型。

2.程序源代碼:

main()

{

long int i;

int bonus1,bonus2,bonus4,bonus6,bonus10,bonus;

scanf(“%ld”,i);

bonus1=100000*0.1;bonus2=bonus1+100000*0.75;

bonus4=bonus2+200000*0.5;

bonus6=bonus4+200000*0.3;

bonus10=bonus6+400000*0.15;

 if(i=100000)

bonus=i*0.1;

 else if(i=200000)

 bonus=bonus1+(i-100000)*0.075;

else if(i=400000)

bonus=bonus2+(i-200000)*0.05;

 else if(i=600000)

 bonus=bonus4+(i-400000)*0.03;

else if(i=1000000)

bonus=bonus6+(i-600000)*0.015;

 else

bonus=bonus10+(i-1000000)*0.01;

printf(“bonus=%d”,bonus);

}

【程序3】

題目:一個整數,它加上100後是一個完全平方數,再加上168又是一個完全平方數,請問該數是多少?

1.程序分析:在10萬以內判斷,先將該數加上100後再開方,再將該數加上268後再開方,如果開方後

的結果滿足如下條件,即是結果。請看具體分析:

2.程序源代碼:

#i nclude “math.h”

main()

{

long int i,x,y,z;

for (i=1;i100000;i++)

 { x=sqrt(i+100); /*x為加上100後開方後的結果*/

y=sqrt(i+268); /*y為再加上168後開方後的結果*/

 if(x*x==i+100y*y==i+268)/*如果一個數的平方根的平方等於該數,這說明此數是完全平方數*/

printf(“\n%ld\n”,i);

 }

}

【程序4】

題目:輸入某年某月某日,判斷這一天是這一年的第幾天?

1.程序分析:以3月5日為例,應該先把前兩個月的加起來,然後再加上5天即本年的第幾天,特殊

情況,閏年且輸入月份大於3時需考慮多加一天。

2.程序源代碼:

main()

{

int day,month,year,sum,leap;

printf(“\nplease input year,month,day\n”);

scanf(“%d,%d,%d”,year,month,day);

switch(month)/*先計算某月以前月份的總天數*/

{

 case 1:sum=0;break;

 case 2:sum=31;break;

 case 3:sum=59;break;

 case 4:sum=90;break;

 case 5:sum=120;break;

 case 6:sum=151;break;

 case 7:sum=181;break;

 case 8:sum=212;break;

 case 9:sum=243;break;

 case 10:sum=273;break;

 case 11:sum=304;break;

 case 12:sum=334;break;

 default: printf(“data error”);break;

}

sum=sum+day; /*再加上某天的天數*/

 if(year%400==0||(year%4==0year%100!=0))/*判斷是不是閏年*/

leap=1;

 else

leap=0;

if(leap==1month2)/*如果是閏年且月份大於2,總天數應該加一天*/

sum++;

printf(“It is the %dth day.”,sum);}

【程序5】

題目:輸入三個整數x,y,z,請把這三個數由小到大輸出。

1.程序分析:我們想辦法把最小的數放到x上,先將x與y進行比較,如果xy則將x與y的值進行交換,

然後再用x與z進行比較,如果xz則將x與z的值進行交換,這樣能使x最小。

2.程序源代碼:

main()

{

int x,y,z,t;

scanf(“%d%d%d”,x,y,z);

if (xy)

{t=x;x=y;y=t;} /*交換x,y的值*/

if(xz)

{t=z;z=x;x=t;}/*交換x,z的值*/

if(yz)

{t=y;y=z;z=t;}/*交換z,y的值*/

printf(“small to big: %d %d %d\n”,x,y,z);

}

【程序6】

題目:用*號輸出字母C的圖案。

1.程序分析:可先用’*’號在紙上寫出字母C,再分行輸出。

2.程序源代碼:

#i nclude “stdio.h”

main()

{

printf(“Hello C-world!\n”);

printf(” ****\n”);

printf(” *\n”);

printf(” * \n”);

printf(” ****\n”);

}

【程序7】

題目:輸出特殊圖案,請在c環境中運行,看一看,Very Beautiful!

1.程序分析:字符共有256個。不同字符,圖形不一樣。

2.程序源代碼:

#i nclude “stdio.h”

main()

{

char a=176,b=219;

printf(“%c%c%c%c%c\n”,b,a,a,a,b);

printf(“%c%c%c%c%c\n”,a,b,a,b,a);

printf(“%c%c%c%c%c\n”,a,a,b,a,a);

printf(“%c%c%c%c%c\n”,a,b,a,b,a);

printf(“%c%c%c%c%c\n”,b,a,a,a,b);}

【程序8】

題目:輸出9*9口訣。

1.程序分析:分行與列考慮,共9行9列,i控制行,j控制列。

2.程序源代碼:

#i nclude “stdio.h”

main()

{

 int i,j,result;

 printf(“\n”);

 for (i=1;i10;i++)

{ for(j=1;j10;j++)

{

 result=i*j;

 printf(“%d*%d=%-3d”,i,j,result);/*-3d表示左對齊,佔3位*/

}

 printf(“\n”);/*每一行後換行*/

}

}

【程序9】

題目:要求輸出國際象棋棋盤。

1.程序分析:用i控制行,j來控制列,根據i+j的和的變化來控制輸出黑方格,還是白方格。

2.程序源代碼:

#i nclude “stdio.h”

main()

{

int i,j;

for(i=0;i8;i++)

 {

for(j=0;j8;j++)

 if((i+j)%2==0)

printf(“%c%c”,219,219);

 else

printf(” “);

 printf(“\n”);

 }

}

【程序10】

題目:打印樓梯,同時在樓梯上方打印兩個笑臉。

1.程序分析:用i控制行,j來控制列,j根據i的變化來控制輸出黑方格的個數。

2.程序源代碼:

#i nclude “stdio.h”

main()

{

int i,j;

printf(“\1\1\n”);/*輸出兩個笑臉*/

for(i=1;i11;i++)

 {

 for(j=1;j=i;j++)

   printf(“%c%c”,219,219);

 printf(“\n”);

 }

}

【程序11】

題目:古典問題:有一對兔子,從出生後第3個月起每個月都生一對兔子,小兔子長到第三個月

 後每個月又生一對兔子,假如兔子都不死,問每個月的兔子總數為多少?

1.程序分析: 兔子的規律為數列1,1,2,3,5,8,13,21….

2.程序源代碼:

main()

{

long f1,f2;

int i;

f1=f2=1;

for(i=1;i=20;i++)

 { printf(“%12ld %12ld”,f1,f2);

 if(i%2==0) printf(“\n”);/*控制輸出,每行四個*/

 f1=f1+f2; /*前兩個月加起來賦值給第三個月*/

 f2=f1+f2; /*前兩個月加起來賦值給第三個月*/

 }

}

【程序12】

題目:判斷101-200之間有多少個素數,並輸出所有素數。

1.程序分析:判斷素數的方法:用一個數分別去除2到sqrt(這個數),如果能被整除,

則表明此數不是素數,反之是素數。

2.程序源代碼:

#i nclude “math.h”

main()

{

 int m,i,k,h=0,leap=1;

 printf(“\n”);

 for(m=101;m=200;m++)

{ k=sqrt(m+1);

 for(i=2;i=k;i++)

 if(m%i==0)

{leap=0;break;}

 if(leap) {printf(“%-4d”,m);h++;

if(h%10==0)

printf(“\n”);

  }

 leap=1;

}

 printf(“\nThe total is %d”,h);

}

【程序13】

題目:打印出所有的“水仙花數”,所謂“水仙花數”是指一個三位數,其各位數字立方和等於該數

 本身。例如:153是一個“水仙花數”,因為153=1的三次方+5的三次方+3的三次方。

1.程序分析:利用for循環控制100-999個數,每個數分解出個位,十位,百位。

2.程序源代碼:

main()

{

int i,j,k,n;

printf(“‘water flower’number is:”);

 for(n=100;n1000;n++)

 {

i=n/100;/*分解出百位*/

j=n/10%10;/*分解出十位*/

k=n%10;/*分解出個位*/

if(i*100+j*10+k==i*i*i+j*j*j+k*k*k)

 {

 printf(“%-5d”,n);

 }

 }

printf(“\n”);

}

【程序14】

題目:將一個正整數分解質因數。例如:輸入90,打印出90=2*3*3*5。

程序分析:對n進行分解質因數,應先找到一個最小的質數k,然後按下述步驟完成:

(1)如果這個質數恰等於n,則說明分解質因數的過程已經結束,打印出即可。

(2)如果nk,但n能被k整除,則應打印出k的值,並用n除以k的商,作為新的正整數你n,

 重複執行第一步。

(3)如果n不能被k整除,則用k+1作為k的值,重複執行第一步。

2.程序源代碼:

/* zheng int is divided yinshu*/

main()

{

int n,i;

printf(“\nplease input a number:\n”);

scanf(“%d”,n);

printf(“%d=”,n);

for(i=2;i=n;i++)

 {

while(n!=i)

{

 if(n%i==0)

 { printf(“%d*”,i);

n=n/i;

 }

 else

break;

}

}

printf(“%d”,n);}

【程序15】

題目:利用條件運算符的嵌套來完成此題:學習成績=90分的同學用A表示,60-89分之間的用B表示,

 60分以下的用C表示。

1.程序分析:(ab)?a:b這是條件運算符的基本例子。

2.程序源代碼:

main()

{

 int score;

 char grade;

 printf(“please input a score\n”);

 scanf(“%d”,score);

 grade=score=90? ‘A’: (score=60? ‘B’:’C’);

 printf(“%d belongs to %c”,score,grade);

}

【程序16】

題目:輸入兩個正整數m和n,求其最大公約數和最小公倍數。

1.程序分析:利用輾除法。

2.程序源代碼:

main()

{

 int a,b,num1,num2,temp;

 printf(“please input two numbers:\n”);

 scanf(“%d,%d”,num1,num2);

 if(num1 { temp=num1;

num1=num2;

num2=temp;

 }

a=num1;b=num2;

while(b!=0)/*利用輾除法,直到b為0為止*/

 {

temp=a%b;

a=b;

b=temp;

 }

printf(“gongyueshu:%d\n”,a);

printf(“gongbeishu:%d\n”,num1*num2/a);

}

【程序17】

題目:輸入一行字符,分別統計出其中英文字母、空格、數字和其它字符的個數。

1.程序分析:利用while語句,條件為輸入的字符不為’\n’.

2.程序源代碼:

#i nclude “stdio.h”

main()

{char c;

 int letters=0,space=0,digit=0,others=0;

 printf(“please input some characters\n”);

 while((c=getchar())!=’\n’)

 {

 if(c=’a’c=’z’||c=’A’c=’Z’)

letters++;

 else if(c==’ ‘)

space++;

 else if(c=’0’c=’9′)

 digit++;

 else

 others++;

}

printf(“all in all:char=%d space=%d digit=%d

others=%d\n”,letters,

space,digit,others);

}

【程序18】

題目:求s=a+aa+aaa+aaaa+aa…a的值,其中a是一個數字。例如2+22+222+2222+22222(此時

 共有5個數相加),幾個數相加有鍵盤控制。

1.程序分析:關鍵是計算出每一項的值。

2.程序源代碼:

main()

{

 int a,n,count=1;

 long int sn=0,tn=0;

 printf(“please input a and n\n”);

 scanf(“%d,%d”,a,n);

 printf(“a=%d,n=%d\n”,a,n);

 while(count=n)

 {

tn=tn+a;

sn=sn+tn;

a=a*10;

++count;

 }

printf(“a+aa+…=%ld\n”,sn);

}

【程序19】

題目:一個數如果恰好等於它的因子之和,這個數就稱為“完數”。例如6=1+2+3.編程

 找出1000以內的所有完數。

1. 程序分析:請參照程序–程序14.

2.程序源代碼:

main()

{

static int k[10];

int i,j,n,s;

for(j=2;j1000;j++)

 {

 n=-1;

 s=j;

for(i=1;i {

 if((j%i)==0)

 {n++;

s=s-i;

k[n]=i;

 }

}

 if(s==0)

 {

 printf(“%d is a wanshu”,j);

 for(i=0;i printf(“%d,”,k);

 printf(“%d\n”,k[n]);

 }

}

}

【程序20】

題目:一球從100米高度自由落下,每次落地後反跳回原高度的一半;再落下,求它在

 第10次落地時,共經過多少米?第10次反彈多高?

1.程序分析:見下面注釋

2.程序源代碼:

main()

{

float sn=100.0,hn=sn/2;

int n;

for(n=2;n=10;n++)

 {

sn=sn+2*hn;/*第n次落地時共經過的米數*/

hn=hn/2; /*第n次反跳高度*/

 }

printf(“the total of road is %f\n”,sn);

printf(“the tenth is %f meter\n”,hn);

}

其他的等整理出來再發! :) :)

【程序21】

題目:猴子吃桃問題:猴子第一天摘下若干個桃子,當即吃了一半,還不癮,又多吃了一個

 第二天早上又將剩下的桃子吃掉一半,又多吃了一個。以後每天早上都吃了前一天剩下

 的一半零一個。到第10天早上想再吃時,見只剩下一個桃子了。求第一天共摘了多少。

1.程序分析:採取逆向思維的方法,從後往前推斷。

2.程序源代碼:

main()

{

int day,x1,x2;

day=9;

x2=1;

while(day0)

 {x1=(x2+1)*2;/*第一天的桃子數是第2天桃子數加1後的2倍*/

 x2=x1;

 day–;

 }

printf(“the total is %d\n”,x1);

}

==============================================================

【程序22】

題目:兩個乒乓球隊進行比賽,各出三人。甲隊為a,b,c三人,乙隊為x,y,z三人。已抽籤決定

 比賽名單。有人向隊員打聽比賽的名單。a說他不和x比,c說他不和x,z比,請編程序找出

 三隊賽手的名單。

1.程序分析:判斷素數的方法:用一個數分別去除2到sqrt(這個數),如果能被整除,

則表明此數不是素數,反之是素數。

2.程序源代碼:

main()

{

char i,j,k;/*i是a的對手,j是b的對手,k是c的對手*/

for(i=’x’;i=’z’;i++)

 for(j=’x’;j=’z’;j++)

 {

 if(i!=j)

for(k=’x’;k=’z’;k++)

{ if(i!=kj!=k)

 { if(i!=’x’k!=’x’k!=’z’)

 printf(“order is a–%c\tb–%c\tc–%c\n”,i,j,k);

 }

}

 }

}

==============================================================

【程序23】

題目:打印出如下圖案(菱形)

*

***

******

********

******

***

*

1.程序分析:先把圖形分成兩部分來看待,前四行一個規律,後三行一個規律,利用雙重

for循環,第一層控制行,第二層控制列。

2.程序源代碼:

main()

{

int i,j,k;

for(i=0;i=3;i++)

 {

 for(j=0;j=2-i;j++)

printf(” “);

 for(k=0;k=2*i;k++)

printf(“*”);

 printf(“\n”);

 }

for(i=0;i=2;i++)

 {

 for(j=0;j=i;j++)

printf(” “);

 for(k=0;k=4-2*i;k++)

printf(“*”);

 printf(“\n”);

 }

}

==============================================================

【程序24】

題目:有一分數序列:2/1,3/2,5/3,8/5,13/8,21/13…求出這個數列的前20項之和。

1.程序分析:請抓住分子與分母的變化規律。

2.程序源代碼:

main()

{

int n,t,number=20;

float a=2,b=1,s=0;

for(n=1;n=number;n++)

 {

 s=s+a/b;

 t=a;a=a+b;b=t;/*這部分是程序的關鍵,請讀者猜猜t的作用*/

 }

printf(“sum is %9.6f\n”,s);

}

==============================================================

【程序25】

題目:求1+2!+3!+…+20!的和

1.程序分析:此程序只是把累加變成了累乘。

2.程序源代碼:

main()

{

float n,s=0,t=1;

for(n=1;n=20;n++)

 {

 t*=n;

 s+=t;

 }

printf(“1+2!+3!…+20!=%e\n”,s);

}

==============================================================

【程序26】

題目:利用遞歸方法求5!。

1.程序分析:遞歸公式:fn=fn_1*4!

2.程序源代碼:

#i nclude “stdio.h”

main()

{

int i;

int fact();

for(i=0;i5;i++)

 printf(“\40:%d!=%d\n”,i,fact(i));

}

int fact(j)

int j;

{

int sum;

if(j==0)

 sum=1;

else

 sum=j*fact(j-1);

return sum;

}

==============================================================

【程序27】

題目:利用遞歸函數調用方式,將所輸入的5個字符,以相反順序打印出來。

1.程序分析:

2.程序源代碼:

#i nclude “stdio.h”

main()

{

int i=5;

void palin(int n);

printf(“\40:”);

palin(i);

printf(“\n”);

}

void palin(n)

int n;

{

char next;

if(n=1)

 {

 next=getchar();

 printf(“\n\0:”);

 putchar(next);

 }

else

 {

 next=getchar();

 palin(n-1);

 putchar(next);

 }

}

==============================================================

【程序28】

題目:有5個人坐在一起,問第五個人多少歲?他說比第4個人大2歲。問第4個人歲數,他說比第

 3個人大2歲。問第三個人,又說比第2人大兩歲。問第2個人,說比第一個人大兩歲。最後

 問第一個人,他說是10歲。請問第五個人多大?

1.程序分析:利用遞歸的方法,遞歸分為回推和遞推兩個階段。要想知道第五個人歲數,需知道

第四人的歲數,依次類推,推到第一人(10歲),再往回推。

2.程序源代碼:

age(n)

int n;

{

int c;

if(n==1) c=10;

else c=age(n-1)+2;

return(c);

}

main()

{ printf(“%d”,age(5));

}

==============================================================

【程序29】

題目:給一個不多於5位的正整數,要求:一、求它是幾位數,二、逆序打印出各位數字。

1. 程序分析:學會分解出每一位數,如下解釋:(這裡是一種簡單的算法,師專數002班趙鑫提供)

2.程序源代碼:

main( )

{

long a,b,c,d,e,x;

scanf(“%ld”,x);

a=x/10000;/*分解出萬位*/

b=x%10000/1000;/*分解出千位*/

c=x%1000/100;/*分解出百位*/

d=x%100/10;/*分解出十位*/

e=x%10;/*分解出個位*/

if (a!=0) printf(“there are 5, %ld %ld %ld %ld

%ld\n”,e,d,c,b,a);

else if (b!=0) printf(“there are 4, %ld %ld %ld

%ld\n”,e,d,c,b);

else if (c!=0) printf(” there are 3,%ld %ld

%ld\n”,e,d,c);

else if (d!=0) printf(“there are 2, %ld

%ld\n”,e,d);

else if (e!=0) printf(” there are

1,%ld\n”,e);

}

==============================================================

【程序30】

題目:一個5位數,判斷它是不是迴文數。即12321是迴文數,個位與萬位相同,十位與千位相同。 

1.程序分析:同29例

2.程序源代碼:

main( )

{

long ge,shi,qian,wan,x;

scanf(“%ld”,x);

wan=x/10000;

qian=x%10000/1000;

shi=x%100/10;

ge=x%10;

if (ge==wanshi==qian)/*個位等於萬位並且十位等於千位*/

 printf(“this number is a huiwen\n”);

else

 printf(“this number is not a huiwen\n”);

}

【程序31】

題目:請輸入星期幾的第一個字母來判斷一下是星期幾,如果第一個字母一樣,則繼續

 判斷第二個字母。

1.程序分析:用情況語句比較好,如果第一個字母一樣,則判斷用情況語句或if語句判斷第二個字母。

2.程序源代碼:

#i nclude stdio.h

void main()

{

char letter;

printf(“please input the first letter of

someday\n”);

while ((letter=getch())!=’Y’)/*當所按字母為Y時才結束*/

{ switch (letter)

{case ‘S’:printf(“please input second letter\n”);

 if((letter=getch())==’a’)

printf(“saturday\n”);

 else if ((letter=getch())==’u’)

 printf(“sunday\n”);

 else printf(“data error\n”);

 break;

case ‘F’:printf(“friday\n”);break;

case ‘M’:printf(“monday\n”);break;

case ‘T’:printf(“please input second letter\n”);

 if((letter=getch())==’u’)

printf(“tuesday\n”);

 else if ((letter=getch())==’h’)

 printf(“thursday\n”);

 else printf(“data error\n”);

 break;

case ‘W’:printf(“wednesday\n”);break;

default: printf(“data error\n”);

}

 }

}

==============================================================

【程序32】

題目:Press any key to change color, do you want to

try it. Please hurry up!

1.程序分析:

2.程序源代碼:

#i nclude conio.h

void main(void)

{

int color;

for (color = 0; color 8; color++)

 {

 textbackground(color);/*設置文本的背景顏色*/

 cprintf(“This is color %d\r\n”, color);

 cprintf(“Press any key to continue\r\n”);

 getch();/*輸入字符看不見*/

 }

}

==============================================================

【程序33】

題目:學習gotoxy()與clrscr()函數 

1.程序分析:

2.程序源代碼:

#i nclude conio.h

void main(void)

{

clrscr();/*清屏函數*/

textbackground(2);

gotoxy(1, 5);/*定位函數*/

cprintf(“Output at row 5 column 1\n”);

textbackground(3);

gotoxy(20, 10);

cprintf(“Output at row 10 column 20\n”);

}

==============================================================

【程序34】

題目:練習函數調用

1. 程序分析:

2.程序源代碼:

#i nclude stdio.h

void hello_world(void)

{

printf(“Hello, world!\n”);

}

void three_hellos(void)

{

int counter;

for (counter = 1; counter = 3; counter++)

hello_world();/*調用此函數*/

}

void main(void)

{

three_hellos();/*調用此函數*/

}

經典C語言程序例子

題目01:在一個已知的字符串中查找最長單詞,假定字符串中只含字母和空格,空格用來分隔不同的單詞。

直接編譯,程序執行結果如下圖所示:

題目02:編寫一個int string_len(char *s),返回字符串s的字符長度(不包括\0)。

直接編譯,程序執行結果如下圖所示:

擴展資料:

C語言是一門通用計算機編程語言,應用廣泛。C語言的設計目標是提供一種能以簡易的方式編譯、處理低級存儲器、產生少量的機器碼以及不需要任何運行環境支持便能運行的編程語言。

儘管C語言提供了許多低級處理的功能,但仍然保持着良好跨平台的特性,以一個標準規格寫出的C語言程序可在許多電腦平台上進行編譯,甚至包含一些嵌入式處理器(單片機或稱MCU)以及超級電腦等作業平台。

C語言編程經典282例,陽陽買蘋果

從你提出的疑問看,思路你也沒看懂。

注意程序語句執行的順序,循環體中money+=0.8*n是花錢的累加和,day++是天數:n*=2是計算下一天買蘋果的數量。

初始值n=2,d=0

執行while循環

money+=0.8*n;//第一天花的錢

day++;//1天,看到了吧,買2個蘋果是第1天,而不是第0天

n*=2;//這條語句你也寫錯了。計算第二天買的蘋果數量

n100,繼續執行循環

money+=0.8*n;//兩天花的錢

day++;//2天

n*=2;//計算第三天買的蘋果數量

n100,繼續執行,依次類推。

直到n*=2,n=128,不滿足循環條件,退出循環,此時n的值是128沒錯,可是並沒有計入花的錢以及天數。花的錢為5天花錢的總和,天數為5天。

做完c語言經典編程282例 計算機什麼水平

只能說是學習了基本的語言和開發方法, 有大量 C 的高級用法(比如函數指針) 以及軟件設計(大規模的程序設計思路), 還有系統相關的(比如POSIX庫,多進程,多線程,信號), 還有算法, 數據結構等等需要學習呢. 的確是萬里長征走完一步, 與您共勉

C語言的經典編程例子

程序員》推薦C++ 圖書三人談

主持人:熊節(透明),《程序員》雜誌編輯,C-View成員

嘉 賓:孟岩(夢魘),聯想公司掌上設備事業部應用開發處任職,C-View成員。與侯捷先生合譯《C++ Standard Library》一書

金尹(惡魔),上海天宇公司CTO,在《程序員》連載有“自由與繁榮的國度”系列文章

透明:“學C++用哪本書入門”,這是被問得最多的一個問題。但是哪一本書是最好的入門書?似乎很難找到答案。《C++ Primer》太厚,《Effective C++》對讀者要求比較高,《Essential C++》又常常被批評為“太淺”。

其實說穿了:no silver bullet。想從一本書學會C++,那是不可能的。有朋友問我如何學C++,我會建議他先去找本數據結構書,把裡面的習題全部用C++做一遍,然後再去看《Effective C++》。myan經常說“要在學習初期養成好習慣”,我對此頗不以為然。

個人認為,《Essential C++》適合作教材,《C++ Primer》適合作參考書,《Effective C++》適合作課外讀物。

惡魔:很後悔當初買了《C++ Primer》。因為從我個人角度來看,它的功能效用基本是和《The C++ Programming Language》重合。當然對於入門來說,它還是很不錯的。但是《C++ Primer》太厚,一來導致看書極其不方便,二來系統學習需要花比較長的時間。對於目前這個越來越快餐化的時代來說,的確有很多不適合的地方,不過可以作為初學者的參考書。現在我以一塊K3 CPU的代價把它借給了別人,希望我那位同事能夠從中得到一些益處。

如果已經具備了C基礎,我建議看國內的書,例如錢能的《 C++大學教程(第二版) 》。(如果沒有C的基礎還是看譚浩強的C語言)。這本書對C講得還算比較清晰,有很多習題值得一做,特別是最後的struct和union兩個部分。其中的一些算法比較拖沓和繁瑣(比如樹和鏈表的遍歷算法),讀者可以嘗試修改這些例子,作為最後對C語言的一些總結測試。

夢魘:這個問題讓我想起四五年前的情形。今天對於C++有一點認識的人,多半是從那幾年就開始學C++了。那時根本沒有品牌觀念。從書店裡找一本C++書,如果看着還算明白,就買下來。我記得那時候宛延闓、張國鋒、麥中凡教授的書都受到很高的讚譽。我個人最早的一本C++書是Greg Perry的一本書,今天想起來,其實是一本打着C++旗號的C語言教程。對我作用最大的一本書是國防科技出版社出版的一本書,書名記不得了,作者叫斯蒂芬·布萊哈。

透明:還記得以前曾批評過一本C++書,是北航出的,整本書就沒有出現過class關鍵字。那本書,說穿了其實只是介紹了C語言和iostream庫的用法,根本不能算C++。而當時我常常推薦的一本書是電子科技大學張松梅老師的C++教程。那本書,直到今天來看也沒有太大的問題,唯一的缺憾就是由於年代久遠,許多東西已經過時了。而對於一本技術書籍來說,“過時”是最不可接受的。

總體來說,那時使用C++的人真是在“盲人摸象”。不過這也有好處,就是對C++的很多細節能搞清楚,以後看到經典好書時比較容易理解;當然壞處就是概念不清,甚至都不知道C++和Visual C++、Borland C++到底有什麼不一樣。

夢魘:整個90年代,其實大部分人對於C++的認識都似是而非。一開始是等同於Borland C++,後來是等同於Visual C++和MFC。所以一般來說,打着BC和VC旗號的書賣得很好,人們覺得這就是C++。而我比較幸運,布萊哈的那本書雖然從現在的眼光來看談不上高超,但基本路子是對的。可能是因為原書是給UNIX程序員的培訓教材,所以沒有讓我一開始就形成“C++ == VC++”的認識。

其實一直到1996年,我們那裡搞計算機的都是唯Borland C++馬首是瞻的,到了VC 4.0出來,一下子格局全變了。1997年VC5推出之後,書店裡MFC書鋪天蓋地,學MFC的人,頭抬得都比別人高一些。不過現在看來,那時候大部分的MFC書都是三流貨色。我曾經有一段時間認為,那一批程序員中間有不少被誤導了。根本原因就是相對的封閉。

透明:我覺得一本書的價值有兩方面:第一,教給你實用的技術;第二,促使你去思考。對於一本介紹VC(或者說MFC)使用方法的書,我根本不希望它能促使我有什麼思考,所以我就一定要求它在技術上精益求精完美無瑕。我剛開始用VC的時候,買的第一本書就是潘愛民老師翻譯的《VC技術內幕》(第四版),沒有受到那些“三流貨色”的誤導,應該說是很幸運的。

夢魘:1999年機械工業出版社開始出版“計算機科學叢書”,其中的《Thinking in C++》第一版受到了廣泛的歡迎。其實我一直不認為這本書很出色,雖然拿過一次大獎。然而我們都得承認,這本書在C++書籍領域裡第一次建立了品牌觀念,很多初學者開始知道,不是隨便買哪一本都一樣的。再往後就是2000年的《 深入淺出MFC(第二版) 》第二版,以及侯先生在《程序員》上發表的那一篇《C++/OOP大系》,加上整個大環境的變化,品牌觀念深入人心,C++書籍市場終於開始逐漸與世界同步。

回想往事,我的感覺是,那個需要戰戰兢兢選擇入門書的時代已經過去,今天的C++初學者,大可以放心地買口碑好、自己讀起來思路順暢的書,入門不再是太大的問題。還有一些程序員已經學了幾年C++,但看到今天出版的一些新書,感覺比較陌生,這也不是什麼問題。侯先生經常說“凡走過必留下足跡”,所謂“走彎路”,未必不是一件好事。

至於具體的推薦表,就不好一概而論了。總之在我的印象里,《Essential C++》、《C++ Primer》、錢能教授的C++教程,都不錯。甚至有人一上來就看Bjarne Stroustrup的《The C++ Programming Language》,只要他喜歡,也沒什麼不可以。

透明:我同意你的觀點。不管怎麼說,編程是門實踐性非常強的學問。要想對C++對象模型有深入的了解,最好的辦法就是寫一串程序去看結果;要想學會OOP,也只能從項目中學。對於初學者,最好的學習方法就是不停地寫程序,寫真正有用的程序,寫到有問題的時候就去查書,於是自然就會知道哪本書好哪本書不好。不過我們的教育制度能不能讓大學裡的學生們有這樣的學習機會,我表示懷疑。

以我的經驗,學C++有兩個門檻:入門和使用。完全看不懂C++,這是一個門檻,但是只要有一本合適的入門書,很快就能跨過。要想真正用上C++,卻不是件很容易的事情。尤其對於學生來說,接觸到的東西多是“玩具”,很難有實戰的機會。所以經常看見有人問“C++到底能做什麼”,這是C++學習中一個比較麻煩的問題。我們都是做了相當長時間的C++程序之後才看到一些真正經典的書,也正是因為走了相當長的彎路之後才知道這些書的經典之所在。所謂彎路,我想也是一種必須的積累。就算一開始就看《Essential C++》和《C++ Primer》,沒有兩三年的時間恐怕還是難有所得。

惡魔:有兩句十分有道理的話,一是我大學的C語言老師說的“寫程序不如說是抄程序”,另一句是一網友說的“好的設計來自借鑒,天才的設計來自剽竊”。對於我這個理性批判主義者來說,這兩句話的確不太適合。但是無論從哪個角度來講,對於初學者來說,剽竊大師的作品是通向成功的最快捷徑。

我個人認為,對於C++的初學者來說,首先要確定自己專業領域內主要使用的特性的方向。因為C++的特性如此眾多,初學者想貪多基本是不可能成功的。C++的編程範式基本可以分為ADT+PP、GP和OO三個方向。對於ADT+PP範式來說,初學者的主要問題不是學習C++,而是學習C的使用。對於這樣的初學者,國內的幾本書還是寫得比較清楚,符合中國人的習慣,比如譚浩強的《C語言教程》、錢能的《C++語言大學教程》。這兩本書我首推第一本,因為這一本我潛心研究了一年,這本書當中很多程序是可以剽竊的,而且可以對這些程序進行加工和提升。比如結構這一章中,它所給出的用struct來實現鏈表、二叉樹的算法是相當蹩腳的。學習ADT+PP的初學者將這本書揣摩透以後可以嘗試修改這兩個程序。另外這本書的第二版稍微涉及了一些關於“類”的內容。學習ADT+PP的初學者,可以不被OO中的一些專有特性擾亂自己的思路,對於類層次扁平、無繼承、無多態的程序編寫是有很大好處的。

透明:你好象比較推崇國內教授寫的書。現在社會上有種不好的風氣:一捧就捧上天,一貶就貶下地。就好象對待譚教授的書,前幾年是奉為經典,這幾年又有很多人使勁批評。學C++更是有點“崇洋媚外”,總是覺得初學就應該看《Essential C++》。我看這種觀點也是片面的。

惡魔:當然《Essential C++》也值得看看。但是我個人覺得這本書沒有譚浩強的《C語言教程》來得好。主要原因是:第一,C++的所有特性都點到了,但是不深,看了以後會三心二意沒有方向;第二,可以抄襲借鑒的例子太少。《C語言教程》中有很多有趣的問題,比如猴子吃桃、漢諾塔等等,這些例子對於剛剛涉及C/C++語言編程的人來說是學習編程很好的例子。《Essential C++》只能是前兩本書看透以後,作為學習C++特性的一個過渡性的書籍。讓讀者真正領略到什麼是C++的編程、和C編程的不同點在哪裡。

透明:我發現一個很有趣的現象:初學者往往喜歡問“哪本書比較好”,這讓我很是不解。這有點像一個剛學打籃球的人問“王治郅和科比誰比較厲害”。當然科比更厲害一些。但如果你是想學打籃球,這兩個人都非常非常有資格教你,你跟誰學都能學得很強——關鍵不是在於你選哪個老師,而是在於你自己用多少功夫去學。

透明:回到原來話題。學會了C++的語法,能看懂C++代碼之後,必須有些書來指導進階(或者叫指點迷津)。我覺得《設計模式》很好,能夠讓讀者看到一些精妙的用法。不過正如我經常說的,模式帶來的麻煩和好處一樣多,甚至麻煩還要更多。而且,C++本身的問題使得在C++中使用GoF模式愈加麻煩。

夢魘:《Design Patterns》這本書絕對是不可以沒有的,而且中英文版都不可少。最初我看中文版,說實話看不懂,但是也不覺得人家翻譯得不好,所以就想,大概是原文就很難懂,加上自己水平有限。於是總是想着再找幾本patterns的書來看。後來找到幾本書,口碑還不錯,不過水平高下,一比就出來了,還是那本《Design Patterns》最經典,最耐看。英文版出來之後,兩個版本對照看,明白多了。現在覺得,其實就設計模式來講,把這本看明白了就很不錯了,不用再花費很多心思找其他的書。我現在的包里始終夾着這本書,隨身攜帶,有備無患。

至於說設計模式的副作用,和可能帶來的弊端,我的體會也挺多。不過是這樣,我們想一想,究竟什麼情況下設計模式可以用得很好呢?一種是有經驗豐富的人引導,比如要是Robert Martin帶隊,你在某個地方用錯了設計模式,他就會指出來,說這裡不對,將來會產生什麼樣的弊端。對於他來說,豐富的實踐經驗足以支持他進行“預測型”設計。但是大部分人沒這個能力,因此我們只好走第二條路和第三條路,就是“試探型”設計和“重構型”設計。遇到一個問題,你覺得用某種模式挺合適的,就大膽地用了,成功是積累經驗,發現不好,出了問題了,只好改回來,那也是積累教訓。這叫做“試探型”。至於重構,應該算是最有組織、成功率最高的工程化方法。先把問題“quick and dirty”地解決了,所有的暗礁都暴露出來,然後再根據實際情況採用合適的模式優化設計。現在XP和UP都高度重視refactory,UP在Elaboration和Construction階段都鼓勵抽出專門的iterations進行重構。所以說如果組織快速的軟件開發,當然比較傾向於這條路——打成功率嘛。

透明:講到重構,我順便說說《Refactoring》這本書的影響。從工程本身的角度來說,你所謂的“重構型設計”是沒有什麼問題的。但中國的開發者(也包括我在內)往往比較衝動,比較容易相信銀彈的存在。曾經有那麼一段時間,我在Java中嘗試過了重構的方法之後,又拿到C++中去嘗試。結果發現,在Java中速度非常快的重構過程,到C++中就被減慢了。究其原因,就是因為C++和Java的約束條件不同。拿着Java中成功的案例直接套C++,不失敗才怪。

所以,我必須說:《Refactoring》這本書很有價值。但對於C++程序員來說,它的價值是讓你思考,思考這種方法的可行性。如果一個C++程序員沒有打算遷移到Java,那麼我必須告訴他:《Refactoring》這本書不是讓你照着它用的,甚至不是讓你去相信它的。對於C++程序員,《Refactoring》全書可以放心相信的只有第13章,其他的部分,都必須非常謹慎地對待。

夢魘:我還要就“試探型”的方法多說兩句,我覺得對於個人發展來講,“試探”也是必不可少的,撞牆不可怕,高水平的人不都是撞出來的嗎?你失敗了一次,就知道這個模式有什麼潛在的問題,下次再用,就會多看幾步,像下棋似的。撞的多了,路數就出來了。

我不知道你們是否有這個感覺:用錯了模式,吃了虧,再回過頭去翻翻《Design Patterns》,看到人家早就指出來這個問題,不過就是那麼幾句話,原來看上去乾巴巴的,現在覺得句句都講到心坎上,GoF的形象馬上就高大起來,還帶着光環,感覺是既興奮又懊悔。

透明:現在回頭來看,我更欣賞myan推薦給我的《Designing Object-Oriented C++ Applications Using Booch Method》。這本書能夠幫助C++程序員理清思路培養習慣,可惜國內沒有引進。相比後來商業味濃厚的UML系列書籍,我覺得這本書對於面向對象的闡釋精闢獨到,至今未有能出其右者。

夢魘:剛才我們兩人都說到Robert Martin,他可是我的榜樣。那本1995年的《Designing Object Oriented C++ Application》,我覺得是每一個C++軟件工程師都應該反覆研讀的書。可惜不僅國內沒有引進,在國外的名氣也不大。如果你覺得面向對象的那些道理你好像都明白,可就是一遇到實際問題就使不上勁,那這本書就是你的最佳導師。

提到理清思路,還有一本書不得不提,就是Andrew Koenig的《Ruminations On C++》。每個人都應該問自己,我學了這麼多年的C++,究竟什麼是C++最基本的設計理念?遇到問題我第一個直覺是什麼?第一個試探型的解決方案應該具有那些特點?如果你不能給出明確的答案,就應該認真地去讀這本書,讀完了你就有了“主心骨”。

透明:插一句話,談談“推薦書”的問題。入門書基本上是放之四海而皆準的,所以推薦的意義也不大。而入門後的發展方向,每個人不同,這個時候就需要“高人”的指點。舉個例子:我學C++的時候,myan還不認識我,所以也沒有給我推薦書,我還是學過來了,所以即使你當時向我推薦了《Essential C++》或者《C++ Primer》,我也不會太感謝你;但在我認真研究OO的時候,你推薦Robert Martin那本書給我,對我幫助就特別大,而且我從別的地方也很難找到類似的推薦,所以我就很感謝你。

一個程序員,必須有framework的意識,要學會用framework,還要主動去分析framework(在這方面,《Design Patterns》能有一定的幫助)。但是,真正高質量、成氣候的framework的書恐怕也就只有針對MFC的。從這個角度來說,MFC縱有千般不是,C++程序員都非常有必要先去用它、熟悉它、研究它,甚至藉助《深入淺出MFC》這樣的書來剖析它。不然,很難有framework的意識和感覺。

當然,另一個framework也很好,那就是STL。不管用不用MFC、STL,對這兩個東西的掌握和理解都是極有幫助的。最近我又在看《深入淺出MFC》,雖然已經不用MFC編程了,但幫助是一定有的。

夢魘:MFC和STL方面,我還是比較推崇侯先生的兩本書《深入淺出MFC》和《STL源碼解析》。

《深入淺出MFC》這本書,名氣自然是大得不得了,不過也有不少人批評。其實書也沒有十全十美的,批評當然是少不了的,不過有的時候我看到有人評論這本書,把它跟Inside VC相比,真的是牛頭不對馬嘴。

你剛才其實說得很對,程序員應該有一點framework意識。而這本《深入淺出MFC》與其說是在講MFC編程,不如說通篇是在拿MFC為例分析Application Framework的架構和脈絡。所以無論你對於MFC本身是什麼態度,這本書對每一個C++程序員都有很大的益處。

透明:是的。《VC技術內幕》會告訴你“DYNAMIC_CREATE這個宏怎麼用”,《深入淺出MFC》則告訴你“DYNAMIC_CREATE這個宏是怎麼實現的”。所以,如果你只需要在VC下寫一些小應用程序,《深入淺出MFC》的價值並不太大;但是,如果你需要設計一個稍微大一點的東西(不一定是framework),MFC的設計思想就會有所幫助。

夢魘:另外,我覺得對於MFC也應該有一個公允的評價。過去是吹捧得天上有地下無,書店裡鋪天蓋地都是MFC的書,搞得大家只知有MFC,不知有C++,甚至直到現在還有人問:“我是學MFC呢,還是學C++?VC++是不是比C++更高級的語言?”MFC成了一尊神像,阻礙了人們的視線。所以得把它從神壇上拉下來。這就是過去一兩年有很多人,包括我在內批評MFC的一個目的。可是現在大家視野開闊了,.NET也出來了,MFC不再是神像了,少數人就開始以貶損MFC為樂了。我覺得這種態度是不對的。

什麼叫好的框架?我覺得在十幾年的時間能夠象MFC這樣保持穩定並且不斷進步的框架就是好的框架。可能我們在一些具體的設計問題上有不同看法,覺得“這個地方這麼設計不是更漂亮嗎?”很多時候是的,但是這不重要,重要的是MFC成熟穩定、有十幾年的成功經驗,這是最了不起的東西。

另外一點,MFC中間包括着學習Win32 API編程的最佳資料。這是除了其framework方面之外的另一個亮點。我現在使用Win32 API開發,但是經常參考MFC的源代碼,收穫很大。

透明:STL方面,我對於剖析它的源代碼興趣並不大,畢竟裡面源代碼多是算法問題。所以,《STL源碼剖析》我也只是隨便翻翻就束之高閣了。我覺得這本書用來做計算機系的數據結構和算法教材不錯,不知道有沒有老師樂意這樣做。

對於STL,我的態度一向都是“應用至上”。不過,我一直認為SGI STL本身就是一本精彩的書,一本數據結構和算法的經典參考書,同時也是泛型技術的參考書。想知道一個算法是如何實現的,看看STL源代碼就行;想知道如何使用type traits,STL源代碼裡面也有例子。看別人寫的書,總覺得隔着一層紗,有點撓不到癢處的感覺。SGI STL的代碼寫得非常漂亮,一個C++程序員如果不看看這本書,實在是可惜。

夢魘:至於STL,除了《STL源碼解析》之外,我舉賢不避親,強烈推薦侯先生與我合譯的那本《The C++ Standard Library》。這本書質量之高是無需懷疑的。我現在手邊常備此書,隨時查閱,對我幫助很大。

透明:C++和Java相比,最大的優勢就是它沒有一個專門的公司來管它,最大的弱點也是它沒有一個專門的公司來管它。Java程序員在學會簡單的語法之後,立刻進入SUN提供的framework,一邊用這個現成的framework做實際開發,一邊在開發過程中繼續學習Java一些幽深的特性。而這個時候,C++程序員恐怕還在問“VC和BCB哪個好”呢。這無疑是浪費時間。

夢魘:剛才你說Java和C++的優劣,這個話題已經成了我們這個年代永不消失的聲波了。我也不想再談這個。不過有一點我得說清楚:現在我們很多用C++的人吃了不少苦頭,探過脖子去看看Java,覺得它真是太可愛了,這種印象是不準確的。另外,Java也不簡單,而且會越來越龐大複雜。在很多場合,Java還不具有競爭力。至於將來如何,我看有些Java愛好者也過分樂觀了,似乎計算機科學界幾十年解決不了的問題都可以藉著Java的東風解決掉,恐怕沒那麼容易。

透明:那當然。我再次強調:No Silver Bullet。讀書很重要,但古人說“行萬里路,讀萬卷書”,還是把“行路”放在“讀書”前面。尤其對於技術書籍,如果它不能幫我解決問題、不能給我帶來非常實際的利益,那麼我是不會去讀它的。惡魔說得對,我們這個社會很快餐,我們這個行業尤其很快餐,我們也只能努力適應它。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/269851.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-16 13:33
下一篇 2024-12-16 13:33

相關推薦

  • AES加密解密算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES算法,並對實現過程進…

    編程 2025-04-29
  • 學習Python對學習C語言有幫助嗎?

    Python和C語言是兩種非常受歡迎的編程語言,在程序開發中都扮演着非常重要的角色。那麼,學習Python對學習C語言有幫助嗎?答案是肯定的。在本文中,我們將從多個角度探討Pyth…

    編程 2025-04-29
  • Python被稱為膠水語言

    Python作為一種跨平台的解釋性高級語言,最大的特點是被稱為”膠水語言”。 一、簡單易學 Python的語法簡單易學,更加人性化,這使得它成為了初學者的入…

    編程 2025-04-29
  • OpenJudge答案1.6的C語言實現

    本文將從多個方面詳細闡述OpenJudge答案1.6在C語言中的實現方法,幫助初學者更好地學習和理解。 一、需求概述 OpenJudge答案1.6的要求是,輸入兩個整數a和b,輸出…

    編程 2025-04-29
  • Python按位運算符和C語言

    本文將從多個方面詳細闡述Python按位運算符和C語言的相關內容,並給出相應的代碼示例。 一、概述 Python是一種動態的、面向對象的編程語言,其按位運算符是用於按位操作的運算符…

    編程 2025-04-29
  • 《Python數據分析》經典書

    這本經典書可以幫助各位數據科學家快速上手 Python 進行數據分析和處理,下面我們從多個方面闡述一下這本書的亮點和有趣之處。 一、數據科學簡介 《Python數據分析》一書旨在幫…

    編程 2025-04-29
  • Python語言由荷蘭人為中心的全能編程開發工程師

    Python語言是一種高級語言,很多編程開發工程師都喜歡使用Python語言進行開發。Python語言的創始人是荷蘭人Guido van Rossum,他在1989年聖誕節期間開始…

    編程 2025-04-28
  • Python語言設計基礎第2版PDF

    Python語言設計基礎第2版PDF是一本介紹Python編程語言的經典教材。本篇文章將從多個方面對該教材進行詳細的闡述和介紹。 一、基礎知識 本教材中介紹了Python編程語言的…

    編程 2025-04-28
  • Python語言實現人名最多數統計

    本文將從幾個方面詳細介紹Python語言實現人名最多數統計的方法和應用。 一、Python實現人名最多數統計的基礎 1、首先,我們需要了解Python語言的一些基礎知識,如列表、字…

    編程 2025-04-28
  • Python作為中心語言,在編程中取代C語言的優勢和挑戰

    Python一直以其簡單易懂的語法和高效的編碼環境而著名。然而,它最近的發展趨勢表明Python的使用範圍已經從腳本語言擴展到了從Web應用到機器學習等廣泛的開發領域。與此同時,C…

    編程 2025-04-28

發表回復

登錄後才能評論