本文目錄一覽:
- 1、C語言中基本的幾種演算法有哪些越多越好!就像打擂台演算法’冒泡排序法等等…
- 2、高分求動態規劃題目!!!
- 3、在大學學C語言能幹什麼?有什麼用?最妤舉些易明白的例子
- 4、裡面的/t是什麼意思?編程c語言的內容
- 5、昨天我看到一個IQ問題,想了一夜把答案想出來了,今天卻找不到那個問題了,只好給大家猜了!
- 6、c語言打碎花瓶題目?
C語言中基本的幾種演算法有哪些越多越好!就像打擂台演算法’冒泡排序法等等…
排序演算法
冒泡排序
選擇排序
快速排序
高精度運算
存儲方法
加法運算
減法運算
乘法運算
擴大進位數
習題與練習
搜索演算法
枚舉演算法
深度優先搜索
廣度優先搜索
8數碼問題
n皇后問題
搜索演算法習題
枚舉法習題
聰明的打字員
量水問題
染色問題
跳馬問題
算24點
圖論演算法
最小生成樹演算法(Prim演算法)
單源最短路徑演算法(Dijkstra演算法)
任意結點最短路徑演算法(Floyd演算法)
求有向帶權圖的所有環
Bellman-Ford演算法
計算圖的連通性
計算最佳連通分支
計算拓撲序列
圖論演算法習題
網路建設問題
最短變換問題
挖地雷
烏托邦城市
烏托邦交通中心
動態規劃
最短路徑問題
動態規劃概念
騎士遊歷問題
最長遞增子序列
合唱隊形
石子合併問題
能量項鏈
0/1背包問題
開心的金明
金明的預算方案
加分二叉樹
字串編輯距離
花瓶插花
凸多邊形三角劃分
快餐店
高分求動態規劃題目!!!
這是我們計算機系演算法設計課的實驗課程,下面是動態規劃內容:
實驗四:動態規劃
實驗目的:理解動態規劃的基本思想,理解動態規劃演算法的兩個基本要素最優子結構性質和子問題的重疊性質。熟練掌握典型的動態規劃問題。掌握動態規劃思想分析問題的一般方法,對較簡單的問題能正確分析,設計出動態規劃演算法,並能快速編程實現。
實驗內容:編程實現講過的例題:最長公共子序列問題、矩陣連乘問題、凸多邊形最優三角剖分問題、電路布線問題等。本實驗中的問題,設計出演算法並編程實現。
習題
1. 最長公共子序列
一個給定序列的子序列是在該序列中刪去若干元素後得到的序列。確切地說,若給定序列X=x1, x2,…, xm,則另一序列Z=z1, z2,…, zk是X的子序列是指存在一個嚴格遞增的下標序列 i1, i2,…, ik,使得對於所有j=1,2,…,k有
解答如下:
a) 最長公共子序列的結構
若用窮舉搜索法,耗時太長,演算法需要指數時間。
易證最長公共子序列問題也有最優子結構性質
設序列X=x1, x2, …, xm和Y=y1, y2, …, yn的一個最長公共子序列Z=z1, z2, …, zk,則:
i. 若xm=yn,則zk=xm=yn且Zk-1是Xm-1和Yn-1的最長公共子序列;
ii. 若xm≠yn且zk≠xm ,則Z是Xm-1和Y的最長公共子序列;
iii. 若xm≠yn且zk≠yn ,則Z是X和Yn-1的最長公共子序列。
其中Xm-1=x1, x2, …, xm-1,Yn-1=y1, y2, …, yn-1,Zk-1=z1, z2, …, zk-1。
最長公共子序列問題具有最優子結構性質。
b) 子問題的遞歸結構
由最長公共子序列問題的最優子結構性質可知,要找出X=x1, x2, …, xm和Y=y1, y2, …, yn的最長公共子序列,可按以下方式遞歸地進行:當xm=yn時,找出Xm-1和Yn-1的最長公共子序列,然後在其尾部加上xm(=yn)即可得X和Y的一個最長公共子序列。當xm≠yn時,必須解兩個子問題,即找出Xm-1和Y的一個最長公共子序列及X和Yn-1的一個最長公共子序列。這兩個公共子序列中較長者即為X和Y的一個最長公共子序列。
由此遞歸結構容易看到最長公共子序列問題具有子問題重疊性質。例如,在計算X和Y的最長公共子序列時,可能要計算出X和Yn-1及Xm-1和Y的最長公共子序列。而這兩個子問題都包含一個公共子問題,即計算Xm-1和Yn-1的最長公共子序列。
我們來建立子問題的最優值的遞歸關係。用c[i,j]記錄序列Xi和Yj的最長公共子序列的長度。其中Xi=x1, x2, …, xi,Yj=y1, y2, …, yj。當i=0或j=0時,空序列是Xi和Yj的最長公共子序列,故c[i,j]=0。建立遞歸關係如下:
c) 計算最優值
由於在所考慮的子問題空間中,總共只有θ(m*n)個不同的子問題,因此,用動態規劃演算法自底向上地計算最優值能提高演算法的效率。
計算最長公共子序列長度的動態規劃演算法LCS_LENGTH(X,Y)以序列X=x1, x2, …, xm和Y=y1, y2, …, yn作為輸入。輸出兩個數組c[0..m ,0..n]和b[1..m ,1..n]。其中c[i,j]存儲Xi與Yj的最長公共子序列的長度,b[i,j]記錄指示c[i,j]的值是由哪一個子問題的解達到的,這在構造最長公共子序列時要用到。最後,X和Y的最長公共子序列的長度記錄於c[m,n]中。
程序如下:
#includestdio.h
#includestring.h
int lcs_length(char x[], char y[]);
int main()
{
char x[100],y[100];
int len;
while(1)
{
scanf(“%s%s”,x,y);
if(x[0]==’0′) //約定第一個字元串以『0』開始表示結束
break;
len=lcs_length(x,y);
printf(“%d\n”,len);
}
}
int lcs_length(char x[], char y[] )
{
int m,n,i,j,l[100][100];
m=strlen(x);
n=strlen(y);
for(i=0;im+1;i++)
l[i][0]=0;
for(j=0;jn+1;j++)
l[0][j]=0;
for(i=1;i=m;i++)
for(j=1;j=n;j++)
if(x[i-1]==y[j-1]) //i,j從1開始,但字元串是從0開始
l[i][j]=l[i-1][j-1]+1;
else if(l[i][j-1]l[i-1][j])
l[i][j]=l[i][j-1];
else
l[i][j]=l[i-1][j];
return l[m][n];
}
由於每個數組單元的計算耗費Ο(1)時間,演算法lcs_length耗時Ο(mn)。
思考:空間能節約嗎?
2. 計算矩陣連乘積
在科學計算中經常要計算矩陣的乘積。矩陣A和B可乘的條件是矩陣A的列數等於矩陣B的行數。若A是一個p×q的矩陣,B是一個q×r的矩陣,則其乘積C=AB是一個p×r的矩陣。由該公式知計算C=AB總共需要pqr次的數乘。其標準計算公式為:
現在的問題是,給定n個矩陣{A1,A2,…,An}。其中Ai與Ai+1是可乘的,i=1,2,…,n-1。要求計算出這n個矩陣的連乘積A1A2…An。
遞歸公式:
程序如下:
#includestdio.h
int main()
{
int p[101],i,j,k,r,t,n;
int m[101][101]; //為了跟講解時保持一致數組從1開始
int s[101][101]; //記錄從第i到第j個矩陣連乘的斷開位置
scanf(“%d”,n);
for(i=0;i=n;i++)
scanf(“%d”,p[i]); //讀入p[i]的值(注意:p[0]到p[n]共n+1項)
for(i=1;i=n;i++) //初始化m[i][i]=0
m[i][i]=0;
for(r=1;rn;r++) //r為i、j相差的值
for(i=1;in;i++) //i為行
{
j=i+r; //j為列
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j]; //給m[i][j]賦初值
s[i][j]=i;
for(k=i+1;kj;k++)
{
t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(tm[i][j])
{
m[i][j]=t; //m[i][j]取最小值
s[i][j]=k;
}
}
}
printf(“%d”,m[1][n]);
}
3. 凸多邊形的最優三角剖分
多邊形是平面上一條分段線性的閉曲線。也就是說,多邊形是由一系列首尾相接的直線段組成的。組成多邊形的各直線段稱為該多邊形的邊。多邊形相接兩條邊的連接點稱為多邊形的頂點。若多邊形的邊之間除了連接頂點外沒有別的公共點,則稱該多邊形為簡單多邊形。一個簡單多邊形將平面分為3個部分:被包圍在多邊形內的所有點構成了多邊形的內部;多邊形本身構成多邊形的邊界;而平面上其餘的點構成了多邊形的外部。當一個簡單多邊形及其內部構成一個閉凸集時,稱該簡單多邊形為凸多邊形。也就是說凸多邊形邊界上或內部的任意兩點所連成的直線段上所有的點均在該凸多邊形的內部或邊界上。
通常,用多邊形頂點的逆時針序列來表示一個凸多邊形,即P=v0 ,v1 ,… ,vn-1表示具有n條邊v0v1,v1v2,… ,vn-1vn的一個凸多邊形,其中,約定v0=vn 。
若vi與vj是多邊形上不相鄰的兩個頂點,則線段vivj稱為多邊形的一條弦。弦 將多邊形分割成凸的兩個子多邊形vi ,vi+1 ,… ,vj和vj ,vj+1 ,… ,vi。多邊形的三角剖分是一個將多邊形分割成互不重迭的三角形的弦的集合T。如圖是一個凸多邊形的兩個不同的三角剖分。
凸多邊形最優三角剖分的問題是:給定一個凸多邊形P=v0 ,v1 ,… ,vn-1以及定義在由多邊形的邊和弦組成的三角形上的權函數ω。要求確定該凸多邊形的一個三角剖分,使得該三角剖分對應的權即剖分中諸三角形上的權之和為最小。
可以定義三角形上各種各樣的權函數W。例如:定義ω(△vivjvk)=|vivj|+|vivk|+|vkvj|,其中,|vivj|是點vi到vj的歐氏距離。相應於此權函數的最優三角剖分即為最小弦長三角剖分。(注意:解決此問題的演算法必須適用於任意的權函數)
4. 防衛導彈
一種新型的防衛導彈可截擊多個攻擊導彈。它可以向前飛行,也可以用很快的速度向下飛行,可以毫無損傷地截擊進攻導彈,但不可以向後或向上飛行。但有一個缺點,儘管它發射時可以達到任意高度,但它只能截擊比它上次截擊導彈時所處高度低或者高度相同的導彈。現對這種新型防衛導彈進行測試,在每一次測試中,發射一系列的測試導彈(這些導彈發射的間隔時間固定,飛行速度相同),該防衛導彈所能獲得的信息包括各進攻導彈的高度,以及它們發射次序。現要求編一程序,求在每次測試中,該防衛導彈最多能截擊的進攻導彈數量,一個導彈能被截擊應滿足下列兩個條件之一:
a)它是該次測試中第一個被防衛導彈截擊的導彈;
b)它是在上一次被截擊導彈的發射後發射,且高度不大於上一次被截擊導彈的高度的導彈。
輸入數據:第一行是一個整數n,以後的n各有一個整數表示導彈的高度。
輸出數據:截擊導彈的最大數目。
分析:定義l[i]為選擇截擊第i個導彈,從這個導彈開始最多能截擊的導彈數目。
由於選擇了第i枚導彈,所以下一個要截擊的導彈j的高度要小於等於它的高度,所以l[i]應該等於從i+1到n的每一個j,滿足h[j]=h[i]的j中l[j]的最大值。
程序如下:
#includestdio.h
int main()
{
int i,j,n,max,h[100],l[100];
scanf(“%d”,n);
for(i=0;in;i++)
scanf(“%d”,h[i]);
l[n-1]=1;
for(i=n-2;i=0;i–)
{
max=0;
for(j=i+1;jn;j++)
if(h[i]h[j]maxl[j])
max=l[j];
l[i]=max+1;
}
printf(“%d”,l[0]);
}
5. 石子合併
在一個圓形操場的四周擺放著n堆石子(n= 100),現要將石子有次序地合併成一堆。規定每次只能選取相鄰的兩堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。編一程序,由文件讀入堆棧數n及每堆棧的石子數(=20)。
選擇一種合併石子的方案,使得做n-1次合併,得分的總和最小;
輸入數據:
第一行為石子堆數n;
第二行為每堆的石子數,每兩個數之間用一個空格分隔。
輸出數據:
從第一至第n行為得分最小的合併方案。第n+1行是空行.從第n+2行到第2n+1行是得分最大合併方案。每種合併方案用n行表示,其中第i行(1=i=n)表示第i次合併前各堆的石子數(依順時針次序輸出,哪一堆先輸出均可)。要求將待合併的兩堆石子數以相應的負數表示。
Sample Input
4
4 5 9 4
Sample Output
-4 5 9 -4
-8 -5 9
-13 -9
22 4 -5 -9 4
4 -14 -4
-4 -18
22
6. 最小代價子母樹
設有一排數,共n個,例如:22 14 7 13 26 15 11。任意2個相鄰的數可以進行歸併,歸併的代價為該兩個數的和,經過不斷的歸併,最後歸為一堆,而全部歸併代價的和稱為總代價,給出一種歸併演算法,使總代價為最小。
輸入、輸出數據格式與「石子合併」相同。
Sample Input
4
12 5 16 4
Sample Output
-12 -5 16 4
17 -16 -4
-17 -20
37
7. 商店購物
某商店中每種商品都有一個價格。例如,一朵花的價格是2 ICU(ICU 是信息學競賽的貨幣的單位);一個花瓶的價格是5 ICU。為了吸引更多的顧客,商店提供了特殊優惠價。特殊優惠商品是把一種或幾種商品分成一組。並降價銷售。例如:3朵花的價格不是6而是5 ICU;2個花瓶加1朵花是10 ICU不是12 ICU。
編一個程序,計算某個顧客所購商品應付的費用。要充分利用優惠價以使顧客付款最小。請注意,你不能變更顧客所購商品的種類及數量,即使增加某些商品會使付款總數減小也不允許你作出任何變更。假定各種商品價格用優惠價如上所述,並且某顧客購買物品為:3朵花和2個花瓶。那麼顧客應付款為14 ICU因為:
1朵花加2個花瓶優惠價:10 ICU
2朵花正常價:4 ICU
輸入數據:第一個文件INPUT.TXT描述顧客所購物品(放在購物筐中);第二個文件描述商店提供的優惠商品及價格(文件名為OFF ER.TXT)。 兩個文件中都只用整數。
第一個文件INPUT.TXT的格式為:第一行是一個數字B(0≤B≤5),表示所購商品種類數。下面共B行,每行中含3個數C,K,P。 C 代表商品的編碼(每種商品有一個唯一的編碼),1≤C≤999。K代表該種商品購買總數,1≤K≤5。P 是該種商品的正常單價(每件商品的價格),1≤P≤999。請注意,購物筐中最多可放5*5=25件商品。
第二個文件OFFER.TXT的格式為:第一行是一個數字S(0≤S≤9 9),表示共有S 種優惠。下面共S行,每一行描述一種優惠商品的組合中商品的種類。下面接著是幾個數字對(C,K),其中C代表商品編碼,1≤C≤9 99。K代表該種商品在此組合中的數量,1≤K≤5。本行最後一個數字P(1≤ P≤9999)代表此商品組合的優惠價。當然, 優惠價要低於該組合中商品正常價之總和。
輸出數據:在輸出文件OUTPUT.TXT中寫 一個數字(佔一行),該數字表示顧客所購商品(輸入文件指明所購商品)應付的最低貨款。
8. 旅遊預算
一個旅行社需要估算乘汽車從某城市到另一城市的最小費用,沿路有若干加油站,每個加油站收費不一定相同。旅遊預算有如下規則:
若油箱的油過半,不停車加油,除非油箱中的油不可支持到下一站;每次加油時都加滿;在一個加油站加油時,司機要花費2元買東西吃;司機不必為其他意外情況而準備額外的油;汽車開出時在起點加滿油箱;計算精確到分(1元=100分)。編寫程序估計實際行駛在某路線所需的最小費用。
輸入數據:從當前目錄下的文本文件「route.dat」讀入數據。按以下格式輸入若干旅行路線的情況:
第一行為起點到終點的距離(實數)
第二行為三個實數,後跟一個整數,每兩個數據間用一個空格隔開。其中第一個數為汽車油箱的容量(升),第二個數是每升汽油行駛的公里數,第三個數是在起點加滿油箱的費用,第四個數是加油站的數量。(〈=50)。接下去的每行包括兩個實數,每個數據之間用一個空格分隔,其中第一個數是該加油站離起點的距離,第二個數是該加油站每升汽油的價格(元/升)。加油站按它們與起點的距離升序排列。所有的輸入都有一定有解。
輸出數據:答案輸出到當前目錄下的文本文件「route.out」中。該文件包括兩行。第一行為一個實數和一個整數,實數為旅行的最小費用,以元為單位,精確到分,整數表示途中加油的站的N。第二行是N個整數,表示N個加油的站的編號,按升序排列。數據間用一個空格分隔,此外沒有多餘的空格。
Sample Input
516.3 38.09 1
15.7 22.1 20.87 3 2
125.4 1.259
297.9 1.129
345.2 0.999
Sample Output
38.09 1
2
9. 皇宮看守
太平王世子事件後,陸小鳳成了皇上特聘的御前一品侍衛。皇宮以午門為起點,直到後宮嬪妃們的寢宮,呈一棵樹的形狀;某些宮殿間可以互相望見。大內保衛森嚴,三步一崗,五步一哨,每個宮殿都要有人全天候看守,在不同的宮殿安排看守所需的費用不同。可是陸小鳳手上的經費不足,無論如何也沒法在每個宮殿都安置留守侍衛。
請你編程計算幫助陸小鳳布置侍衛,在看守全部宮殿的前提下,使得花費的經費最少。
輸入數據:輸入數據由文件名為intput.txt的文本文件提供。輸入文件中數據表示一棵樹,描述如下:
第1行 n,表示樹中結點的數目。
第2行至第n+1行,每行描述每個宮殿結點信息,依次為:該宮殿結點標號i(0i=n),在該宮殿安置侍衛所需的經費k,該邊的兒子數m,接下來m個數,分別是這個節點的m個兒子的標號r1,r2,…,rm。
對於一個n(0 n = 1500)個結點的樹,結點標號在1到n之間,且標號不重複。
輸出數據:輸出到output.txt文件中。輸出文件僅包含一個數,為所求的最少的經費。
如右圖的輸入數據示例:
Sample Input
6
1 30 3 2 3 4
2 16 2 5 6
3 5 0
4 4 0
5 11 0
6 5 0
Sample Output
25
10. 遊戲室問題
有一個遊戲室里有多個遊戲室,並且這每個遊戲室里還有多個遊戲室,每個遊戲室裡面還有遊戲室,依此類推。進入每個遊戲室都可得到一定的快樂,每個遊戲室的門票價格都大於等於0,都有一個快樂值,並且只有進入了一個遊戲室,才可以進入它內部的遊戲室,小明現在有n元錢,問最大能得到多少的快樂。
11. *基因問題
已知兩個基因序列如s:AGTAGT;t:ATTAG。現要你給序列中增加一些空格後,首先使得兩個序列的長度相等,其次兩個串對應符號匹配得到的值最大。基因只有四種分別用A、G、C、T表示,匹配中不允許兩個空格相對應,任意兩符號的匹配值由下表給出:
A G C T 〕
A 5 -2 -1 -2 -4
G -2 5 -4 -3 -2
C -1 -4 5 -5 -1
T -2 -3 -5 5 -2
〕 -4 -2 -1 -2
提示:定義問題l[i][j]為取第一個序列的前i項,和第二個序列的前j項,這兩個序列加空格匹配的最大值。它的最優值與三個子問題有關,l[i-1][j-1]、l[i][j-1]、l[i-1][j]。
建立遞歸公式如下:
其中m[0][t[j]表示表中空格和t[j]匹配的對應值。
思考:本問題的初始化。
12. *田忌賽馬
田忌與齊王賽馬,雙方各有n匹馬參賽(n=100),每場比賽賭注為1兩黃金,現已知齊王與田忌的每匹馬的速度,並且齊王肯定是按馬的速度從快到慢出場,現要你寫一個程序幫助田忌計算他最好的結果是贏多少兩黃金(輸用負數表示)。
分析:先排序,齊王的馬的速度放在數組a中,田忌的馬的速度放在數組b中。本問題應用的演算法是動態規劃和貪心演算法相結合解決的。從兩人的最弱的馬入手:
若田忌的馬快,就讓這兩匹馬比賽;
若田忌的馬慢,乾脆就讓他對付齊王最快的馬;
若兩匹馬的速度相等,這時有兩種選擇方案,或者它倆比賽,或者對付齊王最快的馬。
定義子問題:l(i,j)為齊王的從第i匹馬開始的j匹馬與田忌的最快的j匹馬比賽,田忌所獲得的最大收益。
則:
程序具體實現時,為了適合c數據從0開始,稍加變動,定義子問題:l(i,j)為齊王的從第i匹馬開始到第i+j匹馬共j+1匹馬與田忌的最快的j+1匹馬比賽,田忌所獲得的最大收益。初始化時:l[i][0]表示齊王的第i匹馬與田忌最快的馬比賽的結果。
程序如下:
#includestdio.h
void readdata();
void init();
int n,a[100],b[100],l[100][100];
int main()
{
int i,j;
readdata();
init();
for(i=n-2;i=0;i–)
for(j=1;jn-i;j++)
if(a[i+j]b[j])
l[i][j]=l[i][j-1]+1;
else if(a[i+j]b[j])
l[i][j]=l[i+1][j-1]-1;
else if(l[i+1][j-1]-1l[i][j-1])
l[i][j]=l[i+1][j-1]-1;
else
l[i][j]=l[i][j-1];
printf(“%d”,l[0][n-1]);
}
void readdata()
{
int i;
scanf(“%d”,n);
for(i=0;in;i++)
scanf(“%d”,a[i]);
for(i=0;in;i++)
scanf(“%d”,b[i]);
}
void init()
{
int i;
// qsort(a,n); //略
for(i=0;in;i++)
{
if(a[i]b[0])
l[i][0]=1;
else if(a[i]==b[0])
l[i][0]=0;
else
l[i][0]=-1;
}
}
在大學學C語言能幹什麼?有什麼用?最妤舉些易明白的例子
學了總沒有壞處的,出來工作了,至少你不編程吧,別人說你還是聽得懂,不至於盲
C語言的基本語法我是不打算再提了,很多C語言編程的書,就是將一些基本的數據類型、數據結構、語法,然後就是一些數值
計算的實例,大多數都是雷同的,難免有抄襲之嫌,而且頁沒有多少實用價值。
本書以實用實例作為編程指導,指引大家編寫真正實用的程序。了解到大家對黑客程序、病毒、窗口類程序比較感興趣,因此我就拿這些實例進行講解。基於大家基本都用Windows XP SP3,我也就在這個系統上把程序調試成功後再給大家講解。編程環境,我還是喜歡VisualC++ 6.0
本書計劃從四個大的方面來講,這四個方面是:窗口類、文件操作類、網路類、資料庫類。
都是時下流行的編程必備技術,也是軟體開發者,必須掌握的技術。中間以實例講解,逐步學習,相信大家看完後會有很大的提高的。
第一章窗口類程序的編寫
這一章就先來講解下窗口類程序的編寫。因為現在程序沒有界面,就像人沒有臉面一樣,而且好的界面更能吸引人。從基本的界面開始,相信能給大家指明出一條路的,使大家很容易地掌握窗口序的編寫。其實界面設計利用VC 6.0 的MFC,很容易地製作出來。這裡從底層開始寫代碼來寫界面程序,使大家知道一些底層的東西,為以後學習打下好的基礎,相信您學了這些,再用VC 的MFC會得心應手的。
1.1
用 C 寫的第一個一個窗口程序
作為編程的開始,我們還是以一個Hello World來開始我們的學習之旅。代碼如下:
#include stdio.h
void main()
{
printf(“Hello World!”);
}
這是一個再簡單不過的C程序了,只要有點C語言的知識就能夠懂的,不過這裡估計還有些人,到現在還不知道#include
stdio.h中的頭文件stdio.h到底是什麼東西,我就來說下了,stdio.h是一個文本文件,存在於磁碟上的,已VC為例它的位置如下圖:
也許你聽說過printf()函數是在stdio.h中預定義的,但是你見過其定義的形式沒有,沒有且看下圖
其定義形式,就如圖中所示,也許你並不懂前面那些東西是什麼,不用擔心,以後我會慢慢解釋給大家的。函數是先定義才能使用的,所以stdio.h中定義printf函數,我我們在引用了stdio.h頭文件後就可以在程序中調用printf函數了。
上面是在命令行中顯示一個「Hello World!」,沒什麼意思,下面我寫一個窗口程序,顯示個Hello World!
#include windows.h
void main()
{
MessageBox(NULL,”Hello World!”,”我的第一個窗口程序”,MB_OK);
}
編譯運行後如下圖:
彈出的是一個對話框,上面有Hello World,還有一個標題和一個「確定」按鈕。
當然你會說這對話框也算個窗口嗎?這裡肯定的告訴你:是的,對話框是窗口程序的一個子集。你可能還會這樣問,這樣一個簡單的窗口有啥用呢,其實這樣的窗口非常有用,我們在操作計算機的時候,會出現一些警告或提示的對話框,都是基本是這種方法寫出來的。就算是這個很簡單,學習本來不就是有易向難,有淺顯深奧去的過程嗎。
整個效果幾乎就是靠一個函數MessageBox的功勞。這裡也先不介紹這個函數了,說些其他的。
其實用C編寫一些惡程序,就是把編程環境中所提供的一些函數熟悉了基本就可以了。用VC來寫成序,其中的頭文件有很多,定義了很多Windows API 函數、數據結構、宏,可以讓我們大家運用,通過它們,我們可以快速開發出使用的程序。這些Windows API在微軟的MSDN上查,上面有很多說明,部分還有代碼示例。不會是可以輸入函數名,查找相關信息,建議大家用英文版的Library,因為其內容比中文版的全面,英語不好的同學呢,就先看中文了
中文MSDN:
英文MSDN:
到這裡,我們就完成第一個有界面程序的編寫,你感覺寫有界面的程序難嗎?顯然不難。
下面看一個向鋒和波波感興趣的程序:九九乘法
採用命令行形式
#include 「stdio.h」
int i=0,j=0;
for(i=1;i10;i++)
for(j=1;ji+1;j++)
printf(「%d*%d=%d\t」,j,i,j*i);
printf(「\n」);
和那個javascript效果都是一樣的,所以語言只要學好一樣,其他的就很容易旁通的,學習就撿一種學好,不要貪多。
好的,這一節就這樣吧,大家先各自了解下微軟的MSDN,對以後的學習會有很大的幫助的。
1.2 第一個真正的窗口程序
上一節中,我們用MessageBox函數輕鬆地實現了一個對話框窗口,可能你會說,那僅僅是個沒有用的對話框而已,是的,只是對話框而已。我之所以以一個對話框為例呢,是因為我只是想讓你知道寫一個有界面的程序並不是件難辦的事。明白了這一點後,我們繼續。今天來編寫一個真正的窗口程序。
下面就該羅嗦一段了,由於大家以前並沒有寫過什麼窗口程序,寫的都是命令行下的,我們知道在命令行下的程序都有一個主函數main,這個函數也就是程序的入口函數。我們現在用VC 6.0來寫,而且要寫窗口類程序,VC 6.0給我們提供了一個專門用作窗口類程序的入口函數WinMain()
這個函數原型是這樣的
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTRlpCmdLine,
int nCmdShow
);
大家是不是感覺這個函數挺複雜的,有這麼幾個參數,而像main好像就沒有參數。其實main是有參數,這個向鋒和小四是知道了的。但是main函數的參數是可以省略的,而WinMain是不可以省的。這裡也要對VC6.0的編譯模式改下
看下圖
依次是「工程」→「設置」→「連接」,在「工程選項」里把console改為windows就可以了。如果認真學了彙編,或是手寫命令編譯連接過C程序,就會知道這是幹什麼的。Console是控制台的意思,以前我們用mian函數寫的程序都是以控制台模式連接的,所以很少會有界面的。現在我們要寫有界面的程序,所以要選Windows(窗口)模式了。
我們寫入以下代碼,並按照上面說的方法去做,看看結果
#include “windows.h”
int WINAPI WinMain(HINSTANCEhInstance,
HINSTANCE hPreInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
MessageBox(NULL,”WinMain創建的窗口程序”,”WinMain”,MB_OK);
return0;
}
結果如下圖:
與第一節中的這段代碼代碼比較下
#include 「windows.h」
void main()
{
MessageBox(NULL,”Hello World!”,”我的第一個窗口程序”,MB_OK);
}
兩者比較下,後者多了個cmd窗口。可見用main寫的並沒有完全脫離命令行呀。所以以後我們寫窗口程序就用winmain了。
好了,轉過來,我們來看看WinMain()函數,其中有4個參數
先看下解釋(看不明白得先看完):
hInstance:應用程序當前事例的句柄。
hPrelnstance:應用程序的先事例的句柄。對於同一個程序打開兩次,出現兩個窗口第一次打開的窗口就是先前實例的窗口。對於一個32的位程序,該參數總為NULL。
lpCmdLine:指嚮應用程序命令行的空字元串的指針,不包括函數名。獲得整個命令行,參看GetCommandLine。
nCmdShow:指明窗口如何顯示(是隱藏還是顯示,有沒有最大化按鈕之類的)。取值可以參考MSDN
這裡我相信有一個詞大家好應該比較陌生,句柄(HANDLE)是吧。下面我就來簡單的說下
句柄其實就是Windows系統中一個東西的唯一標識。就是系統中有很多運行的程序或者資源之類的,為了更好的管理使用,Windows系統給它們每人一個ID一樣。懂得網頁製作的人應該知道網頁中各個元素的ID吧,網頁的ID如果重複話可能出現錯誤。那麼系統的句柄會不會有相同的,那是肯定不會有的了,就和我們的學號一樣,系統自動分配每一個模塊的句柄,是不會相同的了。
對於句柄大家可以先這樣理解著,不用一下子搞懂得。以後學著學著就明白了。
估計大家對那幾個參數的類型改犯迷糊了吧。其實那幾個類型,並不是什麼新類型,都是Windows開發人員為了自己和他人編程方便,同過基本的C語言語法定義一種新的結構體,或者是共同體,再者就是枚舉類型。我知道結構體、共同體和枚舉類型,很多老師是沒有講到的,因為在書的後邊,很多教C的,又是很垃圾的老師,所以不會講那麼快的。其實結構體這些數據類型,就是通過我們常用的字元、整型、浮點等數據類型構造一個比較複雜的類型而已,舉個例子,就是我們知道C沒有一個數據類型可以描述一個人吧,那麼我構造一個是不是很方便我們編程呢。我們可以這樣構造一個
struct People
{
intage;//年齡
charsex[2];//性別
intheight;//身高
……
}
我們這樣定義以後就可以在我們以後的程序中利用這個數據類型了,People zhangsan;把zhangsan的身高172放到zhangsan.height中。這樣可以方便完成很多工作。所以結構體是很簡單的,還有其他的複雜數據類型也是很簡單的,都是有常用的簡單的類型來結合到一起構造一個複雜的而已。這和JAVA定義類是很相似的,java定義個人類,不是可以這樣的
public class People
{
publicint age;
publicstring sex;
publicheight;
……
}
看起來都差不多,而且用法也很相像。唯一的差別其實就是類可以有方法,而結構體是沒有的(經過特殊處理也是可以的,這裡不用考慮)。
上面是為了讓大家了解下複雜數據類型的定義,羅嗦了一大堆。下面來看下WinMain中第一個參數的類型HINSTANCE這個只是個結構體而已,實際上和HANDLE這個類型差不多,但是有一點差別,而HANDLE是這樣typedef PVOID HANDLE;定義的,PVOID是什麼呢,我們來看下typedef void *PVOID;說明PVOID是一個指針,初始指向空(void)。因此可以知道句柄也是個指針而已。看著這麼複雜原來也只是指針。
這些都可以在微軟的msdn上查得到的,而且很詳細的
那個第二個LPSTR 根據字面上的意思就知道是字元串類型了。查一查果然是。
大家一定要利用好msdn,很有用的。
本節就到此結束了,主要是說明了一個WinMain函數和結構體的事情,東西也不算太多,大家應該能接受得了吧。下節就來點複雜點深點的東西,希望大家做好心理準備。
1.3 窗口程序的編寫
在來啰嗦之前,希望大家能夠做好準備,這一節知識有點多,內容有點長。但願大家能夠一口氣讀完,如果一口氣讀不完,那就換口氣接著讀。
上節中我們用MessageBox()就實現了一個真正的窗口。MessageBox()中的原型如下:
Int MessageBox(HWND hWnd,
LPCTSTRlpText,
LPCTSTRlpCaption,
UINT uType);
參數解釋
hWnd 所屬對話框所屬窗口的句柄,如果是NULL,則此對話框不屬於任何一個窗口。
lpText 對話框窗口的顯示內容。
lpCaption 對話框窗口的標題。
uType 對話框的樣式和動作(像是確定按鈕,還是取消按鈕就是設置這裡的)
關於這個函數的細節可以看這裡
到此為止,你也算是會了窗口程序的編寫,但只是一個開始,不過這已經很好,可能會讓你感覺到了C的魅力,也可能會稍微解點C語言能幹什麼的疑惑。在開始寫代碼之前,我有必要把細節和原理先說明下。
Windows下一個窗口創建的過程有以下幾個步驟:
1. 程序創建一個窗口,首先要向Windows系統註冊一個窗口類wndclassex,其實就是定義一個變數,變數的類型是WNDCLASSEX(結構體)。該結構體的定義與介紹看這裡(),
typedef struct {
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
HICON hIconSm;
} WNDCLASSEX, *PWNDCLASSEX;
成員介紹
cbSize 值為sizeof(WNDCLASSEX),在調用GetClassInfoEx前必須要先設置它值。
style 窗口類的樣式,它的值可以是窗口樣式值的任意組合。
可以有以下的值
lpfnWndProc 指向窗口處理函數(回調函數)。處理窗口事件,像單擊滑鼠會怎樣,右擊滑鼠會怎樣,都是由此函數控制的。
cbClsExtra 為窗口類的額外信息做記錄,系統初始化為0。
cbWndExtra 記錄窗口實例的額外信息,系統初始為0.如果程序使用WNDCLASSEX註冊一個從資源文件里創建的對話框,則此參數必須設置為DLGWINDOWEXTRA
hIcon 窗口類的圖標,為資源句柄,如果設置為NULL,系統將為窗口提供一個默認的圖標。
hCursor 窗口類的滑鼠樣式,為滑鼠樣式資源的句柄,如果設置為NULL,系統提供一個默認的滑鼠樣式。
hbrBackground 窗口類的背景刷,為背景刷句柄,也可以為系統顏色值,如果顏色值已給出,則必須轉化為以下的HBRUSH的值
· COLOR_ACTIVEBORDER
· COLOR_ACTIVECAPTION
· COLOR_APPWORKSPACE
· COLOR_BACKGROUND
· COLOR_BTNFACE
· COLOR_BTNSHADOW
· COLOR_BTNTEXT
· COLOR_CAPTIONTEXT
· COLOR_GRAYTEXT
· COLOR_HIGHLIGHT
· COLOR_HIGHLIGHTTEXT
· COLOR_INACTIVEBORDER
· COLOR_INACTIVECAPTION
· COLOR_MENU
· COLOR_MENUTEXT
· COLOR_SCROLLBAR
· COLOR_WINDOW
· COLOR_WINDOWFRAME
· COLOR_WINDOWTEXT
lpszMenuName 指向一個以NULL結尾的字元床,同目錄資源的名字一樣。如果使用整型id表示菜單,可以用MAKEINTRESOURCE定義一個宏。如果它的值為NULL,那麼該類創建的窗口將都沒有默認的菜單。
lpszClassName 窗口類的名字,字元串類型。
hIconSm 小圖標的句柄,在任務欄顯示的圖標,可以和上面的那個一樣。
定義一個WNDCLASSEX類型變數後,在給變數成員初始化後,我們就可以用
RegisterWindowEx(wndclassex)來註冊這個窗口類了。
這個註冊過程,就和我們平常創建一個項目一樣,都要先註冊才能創建。
裡面的/t是什麼意思?編程c語言的內容
你要明白\t和\n的作用,\t是製表符,說的通俗點就是一個tab鍵,就是三個空格,\n是換行符
對於你這裡就是做格式調整,代碼書寫具有多樣性
printf(“\t\tLove you\n\n”);printf(“\t\tLove you”);
printf(“\n\n”)以上兩者的效果是等效的,你想畫一個花瓶,不同的人有不同的畫法,最終你看到的只是一個花瓶.
代碼也是一樣的可能你寫法不一樣,但是效果是一樣的
專業解答,我頭像,驚喜
昨天我看到一個IQ問題,想了一夜把答案想出來了,今天卻找不到那個問題了,只好給大家猜了!
1.擊滑鼠
擊滑鼠比賽現在開始!參賽者有拉爾夫、威利和保羅。
拉爾夫10秒鐘能擊10下滑鼠;威利20秒鐘能擊20下滑鼠;保羅5秒鐘能擊5下滑鼠。以上各人所用的時間是這樣
計算的;從第一擊開始,到最後一擊結束。
他們是否打平手?如果不是,誰最先擊完40下滑鼠?
答案:不是平手,威利最先擊完。
2.感覺
用第一感覺判斷8+8=91這個等式正確嗎?說明理由。
答案:正確,倒過來看
3.謊話
如果下列每個人說的話都是假話,那麼是誰打碎了花瓶?
夏克:吉姆打碎了花瓶。
湯姆:夏克會告訴你誰打碎了花瓶。
埃普爾:湯姆,夏克和我不太可能打碎花瓶。
克力斯:我沒打碎花瓶。
艾力克:夏克打碎了花瓶,所以湯姆和埃普爾不太可能打碎花瓶。
吉姆:我打碎了花瓶,湯姆是無辜的。
答案:湯姆+埃普爾+克力斯
4.大有作為
魯道夫、菲利普、羅伯特三位青年,一個當了歌手,一個考上大學,一個加入美軍陸戰隊,個個未來都大有作
為。現已知:
A. 羅伯特的年齡比戰士的大;
B. 大學生的年齡比菲利普小;
C. 魯道夫的年齡和大學生的年齡不一樣。
請問:三個人中誰是歌手?誰是大學生?誰是士兵?
答案:魯道夫、菲利普、羅伯特
士兵 歌手 大學生
5.麻省理工大學的學生
美國麻省理大學的學生來自不同國家。
大衛、比利、特德三名學生,一個是法國人,一個是日本人,一個是美國人。現已知:
1、 大衛不喜歡麵條,特德不喜歡漢堡包;
2、 喜歡麵條的不是法國人;
3、 喜歡漢堡包的是日本人;
4、 比利不是美國人。
請推測出這三名留學生分別來自哪些國家?
答案:大衛 比利 特德
日 法 美
6.宴會桌旁
在某賓館的宴會廳里,有4位朋友正圍桌而坐,侃侃而談。他們用了中、英、法、日4種語言。現已知:
A.甲、乙、丙各會兩種語言,丁只會一種語言;
B.有一種語言4人中有3人都會;
C.甲會日語,丁不會日語,乙不會英語;
D. 甲與丙、丙與丁不能直接交談,乙與丙可以直接交談;
E. 沒有人既會日語,又會法語。
請問:甲乙丙丁各會什麼語言?
答案:甲 乙 丙 丁
日中 中法 英法 中
7.藉機發財
從前有A、B兩個相鄰的國家,它們的關係很好,不但互相之間貿易交往頻繁,貨幣可以通用,匯率也相同。也
就是說A國的100元等於B國的100元。可是兩國關係因為一次事件而破裂了,雖然貿易往來仍然繼續,但兩國國王
卻互相宣布對方貨幣的100元只能兌換本國貨幣的90元。有一個聰明人,他手裡只有A國的100元鈔票,卻藉機撈
了一大把,發了一筆橫財。請你想一想,這個聰明人是怎樣從中發財的?
答案:在A國買90元的貨物,到B國可以賣95元;同樣在B國買90元的貨物到A國可以賣95元……
8.不合理的安排
S先生正在家裡休息時,接到了一個陌生人打來的預約電話。對方很想在下下個星期的周五去他家裡拜訪他。
但是S先生並不想見這個陌生人,於是他連忙說:「下下個禮拜五我非常忙。上午要開會,下午1點鐘要去參加一
個學生的婚禮,接著4點鐘要去參加一個朋友的孩子的葬禮,隨後是我的叔叔的七十壽辰宴會。所以那天我實在
是沒有時間來接待您的來訪了。」
請仔細看題,S先生的話里有一處是不可信的,是哪個地方?
答案: 誰會知道自己再一個星期後死亡呢。
9.快馬加鞭
墨西哥農村現在仍然可以看到人們用馬和驢運載貨物。一位商人把四匹馬從甲村拉到乙村,而從甲村到乙村,
A馬要花一小時,B馬要花兩小時,C馬要花四小時,D馬要花五小時。
這位商人一次只能拉兩匹馬,回來時他還要騎一匹馬,其中以走得慢的那匹馬作為從甲村拉到乙村所需的時間
。聽說有人花了12小時就把四匹馬全部從甲村拉到乙村,請問:他是如何辦到的?
答案:甲到乙 AB 2
乙到甲 A 1
甲到乙 CD 5
乙到甲 B 2
甲到乙 AB 2
我想了一天才作出來,請樓主給分吧
c語言打碎花瓶題目?
int a[4] = {0}; // a[0]:甲;a[1]:乙;a[2]:丙;a[3]:丁
/* 0表示沒打碎,1表示打碎:
* 甲說:乙沒有打碎,是丁打碎的 – a[1]+a[3] == 1
* 乙說:我沒有打碎,是丙打碎的 – a[1]+a[2] == 1
* 丙說:甲沒有打碎,是乙打碎的 – a[0]+a[1] == 1
*/
if (a[1]+a[3] == 1 a[1]+a[2] == 1 a[0]+a[1] == 1)
為什麼上述條件這麼寫呢?我猜測是因為「4個人中每個人要麼是誠實的,要麼總是說謊的。」我沒看懂這個條件。
此類邏輯推理題,說謊與誠實這個條件是很重要的,由此,我用C語言實現了另一道邏輯推理題,供參考。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/282964.html