20145233韓昊辰第二週C語言實習
實習內容
- 學習使用新系統中的C語言教學,完成25個課時的學習,在虛擬機中完成C語言代碼編寫與基礎C語言知識理解。
- 由於虛擬機打開不方便,而且使用的是vc6編譯的,因此在諮詢了老師以後,可使用本身的電腦完成此次實習,因此我接下來會放上本身25個課時的結果截圖,以及程序代碼。
實習一 C語言的概述
- c語言的起源和發展
- c語言的特色
優勢:代碼量小 速度快 功能強大
缺點:危險性高 開發週期長 可移植性不強
- c語言的應用領域
系統軟件開發:操做系統 :windows linux unix
驅動程序:主板驅動 顯卡驅動 攝像頭驅動
數據庫:DB2 Oracle Sql server
應用軟件開發:辦公軟件:Wps
圖形圖像多媒體:ACDSee Photoshop、MediaPlayer
嵌入式軟件開發:智能手機、掌上電腦
遊戲開發:2D、3D遊戲
- c語言的重要性:a.有史以來最重要的語言
b.全部大學工科和理科學生必修課程
c.最重要的系統軟件:Windows、Linux、Unix均使用c開發
d.一名合格黑客必須掌握的語言
e.程序設計和開發人員必須掌握的語言
f.學習數據結構、c++、java、c#奠基基礎
- Visual C++ 6.0軟件的安裝
實習程序代碼
#include <stdio.h>
#include <math.h>
int main(void)
{
int a = 1;
int b = 2;
int c = 3;
float delta;
float x1;
float x2;
delta = b*b - 4*a*c;
if (delta > 0)
{
x1 = (-b + sqrt(delta)) / (2 * a);
x2= (-b - sqrt(delta)) / (2 * a);
printf("該一元二次方程有兩個解,x1=%f,x2=%f\n", x1, x2);
}
else if (delta = 0)
{
x1 = -b / (2 * a);
x2 = x1;
printf("該一元二次方程有惟一一個解,x1=x2=%f\n", x1);
}
else
{
printf("無解\n");
}
return 0;
}
實習一結果
實習二 算法
- 算法
- (1)算法是指解題方案的準確而完整的描述。
A.算法的基本特徵:①可行性;②肯定性;③有窮性;④擁有足夠的情報。
B.算法的基本要素:①算法中對數據的運算和操做:基本的運算和操做包括算術運算、邏輯運算、關係運算和數據傳輸;②算法的控制結構:基本的控制結構包括順序結構、選擇結構、循環結構。
C.算法設計的基本方法:①列舉法;②概括法;③遞推;④遞歸;⑤減半遞推技術;⑥回溯法。
- (2)算法的複雜度
算法的複雜度主要包括時間複雜度和空間複雜度。
A.算法的時間複雜度:是指執行算法所須要的計算工做量。算法的工做量用算法所執行的基本運算次數來度量,而算法所執行的基本運算次數是問題規模的函數。即:算法的工做量=f(n)其中n是問題的規模。
B.算法的空間複雜度:通常是指執行這個算法所須要的內存空間。一個算法所佔用的存儲空間包括算法程序所佔的空間、輸入的初始數據所佔用的存儲空間以及算法執行過程當中所須要的額外空間。
- 數據結構的基本概念
數據結構做爲計算機的一門學科,主要研究和討論如下三個方面的問題:
①數據集合中各數據元素之間所固有的邏輯關係,即數據的邏輯結構;
②在對數據進行處理時,各數據元素在計算機中的存儲關係,即數據的存儲結構;
③對各類數據結構進行的運算。
- (1)數據結構的定義
①數據結構是指相互有關聯的數據元素的集合。
②數據處理是指對數據集合中的各元素以各類方式進行運算,包括插入、刪除、查找、更改等運算,也包括對數據元素進行分析。
③數據的邏輯結構是指反映數據元素之間邏輯關係的數據結構。
④數據的邏輯結構在計算機存儲空間中的存放形式稱爲數據的存儲結構(也稱數據的物理結構)。經常使用的存儲結構有順序、連接、索引等存儲結構。
- (2)數據結構的圖形表示
在數據結構的圖形表示中,對於數據集合D中的每個數據元素用中間標有元素值的方框表示,通常稱之爲數據結點,簡稱結點;爲了進一步表示各數據元素之間的先後件關係,對於關係R中的每個二元組,用一條有向線段從前件結點指向後件結點。
- (3)線性結構與非線性結構
若是一個非空的數據結構知足下列兩個條件:
①有且只有一個根結點;
②每個結點最多有一個前件,也最多有一個後件。
則稱該數據結構爲線性結構。若是一個數據結構不是線性結構,則稱爲非線性結構。
圖解算法的邏輯結構
- 步驟1:順序結構。順序結構是最簡單的算法結構,語句與語句之間,框與框之間是按從上到下的順序進行的。它是由若干個依次執行的處理步驟組成的,它也是任何一個算法都離不開的一種算法結構,如圖,其中A和B兩個框是依次執行的,只有在執行完A框所指定的 操做後,才能接着執行B框所指定的操做。順序結構的一個簡單的例子是交換變量a和b的值。
- 算法以下:
S1:m=a;
S2:a=b;
S1:b=m.
- 程序框圖如圖:
圖 1 邏輯算法圖java
- 步驟2:條件分支結構。在一個算法中,常常會遇到一些條件的判斷、算法的流程根據條件是否成立有不一樣的流向,這種先根據條件做出判斷,再決定執行哪種操做的結構稱爲條件分支結構,如右圖所示的一個條件分支結構,此結構中包含一個判斷框,根據給定的條 件P是否成立而選擇執行A框或B框,請注意,不管P條件是否成立,只能執行A框或B框之一,不可能既執行A框又執行B框,也不可能A框和B框都不執行。不管走哪一條路徑,在執行完A框或B框以後,脫離本條件分支結構。A框或B框兩個框中,能夠有一個是空的,即不執行 任何操做
- 例:
- 寫出求方程px+q=0(其中p和q爲常數)根一個算法,並畫出程序框圖。
- 分析:此方程的根與p和q取值有關。算法以下:
S1:輸入p、q
S2:若是p≠0,則使x=-q/p,並執行S3;不然,執行S4;
S3:輸出x;
S4:若是q≠0,則輸出「方程無實數根」,不然,輸出「方程的解是全體實數」
圖 2 邏輯算法圖linux
- 步驟3:循環結構。須要重複執行同一操做的結構稱爲循環結構,即從某處開始,按照必定條件反覆執行某一處理步驟,反覆執行的處理步驟稱爲循環體。循環結構中一般都有一個起循環計數做用的變量,這個變量的取值通常都包含在執行或終止循環的條件中。循環結 構有while型循環(也稱當型循環)和until型循環(也稱直到型循環)兩種,要注意這兩種循環的聯繫和區別。
實習代碼
# include <stdio.h>
int main(void)
{
int i,j;
for(i = 100;i <= 300;i++)
{
for(j = 2;j <= i;j++)
if(i%j == 0)
break;
if(j ==i)
printf("%-4d",i);
}
return 0;
}
實習二結果
實習三 C語言預備計算機知識
- 彙編語言是最低級的語言,它能夠直接與硬件打交道。高級語言有Pascal、Basic、Fortran等等。高級語言的一條語句對應低級語言的不少條語句,任何高級語言編寫的程序都要通過編譯程序的編譯、鏈接才能成爲能夠運行的程序。
- 編譯鏈接的過程也就是把高級語言翻譯成機器語言(二進制機器碼)的過程,而彙編語言是基本上與機器語言一 一對應的一種語言。這個翻譯過程是由編譯程序自動完成的。把C語言定爲中級語言是有它的道理的,由於C語言既有彙編語言的存取底層硬件的能力,又具備高級語言的許多特色。熟練掌握了C語言,學習其它的各類編程語言應該是很輕鬆的了。
- C語言的書寫格式:
1) 一個C語言編寫的源程序,一定有一個主程序(稱爲main()函數,在C語言中子程序稱爲「函數」(固然,不要理解成爲數學裏面的「函數」)。可是決不能有一個以上的main函數(即只能有一個)。
2) 函數語句塊用‘{’括號開始, 以‘}’反括號結束。這樣的花括號必須成對出現。
3) 表達式寫在小括號裏面,以‘(’括號開始,以‘)’反括號結束。
4) 函數不能嵌套,即函數裏面不能再套函數。(每個函數是完成一個特定功能的函數模塊)
- C語言的組成:
C語言是由許多函數組成的。其中只有一個主函數(main()函數)。C程序執行時老是從main函數的‘{’處開始,至main函數的反大括號'}'處結束。固然還有其它一些規則,這將在之後的學習中去熟悉它。
- C語言的書寫規則:
C語言在書寫時有它自身的特色:書寫格式比較自由,在一行裏能夠寫多條語句,一個語句也能夠分寫在多行上。雖然如此,在書寫源程序時仍是要注意哪些能夠自由書寫,而哪些必需要按照書寫規則來書寫。
- 幾條規則寫在下面:
1) 一行內能夠寫幾個語句,建議一行不超過兩條語句;
2) 一條語句能夠寫在多行上;
3) C語句不須要寫行標號;
4) 每條語句及數據定義的後面要寫上分號以表示該語句結束;
5) C語言中註釋用 //來表示;
6) 建議書寫時採用縮進格式;
7) 花括號、小括號都是成對出現的。
- 一個最簡單的C程序的編寫:
/程序代碼/ /註釋部分/
main() /main是主函數名。緊跟在main後面的括號是放參數的。
括號裏面爲空說明main函數不須要參數/
{ /正寫的大花括號表示main函數從這裏開始/
} /反寫的大花括號表示main函數到這裏結束/
- 說明:因爲是一個演示程序,在函數體內並無任何能夠執行的語句,也就是這個程序什麼事也不作。
這個程序就是這麼簡單: 寫在一行上就是 main() { }
你在TC的編輯環境下把這段代碼輸入進去,按F9鍵編譯鏈接,按CTRL_F5運行,必定很正常。可是什麼結果也不會有,由於在main函數裏面什麼代碼也沒有。
- 下面再舉一個能夠向屏幕上輸出一條信息的例子:
main()
{
printf("這就是C語言編寫的程序!"); /這一條語句的做用是向屏幕輸出一條信息
」這就是C語言編寫的程序!"/
}
- 在這個程序中,main函數只有一條語句:printf("這就是C語言編寫的程序!");這個語句的做用是向屏幕輸出一個字符串。有關這個語句的知識之後再講。如今要注意的是一個C語言程序的框架是怎樣組成的。
- C語言程序的幾種文件格式:
- 一、 源程序---在TC集成環境中輸入的程序文本稱爲源程序。源程序是一種文本文件。它是咱們看得見並認識的一種文件。其擴展名爲.C。例如你把文件保存爲TEST,那麼在磁盤上應看獲得TEST.C這個文件。這樣的文件能夠用記事本打開。
- 二、二進制文件---寫完了源程序後接着要作的是編譯這個文件。在TC集成環境裏是按ALT_F9鍵,編譯後生成了一個二進制文件,這個二進制文件名爲TEST.OBJ,也就是擴展名爲OBJ的目標文件。
- 三、運行文件---最後一步是make(或Link),在TC集成環境裏是按F9鍵Make以後生成了一個能夠在DOS下運行的文件,其擴展名爲EXE。如TEST.EXE。這個EXE文件是由第2步中的OBJ文件生成的。
- OBJ文件雖然是二進制文件,而電腦又是能夠運行二進制文件的,爲何還要把OBJ文件Link爲EXE文件才能運行?這裏的知識就比較多了,這裏不能多講。
- 可是要明白一點,在DOS下僅僅有了一個二進制文件還不能運行,由於操做系統要把這些二進制文件加以規劃,把相應的數據、程序代碼放到應該放的內存位置,這樣的通過嚴密規劃和組織好了的二進制文件才能運行。而這些只有在生成的EXE文件裏面才作完了這些工做。
實習代碼
#include <stdio.h>
int main(void)
{
float x=123.45e-2;
printf("%f\n",x);
return 0;
}
實習三結果
實習四 硬件之間的關係
- 1 軟硬件協同設計概要
- 1.1傳統的設計方法
嵌入式系統由功能模塊組成,按實現方法能夠分爲軟件模塊和硬件模塊兩大類。傳統的設計方法
採用硬件優先的原則。流程如圖1所示。
- 1.2軟硬件協同設計方法
- 軟硬件協同設計讓軟件設計和硬件設計做爲一個總體,在設計初期對系統進行建模(modeling),在
此基礎上實現軟硬件的綜合優化探索和並行開發。
- 硬件模型能夠在必定的抽象層次(相對於RTL層次)實現,一般建的是事務級模型(TransactionLev-el Model),用高級語言C或SystemC來實現。相對於RTL精確到pin和cycle的顆粒度,TLM模型只須要精確到數據傳輸包的顆粒度,所以模型的設計時間遠比RTL設計少,仿真速度遠比RTL快。軟件設計能夠在硬件模型的基 礎上就展開驗證,系統模型在早期就能夠獲得驗證和評估,減小了每次系統優化迭代的時間。硬件設計完成後的系統集成,因爲軟件部分已經基本獲得驗證,因此調試難度也相對較小。
- 基於軟硬件協同設計的原理,提出了一種用c語言建模系統的方法,並將它應用於實際產品研發項目中,大大下降了驗證複雜度,優化了系統性能,縮短了開發週期。在軟件功能函數基礎上,用C語言實現硬件模塊的全部寄存器讀寫功能,主要包括:
①參數寄存器配置模塊參數。
②命令寄存器觸發硬件工做過程。
③狀態寄存器儲存硬件狀態和處理結果。
實習代碼
#include <stdio.h>
int main(void)
{
int x=47;
printf("%x\n",x);
printf("%x\n",x);
printf("%#x\n",x);
printf("%#x\n",x);
return 0;
}
實習四結果
實習五 數據類型和變量
%a,%A 讀入一個浮點值(僅C99有效)
%c 讀入一個字符
%d 讀入十進制整數
%i 讀入十進制,八進制,十六進制整數
%o 讀入八進制整數
%x,%X 讀入十六進制整數
%s 讀入一個字符串,遇空格、製表符或換行符結束。
%f,%F,%e,%E,%g,%G 用來輸入實數,能夠用小數形式或指數形式輸入。
%p 讀入一個指針
%u 讀入一個無符號十進制整數
%n 至此已讀入值的等價字符數
%[] 掃描字符集合
%% 讀%符號
x是1~f,X是1~Fc++
實習代碼
# include <stdio.h>
int main(void)
{
int x = 47;
printf("%x\n",x);
printf("%x\n",x);
printf("%#x\n",x);
printf("%#x\n",x);
return 0;
}
實習五結果
實習六 什麼叫進制
- 一)、數制
計算機中採用的是二進制,由於二進制具備運算簡單,易實現且可靠,爲邏輯設計提供了有利的途徑、節省設備等優勢,爲了便於描述,又經常使用8、十六進制做爲二進制的縮寫。
- 通常計數都採用進位計數,其特色是:
(1)逢N進一,N是每種進位計數製表示一位數所須要的符號數目爲基數。
(2)採用位置表示法,處在不一樣位置的數字所表明的值不一樣,而在固定位置上單位數字表示的值是肯定的,這個固定位上的值稱爲權。
在計算機中:D7 D6 D5 D4 D3 D2 D1 D0 只有兩種0和1
8 4 2 1
- 二)、數制轉換
- 不一樣進位計數制之間的轉換原則:不一樣進位計數制之間的轉換是根據兩個有理數如相等,則兩數的整數和分數部分必定分別相等的原則進行的。也就是說,若轉換前兩數相等,轉換後仍必須相等。
有四進制
十進制:有10個基數:0 ~~ 9 ,逢十進一
二進制:有2 個基數:0 ~~ 1 ,逢二進一
八進制:有8個基數:0 ~~ 7 ,逢八進一
十六進制:有16個基數:0 ~~ 9,A,B,C,D,E,F (A=10,B=11,C=12,D=13,E=14,F=15) ,逢十六進一
- 一、數的進位記數法
N=a n-1p n-1+a n-2p n-2+…+a2p2+a1p1+a0*p0
- 二、十進制數與P進制數之間的轉換
①十進制轉換成二進制:十進制整數轉換成二進制整數一般採用除2取餘法,小數部分乘2取整法。例如,將(30)10轉換成二進制數。
將(30)10轉換成二進制數
2| 30 ….0 ----最右位
2 15 ….1
2 7 ….1
2 3 ….1
1 ….1 ----最左位
∴ (30)10=(11110)2
將(30)10轉換成8、十六進制數
8| 30 ……6 ------最右位
3 ------最左位
∴ (30)10 =(36)8
16| 30 …14(E)----最右位
1 ----最左位
∴ (30)10 =(1E)16
- 三、將P進制數轉換爲十進制數
把一個二進制轉換成十進制採用方法:把這個二進制的最後一位乘上20,倒數第二位乘上21,……,一直到最高位乘上2n,而後將各項乘積相加的結果就它的十進制表達式。
把二進制11110轉換爲十進制
(11110)2=124+123+122+121+020=
=16+8+4+2+0
=(30)10
把一個八進制轉換成十進制採用方法:把這個八進制的最後一位乘上80,倒數第二位乘上81,……,一直到最高位乘上8n,而後將各項乘積相加的結果就它的十進制表達式。
把八進制36轉換爲十進制
(36)8=3\81+680=24+6=(30)10
把一個十六進制轉換成十進制採用方法:把這個十六進制的最後一位乘上160,倒數第二位乘上161,……,一直到最高位乘上16n,而後將各項乘積相加的結果就它的十進制表達式。
把十六制1E轉換爲十進制
(1E)16=1161+14*160=16+14=(30)10
- 四、二進制轉換成八進制數
(1)二進制數轉換成八進制數:對於整數,從低位到高位將二進制數的每三位分爲一組,若不夠三位時,在高位左面添0,補足三位,而後將每三位二進制數用一位八進制數替換,小數部分從小數點開始,自左向右每三位一組進行轉換便可完成。例如:
將二進制數1101001轉換成八進制數,則
(001 101 001)2
| | |
( 1 5 1)8
( 1101001)2=(151)8
(2)八進制數轉換成二進制數:只要將每位八進制數用三位二進制數替換,便可完成轉換,例如,把八進制數(643.503)8,轉換成二進制數,則
(6 4 3 . 5 0 3)8
| | | | | |
(110 100 011 . 101 000 011)2
(643.503)8=(110100011.101000011)2
- 五、二進制與十六進制之間的轉換
(1)二進制數轉換成十六進制數:因爲2的4次方=16,因此依照二進制與八進制的轉換方法,將二進制數的每四位用一個十六進制數碼來表示,整數部分以小數點爲界點從右往左每四位一組轉換,小數部分從小數點開始自左向右每四位一組進行轉換。
(2)十六進制轉換成二進制數
如將十六進制數轉換成二進制數,只要將每一位十六進制數用四位相應的二進制數表示,便可完成轉換。
例如:將(163.5B)16轉換成二進制數,則
( 1 6 3 . 5 B )16
| | | | |
(0001 0110 0011. 0101 1011 )2
(163.5B)16=(101100011.01011011)2
實習代碼
#include <stdio.h>
int powe(int n)
{
int i;
int s=1;
for(i=1;i<=n;i++)
{
s=s*16;
}
return s;
}
void main()
{
int m;
int n;
int i;
int r;
int a;
printf("請輸入一個16進制數");
scanf("%d",&m);
a=m;
n=0,i=0;
while(m)
{
r=m%10;
n=n+r*powe(i);
m=m/10;
i++;
}
printf("16進制數%d對應的10進制數是%d\n",a,n);
}
實習六結果
實習七 代碼的規範化
- 1 排版
1-1:程序塊要採用縮進風格編寫,縮進的TAB鍵一個.
1-2:相對獨立的程序塊之間、變量說明以後必須加空行.
1-3:較長的語句(>80字符)要分紅多行書寫,長表達式要在低優先級操做符處劃分新行,操做符放在新行之首,劃分出的新行要進行適當的縮進,使排版整齊,語句可讀.
1-4:循環、判斷等語句中如有較長的表達式或語句,則要進行適應的劃分,長表達式要在低優先級操做符處劃分新行,操做符放在新行之首.
1-5:若函數或過程當中的參數較長,則要進行適當的劃分.
1-6:不容許把多個短語句寫在一行中,即一行只寫一條語句.
1-7:if、while、for、default、do等語句自佔一行.
1-8:對齊只使用TAB鍵,不使用空格鍵.
1-9:函數或過程的開始、結構的定義及循環、判斷等語句中的代碼都要採用縮進風格,case語句下的狀況處理語句也要聽從語句縮進要求.
1-10:程序塊的分界符(如C/C++語言的大括號'{'和'}')應各獨佔一行而且位於同一列,同時與引用它們的語句左對齊.在函數體的開始、類的定義、結構的定義、枚舉的定義以及if、for、do、while0、switch、case語句中的程序都要採用如上的縮進方式.
1-11:在兩個以上的關鍵字、變量、常量進行對等操做時,它們之間的操做符以前、以後或者先後要加空格;進行非對等操做時,若是是關係密切的當即操做符(如->),後不該加空格.
1-12: 程序結構清析,簡單易懂,單個函數的程序行數不得超過100行.
- 2 註釋
2-1:通常狀況下,源程序有效註釋量必須在20%以上.
2-2:說明性文件(如頭文件.h文件、.inc文件、.def文件、編譯說明文件.cfg等)頭部應進行註釋,註釋必須列出:版權說明、版本號、生成日期、做者、內容、功能、與其它文件的關係、修改日誌等,頭文件的註釋中還應有函數功能簡要說明.
2-3:源文件頭部應進行註釋,列出:版權說明、版本號、生成日期、做者、模塊目的/功能、主要函數及其功能、修改日誌等.
2-4:函數頭部應進行註釋,列出:函數的目的/功能、輸入參數、輸出參數、返回值、調用關係(函數、表)等.
2-5:邊寫代碼邊註釋,修改代碼同時修改相應的註釋,以保證註釋與代碼的一致性.再也不有用的註釋要刪除.
2-6:註釋的內容要清楚、明瞭,含義準確,防止註釋二義性.
2-7:避免在註釋中使用縮寫,特別是很是用縮寫.
2-8:註釋應與其描述的代碼相近,對代碼的註釋應放在其上方或右方(對單條語句的註釋)相鄰位置,不可放在下面,如放於上方則需與其上面的代碼用空行隔開.
2-9:對於全部有物理含義的變量、常量,若是其命名不是充分自注釋的,在聲明時都必須加以註釋,說明其物理含義.變量、常量、宏的註釋應放在其上方相鄰位置或右方.
2-10:數據結構聲明(包括數組、結構、類、枚舉等),若是其命名不是充分自注釋的,必須加以註釋.對數據結構的註釋應放在其上方相鄰位置,不可放在下面;對結構中的每一個域的註釋放在此域的右方.
2-11:全局變量要有較詳細的註釋,包括對其功能、取值範圍、哪些函數或過程存取它以及存取時注意事項等的說明.
2-12:註釋與所描述內容進行一樣的縮排.
2-13:將註釋與其上面的代碼用空行隔開.
2-14:對變量的定義和分支語句(條件分支、循環語句等)必須編寫註釋.
2-15:對於switch語句下的case語句,若是由於特殊狀況須要處理完一個case後進入下一個case處理,必須在該case語句處理完、下一個case語句前加上明確的註釋.
- 3 標識符命名
3-1:標識符的命名要清晰、明瞭,有明確含義,同時使用完整的單詞或你們基本能夠理解的縮寫,避免令人產生誤解.
3-2:命名中若使用特殊約定或縮寫,則要有註釋說明.
3-3:本身特有的命名風格,要自始至終保持一致,不可來回變化.
3-4:對於變量命名,禁止取單個字符(如i、j、k...),建議除了要有具體含義外,還能代表其變量類型、數據類型等,但i、j、k做局部循環變量是容許的.
3-5:命名規範必須與所使用的系統風格保持一致,並在同一項目中統一,好比採用UNIX的全小寫加下劃線的風格或大小寫混排的方式,不要使用大小寫與下劃線混排的方式.
- 4 可讀性
4-1:注意運算符的優先級,並用括號明確表達式的操做順序,避免使用默認優先級.
4-2:避免使用不易理解的數字,用有意義的標識來替代.涉及物理狀態或者含有物理意義的常量,不該直接使用數字,必須用有意義的枚舉或宏來代替.
- 5 變量
5-1:去掉不必的公共變量.
5-2:仔細定義並明確公共變量的含義、做用、取值範圍及公共變量間的關係.
5-3:明確公共變量與操做此公共變量的函數或過程的關係,如訪問、修改及建立等.
5-4:當向公共變量傳遞數據時,要十分當心,防止賦與不合理的值或越界等現象發生.
5-5:防止局部變量與公共變量同名.
5-6:嚴禁使用未經初始化的變量做爲右值.
- 6 函數、過程
6-1:對所調用函數的錯誤返回碼要仔細、全面地處理.
6-2:明確函數功能,精確(而不是近似)地實現函數設計.
6-3:編寫可重入函數時,應注意局部變量的使用(如編寫C/C++語言的可重入函數時,應使用auto即缺省態局部變量或寄存器變量).
6-4:編寫可重入函數時,若使用全局變量,則應經過關中斷、信號量(即P、V操做)等手段對其加以保護。
實習代碼
#include<stdio.h>
int main(void)
{
float a,b,c,t;
scanf("%f, %f, %f", &a, &b, &c);
if(a>b)
{
t=a;
a=b;
b=t;
}
if(a>c)
{
t=a;
a=c;
c=t;
}
if(b>c)
{
t=b;
b=c;
c=t;
}
printf("%5.2f, %5.2f, %5.2f\n", a, b, c);
return 0;
}
實習七結果
實習八 不一樣數據類型之間的賦值問題
-
- 各種數值型數據間混合運算時的類型轉換規則
- 整型、實型、字符型數據間能夠混合運算。在這種狀況下,須要將不一致的數據類型轉換成一致的數據類型,而後進行運算。爲了保證運算精度,系統在運算時的轉換規則是將存儲長度較短的運算對象轉換成存儲長度較長的類型,而後再進行處理。這種轉換是系統自動進行的。
1) 縱向箭頭表示一定會進行的轉換,如float型數據必先轉換爲double型數據,而後與其餘操做數進行運算。與此相似,char型或short型數據必先轉換爲int型數據,而後進行運算。
2) 橫向箭頭表示當運算對象爲不一樣類型數據時的轉換方向,如int型數據與unsigned型數據進行運算,int型轉換爲unsigned型後方可進行運算。int型數據與double型數據進行運算,int型直接轉換爲double型後進行運算,不能理解爲先轉換爲unsigned int型,而後轉換爲long int型,最後再轉換爲double型。
- 賦值時的類型轉換
- 當賦值運算符兩側的類型不一樣時,需進行類型轉換,這種轉換也是系統自動進行的。具體轉換原則以下:
1)float、double型賦值給int型:直接截斷小數。
例如:int i=f+0.6; f的值4.0,右邊算術表達式運算後的結果爲一個值爲4.6的double型數據,根據上述轉換原則,直接捨棄小數,因此i的值爲4。
2)int、char型賦值給float、double型:補足有效位以進行數據類型轉換。
例如:float f=4; float爲7位有效數字,因此f的值爲4.000000。
3)char型(1字節)賦值給int型(2字節):數值賦給int的低8位,高8位補0。
4)long int型賦值給int型:long int截斷低字節給int型。
5)int 型賦值給long int:賦給long int的低16位,若是int的最高位是0,則long int的高16位全爲0;若是int的最高位是1,則long int的高8位全爲1(稱爲「符號擴展」)。
6)unsigned int型賦值給int型:直接傳送數值。
7)非unsigned數據型賦值給位數相同的unsigned 數據:直接傳送數值
- 強制類型轉換
除了以上的兩種自動類型轉換外,在C語言中,容許強制類型轉換,將某一數據的數據類型轉換爲指定的另外一種數據類型。強制轉換是用強制轉換運算符進行的,強制轉換運算符爲:(類型名),強制轉換運算符組成的運算表達式的通常形式爲:
(類型名)(表達式)
- 例如:
(int)(x + y) //將x+y的值轉換成整型,即取整數部分。
(float)x + y //將x轉換成單精度型。
- 強制轉換運算符優先級比算術運算符高。同表達式中數據類型的自動轉換同樣,強制類型轉換也是臨時轉換,對原運算對象的類型沒有影響。
- 例如,已知有變量定義:int b=7;float a=2.5,c=4.7;求下面算術表達式的值。
a+(int)(b/3*(int)(a+c)/2.0)%4;
- 根據運算符結合性規則,上述表達式要自左之右執行,b/3爲2,2*int(a+c)爲14,14/2.0爲7.0,強制類型轉換後爲7,7%4爲3;a的值2.5與3相加,最終結果爲5.5。
實習代碼
# include <stdio.h>
# include <stdlib.h>
int main(int argc,char**argv)
{
unsigned int right = 1;
char left = -1;
if(left < right)
printf("%d<%d\n",left,right);
else if(left == right)
printf("%d=%d\n",left,right);
else
printf("%d>%d\n",left,right);
system("PAUSE");
return 0;
}
實習結果
實習九 什麼是ASCII碼
實習代碼
#include <stdio.h>
int main(void)
{
char ch='b';
printf("%d\n",ch);
return 0;
}
實習九結果
實習十 基本的輸入與輸出
- int scanf(const char *format, arg_list)
- scanf主要從標準輸入流中獲取參數值,format爲指定的參數格式及參數類型,如scanf("%s,%d",str,icount);它要求在標準輸入流中輸入相似"son of bitch,1000"這樣的字符串,同時程序會將"son of bitch"給str,1000給icount.
- scanf函數的返回值爲int值,即成功賦值的個數,在上例中若是函數調用成功,則會返回2,因此咱們在寫程序時,能夠經過
- 語句if(scanf("%s,%d",str,icount) != 2){...}來判斷用戶輸入是否正確.
int printf(const char format, arg_list)
- printf主要是將格式化字符串輸出到標準輸出流中,在stdio.h頭文件中定義了標準的輸入和輸出,分別是stdin,stdout.
arg_list能夠是變量名,也能夠是表達式,但最終都會以值的形式填充進format中.
int getc(FILE \fp)
- getc主要是從文件中讀出一個字符.經常使用的判斷文件是否讀取結束的語句爲:(ch = getc(fp)) != EOF.EOF爲文件結束標誌,定義在stdio.h中,就像EXIT_SUCCESS,EXIT_FAILURE定義在stdlib.h中同樣,文件也能夠被理解爲一種流,因此當fp爲stdin時,getc(stdin) 就等同於getchar()了.
- int putc(int ch,FILE *fp)
- putc主要是把字符ch寫到文件fp中去.若是fp爲stdout,則putc就等同於putchar()了.
- int getchar(void)
- getchar主要是從標準輸入流讀取一個字符.默認的標準輸入流即stdio.h中定義的stdin.可是從輸入流中讀取字符時又涉及到緩衝的問題,因此並非在屏幕中敲上一個字符程序就會運行,通常是經過在屏幕上敲上回車鍵,而後將回車前的字符串放在緩衝區中,getchar就是在 緩衝區中一個一個的讀字符.固然也能夠在while循環中指定終止字符,以下面的語句:
- while ((c = getchar()) != '#')這是以#來結束的.
int putchar(int ch)
- putchar(ch)主要是把字符ch寫到標準流stdout中去.
char gets(char \str)
- gets主要是從標準輸入流讀取字符串並回顯,讀到換行符時退出,並會將換行符省去.
int puts(char *str)
- puts主要是把字符串str寫到標準流stdout中去,並會在輸出到最後時添加一個換行符.
char fgets(char \str, int num, FILE *fp)
- str是存放讀入的字符數組指針,num是最大容許的讀入字符數,fp是文件指針.fgets的功能是讀一行字符,該行的字符數不大於num-1.由於fgets函數會在末尾加上一個空字符以構成一個字符串.另外fgets在讀取到換行符後不會將其省略.
int fputs(char *str, file fp)
- fputs將str寫入fp.fputs與puts的不一樣之處是fputs在打印時並不添加換行符.
int fgetc(FILE \fp)
- fgetc從fp的當前位置讀取一個字符.
int fputc(int ch, file *fp)
- fputc是將ch寫入fp當前指定位置.
int fscanf(FILE fp, char format,...)
- fscanf按照指定格式從文件中出讀出數據,並賦值到參數列表中.
int fprintf(FILE fp, char format,...)
- fprintf將格式化數據寫入流式文件中.
實習代碼
#include<stdio.h>
int main(void)
{
char a,b,c; //定義字符變量a,b,c
a=getchar(); //從鍵盤輸入一個字符,送給字符變量a
b=getchar(); //從鍵盤輸入一個字符,送給字符變量b
c=getchar(); //從鍵盤輸入一個字符,送給字符變量c
putchar(a); //將變量a的值輸出
putchar(b); //將變量b的值輸出
putchar(c); //將變量c的值輸出
putchar('\n'); //換行
return 0;
}
實習十結果
實習十一 除法與取餘運算符
# include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a,b;
float c;
printf("input a integer number a=");
scanf("%d",&a);
printf("\ninput a integer number b=");
scanf("%d",&b);
printf("\ninput a floating number c=");
scanf("%d",&c);
printf("\nthe results: a/b=%d a/c=%f a(mod)b=%d\n",a/b,a/c,a%b);
system("pause");
return 0;
}
實習十一結果
實習十二 流程控制
- 1.什麼是流程控制
程序代碼的執行順序
- 2.流程控制的分類
順序執行
選擇執行
定義:
某些代碼可能執行,也可能不執行,有選擇的執行某些代碼
分類:
- If
1.if最簡單的用法
格式:
if(表達式)
語句
功能:若是表達式爲真,執行語句
若是表達式爲假,語句不執行
2.if的範圍問題
(1) if(表達式)
語句A;
語句B;
解釋:if默認的只能控制一個語句的執行
if沒法控制語句B的執行或不執行
(2)if(表達式)
{
語句A;
語句B;
}
此時if能夠控制語句A和語句B
因而可知:if默認只能控制一個語句的執行或不執行
若是想控制多個語句的執行或不執行就必須把這些語句用{}括氣來
3.if..else...的用法
4.if..else if..else...的用法
例子:
if (1)
printf ("A");
else if (2)
printf ("B");
else if (3)
printf ("C");
else
printf("D");
若是寫爲:
if (1)
printf("A");
printf("H");//在這句出錯
else if .. //緣由else沒有對應的if.
5.c語言對真假的處理
非零是真
零就是假
真用1表示
假用0表示
6.if舉例--求分數的等級
7.if的常見問題解析
1.空語句問題
if (3 > 2);
等價於
if (3 > 2)
//這就是空語句
- switch
循環執行
定義:
某些代碼會被重複執行
分類
- for
1.格式:
for (1; 2; 3)
語句A;
2.執行的流程
單個for循環的使用
多個for循環的嵌套使用
for(1; 2; 3)
for(4; 5; 6)
A;
B;
3.範圍
4.舉例:
1+2+3+4+...+100
1+1/2+1/3+...+1/100
- while
do...while
break和continue
實習代碼
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a=3,b=2,c=1;
system("cls");
printf("[1]:%d,%d,%d\n",a,b,c);
{
int b=5;
int c=12;
printf("[2]:%d,%d,%d\n",a,b,c);
}
printf("[3]:%d,%d,%d\n",a,b,c);
getchar();
return 0;
}
實習十二結果
實習十三 if概述
#include<stdio.h>
int main()
{
int iSignal; //定義變量表示信號燈的狀態
printf("the Red Light is 0,the Green Light is 1\n");//輸出提示信息
scanf("%d",&iSignal); //輸入iSignal變量
if(iSignal==1) //使用if語句進行判斷
{
printf("the Light is green,cars can run\n"); //判斷結果爲真是輸出
}
return 0;
}
實習十三結果
實習十四 C語言常見誤區
- 1.書寫標識符時,忽略了大小寫字母的區別。
main()
{
int a=5;
printf("%d",A);
}
編譯程序把a和A認爲是兩個不一樣的變量名,而顯示出錯信息。C認爲大寫字母和小寫字母是兩個不一樣的字符。習慣上,符號常量名用大寫,變量名用小寫表示,以增長可讀性。
- 2.忽略了變量的類型,進行了不合法的運算。
main()
{
float a,b;
printf("%d",a%b);
}
%是求餘運算,獲得a/b的整餘數。整型變量a和b能夠進行求餘運算,而實型變量不容許進行「求餘」運算。
- 3.將字符常量與字符串常量混淆。
char c;
c="a";
在這裏就混淆了字符常量與字符串常量,字符常量是由一對單引號括起來的單個字符,字符串常量是一對雙引號括起來的字符序列。C規定以「」做字符串結束標誌,它是由系統自動加上的,因此字符串「a」實際上包含兩個字符:‘a'和‘',而把它賦給一個字符變量是不行的。
- 4.忽略了「=」與「==」的區別。
在許多高級語言中,用「=」符號做爲關係運算符「等於」。如在BASIC程序中能夠寫if (a=3) then …但C語言中,「=」是賦值運算符,「==」是關係運算符。如:
if (a==3) a=b;前者是進行比較,a是否和3相等,後者表示若是a和3相等,把b值賦給a。因爲習慣問題,初學者每每會犯這樣的錯誤。
- 5.忘記加分號。
- 6.多加分號。
- 7.輸入變量時忘記加地址運算符「&」。
int a,b;
scanf("%d%d",a,b);
這是不合法的。Scanf函數的做用是:按照a、b在內存的地址將a、b的值存進去。「&a」指a在內存中的地址。
- 8.輸入數據的方式與要求不符。
①scanf("%d%d",&a,&b);輸入時,不能用逗號做兩個數據間的分隔符,以下面輸入不合法:3,4輸入數據時,在兩個數據之間以一個或多個空格間隔,也可用回車鍵,跳格鍵tab。
②scanf("%d,%d",&a,&b);C規定:若是在「格式控制」字符串中除了格式說明之外還有其它字符,則在輸入數據時應輸入與這些字符相同的字符。下面輸入是合法的:
3,4此時不用逗號而用空格或其它字符是不對的。
3 4 3:4
又如:scanf("a=%d,b=%d",&a,&b);輸入應如如下形式:a=3,b=4
- 9.輸入字符的格式與要求不一致。
在用「%c」格式輸入字符時,「空格字符」和「轉義字符」都做爲有效字符輸入。
scanf("%c%c%c",&c1,&c2,&c3);如輸入a b c字符「a」送給c1,字符「 」送給c2,字符「b」送給c3,由於%c只要求讀入一個字符,後面不須要用空格做爲兩個字符的間隔。
- 10.輸入輸出的數據類型與所用格式說明符不一致。
例如,a已定義爲整型,b定義爲實型,a=3;b=4.5;printf("%f%d\n",a,b);編譯時不給出出錯信息,但運行結果將與原意不符。這種錯誤尤爲須要注意。
- 11.輸入數據時,企圖規定精度。scanf("%7.2f",&a);這樣作是不合法的,輸入數據時不能規定精度。
- 12.switch語句中漏寫break語句。
例如:根據考試成績的等級打印出百分制數段。
switch(grade)
{ case 'A':printf("85~100\n");
case 'B':printf("70~84\n");
case 'C':printf("60~69\n");
case 'D':printf("<60\n");
default:printf("error\n");
因爲漏寫了break語句,case只起標號的做用,而不起判斷做用。所以,當grade值爲A時,printf函數在執行完第一個語句後接着執行第2、3、4、五個printf函數語句。正確寫法應在每一個分支後再加上「break;」。例如case 'A':printf("85~100\n");break;
- 13.忽視了while和do-while語句在細節上的區別。由於while循環是先判斷後執行,而do-while循環是先執行後判斷。
- 14.定義數組時誤用變量。
int n;
scanf("%d",&n);
int a[n];
數組名後用方括號括起來的是常量表達式,能夠包括常量和符號常量。即C不容許對數組的大小做動態定義。
- 15.在定義數組時,將定義的「元素個數」誤認爲是可以使的最大下標值。
main()
{static int a[10]={1,2,3,4,5,6,7,8,9,10};
printf("%d",a[10]);
}
C語言規定:定義時用a[10],表示a數組有10個元素。其下標值由0開始,因此數組元素a[10]是不存在的。
- 16.在不該加地址運算符&的位置加了地址運算符。scanf("%s",&str);C語言編譯系統對數組名的處理是:數組名錶明該數組的起始地址,且scanf函數中的輸入項是字符數組名,沒必要要再加地址符&。應改成:scanf("%s",str);
17.同時定義了形參和函數中的局部變量。
int max(x,y)
int x,y,z;
{
z=x>y?x:y;
return(z);
}
形參應該在函數體外定義,而局部變量應該在函數體內定義。應改成:
int max(x,y)
int x,y;
{
int z;
z=x>y?x:y;
return(z);
}編程
實習代碼
# include<stdio.h>
int main() //主函數main中
{
int iNumber1=1; //在第1個iNumber1定義位置
printf("%d\n",iNumber1); //輸出變量值
if(iNumber1>0)
{
int iNumber1=2; //在第2個iNumber1定義位置
printf("%d\n",iNumber1);//輸出變量值
if(iNumber1>0)
{
int iNumber1=3; //在第3個iNumber1定義位置
printf("%d\n",iNumber1);//輸出變量值
}
printf("%d\n",iNumber1);//輸出變量值
}
printf("%d\n",iNumber1); //輸出變量值
return 0;
}
實習十四結果
實習十五 循環概述
- C語言循環控制語句提供了 while語句、do-while語句和for語句來實現循環結構。
- while循環語句
通常形式以下:
while(表達式)
語句
- do-while語句
通常形式以下:
- do語句while(表達式);
do-while循環是先執行語句,而後對錶達式求值。若值爲真,則再次執行語句,如此反覆執行,不然將結束循環。語句能夠是簡單語句,也能夠是複合語句。
- for語句
for語句是循環控制結構中使用最普遍的一種循環控制語句,特別適合已知循環次數的狀況。
- 通常形式以下:
for ( [表達式 1]; [表達式 2 ]; [表達式3] )語句
- 其中:
表達式1:通常爲賦值表達式,給控制變量賦初值;
表達式2:關係表達式或邏輯表達式,循環控制條件;
表達式3:通常爲賦值表達式,給控制變量增量或減量;
語句:循環體,當有多條語句時,必須使用複合語句。
其執行過程以下:首先計算表達式1,而後計算表達式 2。若表達式2爲真,則執行循環體;不然,退for循環,執行for循環後的語句。若是執行了循環體,則循環體每執行一次,都計算表達式3,而後從新計算表達式2,依此循環,直至表達式 2的值爲假,退出循環。
- for語句的三個表達式都是能夠省略的,但分號「;」絕對不能省略。for語句有如下幾種格式:
(1)for(; ;) 語句;
(2)for(;表達式2;表達式3 ) 語句;
(3)for(表達式1;表達式2;) 語句;
(4)for(i=1,j = n; i < j; i ++,j - - ) 語句;
- 三種語句比較
同一個問題,每每既能夠用 while語句解決,也能夠用 do-while或者for語句來解決,但在實際應用中,應根據具體狀況來選用不一樣的循環語句。選用的通常原則是:
(1) 若是循環次數在執行循環體以前就已肯定,通常用 for語句。若是循環次數是由循環體的執行狀況肯定的,通常用 while語句或者do- while語句。
(2) 當循環體至少執行一次時,用 do-while語句,反之,若是循環體可能一次也不執行,則選用while語句。
C++/C循環語句中,for語句使用頻率最高,while語句其次,do語句不多用。
三種循環語句for、while、do-while能夠互相嵌套自由組合。但要注意的是,各循環必須完整,相互之間毫不容許交叉。
其餘循環語句
- 多重循環結構
在多重循環中,若是有可能,應當將最長的循環放在最內層,最短的循環放在最外層,以減小CPU跨越循環層的次數。
一個循環體內又包含另外一個完整的循環結構
三種循環可互相嵌套,層數不限
外層循環可包含兩個以上內循環,但不能相互交叉
實習代碼
#include <stdio.h>
int main()
{
int iSum=0;
int iNumber=1;
while(iNumber<=100)
{
iSum=iSum+iNumber;
iNumber++;
}
printf("the result is: %d\n",iSum);
return 0;
}
實習十五結果
實習十六 while循環
- while循環的通常格式爲
- while ( 條件 )
語句1
語句2
...
wend
若是條件爲真(即式子的值是對的),就執行while和wend之間的循環體,執行以後返回while頂部,再次檢查條件是否爲真,若是爲真則又繼續執行循環體,爲假則不執行循環體,跳到wend以後,接着執行wend以後的語句,結束循環。c#
while (a<101) h=h+a a=a+1 wendwindows
在while循環中,特別要注意兩個地方,一個是while後面的條件,一個是while和wend之間必需要有一個語句改變條件裏某個變量的值,以免出現循環不執行或一直執行不能中止的狀況。在上面的例子裏,a=a+1每執行一次,a的值增長1,a的值增長到必定的狀況,就不會小於101,循環就中止了。若是少了a=a+1這一行,a的值將不會改變,循環將一直執行,不會中止。應注意避免這種狀況出現。數組
實習代碼
#include<stdio.h>
int main()
{
int i=1,sum=0; //定義變量i的初始值爲1,sum的初始值爲0
while(i<=100) //當i>100,條件表達式i<=100的值爲假,不執行循環體
{ //循環體開始
sum=sum+i; //第一次累加後,sum的值爲1
i++; //加完後,i的值加1,爲下次累加作準備
} //循環體結束
printf("sum=%d\n",sum);//輸出1+2+3+...+100的累加和
return 0;
}
實習十六結果
實習十七 for 和 while的比較
- int i =0;
for(i=0;i<10;i++)
{
printf("如今循環第"+i+"次");
}
- 首先咱們設置了一個整型(int)變量 i 這裏要注意 變量的設置須要是標識量, 及開始的第一個字母必須是字母后者下劃線,整個變量名裏只能含有字母、數字、下劃線,c語言裏的關鍵字不能爲變量名。
C語言32個關鍵字
auto :聲明自動變量 通常不使用
double :聲明雙精度變量或函數
int: 聲明整型變量或函數
struct:聲明結構體變量或函數
break:跳出當前循環
else :條件語句否認分支(與 if 連用)
long :聲明長整型變量或函數
switch :用於開關語句
case:開關語句分支
enum :聲明枚舉類型
register:聲明積存器變量
typedef:用以給數據類型取別名(固然還有其餘做用)
char :聲明字符型變量或函數
extern:聲明變量是在其餘文件正聲明(也能夠看作是引用變量)
return :子程序返回語句(能夠帶參數,也看不帶參數)
union:聲明聯合數據類型
const :聲明只讀變量
float:聲明浮點型變量或函數
short :聲明短整型變量或函數
unsigned:聲明無符號類型變量或函數
continue:結束當前循環,開始下一輪循環
for:一種循環語句(可意會不可言傳)
signed:生命有符號類型變量或函數
void :聲明函數無返回值或無參數,聲明無類型指針(基本上就這三個做用)
default:開關語句中的「其餘」分支
goto:無條件跳轉語句
sizeof:計算數據類型長度
volatile:說明變量在程序執行中可被隱含地改變
do :循環語句的循環體
while :循環語句的循環條件
static :聲明靜態變量
if:條件語句
- 而後使用for循環關鍵字 for循環的基本格式是
for(循環開始;循環結束條件;每次循環的累加)
{
//循環體
}
因此咱們的循環就是把i的起始值設置爲0; 當i<10的時候就繼續循環,每次循環後i加一。那麼本循環就執行了10次。printf("如今循環第"+i+"次"); 就是說在屏幕打印出循環的次數,不過咱們的i值是0開始的因此第一次就是打印如今是第0次循環.
思考:一、在不改變i值的狀況下怎樣作才能實現打印出如今是第1次循環。
二、怎樣才能實現換行
- while循環
int i=0
while(i<10)
{
printf("如今是第"+(i+1)+次打印\n");
i++;
}
- 上面就是while循環,while括號裏只填寫開始條件,可是須要注意,循環體必須給定結束條件,不然就會進入死循環。
i++不能少
例題:兔子問題
實習代碼
#include<stdio.h>
int main()
{
int f1=1,f2=1;
int i;
for (i=1;i<=20;i++) //每一個循環中輸出2個月的數據,故循環20次便可
{
printf ("%12ld%12ld",f1,f2); //輸出已知的兩個月的兔子數
if (i%2==0)
printf ("\n");
f1=f1+f2; //計算出下個月的兔子數,並存放在f1中
f2=f2+f1; //計算出下兩個月的兔子數,並存放在f2中
}
return 0;
}
實習十七結果
實習十八 Do...while與while和for的比較
- (1)while語句和do...while語句,只在while後面指定循環條件,可是須要在循環體中包括使循環趨於結束的語句,而for語句則能夠在迭代語句中包含使循環趨於結束的語句。
(2)用while語句和do...while語句時,對循環變量的初始化操做應該放在while語句和do...while語句以前,而for語句則能夠在初始化語句中完成。
(3)while語句和do...while語句實現的功能相同,惟一的區別就是do…while語句先執行後判斷,不管表達式的值是否爲true,都將執行一次循環;而while語句則是首先判斷表達式的值是否爲true,若是爲true則執行循環語句;不然將不執行循環語句。
(4)for循環語句通常用在對於循環次數已知的狀況下,而while語句和do...while語句則通常用在對於循環次數不肯定的狀況下
- 一、while語句
while關鍵字的中文意思是「當……的時候」,也就是當條件成立時循環執行對應的代碼。while語句是循環語句中基本的結構,語法格式比較簡單。
- 二、do-while語句
do-while語句由關鍵字do和while組成,是循環語句中最典型的「先循環再判斷」的流程控制結構,這個和其它2個循環語句都不相同。
- 三、for語句
for關鍵字的意思是「當…的時候」,是實際開發中比較經常使用的循環語句,其語法格式相對於前面的循環語句來講稍顯複雜,可是在熟悉之後,將會發現其語法安排的比較條理,把循環控制和循環體很清晰的分開
實習代碼
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,sum=0;
printf("please enter i,i=?");
scanf("%d",&i);
do
{
sum=sum+i;
i++;
}
while(i<=100);
printf("sum=%d\n",sum);
system("PAUSE");
return 0;
}
實習十八結果
實習十九 Switch簡介
- C語言還提供了另外一種用於多分支選擇的switch語句, 其通常形式爲:
switch(表達式){
case常量表達式1: 語句1;
case常量表達式2: 語句2;
…
case常量表達式n: 語句n;
default:語句n+1;
}
- 其語義是:計算表達式的值。 並逐個與其後的常量表達式值相比較,當表達式的值與某個常量表達式的值相等時, 即執行其後的語句,而後再也不進行判斷,繼續執行後面全部case後的語句。如表達式的值與全部case後的常量表達式均不相同時,則執行default後的語句。
main(){
int a;
printf("input integer number: ");
scanf("%d",&a);
switch (a){
case 1:printf("Monday\n");
case 2:printf("Tuesday\n");
case 3:printf("Wednesday\n");
case 4:printf("Thursday\n");
case 5:printf("Friday\n");
case 6:printf("Saturday\n");
case 7:printf("Sunday\n");
default:printf("error\n");
}
}
- 本程序是要求輸入一個數字,輸出一個英文單詞。可是當輸入3以後,卻執行了case3以及之後的全部語句,輸出了Wednesday 及之後的全部單詞。這固然是不但願的。爲何會出現這種狀況呢?這偏偏反應了switch語句的一個特色。在switch語句中,「case 常量表達式」只至關於一個語句標號, 表達式的值和某標號相等則轉向該標號執行,但不能在執行完該標號的語句後自動跳出整個switch 語句,因此出現了繼續執行全部後面case語句的狀況。 這是與前面介紹的if語句徹底不一樣的,應特別注意。
實習代碼
#include <stdio.h>
int main ()
{
char grade;
scanf("%c",&grade);
printf("Your corce:");
switch(grade)
{
case 'A':printf("85-100\n");break;
case 'B':printf("70-84\n");break;
case 'C':printf("60-69\n");break;
case 'D':printf("60\n");break;
default:printf("enter data error!\n");
}
return 0;
}
實習十九結果
實習二十 Break用法
- break語句
- break語句一般用在循環語句和開關語句中。當break用於開關語句switch中時,可以使程序跳出switch而執行switch之後的語句;若是沒有break語句,則將成爲一個死循環而沒法退出。break在switch 中的用法已在前面介紹開關語句時的例子中碰到,這裏再也不舉例。
- 當break語句用於do-while、for、while循環語句中時,可以使程序終止循環而執行循環後面的語句, 一般break語句老是與if語句聯在一塊兒。即知足條件時便跳出循環。
- 注意:
1)break語句對if-else的條件語句不起做用。
2)在多層循環中, 一個break語句只向外跳一層。
- break語句一般用在循環語句和開關語句中。當break用於開關語句switch中時,可以使程序跳出switch而執行switch之後的語句;若是沒有break語句,則將成爲一個死循環而沒法退出。break在switch 中的用法已在前面介紹開關語句時的例子中碰到,這裏再也不舉例。
- 當break語句用於do-while、for、while循環語句中時,可以使程序終止循環而執行循環後面的語句, 一般break語句老是與if語句聯在一塊兒。即知足條件時便跳出循環。
main()
{
int i=0;
char c;
while(1) /設置循環/
{
c='\0'; /變量賦初值/
while(c!=13&&c!=27) /鍵盤接收字符直到按回車或Esc鍵/
{
c=getch();
printf("%c\n", c);
}
if(c==27)
break; /判斷若按Esc鍵則退出循環/
i++;
printf("The No. is %d\n", i);
}
printf("The end");
}
- 注意:
break語句對if-else的條件語句不起做用。
在多層循環中, 一個break語句只向外跳一層。
- 例題:在全系1000學生中,徵集慈善募捐,當總數達到10萬元時就結束,統計此時捐款的人數,以及平均每人的數目
- 編程思路:
- 顯然應該用循環來處理。實際循環的次數事先不能肯定,能夠設爲最大值,即1000,在循環體中累計捐款總數,並用if語句檢查是否達到10萬元,若是達到就再也不繼續執行循環,終止累加並計算人均捐款數。在程序中定義變量amount,用來存放捐款數,變量total,用來存放累加後的總捐款數,變量aver,用來存放人均捐款數,以上3個變量均爲單精度浮點型。定義整型變量i做爲循環變量。定衣符號常量SUM表明100000.
實習代碼
#include <stdio.h>
#define SUM 100000
int main()
{
float amount,aver,total;
int i;
for(i=1,total=0;i<=1000;i++)
{
printf("please enter amount:");
scanf("%f",&amount);
total=total+amount;
if(total>=SUM) break;
}
aver=total/i;
printf("num=%ld\n aver=10.2f\n",i,aver);
return 0;
}
實習二十結果
實習二十一 數組
- 一、數組的概念、定義和使用
數組(array)是C語言中用於組合同類型數據對象的機制。一個數組裏聚集一批對象(數組元素)。程序中既能從數組出發處理其中的個別元素,也能以統一方式處理數組的一批元素或全部元素。後一處理方式特別重要,是由一批成員構成的數組和一批獨立命名的變量間的主要區別。數組機制要解決三個問題:)描述數組的性質,定義數組變量; )使用數組,包括經過數組變量使用元素; )實現數組,即在內存裏爲數組安排一種存儲方式,使程序裏能夠方便地操做它們。固然,最後一個問題主要與語言的實現有關係,在實現C語言系統時,必須肯定如何實現數組變量。瞭解這方面狀況也有利於在編程時正確使用數組。
- 二、數組變量定義
根據數組的性質,在定義數組變量(下面簡單說成 「定義數組」)須要說明兩個問題: )該數組(變量)的元素是什麼類型的; )這個數組裏包含多少個元素。C語言規定,每一個數組變量的大小是固定的,須要在定義時說明。數組定義的形式與簡單變量相似,但須要增長有關元素個數的信息。在被定義變量名以後寫一對方括號就是一個數組定義,指定元素個數的方式是在括號裏寫一個整型表達式。人們常把數組元素類型看做數組的類型,把元素類型爲整型的數組說成是整型數組,相似地說雙精度數組等。本書下面也採用這種說法。
例如,下面的描述定義了兩個數組:
int a[ 0];
double a [ 00];
定義了一個包含有 0個元素的整型數組a和一個 00個元素的雙精度數組a 。數組元素個數也稱爲數組的大小或數組的長度。數組定義能夠與其餘變量的定義寫在一塊兒,例如能夠寫:
int a [ ], n, a [ ], m;
數組變量也是變量,數組定義能夠出如今任何能定義簡單變量的地方。數組變量也是變量,在做用域和存在期方面與簡單變量沒有差異。根據定義位置不一樣,數組也分爲外部數組和函數內的局部數組,包括函數內的靜態數組(用關鍵字static)和普通的自動數組,定義方式(及位置)決定了它們的做用域與存在期。
能夠寫出數組的外部說明。C語言規定,在寫數組變量的外部說明時沒必要寫數組大小,只要在數組變量名後寫一對方括號。例以下面是兩個數組的外部說明:
extern int a[];
extern double a [];
這兩個說明通知本源文件的其餘部分,有兩個數組(a和a )在其餘地方定義,它們的元素類型分別是整型和雙精度類型。數組元素個數必須能在編譯時靜態肯定,所以這個表達式必須能靜態求值,最簡單的狀況就是寫一個整型字面量(整數)。根據這個規定,下面數組定義不合法
void f(int m, int n) {
int b[n];
....
}
此時局部數組b的大小依賴於函數的參數值,這個值在編譯時沒法肯定。
- 三、數組的使用
使用數組的最基本操做是元素訪問,對數組的使用最終都經過對元素的使用而實現。數組元素在數組裏順序排列編號,首元素的編號規定爲0,其餘元素順序編號。這樣,n個元素的數組的元素編號範圍是0到n-1 。若是程序裏定義了數組:
int b[ ];
b的元素將依次編號爲0、 、 、 。數組元素的編號也稱爲元素的下標或指標。
數組元素訪問經過數組名和表示下標的表達式進行,用下標運算符[]描述。下標運算符[]是C語言裏優先級最高的運算符之一,它的兩個運算對象的書寫形式比較特殊:一個運算對象寫在方括號前面,應表示一個數組(簡單狀況是數組名);另外一個應該是整型表達式,寫在括號裏面表示元素下標。元素訪問是一種基本表達式,寫在表達式裏的b[ ]就是一個下標表達式,表示訪問數組b中編號爲 的元素,即上面定義的數組b的最後元素。
實習代碼
#include <stdio.h>
int main()
{
int a[3][4]={{1,2,3,4},{9,8,7,6},{-10,10,-5,2}};
int i,j,row=0,colum=0,max;
max=a[0][0];
printf("array a:\n");
for(i=0;i<=2;i++)
for(j=0;j<=3;j++)
if(a[i][j]>max)
{
max=a[i][j];
row=i;
colum=j;
}
printf("max=%d\nrow=%d\n",max,row,colum);
return 0;
}
實習二十一結果
實習二十二 函數
- 1、無參函數的定義形式
類型標識符 函數名()
{
聲明部分
語句
}
其中類型標識符和函數名稱爲函數頭。類型標識符指明瞭本函數的類型,函數的類型其實是函數返回值的類型。該類型標識符與前面介紹的各類說明符相同。函數名是由用戶定義的標識符,函數名後有一個空括號,其中無參數,但括號不可少。
{}中的內容稱爲函數體。在函數體中聲明部分,是對函數體內部所用到的變量的類型說明。
在不少狀況下都不要求無參函數有返回值,此時函數類型符能夠寫爲void。
咱們能夠改寫一個函數定義:
void Hello()
{
printf ("Hello,world \n");
}
這裏,只把main改成Hello做爲函數名,其他不變。Hello函數是一個無參函數,當被其它函數調用時,輸出Hello world字符串。
- 2、有參函數定義的通常形式
類型標識符 函數名(形式參數表列)
{
聲明部分
語句
}
有參函數比無參函數多了一個內容,即形式參數表列。在形參表中給出的參數稱爲形式參數,它們能夠是各類類型的變量,各參數之間用逗號間隔。在進行函數調用時,主調函數將賦予這些形式參數實際的值。形參既然是變量,必須在形參表中給出形參的類型說明。
例如,定義一個函數,用於求兩個數中的大數,可寫爲:
int max(int a, int b)
{
if (a>b) return a;
else return b;
}
第一行說明max函數是一個整型函數,其返回的函數值是一個整數。形參爲a,b,均爲整型量。a,b的具體值是由主調函數在調用時傳送過來的。在{}中的函數體內,除形參外沒有使用其它變量,所以只有語句而沒有聲明部分。在max函數體中的return語句是把a(或b)的值做爲函數的值返回給主調函數。有返回值函數中至少應有一個return語句。
在C程序中,一個函數的定義能夠放在任意位置,既可放在主函數main以前,也可放在main以後。
實習代碼
#include<stdio.h>
int main()
{ void print_star(); //聲明print_star 函數
void print_message(); //聲明print_message函數
print_star(); //調用print_star 函數
print_message(); //調用print_message函數
print_star(); //調用print_star 函數
return 0;
}
void print_star() //定義print_star函數
{
printf("*************\n"); //輸出一行*號
}
void print_message() //定義print_message函數
{
printf("How do you do!\n"); //輸出一行文字信息
}
實習二十二結果
實習二十三 指針
- 1.定義方法
形式:
類型標識符變量標識符;
定義存放指定類型數據地址的指針變量。
類型標識符是定義指針的基類型,給出指針數據對應存儲單元所存放的數據的類型,通常用「指向」這個詞來講明這種關係,即類型標識符給出指針所指向的數據類型,能夠是簡單類型,也能夠是複雜類型。用「」表示定義的是指針變量,不是普通變量。變量標識符給出的是指針變量名。
例如:
(1)Int p1,p2,p3;
定義指向整型數據的指針變量p一、p二、p3。
(2)float q1,q2,q3;
定義指向實型數據的指針變量q一、q二、q3。
(3)charr1,r2,r3;
定義指向字符型數據的指針變量r一、r二、r3。
(4)struct date
{int year;
int month;
int day;
}t1, t2, t3;
定義指向struct date類型數據的指針變量t一、t二、t3。
- 2.指針變量所指向的變量特定類型的數據
定義的指針變量用於存放指向類型數據的地址,咱們能夠經過指針運算「」,引用指針變量所指向的數據。有關內容咱們在指針運算中加以介紹。
例如,對指針變量p一、p二、p3,假定已有值,\p一、p二、p3表明指針變量p一、p二、p3所指向的數據,也就是p一、p二、p3的值對應的存儲單元裏存放的數據,稱爲指針變量所指向的變量,簡稱指針指向變量。
指針類型也是一種複雜類型,指針指向變量能夠認爲是指針數據的份量。指針指向變量至關於基類型變量。
若是指針變量p一、p二、p3分別存放整型變量i、j、k的地址,則p1指向i,p2指向j,p3指向k。
實習代碼
#include<stdio.h>
int main()
{ int a=100,b=10; //定義整型變量a,b,並初始化
int * pointer_1,* pointer_2; //定義指向整型數據的指針變量pointer_1,pointer_2
pointer_1=&a; //把變量a的地址賦給指針變量pointer_1
pointer_2=&b; //把變量b的地址賦給指針變量pointer_2
printf("a=%d,b=%d\n",a,b); //輸出變量a和b的值
printf("* pointer_1=%d,* pointer_2=%d\n",* pointer_1,* pointer_2); //輸出變量a和b的值
return 0;
}
實習二十三結果
實習二十四 文件的輸入與輸出
- C語言是經過將一個文件類型指針與文件關聯起來來對文件進行打開、關閉、輸入、輸出。
文件類型爲FILE(其實是一個結構體)。定義一個文件指針爲FILE fp;就能夠將fp和某個文件關聯起來進行操做了。例如要打開一個文件:
FILE \fp;fp=fopen("filename",「打開方式」);//fopen的返回值爲NULL或指向文件的指針或者直接FILE *fp=("filename","打開方式");若是要重定向只需將指針fp和另外一個文件關聯。意思是可用一個文件指針操做多個文件。
文件使用完後要及時關閉。這是個好習慣。關閉函數爲fclose(fp);這樣fp就不在和以前指向的文件關聯了。
- 1.判斷文件是否打開成功: www.2cto.com
判斷文件是否打開成功可用fopen的返回值if((fp=fopen("filename","r"))==NULL)則打開失敗。
- 2.判斷文件是否結束:
判斷ASCII文件是否結束fgetc()會返回結束標誌EOF(即-1)因爲二進制文件數據會出現-1因此必須用函數feof(fp)判斷,feof(fp)==1則已結束。
- 3.單個字符的輸入輸出:fgetc()和fputc()
ch=fgetc(fp);fp爲文件指針,且fgetc()不會忽略空格和回車符,只能用於讀入字符。相應的fputc(ch,fp);向文件輸出字符時也不會忽略空格,回車符由於fgetc()返回字符因此fgetc()和fputc()一般嵌套使用:fputc(fgetc(in),out)。
fputc()的返回值爲輸入的字符或EOF(-1)(失敗的狀況下)
fgetc()的返回值爲讀入的字符(包括文件結束標誌EOF(-1))
- 4.數據塊的輸入輸出:
fread(buff,size,count,fp)和發fwrite(buffer,size,count,fp)buffer是一個指針,對於fread,它是讀入數據的存放地址,對於發fwrite它是要輸出數據的地址,size是指要讀寫的字節數,count是要進行讀寫多少個size字節的數據項。
若是成功fread和fwrite都返回成功輸入和讀取的數據塊個數有可能比count小;
注意:fread參數buffer指向的空間必須大於或等於要讀入的數據塊大小。
fread和fwrite通常用於二進制文件的輸入輸出。用於ASCII文件字符發生轉換的狀況下可能出現與原設想的狀況不一樣。
- 5.putw()和getw()用來對磁盤文件讀寫一個整數。
例如putw(10,fp);//返回值爲輸出的數字(int)
int i=getw(fp);//失敗則返回-1
但注意putw()和getw()都是按二進制輸入輸出的。
因此若是你用putw()輸入數據到文件後以文本的方式打開看到的將都是亂碼。
一樣若是你在文本文件中輸入了數字並保存,用getw()來讀入的話讀入的結果並非你想象的那樣。由於它是按二進制讀的。
實習代碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
FILE * fp;
char str[3][10],temp[10];
int i,j,k,n=3;
printf("Enter strings :\n");
for(i=0;i<n;i++)
gets(str[i]);
for(i=0;i<n-1;i++)
{
k=1;
for(j=i+1;j<n;j++)
if(strcmp(str[k],str[j])>0)
k=j;
if(k!=j)
{
strcpy(temp,str[i]);
strcpy(str[i],str[k]);
strcpy(str[k],temp);
}
if((fp=fopen("D:\\CC\\string.dat","w+"))==NULL)
{
printf("can not open file!\n");
exit(0);
}
printf("\nThe new sequence :\n");
for(i=0;i<n;i++)
{
fputs(str[i],fp);
fputs("\n",fp);
printf("%s\n",str[i]);
}
}
return 0;
}
實習二十四結果
實習二十五 用戶本身創建數據類型
- 結構(struct)
結構是由基本數據類型構成的、並用一個標識符來命名的各類變量的組合。
結構中可使用不一樣的數據類型。
- 1.結構說明和結構變量定義
在Turbo C中,結構也是一種數據類型,可使用結構變量,所以,象其它類型的變量同樣,在使用結構變量時要先對其定義。
定義結構變量的通常格式爲:
struct 結構名
{
類型 變量名;
類型 變量名;
...
} 結構變量;
結構名是結構的標識符不是變量名。類型爲第二節中所講述的五種數據類型(整型、浮點型、字符型、指針型和無值型)。構成結構的每個類型變量稱爲結構成員,它象數組的元素同樣,但數組中元素是如下標來訪問的,而結構是按變量名字來訪問成員的。
下面舉一個例子來講明怎樣定義結構變量。
struct string
{
char name[8];
int age;
char sex[2];
char depart[20];
float wage1, wage2, wage3, wage4, wage5;
} person;
這個例子定義了一個結構名爲string的結構變量person, 若是省略變量person, 則變成對結構的說明。用已說明的結構名也可定義結構變量。這樣定義時上例變成:
struct string
{
char name[8];
int age;
char sex[2];
char depart[20];
float wage1, wage2, wage3, wage4, wage5;
};
struct string person;
若是須要定義多個具備相同形式的結構變量時用這種方法比較方便, 它先做結構說明, 再用結構名來定義變量。
例如:
struct string Tianyr, Liuqi, ...;
若是省略結構名, 則稱之爲無名結構, 這種狀況經常出如今函數內部, 用這種結構時前面的例子變成:
struct
{
char name[8];
int age;
char sex[2];
char depart[20];
float wage1, wage2, wage3, wage4, wage5;
} Tianyr, Liuqi;
- 2.結構變量的使用
結構是一個新的數據類型, 所以結構變量也能夠象其它類型的變量同樣賦值、運算,不一樣的是結構變量以成員做爲基本變量。
結構成員的表示方式爲:結構變量.成員名若是將"結構變量.成員名"當作一個總體, 則這個總體的數據類型與結構中該成員的數據類型相同, 這樣就可象前面所講的變量那樣使用。
實習代碼
#include<string.h>
#include<stdio.h>
struct Person //聲明結構體類型struct Person
{char name[20]; //候選人姓名
int count; //候選人得票數
}leader[3]={"Li",0,"Zhang",0,"Sun",0};//定義結構體數組並初始化
int main ()
{ int i,j;
char leader_name[20]; //定義字符數組
for(i=1;i<=10;i++)
{scanf("%s",leader_name); //輸入所選的候選人姓名
for(j=0;j<3;j++)
if(strcmp(leader_name,leader[j].name)==0)leader[j].count++;
}
printf("\nResult:\n");
for(i=0;i<3;i++)
printf("%5s:%d\n",leader[i].name,leader[i].count);
return 0;
}
實習二十五結果
實習感想
- 本次實習內容我選擇了以前本身不是很熟悉的C語言部分,經過這25個課時的學習,我對以前不太清楚地C語言知識有了補充,而且經過比較簡單的25個代碼來強化了這些知識,整體來講,收穫蠻多。