官术网_书友最值得收藏!

第2章 C程序的組成

本章視頻教學(xué)錄像:1 小時(shí)28 分鐘

在C語(yǔ)言中,根據(jù)存儲(chǔ)方式和表示形式,數(shù)據(jù)有常量和變量之分,就像方程有已知數(shù)和未知數(shù)一樣。

本章要點(diǎn)(已掌握的在方框中打鉤)

□ 聲明區(qū)

□ 主函數(shù)

□ 函數(shù)定義區(qū)

□ 注釋

□ 代碼的規(guī)矩

2.1 簡(jiǎn)單例子

本節(jié)視頻教學(xué)錄像:7分鐘

【范例2-1】 計(jì)算圓的周長(zhǎng)。

⑴ 在Visual C++ 6.0中,新建名為“計(jì)算圓周長(zhǎng).c”的【Text File】文件。

⑵ 在代碼編輯區(qū)域輸入以下代碼(代碼2-1.txt)。

        01 /*內(nèi)容:計(jì)算圓周長(zhǎng)
         02  目的:了解C語(yǔ)法*/
        03 #include<stdio.h>      /*包含標(biāo)準(zhǔn)輸入輸出頭文件*/
        04 #include<math.h>       /*包含數(shù)學(xué)函數(shù)庫(kù)頭文件*/
        05 #define PI 3.14     /*定義常量PI,它的值是3.14*/
        06 int main()        /*主函數(shù)*/
        07 {
        08  int radius;      /*整型變量,存儲(chǔ)半徑值*/
        09  float circum;     /*浮點(diǎn)型變量,存儲(chǔ)周長(zhǎng)值*/
        10  radius=2;       /*半徑賦值*/
        11  circum=2*PI*radius;   /*計(jì)算周長(zhǎng)*/
        12  printf("變量radius地址是%d\n",&radius);    /*輸出變量radius存儲(chǔ)地址*/
        13  printf("半徑開方值是%f\n",sqrt(radius));   /*輸出變量radius的開方值*/
        14  printf("半徑是%d,周長(zhǎng)是%f\n",radius,circum);     /*輸出變量radius值和circum值*/
        15  return 0;        /*返回值*/
        16 }       /*函數(shù)體結(jié)束*/

【運(yùn)行結(jié)果】

編譯、連接、運(yùn)行程序,即可在命令行中輸出以下結(jié)果。

【范例分析】

這個(gè)范例的目的是讓大家看到一個(gè)較復(fù)雜的C程序的組成,所謂復(fù)雜只是多了些說明和代碼。

2.2 聲明區(qū)

本節(jié)視頻教學(xué)錄像:23分鐘

2.2.1 頭文件

一個(gè)C程序可以由若干個(gè)源程序文件組成,每一個(gè)源文件可以由若干個(gè)函數(shù)和預(yù)處理命令以及全局變量聲明部分組成,每一個(gè)函數(shù)由函數(shù)首部和函數(shù)體組成。C程序的結(jié)構(gòu)如圖所示。

作為一名程序開發(fā)人員,不可能每次編寫都從最底層開發(fā)。比如在上例中,要輸入一串字符到輸出設(shè)備上,我們需要做的僅是調(diào)用printf()函數(shù),至于“Hello C!”是怎樣顯示的,我們并不關(guān)心。我們認(rèn)識(shí)printf()函數(shù),在編寫程序時(shí)調(diào)用它,更需要讓程序認(rèn)識(shí)它,這樣才能使用printf()函數(shù)提供的功能,這就需要使用#include <stdio.h>,包含標(biāo)準(zhǔn)輸入輸出頭文件,這樣程序就能夠認(rèn)識(shí)printf()函數(shù),并執(zhí)行其功能。

C提供有豐富的函數(shù)集,我們稱之為標(biāo)準(zhǔn)函數(shù)庫(kù)。標(biāo)準(zhǔn)函數(shù)庫(kù)包括15個(gè)頭文件,借助這些函數(shù)可以完成不同的功能。

例如,【范例2-1】中有#include<math.h>時(shí),就可以使用該數(shù)學(xué)函數(shù)庫(kù)頭文件提供的如開平方函數(shù)sqrt(),求出半徑radius為2時(shí)的開平方值1.414;又如,當(dāng)程序包含頭文件“malloc.h”時(shí),就可以完成對(duì)內(nèi)存申請(qǐng)和釋放等功能。

2.2.2 函數(shù)聲明

標(biāo)準(zhǔn)C語(yǔ)言引入了新的更好的函數(shù)聲明方法,即用函數(shù)原型指定函數(shù)更多的信息,通過函數(shù)原型可以將函數(shù)的名字和函數(shù)類型以及形式參數(shù)的個(gè)數(shù)、類型、順序通知編譯系統(tǒng),以便在調(diào)用函數(shù)時(shí),系統(tǒng)可以對(duì)照檢查。

函數(shù)聲明由函數(shù)返回類型、函數(shù)名和形參列表組成。形參列表必須包括形參類型,但是不必對(duì)形參命名。這3個(gè)元素被稱為函數(shù)原型,函數(shù)原型描述了函數(shù)的接口。定義函數(shù)的程序員提供函數(shù)原型,使用函數(shù)的程序員就只需要對(duì)函數(shù)原型編輯即可。

函數(shù)聲明的一般形式為:

      函數(shù)返回類型  函數(shù)名(參數(shù)類型1,參數(shù)類型2,……);

函數(shù)聲明包括函數(shù)的返回類型和函數(shù)名,來看下面這個(gè)例子。

        01 int fun(int a,int b);
        02 void display();
        03 float fn(float x);

其中,int、void和float都是函數(shù)返回類型,也屬于數(shù)據(jù)類型。fun、display和fn是所調(diào)用的函數(shù)名。也就是說,fun()函數(shù)返回的數(shù)據(jù)類型為整型int;display()函數(shù)返回的類型為void型,指函數(shù)無(wú)返回值;fn()返回的數(shù)據(jù)類型為浮點(diǎn)型float。

fun(int a, int b)函數(shù)內(nèi)部的a和b為形參,其參數(shù)類型都為int型。fn (float x)函數(shù)內(nèi)部參數(shù)x的類型為float型。函數(shù)聲明中的形參名往往被忽略,如果聲明中提供了形參的名字,也只是用作輔助文檔。另外要注意函數(shù)聲明是一個(gè)語(yǔ)句,后面不可漏分號(hào)!

進(jìn)一步對(duì)函數(shù)做解釋,需要注意的有以下幾點(diǎn)。

⑴ 函數(shù)名稱后面必須有小括號(hào),不能省略,這是函數(shù)的特征。

⑵ 函數(shù)結(jié)束必須有分號(hào),不能省略。

⑶ 字符串結(jié)尾有這樣的內(nèi)容“\n”,它叫做轉(zhuǎn)義符,表示的含義是把光標(biāo)移動(dòng)到下一行的行首,也就是回車換行,因?yàn)槲覀儫o(wú)法直接通過鍵盤輸入換行的指令,所以需要使用轉(zhuǎn)義符;又比如輸出內(nèi)容后希望返回該行的行首,重新輸出內(nèi)容,鍵盤上也沒有對(duì)應(yīng)的功能鍵,我們就可以使用回車符轉(zhuǎn)義符“\r”來代替。當(dāng)然,轉(zhuǎn)義還包含其他內(nèi)容,后續(xù)章節(jié)中會(huì)詳細(xì)講述。

2.2.3 變量聲明

在大多數(shù)語(yǔ)言中,在使用一個(gè)變量之前,都要對(duì)這個(gè)變量進(jìn)行聲明,C語(yǔ)言同樣如此。那么,什么是變量的聲明呢?有什么作用呢?變量的聲明其實(shí)就是在程序運(yùn)行前,告訴編譯器程序使用的變量以及與這些變量相關(guān)的屬性,包括變量的名稱、類型和長(zhǎng)度等。這樣,在程序運(yùn)行前,編譯器就可以知道怎樣給變量分配內(nèi)存空間,可以優(yōu)化程序。

變量的聲明語(yǔ)句的形式如下:

      變量類型名 變量名

變量的聲明包括變量類型名和變量名兩個(gè)部分。來看下面的例子:

         01 int num
        02 double area
        03 char ppt

其中,int、double和char是變量類型名,num、area和ppt是變量名。其實(shí),變量類型名也是數(shù)據(jù)類型的一種,就是說變量num是int類型,area是double類型,ppt是char類型。

變量類型名是C語(yǔ)言自帶的數(shù)據(jù)類型和用戶自定義的數(shù)據(jù)類型。C語(yǔ)言自帶的數(shù)據(jù)類型包括整型、字符型、浮點(diǎn)型、枚舉型和指針類型等。

變量名其實(shí)就是一個(gè)標(biāo)識(shí)符,當(dāng)然,標(biāo)識(shí)符的命名規(guī)則在此處同樣適用。除此之外,變量命名的時(shí)候還需要注意以下幾點(diǎn)。

⑴ 變量名區(qū)分大小寫,變量Num和num是兩個(gè)不同的變量。

⑵ 變量的命名最好與實(shí)際應(yīng)用有關(guān)聯(lián),例如:num一般表示數(shù)量,area表示面積等。

⑶ 變量的命名必須在變量使用之前。

提示

如果變量沒有經(jīng)過聲明而直接使用,則會(huì)出現(xiàn)編譯器報(bào)錯(cuò)的現(xiàn)象。

下面用一個(gè)例子來驗(yàn)證聲明必須在變量使用的前面。

【范例2-2】 驗(yàn)證未聲明的標(biāo)識(shí)符不可用。

⑴ 在Visual C++ 6.0中,新建名為“undeclaredvar.c”的【Text File】文件。

⑵ 在編輯窗口中輸入以下代碼(代碼2-2.txt)。

        01 #include<stdio.h>
        02 int main(void)
        03 {
        04  printf("output undeclaredvar num=%d\n",num);
        05  return 0;
        06 }

【運(yùn)行結(jié)果】

編譯后顯示出錯(cuò),信息如下:

undeclaredvar.c(4) : error C2065: 'num' : undeclared identifier

【范例分析】

在此例子中,沒有對(duì)標(biāo)識(shí)符num進(jìn)行聲明就直接引用,編譯器不知道num是什么,所以調(diào)試時(shí)編譯器就會(huì)報(bào)錯(cuò)。

【拓展訓(xùn)練】

在第3句和第4句之間插入語(yǔ)句:

         04  int num=10;

或者:

         04  int num;
        05  num=10;

檢驗(yàn)一下程序能否運(yùn)行,是否還報(bào)錯(cuò)。

2.3 主函數(shù)

本節(jié)視頻教學(xué)錄像:9分鐘

每個(gè)C程序必須有而且只有一個(gè)主函數(shù),也就是main()函數(shù),它是程序的入口。main()函數(shù)有時(shí)也作為一種驅(qū)動(dòng),按次序控制調(diào)用其他函數(shù),C程序是由函數(shù)構(gòu)成的,這使得程序容易實(shí)現(xiàn)模塊化;main()函數(shù)后面的“()”不可省略,表示函數(shù)的參數(shù)列表;“{”和“}”是函數(shù)開始和結(jié)束的標(biāo)志,不可省略。

下圖是對(duì)主函數(shù)調(diào)用其他函數(shù)的說明。

主函數(shù)main()在程序中可以放在任何位置,但是編譯器都會(huì)首先找到它,并從它開始運(yùn)行。它就像汽車的引擎,控制程序中各部分的執(zhí)行次序。

下圖是對(duì)主函數(shù)各部分名稱的說明。

在前面的兩個(gè)范例中,主函數(shù)main()的部首都是int類型,int是整數(shù)integer單詞的縮寫,表示返回給系統(tǒng)的數(shù)據(jù)類型是整型數(shù)據(jù),返回值是0,在return語(yǔ)句中體現(xiàn)了出來。

2.4 函數(shù)定義區(qū)

本節(jié)視頻教學(xué)錄像:17分鐘

C語(yǔ)言編譯系統(tǒng)是由上往下編譯的。一般被調(diào)函數(shù)放在主調(diào)函數(shù)后面時(shí),前面就該有聲明,不然C語(yǔ)言由上往下的編譯系統(tǒng)將無(wú)法識(shí)別。正如變量必須先聲明后使用一樣,函數(shù)也必須在被調(diào)用之前先聲明,否則無(wú)法調(diào)用!函數(shù)的聲明可以與定義分離,要注意的是一個(gè)函數(shù)只能被定義一次,但可以聲明多次。

函數(shù)定義:

        返回類型 函數(shù)名(參數(shù)類型1 參數(shù)名1,…,參數(shù)類型n 參數(shù)名n)
         {
        函數(shù)體...
        }

例如:

        int fun(int a,int b)
        {
          int c;
          c=a+b;
          return c;
        }

在程序中,如果main()函數(shù)在前,必須在mian()中寫函數(shù)聲明;如果函數(shù)在main()前面,可以不在main()中寫函數(shù)聲明!

下面看一個(gè)有關(guān)函數(shù)聲明和函數(shù)定義的綜合例子,比較一下它們有何不同。

        #include<stdio.h>
        int add(int x,int y); //函數(shù)聲明語(yǔ)句
         main()
        {
          int a,b,c;
          c=add(a,b);
          printf("%d",c);
        }
          int add(int x,int y)//函數(shù)定義
         {
          int z;
         z=x+y;
           return z;
        }

2.5 注釋

本節(jié)視頻教學(xué)錄像:8分鐘

讀者可能已經(jīng)注意到,很多語(yǔ)句后面都跟有“/*”和“*/”符號(hào),它們表示什么含義呢?

在前文已經(jīng)說過,我們?cè)诰庉嫶a的過程中,希望加上一些說明的文字,來表示代碼的含義,這是很有必要的。

費(fèi)了很大精力,絞盡腦汁編寫的代碼,如果沒有寫注釋或者注釋得不夠清楚,一年后又要使用這段代碼時(shí),當(dāng)年的思路全部記不得了,無(wú)奈之中,只得重分析、重理解。試問,因?yàn)楫?dāng)初一時(shí)的懶散造成了今日的結(jié)局,值得嗎?又比如,一個(gè)小組共同開發(fā)程序,別人需要在該小組寫的代碼上進(jìn)行二次開發(fā),如果代碼很復(fù)雜、沒有注釋,恐怕只能用4個(gè)字形容組員此時(shí)的心情:欲哭無(wú)淚。所以,編寫代碼時(shí)最好書寫注釋,這樣做有百利而無(wú)一弊。

注釋的要求如下。

⑴ 使用“/*”和“*/”表示注釋的起止,注釋內(nèi)容寫在這兩個(gè)符號(hào)之間,注釋表示對(duì)某語(yǔ)句的說明,不屬于程序代碼的范疇,比如【范例1-1】和【范例2-1】代碼中“/*”和“*/”之間的內(nèi)容。

⑵ “/”和“*”之間沒有空格。

⑶ 注釋可以注釋單行,也可以注釋多行,而且注釋不允許嵌套,嵌套會(huì)產(chǎn)生錯(cuò)誤,比如:

/*這樣的注釋/*特別*/有用*/

這段注釋放在程序中不但起不到說明的作用,反而會(huì)使程序產(chǎn)生錯(cuò)覺,原因是“這樣”前面的“/*”與“特別”后面的“*/”匹配,注釋結(jié)束,而“有用*/”就被編譯器認(rèn)為是違反語(yǔ)法規(guī)則的代碼。

2.6 代碼的規(guī)矩

本節(jié)視頻教學(xué)錄像:8分鐘

從書寫代碼清晰,便于閱讀、理解、維護(hù)的角度出發(fā),在書寫程序時(shí)應(yīng)遵循以下規(guī)則。

⑴ 一個(gè)說明或一個(gè)語(yǔ)句占一行。我們把空格符、制表符、換行符等統(tǒng)稱為空白符。除了字符串、函數(shù)名和關(guān)鍵字,C忽略所有的空白符,在其他地方出現(xiàn)時(shí),只起間隔作用,編譯程序?qū)λ鼈兒雎圆挥?jì)。因此在程序中使用空白符與否,對(duì)程序的編譯不產(chǎn)生影響,但在程序中適當(dāng)?shù)牡胤绞褂每瞻追梢栽黾映绦虻那逦院涂勺x性。

例如下面的代碼:

        int
        main(
        ){
          printf(“Hello C!\n”
        );
        }  /*這樣的寫法也能運(yùn)行,但是太亂,很不妥*/

⑵ 用“{”和“}”括起來的部分,通常表示程序某一層次的結(jié)構(gòu)。“{”和“}”一般與該結(jié)構(gòu)語(yǔ)句的第1個(gè)字母對(duì)齊,并單獨(dú)占一行。

例如下面的代碼:

        int main()
        {
        printf(“Hello C!\n”);
        return 0;}    /*這樣的寫法也能運(yùn)行,但是閱讀起來比較費(fèi)事*/

⑶ 低一層次的語(yǔ)句通常比高一層次的語(yǔ)句留有一個(gè)縮進(jìn)后再書寫。一般來說,縮進(jìn)指的是存在兩個(gè)空格或者一個(gè)制表符的空白位置。

例如下面的代碼:

        int main()
        {
          printf(“Hello C!\n”);
        {
          printf(“Hello C!\n”);
        }
          return 0;
        }

⑷ 在程序中書寫注釋,用于說明程序做了什么,同樣可以增加程序的清晰性和可讀性。

以上介紹的4點(diǎn)規(guī)則,大家在編程時(shí)應(yīng)力求遵循,以養(yǎng)成良好的編程習(xí)慣。

2.7 高手點(diǎn)撥

本節(jié)視頻教學(xué)錄像:7分鐘

文件中聲明函數(shù),就像變量可以在頭文件中聲明,而在源文件中定義一樣,函數(shù)也可以在頭文件中聲明,在源文件中定義。把函數(shù)聲明直接放在每個(gè)使用該函數(shù)的源文件中是大多數(shù)新手習(xí)慣并喜愛的方式,這是合法的。但是這種方式古板且易出錯(cuò)。解決方法就是把函數(shù)的聲明放在頭文件中,這樣可以確保指定函數(shù)的所有聲明保持一致。如果函數(shù)接口發(fā)生變化,則只需修改其唯一的聲明即可。

將提供函數(shù)聲明的頭文件包含在定義該函數(shù)的源文件中,可使編譯器能檢查該函數(shù)的定義和聲明是否一致。特別地,如果函數(shù)定義和函數(shù)聲明的形參列表一致,但返回類型不一致,編譯器會(huì)發(fā)出警告或出錯(cuò)信息來指出差異。

那么學(xué)過了函數(shù)聲明與函數(shù)定義,它們到底有什么不同呢?我們知道函數(shù)的定義是一個(gè)完整的函數(shù)單元,它包含函數(shù)類型、函數(shù)名、形參及形參類型、函數(shù)體等,并且在程序中,函數(shù)的定義只能有一次,函數(shù)首部與花括號(hào)間也不加分號(hào)。而函數(shù)聲明只是對(duì)定義函數(shù)的返回值類型進(jìn)行說明,以通知系統(tǒng)在本函數(shù)中所調(diào)用的函數(shù)是什么類型。它不包含函數(shù)體,并且調(diào)用幾次該函數(shù)就應(yīng)在各個(gè)主調(diào)函數(shù)中作相應(yīng)聲明,函數(shù)聲明是一個(gè)說明語(yǔ)句,必須以分號(hào)結(jié)束!

學(xué)習(xí)了這一章的內(nèi)容,讀者是不是對(duì)C語(yǔ)言有更好的理解呢?下面了解一下我們?cè)谑褂煤瘮?shù)時(shí),需要注意的一些問題。

① 函數(shù)聲明可以省略形參名,但是函數(shù)定義的首部必須寫出所有形參名并給出其對(duì)應(yīng)的數(shù)據(jù)類型。

② 函數(shù)原型的主要目的是為了聲明函數(shù)返回值類型以及函數(shù)期望接受的參數(shù)的個(gè)數(shù)、參數(shù)類型和參數(shù)順序。

③ 如果程序中沒有某個(gè)函數(shù)的函數(shù)原型(沒有說明),編譯系統(tǒng)就會(huì)用第一次出現(xiàn)的這個(gè)函數(shù)(函數(shù)定義或函數(shù)調(diào)用)構(gòu)造函數(shù)原型。

④ 在默認(rèn)下,編譯系統(tǒng)默認(rèn)函數(shù)返回值為int。

在編寫函數(shù)時(shí)的常見錯(cuò)誤:當(dāng)調(diào)用的函數(shù)與函數(shù)原型不相匹配時(shí),程序會(huì)提示語(yǔ)法錯(cuò)誤,并且當(dāng)函數(shù)原型和函數(shù)定義不一致時(shí),也會(huì)產(chǎn)生錯(cuò)誤。

2.8 實(shí)戰(zhàn)練習(xí)

⒈ 要求輸入兩個(gè)整數(shù)a和b,然后再輸出這兩個(gè)數(shù)。

⒉ 輸入兩個(gè)數(shù),求兩個(gè)數(shù)的和sum以及平均數(shù)avg(float類型)。

提示:求和的公式是sum=a+b;

求平均數(shù)的公式是avg=sum/2。

      **************************
      Very  Good!
      **************************

⒊ 請(qǐng)參照本章例題,編寫一個(gè)C程序,輸出以下信息:

主站蜘蛛池模板: 时尚| 新源县| 平昌县| 东兰县| 福清市| 阳西县| 德昌县| 尉犁县| 辽宁省| 金寨县| 兴隆县| 霍山县| 彰化市| 本溪| 曲水县| 沭阳县| 黄骅市| 凤冈县| 海盐县| 景宁| 黄浦区| 镇坪县| 伊春市| 图片| 永城市| 茂名市| 石景山区| 平塘县| 诸暨市| 南丹县| 马龙县| 灵寿县| 宁安市| 焦作市| 堆龙德庆县| 通城县| 翼城县| 钟祥市| 萨嘎县| 库车县| 资阳市|