關(guān)于C語(yǔ)言的相關(guān)問(wèn)題_第1頁(yè)
關(guān)于C語(yǔ)言的相關(guān)問(wèn)題_第2頁(yè)
關(guān)于C語(yǔ)言的相關(guān)問(wèn)題_第3頁(yè)
關(guān)于C語(yǔ)言的相關(guān)問(wèn)題_第4頁(yè)
關(guān)于C語(yǔ)言的相關(guān)問(wèn)題_第5頁(yè)
已閱讀5頁(yè),還剩92頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

關(guān)于C語(yǔ)言的相關(guān)問(wèn)題

說(shuō)而明:本內(nèi)容涉及到單片機(jī)的內(nèi)容都是關(guān)于8051和keilC51編譯器。

C程序開(kāi)發(fā)步驟:

編輯一一編譯一一連接一一運(yùn)行。

編輯就是程序代碼的錄入,生成源程序*.c一編譯就是語(yǔ)法分析查錯(cuò),翻譯生

成目標(biāo)程序.obj,由編譯器完成一連接就是與其它目標(biāo)程序或庫(kù)鏈接裝配,生成可

執(zhí)行程序*.exe

源程序目標(biāo)程序可執(zhí)行程序

內(nèi)容程序設(shè)計(jì)語(yǔ)言機(jī)器語(yǔ)言機(jī)器語(yǔ)言

格式ASCII二進(jìn)制二進(jìn)制

可執(zhí)行不可以不可以(因不含庫(kù)文件和其它目標(biāo)文件)可以

文件名后綴.c或.cpp.obj.exe

說(shuō)明:C語(yǔ)言編制的單片機(jī)程序在編譯時(shí),C51要求先產(chǎn)生一個(gè)匯編語(yǔ)言源文

件,再編譯此匯編文件。用C語(yǔ)言和匯編混合編制的程序,位于#pragmaasm和

#pragmaendasm之間的匯編段或匯編語(yǔ)言編寫(xiě)的函數(shù)是用A51編譯,C程序

是用C51編譯,然后用L51連接成.obj。*.asm是匯編語(yǔ)言程序

若在window中使用寫(xiě)字板編寫(xiě)程序,也是ASCH格式,但要存為*.c文件,不

能存為*.txt格式。

一、運(yùn)算優(yōu)先級(jí):

1、運(yùn)算符的優(yōu)先級(jí):C語(yǔ)言中,運(yùn)算符的運(yùn)算優(yōu)先級(jí)共分為15級(jí)。1級(jí)最

高,15級(jí)最低。在表達(dá)式中,優(yōu)先級(jí)較高的先于優(yōu)先級(jí)較低的進(jìn)行運(yùn)算。而在

一個(gè)運(yùn)算量?jī)蓚?cè)的運(yùn)算符優(yōu)先級(jí)相同時(shí)一,則按運(yùn)算符的結(jié)合性所規(guī)定的結(jié)合方向

處理。

2、運(yùn)算符的結(jié)合性:C語(yǔ)言中各運(yùn)算符的結(jié)合性分為兩種,即左結(jié)合性(自

左至右)和右結(jié)合性(自右至左)。例如算術(shù)運(yùn)算符的結(jié)合性是自左至右,即先左后

右。如有表達(dá)式x-y+z則y應(yīng)先與號(hào)結(jié)合,執(zhí)行x-y運(yùn)算,然后再執(zhí)行+z

的運(yùn)算。這種自左至右的結(jié)合方向就稱(chēng)為“左結(jié)合性”。而自右至左的結(jié)合方向

稱(chēng)為“右結(jié)合性”。最典型的右結(jié)合性運(yùn)算符是賦值運(yùn)算符。如x=y=z,由于“=”

的右結(jié)合性,應(yīng)先執(zhí)行y=z再執(zhí)行x=(y=z)運(yùn)算。C語(yǔ)言運(yùn)算符中有不少為右結(jié)

合性,應(yīng)注意區(qū)別,以避免理解錯(cuò)誤。

C語(yǔ)言中的算術(shù)表達(dá)式只能由運(yùn)算符、圓括號(hào)、系統(tǒng)函數(shù)和運(yùn)算對(duì)象構(gòu)成,

運(yùn)算的順序不但受優(yōu)先級(jí)控制,還受結(jié)合性的影響,如上例中的:x-y+z;

C語(yǔ)言中有15個(gè)優(yōu)先級(jí),在表達(dá)式中,優(yōu)先級(jí)高的先于優(yōu)先級(jí)低的運(yùn)算,

在一個(gè)運(yùn)算量?jī)蓚?cè)的運(yùn)算符優(yōu)先級(jí)相同,則按運(yùn)算符的結(jié)合性規(guī)定的結(jié)合方向處

理。如:a+b*(a+2)/c*(b+3).

運(yùn)算符:?jiǎn)文?,雙目、三目

關(guān)系運(yùn)算符都是雙目運(yùn)算符,其結(jié)合性均為左結(jié)合。關(guān)系運(yùn)算符的優(yōu)先級(jí)低

于算術(shù)運(yùn)算符,高于賦值運(yùn)算符。在六個(gè)關(guān)系運(yùn)算符中,<,<=,>,>=的優(yōu)先級(jí)相

同,高于==和!=,==和!=的優(yōu)先級(jí)相同。

!(非)->算術(shù)運(yùn)算符一關(guān)系運(yùn)算符一&&和II-*賦值運(yùn)算符

“&&”和低于關(guān)系運(yùn)算符,“!”高于算術(shù)運(yùn)算符。

邏輯運(yùn)算符也有優(yōu)先級(jí)別,?。ㄟ壿嫹牵ゝ&&(邏輯與)一||(邏輯或),

邏輯非的優(yōu)先值最高。C語(yǔ)言中的以上三個(gè)邏輯運(yùn)算的結(jié)果是波爾值“真”或

“假二

位運(yùn)算符也有優(yōu)先級(jí),從高到低依次是:“?”(按位取反)一“<<"(左移)一

“>>"(右移)一(按位與)一“人”(按位異或)一T(按位或)

以上的位運(yùn)算符運(yùn)算按位運(yùn)算后的結(jié)果是具體的數(shù),8051匯編語(yǔ)言中的

ANL、ORL、XRL等按位運(yùn)算后運(yùn)算的結(jié)果也是具體的數(shù)值。

優(yōu)先級(jí)運(yùn)算符結(jié)合性

(最高)()□.自左向右1級(jí)

!~++—+-*(取值)、&(取地址)sizeof自右向左2級(jí)

*/%自左向右3級(jí)

+-自左向右4級(jí)

<<>>自左向右5級(jí)

<<=>>=自左向右6級(jí)

==!=自左向右7級(jí)

&自左向右

「自左向右

I自左向右

&&自左向右11級(jí)

II自左向右12級(jí)

?:自右向左13級(jí)唯一的三目運(yùn)算符,格式:邏輯表達(dá)式?表達(dá)式1:

表達(dá)式2如:max=(a>b)?a:b;將條件運(yùn)算符的結(jié)果賦給max.

條件運(yùn)算符可嵌套,如:嵌套:x>0?l:(x〈0?T:0)

賦值和復(fù)合賦值運(yùn)算符:=,+=,-=,*二,/=,%二,&=「二,仁,〈〈=,>>=自

右向左

賦值運(yùn)算符左邊必須是變量。連續(xù)賦值如:a=b=c=l不能在定義時(shí)使用。

格式:變量名復(fù)合賦值運(yùn)算符表達(dá)式,其含義就是變量與表達(dá)式先進(jìn)行

運(yùn)算符所要求的運(yùn)算,再把運(yùn)算結(jié)果賦值給參與運(yùn)算的

變量。其實(shí)這是C語(yǔ)言中一種簡(jiǎn)化程序的一種方法,凡是二目運(yùn)算都能用

復(fù)合賦值運(yùn)算符去簡(jiǎn)化表達(dá)。例如:

a+=56等價(jià)于a=a+56

派y/=x+9等價(jià)于y=y/(x+9)——把賦值運(yùn)算符右邊看為一個(gè)整體。

,運(yùn)算符:自左向右(15級(jí)最低)

逗號(hào)在C語(yǔ)言中的作用作兩種:1、一種就是起隔離作用;2、在C語(yǔ)言中

逗號(hào)還是一種特殊的運(yùn)算符,也就是逗號(hào)運(yùn)算符,能用它將兩個(gè)或多個(gè)表達(dá)式連

接起來(lái),形成逗號(hào)表達(dá)式。逗號(hào)表達(dá)式的一般形式為:

表達(dá)式],表達(dá)式2,表達(dá)式3...表達(dá)式n

這樣用逗號(hào)運(yùn)算符組成的表達(dá)式在程序運(yùn)行時(shí),是從左到右計(jì)算出各個(gè)表達(dá)

式的值,而整個(gè)用逗號(hào)運(yùn)算符組成的表達(dá)式的值等于最右邊表達(dá)式的值,就是

“表達(dá)式n”的值。

sizeof運(yùn)算符:奇怪的運(yùn)算符,有點(diǎn)像函數(shù),卻又不是。sizeof是用來(lái)求

數(shù)據(jù)類(lèi)型、變量或是表達(dá)式的字節(jié)數(shù)的一個(gè)運(yùn)算符,但它并不像“=”之類(lèi)運(yùn)算

符那樣在程序執(zhí)行后才能計(jì)算出結(jié)果,它是直接在編譯時(shí)產(chǎn)生結(jié)果的。它的語(yǔ)

法如卜:sizeof(數(shù)據(jù)類(lèi)型或變量或是表達(dá)式).

二、數(shù)據(jù)類(lèi)型及其轉(zhuǎn)換:

C語(yǔ)言的數(shù)據(jù)分為常量和變量。

★標(biāo)識(shí)符定義和命名規(guī)則

定義:標(biāo)識(shí)變量名、符號(hào)常量名、函數(shù)名、數(shù)組名、文件名的字符串序列——

名字。

命名規(guī)則:

只能由字母、數(shù)字、下劃線組成,且第一個(gè)字符必須是字母或下劃線大小寫(xiě)

字母含義不同,一般用小寫(xiě),不能使用關(guān)鍵字。

C語(yǔ)言大小是敏感的,同一個(gè)字母大和小寫(xiě)被認(rèn)為是兩個(gè)不同的數(shù)據(jù)。關(guān)鍵

字一般都是小寫(xiě)。

TC允許最長(zhǎng)32個(gè)字符,建議長(zhǎng)度不超過(guò)8個(gè)字符使用:先定義、后使用。

1、數(shù)值數(shù)據(jù)有兩種:整數(shù)和浮點(diǎn)小數(shù)

整數(shù)(包含整型常數(shù))的三種表示方法:

?十進(jìn)制整數(shù):由數(shù)字0?9和正負(fù)號(hào)表示.如123,-456,0

?八進(jìn)制整數(shù):由數(shù)字0開(kāi)頭,后跟數(shù)字0?7表示.如0123,011

?十六進(jìn)制整數(shù):由Ox開(kāi)頭,后跟。?9,a~f,A?F表示.如0xl23,0xff

★在C語(yǔ)言中計(jì)算超出數(shù)據(jù)類(lèi)型的范圍就溢出,但是系統(tǒng)不報(bào)錯(cuò),編譯時(shí)要

注意。如:整型變量最大值32767,加1后是-32768的補(bǔ)碼形式。

浮點(diǎn)數(shù)(float、double)不能用“==0”進(jìn)行關(guān)系判斷,用<=10-6;

單精度f(wàn)loat有效數(shù)字6?7位,雙精度double型有效數(shù)字15?16位.

?浮點(diǎn)型常量一般按雙精度64位處理,數(shù)后加F或f按單精度;

?浮點(diǎn)型常量不分float和double

?\ddd:3位8進(jìn)制數(shù)代表的字是ASCII表中該數(shù)值所對(duì)應(yīng)的字符。

?\xhh:2位16進(jìn)制數(shù)代表的字是ASCII表中該數(shù)值所對(duì)應(yīng)的字符。

?字符數(shù)據(jù)在內(nèi)存中的存儲(chǔ)形式及其使用方法

?單個(gè)字符常量是用單引號(hào)括起來(lái)的,以二進(jìn)制存放字符的ASCII碼值(0?

255整數(shù))如:'a'存的就是65,"\"反斜杠加字符是轉(zhuǎn)義字符,單個(gè)轉(zhuǎn)義常

量也是用單引號(hào)括起來(lái),如:<\n,表示換行,'\\'表示單斜杠,''表示單

引號(hào),''表示雙引號(hào)。

?字符串是用雙引號(hào)括起來(lái)的單個(gè)或多個(gè)字符,從左到右以二進(jìn)制存放字符

的ASCII碼值,字符串常量或自后邊自動(dòng)加一個(gè)空字符“\0”,實(shí)際占有空間是

實(shí)際字符數(shù)(空格也算)+lo

?與整數(shù)的存儲(chǔ)形式類(lèi)似

字符數(shù)據(jù)可以字符或整數(shù)形式輸出;字符型與整型間互相賦值。

如:inti;chara;i=A;i的值是A在ASCH表中對(duì)應(yīng)的65;

a=65,a的值是65在ASCH表中對(duì)應(yīng)的A;a=,9';把9當(dāng)作字符賦給了

a,a在存儲(chǔ)器中存的是字母9就對(duì)應(yīng)的57的值。

表達(dá)式返回的結(jié)果值是有類(lèi)型的。表達(dá)式隱含的數(shù)據(jù)類(lèi)型取決于組成表達(dá)式

的變量和常量的類(lèi)型。類(lèi)型轉(zhuǎn)化的原則是從低級(jí)向高級(jí)自動(dòng)轉(zhuǎn)化(除非人為的加

以控制)。計(jì)算的轉(zhuǎn)換順序基本是這樣的:

字符型一>整型一>長(zhǎng)整型一>浮點(diǎn)型一>單精度型一》雙精度型

就是當(dāng)字符型和整型在一起運(yùn)算時(shí),結(jié)果為整型,如果整型和浮點(diǎn)型在一起

運(yùn)算,所得的結(jié)果就是浮點(diǎn)型,如果有雙精度型參與運(yùn)算,那么答案就是雙精度

型了。

?將一個(gè)浮點(diǎn)小數(shù)賦給一個(gè)整型變量,則小數(shù)部分被舍去,如:inta=6.5;

實(shí)際存的a的值是6。

?將一個(gè)整數(shù)數(shù)據(jù)賦給一個(gè)float型,整數(shù)部分不變,后邊加小數(shù)點(diǎn)和0,

如:floata=12;a=12.000000

?字符變量可以給它賦字符常量、-128?127之間的整數(shù)或轉(zhuǎn)義字符。

強(qiáng)制轉(zhuǎn)換是這樣的,在類(lèi)型說(shuō)明符的兩邊加上括號(hào),就把后面的變量轉(zhuǎn)換成

所要的類(lèi)型了。如:(int)a;(float)b;

第一個(gè)式子是把a(bǔ)轉(zhuǎn)換成整型,如果原先原小數(shù)部分,則舍去。

第二個(gè)式子是把b轉(zhuǎn)換成浮點(diǎn)型,如果原先是整數(shù),則在后面補(bǔ)0。

每一個(gè)表達(dá)式的返回值都具有邏輯特性。如果返回值為非0,則該表達(dá)式返

回值為真,否則為假。

2、C語(yǔ)言有四種對(duì)數(shù)據(jù)類(lèi)型進(jìn)行修飾的符號(hào)

long長(zhǎng)型、short短型、signed有符號(hào)型、unsigned無(wú)負(fù)號(hào)型。

Long——般修飾int、double:int2個(gè)字節(jié),16位;Longint4個(gè)字節(jié),

32位;double8個(gè)字節(jié),64位,Longdouble16個(gè)字節(jié),128位。

short一般修飾int,shorint2個(gè)字節(jié),16位。

signed和unsigned一般修飾(long、short)int、char,表示是否是帶符號(hào)

數(shù),最高位是否負(fù)號(hào)位。

3、關(guān)于補(bǔ)碼存儲(chǔ)問(wèn)題

計(jì)算機(jī)中數(shù)據(jù)是以補(bǔ)碼形式存儲(chǔ)的,正數(shù)的補(bǔ)碼是本身,負(fù)數(shù)的補(bǔ)碼要轉(zhuǎn)換,

但是機(jī)器不能區(qū)分正負(fù),CPU它只識(shí)別‘0'、T',由于計(jì)算機(jī)是用高級(jí)語(yǔ)言編

寫(xiě)程序,所以把負(fù)數(shù)轉(zhuǎn)換為補(bǔ)碼存儲(chǔ)是編譯系統(tǒng)完成的,但匯編語(yǔ)言是直接面對(duì)

機(jī)器編成,使用的是助記符和16進(jìn)制操作數(shù),沒(méi)有數(shù)據(jù)類(lèi)型,沒(méi)有明確的正負(fù)

數(shù)標(biāo)記,機(jī)器本身不能區(qū)分正數(shù)和負(fù)數(shù),數(shù)據(jù)的正負(fù)都在程序員的心里,程序員

認(rèn)為是正數(shù)就按正數(shù)規(guī)則處理,認(rèn)為是負(fù)數(shù)就按負(fù)數(shù)規(guī)則處理,單片機(jī)的加減程

序運(yùn)算各位都參與計(jì)算,機(jī)器是按無(wú)符號(hào)數(shù)處理,加減判斷溢出是看0V,0V溢

出是按負(fù)數(shù)以補(bǔ)碼參與運(yùn)算的情況下進(jìn)行判斷的,要進(jìn)行有符號(hào)數(shù)運(yùn)算,必須把

負(fù)數(shù)轉(zhuǎn)換為補(bǔ)碼進(jìn)行,所以用戶(hù)先要將負(fù)數(shù)變成補(bǔ)碼存入,再進(jìn)行加減,然后根

據(jù)0V的情況進(jìn)行修正(用戶(hù)軟件)。0V溢出是建立在補(bǔ)碼基礎(chǔ)上判斷的,所以

一旦0V溢出后,說(shuō)明有效位不夠,要增加1位有效位,然后根據(jù)Cy判斷數(shù)的正

負(fù),最后再求該數(shù)的補(bǔ)碼(CPL+1),才能得到實(shí)際的數(shù)。有效位的多少?zèng)Q定求補(bǔ)

的數(shù)值,如:101補(bǔ)碼是:111(-3),1001補(bǔ)碼是:1111(-7)

高級(jí)語(yǔ)言不用用戶(hù)干涉,轉(zhuǎn)換和修正是編譯系統(tǒng)進(jìn)行,因此在高級(jí)語(yǔ)言中要

輸入負(fù)數(shù)就要在10進(jìn)制數(shù)前加上負(fù)號(hào)“-"明確標(biāo)記,若標(biāo)記為負(fù)數(shù)則編譯系統(tǒng)

將其變成2進(jìn)制補(bǔ)碼存入,如:chara=-1,存入的就是口1111111(char類(lèi)型

一個(gè)字節(jié)),如:inta=-l,存入的就是類(lèi)型兩個(gè)字節(jié)),

若無(wú)負(fù)號(hào)(正數(shù)不加+)編譯系統(tǒng)是按正數(shù)處理,直接轉(zhuǎn)換為2進(jìn)制存入,如:

inta=127,存入的就是冰)00000001111111;

在C語(yǔ)言中超出數(shù)據(jù)類(lèi)型的范圍就溢出,但是系統(tǒng)不報(bào)錯(cuò),超出該類(lèi)型總

長(zhǎng)的部分丟失。

如:chara=129,超出-128?127范圍,但編譯系統(tǒng)轉(zhuǎn)換為2進(jìn)制為

010000001,符號(hào)位“0”丟失,存入10000001,最高位是1,因a是char類(lèi)型,

是有符號(hào)數(shù)據(jù),若用〃%C〃格式輸出,編譯系統(tǒng)把最高位1看為負(fù)號(hào),“10000001”

是-127的補(bǔ)碼,則按-127對(duì)應(yīng)的ASCII字符處理,若用10進(jìn)制int格式輸出,

先把“10000001”看作-127,再轉(zhuǎn)換為int類(lèi)型(16位)補(bǔ)碼,是

1111111110000001,"%d”格式輸出是T27,"%u〃格式輸出是65409。

如:chara=-129,超出-128?127范圍,但編譯系統(tǒng)轉(zhuǎn)換為2進(jìn)制補(bǔ)碼為

lOmilll,符號(hào)位“1”丟失,存入01111111,最高位是0,因a是char類(lèi)型,

是有符號(hào)數(shù)據(jù),若用〃%C〃格式輸出,把最高位。看為正號(hào),“01111111”是127,

則按127對(duì)應(yīng)的ASCII字符處理,若用10進(jìn)制int格式輸出,先把“01111111”

看作127,再轉(zhuǎn)換為int類(lèi)型(16位)補(bǔ)碼,是0000000001111111,"%d”格式輸

出是127,"%u”格式輸出是127。

如:unsignedchara=129,在0?255范圍內(nèi),但編譯系統(tǒng)轉(zhuǎn)換為2進(jìn)制為

10000001直接存入,無(wú)符號(hào)位,因a是unsignedchar類(lèi)型,是無(wú)符號(hào)數(shù)據(jù),

若用"%C”格式輸出,“10000001”是129,則按129對(duì)應(yīng)的ASCII字符處理,若用

10進(jìn)制int格式輸出,先把“10000001”看作129,再轉(zhuǎn)換為int類(lèi)型(16位)

補(bǔ)碼,是0000000010000001,〃%『'格式輸出是129,“%u〃格式輸出是129。

在定義數(shù)據(jù)的時(shí)候,如果定義的是有符號(hào)數(shù),編譯系統(tǒng)就會(huì)把最高位當(dāng)符號(hào)

位,定義的是無(wú)符號(hào)數(shù),編譯系統(tǒng)就不會(huì)把最高位當(dāng)符號(hào)位。無(wú)論以何種格式輸

出,有符號(hào)的就當(dāng)作有符號(hào)處理,無(wú)符號(hào)就當(dāng)作無(wú)符號(hào)處理。

★其實(shí)單片機(jī)編成很少用帶符號(hào)數(shù)運(yùn)算,一般都用無(wú)符號(hào)運(yùn)算,加就用

ADD,ADDC,減就直接用SUBB,不要搞得太復(fù)雜。

三、printf()和scanf()函數(shù)的調(diào)用格式為:

1、printf(格式控制,輸出列表);即〈格式化字符串〉〈參量表》

格式控制由輸出文字和數(shù)據(jù)格式說(shuō)明組成,一般用雙引號(hào)括起來(lái),格式說(shuō)

明是以“%”開(kāi)頭,形式是:京數(shù)據(jù)輸出寬度說(shuō)明X格式符>,寬度說(shuō)明可以省略.

格式控制中雙引號(hào)內(nèi)除格式說(shuō)明外的其它字符原樣輸出,輸出列表中可以是變

量、表達(dá)式、數(shù)值(常量)。

量表是需要輸出的一系列參數(shù),其個(gè)數(shù)必須與格式化字符串所說(shuō)明的輸出參

數(shù)個(gè)數(shù)一樣多各參數(shù)之間用,分開(kāi),且順序一一對(duì)應(yīng),否則將會(huì)出現(xiàn)意想不到的

錯(cuò)誤。

注意:printf("%d”“%d",a,b)格式控制符可以分別用多個(gè)銀號(hào)擴(kuò)起來(lái),

引號(hào)內(nèi)的非格式字符原樣打印。

(1).可以在%和字母之間插進(jìn)數(shù)字表示最大場(chǎng)寬。(要求格式字符在外之后,所以

表示寬度的數(shù)字也要在%之后。)

例如:%3d表示輸出3位整型數(shù),不夠3位右對(duì)齊。

%9.2f表示輸出場(chǎng)寬為9的浮點(diǎn)數(shù),其中小數(shù)位為2,整數(shù)位為6,小數(shù)點(diǎn)占一

位,不夠9位右對(duì)齊。

%8s表示輸出8個(gè)字符的字符串,不夠8個(gè)字符右對(duì)齊。

如果字符串的長(zhǎng)度、或整型數(shù)位數(shù)超過(guò)說(shuō)明的場(chǎng)寬,將按其實(shí)際長(zhǎng)度輸出。

但對(duì)浮點(diǎn)數(shù),若整數(shù)部分位數(shù)超過(guò)了說(shuō)明的整數(shù)位寬度,將按實(shí)際整數(shù)位輸出;若

小數(shù)部分位數(shù)超過(guò)了說(shuō)明的小數(shù)位寬度,則按說(shuō)明的寬度以四舍五入輸出。

另外,若想在輸出值前加一些0,就應(yīng)在場(chǎng)寬項(xiàng)前加個(gè)0。

例如:%04d表示在輸出一個(gè)小于4位的數(shù)值時(shí),將在前面補(bǔ)0使其總寬度為

4位。

如果用浮點(diǎn)數(shù)表示字符或整型量的輸出格式,小數(shù)點(diǎn)后的數(shù)字代表最大寬度,

小數(shù)點(diǎn)前的數(shù)字代表最小寬度。

例如:%6.9s表示顯示一個(gè)長(zhǎng)度不小于6且不大于9的字符串。若大于9,

則第9個(gè)字符以后的內(nèi)容將被刪除。

(2).可以在%和字母之間加小寫(xiě)字母1,表示輸出的是長(zhǎng)型數(shù)。

例如:%ld表示輸出long整數(shù)

%lf表示輸出double浮點(diǎn)數(shù)

(3).可以控制輸出左對(duì)齊或右對(duì)齊,即在%和字母之間加入一個(gè)-號(hào)可說(shuō)明

輸出為左對(duì)齊,否則為右對(duì)齊。

例如:7d表示輸出7位整數(shù)左對(duì)齊

格式符:輸出十進(jìn)制整數(shù),有3種用法

★%d格式:以帶符號(hào)的十進(jìn)制形式輸出整數(shù),按數(shù)據(jù)實(shí)際長(zhǎng)度輸出,數(shù)據(jù)范

圍-32768—32767

★%md格式:m指定輸出字段的寬度,數(shù)據(jù)位數(shù)小于m,左端補(bǔ)空格,反之按

實(shí)際輸出。

★%ld格式:輸出長(zhǎng)整型數(shù)據(jù);可以用%mid格式指定輸出列寬;

★0格式符:以不帶符號(hào)的八進(jìn)制輸出整數(shù),是將內(nèi)存中的二進(jìn)制位整個(gè)按

八進(jìn)制輸出,所以輸出值沒(méi)有符號(hào)??梢灾付ㄝ敵鰧挾?m。,長(zhǎng)整型可以用%1。

格式輸出。(該處是字母“。”,在輸出格式中用字母。表示八進(jìn)制輸出,在立即

數(shù)前加數(shù)字0表示該數(shù)是八進(jìn)制數(shù)。)

★x格式符:以不帶符號(hào)的十六進(jìn)制輸出整數(shù),同。格式符,無(wú)符號(hào),即無(wú)

負(fù)十六進(jìn)制數(shù)。可以指定輸出寬度%mx,長(zhǎng)整型可以用%lx格式輸出。

★u格式符:以不帶符號(hào)的號(hào)進(jìn)制輸出整型數(shù)據(jù),unsigned(無(wú)符號(hào));

int型可以用%u格式輸出,unsigned型也可以用%d、%。和%x格式輸出。

例4.3無(wú)符號(hào)數(shù)據(jù)的輸出

#include<stdio.h>

voidmain()

{unsignedinta=65535;

intb=-2;

printf("a=%d,%o,%x,%u\n”,a,a,a,a);

printf("b=%d,%o,%x,%u\n”,b,b,b,b);

)

運(yùn)行結(jié)果:

a=-1,177777,ffff,65535

b=-2,177776,fffe,65534

以上可以看出,%d是按有符號(hào)數(shù)輸出整數(shù),%口按無(wú)符號(hào)數(shù)輸出整數(shù),整數(shù)

在機(jī)器中是以二進(jìn)制存的,且以補(bǔ)碼形式存儲(chǔ),所以若把無(wú)符號(hào)數(shù)按照9團(tuán)有符

號(hào)輸出,會(huì)將最高位看成符號(hào)位進(jìn)行處理,將數(shù)看作補(bǔ)碼,進(jìn)行處理后輸出真值,

所以上例中a=T;若把有符號(hào)數(shù)按照%u無(wú)符號(hào)輸出,會(huì)將最高的符號(hào)位按照有效

數(shù)值處理,處理后按正整數(shù)輸出,所以上例中b=65534;所以輸出格式要和數(shù)據(jù)

類(lèi)型一致,防止出錯(cuò)。

%。和%x格式輸出都是把最高位當(dāng)作有效數(shù)據(jù)處理,直接轉(zhuǎn)換為相應(yīng)的進(jìn)制

輸出。

★c格式符:輸出一個(gè)字符;值在。-255的整數(shù),可以用%c形式輸出為字符。

★s格式符:輸出——個(gè)字符串,有%s,%ms,%—ms,%m.ns,%—m.ns五種用

法。printf(“%s”,“ABC”);結(jié)果:ABC

★f格式符:輸出實(shí)數(shù)

%f格式:整數(shù)部分全部輸出,小數(shù)6位??梢杂蟹怯行?shù)字輸出,因?yàn)閱?/p>

精度有效位7位,雙精度16位。%m.nf格式:占m歹!],其中n位小數(shù),左補(bǔ)空

格。%-m.nf格式:右補(bǔ)空格。如:floata=567.789;printf(“%f”,a);

結(jié)果:567.789000

★e格式符:指數(shù)形式輸出實(shí)數(shù)

%e格式:不指定m和n,小數(shù)6位,指數(shù)部分共5位,

其中e和指數(shù)符號(hào)各1位,指數(shù)值3位。%m.ne和%-m.ne格式:m、n、一的含義

同前面。沒(méi)有n時(shí),自動(dòng)=6。如:floata=567.789;printf("%e”,a);

結(jié)果:5.677890e+002

★g格式符:輸出實(shí)數(shù)

可以自動(dòng)根據(jù)數(shù)值大小選擇f或e格式(選列少的)不輸出無(wú)意義的零。

2、scanf函數(shù)(格式輸入函數(shù)函通過(guò)標(biāo)準(zhǔn)輸入設(shè)備輸入一組數(shù)據(jù)。

格式:scanf(,地址表列);

功能:按指定格式從鍵盤(pán)讀入數(shù)據(jù),存入地址表指定的存儲(chǔ)單元中,并按回

車(chē)鍵結(jié)束。

格式控制中盡量簡(jiǎn)單,避免出錯(cuò)。

★輸入分隔符的指定

一般以空格、TAB或“或作為分隔符;

輸入數(shù)據(jù)時(shí),遇非法輸入則認(rèn)為數(shù)據(jù)結(jié)束;

其它字符在格式控制中作分隔符:格式串中兩個(gè)格式符間有其它字符,則輸

入時(shí)對(duì)應(yīng)位置也要有相同的字符。也就是說(shuō)在格式控制中加入了格式說(shuō)明之外的

其它字符,則輸入數(shù)據(jù)時(shí)這些字符也同樣輸入。但只作為間隔。若格式控制中沒(méi)

有間隔的符號(hào),在輸入時(shí),用戶(hù)可以用空格、“,”等分隔,不然機(jī)器無(wú)法區(qū)分。

如:scanf("x=%d,y=%d",&a,&b);輸入時(shí)要以:x=12,y=10輸入。

注意:scanf以字符串格式輸入數(shù)組時(shí),以空格和回車(chē)為結(jié)束符。get只以

回車(chē)為結(jié)束符。如:

gets(al);scanf("%s”,a2);

輸入:chinabeijingJchinabeijingJ

輸出:al=chinabeijinga2=china

四、書(shū)寫(xiě)規(guī)則

(1).一5〈二x&&x〈l不能寫(xiě)成一5<=x〈l;1〈二x&&x〈4也不能寫(xiě)成1〈二x<4;在C語(yǔ)言

中,不能認(rèn)識(shí)連續(xù)不等式。

(2).y=2*x+5不能寫(xiě)成y=2x+5;y=3*x-2也不能寫(xiě)成y=3x-2;這與我們平時(shí)所

寫(xiě)的方法不一樣。

五、goto語(yǔ)句

格式為:goto語(yǔ)句標(biāo)號(hào);/*不能跟數(shù)字等其它*/

如:loop:if(i<=100)

{sum+=i;

i++;

gotoloop;

}

goto語(yǔ)句是一種無(wú)條件轉(zhuǎn)移語(yǔ)句,語(yǔ)句標(biāo)識(shí)符加上一個(gè)“:”一起出現(xiàn)在函

數(shù)內(nèi)某處,執(zhí)行g(shù)oto語(yǔ)句后,程序?qū)⑻D(zhuǎn)到該標(biāo)號(hào)處并執(zhí)行其后的語(yǔ)句。標(biāo)號(hào)

既然是一個(gè)標(biāo)識(shí)符,也就要滿(mǎn)足標(biāo)識(shí)符的命名規(guī)則。另外標(biāo)號(hào)必須與goto語(yǔ)句

同處于一個(gè)函數(shù)中,但可以不在一個(gè)循環(huán)層中。通常got。語(yǔ)句與if條件語(yǔ)句連

用,當(dāng)滿(mǎn)足某一條件時(shí),程序跳到標(biāo)號(hào)處運(yùn)行。goto語(yǔ)句通常不用,主要因?yàn)?/p>

它將使程序?qū)哟尾磺澹也灰鬃x,但在多層嵌套退出時(shí),用goto語(yǔ)句則比較合

理。所以在同時(shí)跳出多層循環(huán)時(shí),應(yīng)該使用got。語(yǔ)句。記住,所有的got。語(yǔ)句

其實(shí)都是可以用break,continue代替的。

常見(jiàn)的goto語(yǔ)句使用方法是用它來(lái)跳出多重循環(huán),不過(guò)它只能從內(nèi)層循環(huán)

跳到外層循環(huán),不能從外層循環(huán)跳到內(nèi)層循環(huán)。(只能向外跳不能往里跳。)

六、函數(shù)

C語(yǔ)言的函數(shù)一般有三種:主函數(shù)(main函數(shù))、用戶(hù)自定義函數(shù)、庫(kù)函數(shù),

程序是開(kāi)始于主函數(shù),結(jié)束于主函數(shù),在程序中,預(yù)處理語(yǔ)句必須以開(kāi)頭,

不能加“;”,在函數(shù)書(shū)中,C語(yǔ)言語(yǔ)句后邊必須加。

1、概述

有參函數(shù)定義的一般形式:

類(lèi)型標(biāo)識(shí)符函數(shù)名(形式參數(shù)表列)〃函數(shù)返回值類(lèi)型隱含為int型

{說(shuō)明部分

語(yǔ)句

形參的數(shù)據(jù)類(lèi)型一一聲明,不能合并,

如:intmax(intx,inty)(對(duì))

intmax(intx,y)(錯(cuò))

對(duì)形參的聲明的傳統(tǒng)方式

類(lèi)型標(biāo)識(shí)符函數(shù)名(形參表)/*很少用*/

形參類(lèi)型說(shuō)明

{說(shuō)明部分

語(yǔ)句

}

如:intmax(x,y):老版

intx,y;/*在打括號(hào)外*/

{intz;

z=x>y?x:y;

return(z);

形式參數(shù)和實(shí)際參數(shù)

形式參數(shù):定義函數(shù)時(shí)函數(shù)名后面括號(hào)中的變量名

實(shí)際參數(shù):調(diào)用函數(shù)時(shí)函數(shù)名后面括號(hào)中的表達(dá)式

幾點(diǎn)說(shuō)明:

1、實(shí)參可以是常量、變量或表達(dá)式。必須有確定的值。當(dāng)函數(shù)調(diào)用時(shí),將

實(shí)參的值傳遞給形參,若是數(shù)組名,則傳送的是數(shù)組首地址。

2、形參必須指定類(lèi)型,只能是簡(jiǎn)單變量或數(shù)組,不能是常量或表達(dá)式;

3、形參與實(shí)參類(lèi)型一致,個(gè)數(shù)相同順序相同。

4、若形參與實(shí)參類(lèi)型不一致,自動(dòng)按形參類(lèi)型轉(zhuǎn)換-----函數(shù)調(diào)用轉(zhuǎn)換;

4、形參在函數(shù)被調(diào)用前不占內(nèi)存;函數(shù)調(diào)用時(shí)為形參分配內(nèi)存;調(diào)用結(jié)束,

內(nèi)存釋放;

5、實(shí)參對(duì)形參的數(shù)據(jù)傳送是值傳送,也是單向傳送,當(dāng)被調(diào)函數(shù)的形參發(fā)

生變化時(shí),并不改變主調(diào)函數(shù)實(shí)參的值。形、實(shí)參占據(jù)的是不同的存儲(chǔ)單元

函數(shù)調(diào)用時(shí)直接將實(shí)參寫(xiě)在()中,不能帶數(shù)據(jù)類(lèi)型,如:delay(5)

例:形、實(shí)參占據(jù)的是不同的存儲(chǔ)單元

#include<stdio.h>

voidmain()

{inta=2,b=3;

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

printf("&a=%x,&b=%x\n”,&a,&b);

add(a,b);

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

printf("&a=%x,&b=%x\n”,&a,&b);

)

add(intx,inty)

{x=x+8;y=y+12;

printf(“x=%d,y=%d\nw,x,y);

printf("&x=%x,&y=%x\n”,&x,&y);

)

運(yùn)行結(jié)果:

a=2,b=3

&a=ffd6,&b=ffd8

x=10,y=15

&x=ffd2,&y=ffd4

a=2,b=3

&a=ffd6,&b=ffd8

注意:如果以數(shù)組名或指針傳過(guò)來(lái)的是地址,那么改變的就是同一地址單元

的值,該地址的存放的變量自然就改變。

★函數(shù)的返回值

返回語(yǔ)句形式:

return(表達(dá)式);或return表達(dá)式;

功能:使程序控制從被調(diào)用函數(shù)返回到調(diào)用函數(shù)中,同時(shí)把返值帶給調(diào)用

函數(shù)。

★說(shuō)明:

1、函數(shù)的返回值,必須用return語(yǔ)句帶回。

2、return語(yǔ)句只能把一個(gè)返值傳遞給調(diào)用函數(shù)。

3、函數(shù)中可有多個(gè)return語(yǔ)句,執(zhí)行哪一個(gè)由程序執(zhí)行情況來(lái)定。

if(a>b)return(a);

elsereturn(b);

4、return后的值可以是一個(gè)表達(dá)式,如:return(x>y?x:y);

5、返回值的類(lèi)型為定義的函數(shù)類(lèi)型,不指定的按整型處理。

6、若return語(yǔ)句中表達(dá)式類(lèi)型與函數(shù)類(lèi)型不一致,則轉(zhuǎn)換為函數(shù)類(lèi)型。

7、若無(wú)return語(yǔ)句,遇}時(shí),自動(dòng)返回調(diào)用函數(shù)??赡芊祷匾粋€(gè)不確定

或無(wú)用的值。

8、無(wú)返回值的函數(shù),定義為void類(lèi)型。

★函數(shù)調(diào)用的一般形式:函數(shù)名(實(shí)參表列)

函數(shù)調(diào)用的方式:

1、函數(shù)語(yǔ)句:以獨(dú)立的語(yǔ)句去調(diào)用函數(shù)。不要求有返回值,僅完成一定

的操作。

2、函數(shù)表達(dá)式:

函數(shù)返回一個(gè)確定值,以參加表達(dá)式的運(yùn)算。不可用于void

例:m=max(a,b)*2;

3、函數(shù)參數(shù):函數(shù)調(diào)用作為另一個(gè)函數(shù)的參數(shù)。

例:printf("%d”,max(a,b));/*輸出大數(shù)*/

第3種這種調(diào)用只能在實(shí)參中使用,不能在定義函數(shù)時(shí)在形參中寫(xiě)其它函

數(shù)。

☆數(shù)組名可作函數(shù)參數(shù)時(shí)類(lèi)型應(yīng)一致,采用數(shù)組名作為參數(shù)的傳遞,傳遞

是地址,就是主調(diào)函數(shù)和被調(diào)函數(shù)處理的是同一空間,形參的改變實(shí)參也會(huì)改變,

具有雙向傳遞性,這是指針的性質(zhì)。

數(shù)組名作形參時(shí)一維數(shù)組大小或多維數(shù)組第一維可不指定在定義數(shù)組時(shí)

在數(shù)組名后面跟一個(gè)空的方括弧,方括弧不能少,否則就不能說(shuō)明是數(shù)組名,數(shù)

據(jù)類(lèi)型也不能少。但多維數(shù)組形參的第二維不能省,而且實(shí)參和形參的數(shù)要相同。

每個(gè)程序有且只有一個(gè)main函數(shù),一個(gè)程序可能由多個(gè)文件(乎c)構(gòu)成,

但只能有,個(gè)main函數(shù)。每個(gè)C程序的入口和出口者M(jìn)立于函數(shù)main()之中。main。

函數(shù)可以調(diào)用其他函數(shù),這些函數(shù)執(zhí)行完畢后程序的控制又返回到main。函數(shù)

中,也就是開(kāi)始于main,也結(jié)束于main函數(shù)。main()函數(shù)不能被別的函數(shù)所調(diào)

用。通常我們把這些被調(diào)用的函數(shù)稱(chēng)為下層(lowerTevel)函數(shù)。函數(shù)調(diào)用發(fā)生

時(shí),立即執(zhí)行被調(diào)用的函數(shù),而調(diào)用者則進(jìn)入等待狀態(tài),直到被調(diào)用函數(shù)執(zhí)行完

畢。函數(shù)可以有參數(shù)和返回值。

為了調(diào)用一個(gè)函數(shù),必須事先聲明該函數(shù)的返回值類(lèi)型和參數(shù)類(lèi)型,這和使

用變量的道理是一樣的。當(dāng)定義在調(diào)用之前時(shí)\可以不聲明函數(shù)。也可以在主函

數(shù)內(nèi)部,調(diào)用之前聲明。

一般來(lái)說(shuō),比較好的程序書(shū)寫(xiě)順序是,先聲明函數(shù),然后寫(xiě)主函數(shù),然后再

寫(xiě)那些自定義的函數(shù)。

函數(shù)在聲明、調(diào)用、定義的時(shí)候,形參和實(shí)參不僅個(gè)數(shù)要一樣,類(lèi)型也要對(duì)

應(yīng)。

這里先講講KEILC編譯器所支持的注釋語(yǔ)句。一種是以“〃”符號(hào)開(kāi)始的

語(yǔ)句,符號(hào)之后的語(yǔ)句都被視為注釋?zhuān)钡接谢剀?chē)換行。另一種是在“/*”和

“*/”符號(hào)之內(nèi)的為注釋。注釋不會(huì)被C編譯器所編譯。一個(gè)C應(yīng)用程序中

應(yīng)有一個(gè)main主函數(shù),main函數(shù)能調(diào)用別的功能函數(shù),但其它功能函數(shù)不允

許調(diào)用main函數(shù)。不論main函數(shù)放在程序中的那個(gè)位置,總是先被執(zhí)行。

★幾點(diǎn)說(shuō)明:

(1)一個(gè)源文件由一個(gè)或者多個(gè)函數(shù)組成。

(2)一個(gè)C程序由一個(gè)或者多個(gè)源文件組成。

(3)所有函數(shù)都是平行的,不能嵌套定義。

注意:定義多個(gè)子函數(shù),若都放在所有函數(shù)之前聲明(程序的開(kāi)頭),不分

先后順序。多個(gè)外部變量也一樣,若放在在所有函數(shù)之前聲明(程序的開(kāi)頭),

不分先后順序。因卷現(xiàn)處理聲明,才處理函數(shù)(包含調(diào)用),所以不用分先后。

2、中斷函數(shù)(C51)

Void函數(shù)名(void)interruptn[usingm]

{函數(shù)體}

Interrupt表示該函數(shù)是中斷函數(shù),n表示中斷號(hào),如INTO排第一為0,本

項(xiàng)不能省,它告訴中斷函數(shù)的入口地址,在單片機(jī)中,中斷的入口地址是規(guī)定死

的,匯編語(yǔ)言一般在每個(gè)中斷的入口地址出寫(xiě)一個(gè)無(wú)條件跳轉(zhuǎn)指令,使其跳到中

斷子程序(不放調(diào)用指令,因?yàn)檎{(diào)用指令要壓棧)。C語(yǔ)言就是用這個(gè)告訴中斷入口地

址的,編譯器會(huì)自動(dòng)處理。

m表示工作寄存器組,8051有四個(gè)工作寄存器組。中括號(hào)項(xiàng)可省略。

注意:

①中斷函數(shù)不用調(diào)用,中斷相應(yīng)后直接進(jìn)入;

②中斷函數(shù)沒(méi)有返回值;

③中斷函數(shù)不能傳遞參數(shù);

④中斷函數(shù)中調(diào)用其它函數(shù),要保證使用同一個(gè)寄存器組(就是工作寄存器

區(qū))。

※中斷函數(shù)是一個(gè)特殊的函數(shù),沒(méi)有參數(shù),也沒(méi)有返回值;但是程序中允不

允許使用return呢?答案是允許的,不過(guò)只能用"return;〃,不能用

"return(z);";用在一些需要快速返回的地方,對(duì)應(yīng)的匯編會(huì)有多個(gè)RET語(yǔ)句,

相對(duì)效率會(huì)高一些。

Xusing的用法,using可以修飾任何函數(shù),不過(guò)個(gè)人建議只用來(lái)修飾中斷

函數(shù);簡(jiǎn)單的說(shuō),''using〃會(huì)指定工作寄存器組,由于中斷函數(shù)一般都是比較緊

急的事情,有時(shí)一條語(yǔ)句都會(huì)斤斤計(jì)較,所以使用using切換寄存器組可以省去

一些壓棧的動(dòng)作,由于51只有兩級(jí)中斷,同級(jí)中斷不能被打斷,因此,我們可

以同級(jí)中斷設(shè)成同樣的寄存器組,從某種意義上來(lái)說(shuō),有一組寄存器是多余的。

同時(shí)個(gè)人建議中斷函數(shù)應(yīng)該使用using這個(gè)關(guān)鍵字。

※中斷函數(shù)也可以調(diào)用其它函數(shù),但是一般很少這樣使用,中斷中調(diào)用的函

數(shù)最好不要被中斷外的其它函數(shù)調(diào)用,因?yàn)闀?huì)出現(xiàn)“重復(fù)調(diào)用”的警告,有時(shí)這

種調(diào)用是很致命的。中斷調(diào)用了函數(shù),會(huì)出現(xiàn)一些莫名其妙的問(wèn)題,一些數(shù)據(jù)不

對(duì)。其實(shí)一般是因?yàn)閰R編中使用了絕對(duì)寄存器引起的,有人說(shuō)中斷函數(shù)使用那個(gè)

寄存器組,被中斷調(diào)用的函數(shù)就使用哪個(gè)寄存器組,我認(rèn)為這樣不好:這樣會(huì)

增加額外的消耗,使用using會(huì)增加一下語(yǔ)句:PUSHPSWMOVPSW,#XX(壓

棧保護(hù))。推薦的方法有兩種:

①使用"ttpragmaNOAREGS"禁止使用絕對(duì)寄存器

②使用“和ragmaRB(x)”來(lái)指定本文件的工作寄存器組

★內(nèi)部函數(shù)和外部函數(shù)

根據(jù)函數(shù)能否被其它源文件調(diào)用,將函數(shù)分為內(nèi)部函數(shù)和外部函數(shù)。

內(nèi)部函數(shù)一一靜態(tài)函數(shù),只能被本文件中其它函數(shù)所調(diào)用

定義形式:

static類(lèi)型標(biāo)識(shí)符函數(shù)名(形參表)

如:staticintfun(inta,intb)

內(nèi)部函數(shù),其作用域僅限于定義它的所在文件。此時(shí),在其它的文件中可以

有相同的函數(shù)名,它們相互之間互不干擾。

外部函數(shù)

能被其它文件中的函數(shù)所調(diào)用

定義形式:

[extern]類(lèi)型標(biāo)識(shí)符函數(shù)名(形參表)※定羲畤一般不是用extern,

在調(diào)用的文件中用extern迤行馨明就可以.

如:[extern]intfun(inta,intb)

省略extern,隱含為外部函數(shù),調(diào)用此函數(shù)的文件中也要用extern聲明所用

函數(shù)是外部函數(shù)。

用航巧山(16把文件2.C包含在文件1.C中,在文件1.C中定義的函數(shù)書(shū)寫(xiě)

在包含之后,所以仍然要在2.c中用extern聲明;

七、變量的作用域、存儲(chǔ)類(lèi)型和存儲(chǔ)器類(lèi)型

1、作用域和生存期

C程序的標(biāo)識(shí)符作用域有三種:局部、全局、文件。

1.1局部作用域

前面各個(gè)例子中的變量都是局部作用域,他們都是聲明在函數(shù)內(nèi)部,無(wú)法被

其他函數(shù)的代碼所訪問(wèn)。函數(shù)的形式參數(shù)的作用域也是局部的,它們的作用范圍

僅限于函數(shù)內(nèi)部所用的語(yǔ)句塊。

在符合語(yǔ)句中定義的變量值在符合語(yǔ)句中起作用。

在內(nèi)部定義的變量就是局部變量,不能用extem進(jìn)行聲明。

1.2.全局作用域

對(duì)于具有全局作用域的變量,我們可以在程序的任何位置訪問(wèn)它們。當(dāng)一個(gè)

變量是在程序的開(kāi)頭(所有函數(shù)之前),且在所有函數(shù)的外部聲明(定義),那么

這個(gè)變量就是全局變量。如果不是在程序的開(kāi)頭,而自其它位置,但也在所有函

數(shù)之外定義,這就是外部變量,其之后的函數(shù)能使用,前面的不能使用,前面

的要使用就的在前面聲明,若在函數(shù)內(nèi)聲明,只有本函數(shù)能使用,定義之前的其

它函數(shù)不能使用,在外部聲明,聲明之前還是不能用。若是后邊定義,程序開(kāi)頭

聲明,所有的函數(shù)都能用(就是全部局變量)。因此外部變量和全局變量的含義

還是有區(qū)別的。

在外部定義的才是外部變量,可以用extern聲明為全局變量,或擴(kuò)展作用

范圍。外部變量是以靜態(tài)存儲(chǔ)方式存儲(chǔ)在靜態(tài)存儲(chǔ)區(qū)中,編譯時(shí)只賦一次初值(定

義時(shí)的賦初值),不賦初值自動(dòng)賦0

1.3.文件作用域

在很多C語(yǔ)言書(shū)上,都沒(méi)有說(shuō)明文件作用域,或者只是略微的提到,其實(shí)文

件作用域在較大程序中很有作用(在多文件系統(tǒng)中)。文件作用域是指外部標(biāo)識(shí)符

僅在聲明它的同一個(gè)轉(zhuǎn)換單元內(nèi)的函數(shù)匯總可見(jiàn)。所謂轉(zhuǎn)換單元是指定義這些變

量和函數(shù)的源代碼文件(包括任何通過(guò)#include指令包含的源代碼文件)。如:

staticintnum;

staticvoidadd(int);

main()

(

scanf(%d,&num);

add(num)

printf(%d\n,num);

)

voidadd(num)

(

num++;

)

上面的程序中變量num和函數(shù)add()在聲明是采用了static存儲(chǔ)類(lèi)型修飾

符,這使得它們具有文件作用域,僅在定義它們的文件內(nèi)可見(jiàn)。

由于我們提到的大多數(shù)程序都只有一個(gè)編譯文件組成,所以這種寫(xiě)法沒(méi)有實(shí)

際意義。但是實(shí)際工程上的文件有很多,它們不是由一個(gè)人寫(xiě)成的,由很多人共

同完成,這些文件都是各自編譯的,這難免使得某些人使用了一樣的全局變量名,

那么為了以后程序中各自的變量和函數(shù)不互相干擾,就可以使用static修飾符,

這樣在連接到同一個(gè)程序的其他代碼文件而言就是不可見(jiàn)的。

外部變量的聲明既可以在引用它的函數(shù)的內(nèi)部,也可以在外部。如果變量聲

明在函數(shù)外部,那么同一轉(zhuǎn)換單元內(nèi)的所有函數(shù)都可以使用這個(gè)外部變量。反之,

如果在函數(shù)內(nèi)部,那么只有這一個(gè)函數(shù)可以使用該變量。

前面說(shuō)了文件作用域的問(wèn)題,如果在聲明全局變量時(shí),加上static修飾符,

那么該變量只在當(dāng)前文件內(nèi)可見(jiàn),而extern又可以引用其它文件里的變量。所

以在一個(gè)大型程序中,每個(gè)程序員只是完成其中的一小塊,為了讓自己的變量不

讓其他程序員使用,保持一定的獨(dú)立性,經(jīng)常在全局變量前加static。我們可

以這樣來(lái)說(shuō)明一下:

注意:static聲明的變量一般認(rèn)為是在編譯時(shí)分配存貯存間,其實(shí)應(yīng)該理解

為程序規(guī)定死了該變量的地址,在程序初始化時(shí)(包含復(fù)位)開(kāi)辟出來(lái),在整個(gè)

程序運(yùn)行的過(guò)程能中都不釋放。static聲明的變量一般是在編譯的時(shí)候賦初值

的,即只賦值一次。在程序初始時(shí)已經(jīng)有初值,則以后每次調(diào)用的時(shí)候不再重新

賦值,如果定義時(shí)候不賦值,則編譯的時(shí)候自動(dòng)賦值為0,static變量只初始化

一次,無(wú)論是在循環(huán)語(yǔ)句中,還是在遞歸中,這里的初始化是指定義同時(shí)的初始

化,定義后,再賦初值,不認(rèn)為是初始化。Auto變量在函數(shù)結(jié)束或循環(huán)語(yǔ)句結(jié)

束(循環(huán)語(yǔ)句內(nèi)部變量)空間釋放,在調(diào)用時(shí)重新初始化。

注解:就是說(shuō)在工程文件中,一個(gè)程序有很多文件組成,各文件分開(kāi)各自編

譯,然后連接成一個(gè)執(zhí)行文件(.exe文件),所以用static聲明的變量和函數(shù)只在

各自的文件內(nèi)起作用,不在分開(kāi)編譯的其它文件中起作用,但用include包含進(jìn)

來(lái)的文件是統(tǒng)一編譯的,所以是一個(gè)文件。

*用extern聲明的外部變量只能只同一個(gè)工程文件內(nèi)部分開(kāi)編譯的各文件之

間起作用,不同的工程文件毫不相關(guān)的文件是不起作用的。在同一工程文件中一

個(gè)文件要用另外一個(gè)文件中的全局變量,就的在引用文件中用extern聲明.

在C語(yǔ)言中,是先定義后使用,有先后性和位置性。如:用二田山(16把文

件2.c包含在文件l.c中,在文件Lc中,^include“2.c"inta;因?yàn)?/p>

#include"2.c"在前,inta;在后,所以仍然要在2.c中聲明externinta;

注意:在用extern聲明變量只是擴(kuò)大它的作用范圍,變量聲明時(shí)可省略數(shù)據(jù)類(lèi)

型,但最好不要省。

■全局變量和局部變量同名沖突時(shí),在局部變量的作用范圍內(nèi)全局變量被屏

蔽不起作用,局部變量起作用。

2.寄存器存儲(chǔ)類(lèi)型

使用寄存器存儲(chǔ)類(lèi)型的目的是讓程序員指定某個(gè)局部變量存放在計(jì)算機(jī)的

某個(gè)硬件寄存器里而不是內(nèi)存中,以提高程序的運(yùn)行速度。不過(guò),這只是反映了

程序員的主觀意愿,編譯器可以忽略寄存器存儲(chǔ)類(lèi)型修飾符。

寄存器變量的地址是無(wú)法取得的,因?yàn)榻^為多數(shù)計(jì)算機(jī)的硬件寄存器都不占

用內(nèi)存地址。而且,即使編譯器忽略寄存器類(lèi)型修飾符把變量放在可設(shè)定地址的

內(nèi)存中,我們也無(wú)法取地址的限制仍然存在。

long,double,float不能設(shè)為register型,因?yàn)槌^(guò)寄存器長(zhǎng)度。

3、存儲(chǔ)器類(lèi)型(在C51中,其它系列單片機(jī)不一定適合)

C51中:[存儲(chǔ)種類(lèi)]數(shù)據(jù)類(lèi)型[存儲(chǔ)器類(lèi)型]變量名表

在定義格式中除了數(shù)據(jù)類(lèi)型和變量名表是必要的,其它都是可選項(xiàng)。存儲(chǔ)種

類(lèi)有四種:自動(dòng)(auto),外部(extern),靜態(tài)(static)和寄存器(register

缺省類(lèi)型為自動(dòng)(auto)。

而這里的數(shù)據(jù)類(lèi)型則是和我們?cè)诘谒恼n中學(xué)習(xí)到的名種數(shù)據(jù)類(lèi)型的定義是

一樣的。說(shuō)明了一個(gè)變量的數(shù)據(jù)類(lèi)型后,還可選擇說(shuō)明該變量的存儲(chǔ)器類(lèi)型。存

儲(chǔ)器類(lèi)型的說(shuō)明就是指定該變量在單片機(jī)C語(yǔ)言硬件系統(tǒng)中所使用的存儲(chǔ)區(qū)域,

并在編譯時(shí)準(zhǔn)確的定位。表6—1中是KEILuVision2所能認(rèn)別的存儲(chǔ)器類(lèi)型。

注意的是在AT89c51芯片中RAM只有低128位,位于80H到FFH的高128位則在

52芯片中才有用,并和特殊寄存器地址重疊。特殊寄存器(SFR)的地址表請(qǐng)看

附錄二AT89c51特殊功能寄存器列表

存儲(chǔ)器類(lèi)型說(shuō)明

data直接訪問(wèn)內(nèi)部數(shù)據(jù)存儲(chǔ)器(128字節(jié)),訪問(wèn)速度最快

bdata可位尋址內(nèi)部數(shù)據(jù)存儲(chǔ)器(16字節(jié)),允許位與字節(jié)混合訪問(wèn)

idata間接訪問(wèn)內(nèi)部數(shù)據(jù)存儲(chǔ)器(256字節(jié)),允許訪問(wèn)全部?jī)?nèi)部地址

pdata分頁(yè)訪問(wèn)外部數(shù)據(jù)存儲(chǔ)器(256字節(jié)),用MOVX@Ri指令訪問(wèn)

xdata外部數(shù)據(jù)存儲(chǔ)器(64KB),用MOVX@DPTR指令訪問(wèn)

code程序存儲(chǔ)器(64KB),用MOVC@A+DPTR指令訪問(wèn)

上表是存儲(chǔ)器類(lèi)型的關(guān)鍵字。

關(guān)于存儲(chǔ)器類(lèi)型一般放在變量名前:如autointdatai;但是要定義指針

變量本身的存儲(chǔ)器類(lèi)型時(shí)一般放在最前面或放在*和變量名之間。如:dataint*p;

或int*datap;以上是定義指針本身存在data區(qū),*和data之間沒(méi)有空格;

下面:intdata*datap;本句的意思是指針和指針指向的數(shù)據(jù)都在data區(qū)。

一般C51編譯器不允許在BDATA區(qū)域聲明float和double。

對(duì)于C語(yǔ)言這樣的高級(jí)語(yǔ)言一般編程不考慮存儲(chǔ)器類(lèi)型,就是不管變量存

在哪個(gè)區(qū)域,所以C語(yǔ)言中不涉及存儲(chǔ)器類(lèi)型,但是對(duì)于針對(duì)單片機(jī)的編程需要

知道變量存在什么地方,就是存儲(chǔ)器類(lèi)型。所以C51中有存儲(chǔ)器類(lèi)型。

4、存儲(chǔ)模式(在C51中,其它系列單片機(jī)不一定適合)

存儲(chǔ)模式?jīng)Q定了沒(méi)有明確指定存儲(chǔ)類(lèi)型的變量、函數(shù)參數(shù)等的缺省存儲(chǔ)區(qū)

域,(沒(méi)有說(shuō)明的存儲(chǔ)器類(lèi)型就由存儲(chǔ)模式?jīng)Q定)共三種:

Small模式

所有缺省變量參數(shù)均裝入內(nèi)部RAM(若內(nèi)部空間不夠,才會(huì)存到外部RAM),

優(yōu)點(diǎn)是訪問(wèn)速度快,缺點(diǎn)是空間有限,只適用于小程序。和使用data指定存儲(chǔ)

器類(lèi)型是一樣。

Compact模式

所有跳省變量均位于夕卜部RAM區(qū)的一頁(yè)(256Bytes),具體哪一頁(yè)可由P2口

指定(通過(guò)程序指定),在STARTUP.A51文件中說(shuō)明,和使用pdata指定存儲(chǔ)器類(lèi)型

是一樣,優(yōu)點(diǎn)是空間較Small為寬裕,速度較Small慢,較large要快,是一種

中間狀態(tài)。

large模式

所有缺省變量可放在多達(dá)64KB的外部RAM區(qū),優(yōu)點(diǎn)是空間大,可存變量多,

缺點(diǎn)是速度較慢。和使用Xdata指定存儲(chǔ)器類(lèi)型是一樣。

指定存儲(chǔ)模式:由smallcompact及l(fā)arge說(shuō)明。

每個(gè)編譯器都有自己的默認(rèn)存儲(chǔ)模式,要說(shuō)明本程序的存儲(chǔ)模式使用

“#pragma模式(smallcompact及l(fā)arge)“如#pragmasmall。

例如:voidfunl(void)small{}

提示:small說(shuō)明的函數(shù)內(nèi)部變量全部使用內(nèi)部RAM(若內(nèi)部空間不夠,才會(huì)存

到外部RAM)。關(guān)鍵的經(jīng)常性的耗時(shí)

的地方可以這樣聲明,以提高運(yùn)行速度。

在那個(gè)函數(shù)名后聲明就只在本函數(shù)內(nèi)有作用,之外無(wú)效,還是默認(rèn)的存儲(chǔ)

模式,若本函數(shù)內(nèi)部變量又特別聲明存儲(chǔ)類(lèi)型,那該變量遵循內(nèi)部聲明。

5、絕對(duì)地址訪問(wèn)

C51提供了三種訪問(wèn)絕對(duì)地址的方法:

5.1.絕對(duì)宏:在absacc.h文件中定義的,必須包含進(jìn)來(lái)才能使用。

在程序中,用“#in序ude〈absacc.h>”即可使用其中定義的宏來(lái)訪問(wèn)絕

對(duì)地址,包括:CBYTE(程序區(qū)以字節(jié)形式)、XBYTE(外部XDATA區(qū)以字節(jié)形式)、PBYTE

(外部PDATA區(qū)以字節(jié)形式)、DBYTE(內(nèi)部DATA區(qū)以字節(jié)形式)、PWORD(外部PDATA區(qū)以

字形式)、CWORD(程序區(qū)以字形式)、XWORD(外部XDATA區(qū)以字形式)、DWORD(內(nèi)部DATA

區(qū)以字形式)。

具體使用可看一看absacc.h便知

例如:

rval=CBYTE[0x0002];指向程序存貯器的0002h地址

rval=XWORD[0x0002];指向外RAM的0004h地址

5.2._at_關(guān)鍵字

直接在數(shù)據(jù)定義后加上_at_const(常量地址)即可,但是注意:

(1)絕對(duì)變量不能被初使化;

(2)bit型函數(shù)及變量不能用_at_指定。

例如:

idatastructlinklist_at_0x40;指定list結(jié)構(gòu)從40h開(kāi)始。(idata區(qū))

xdatachartext[25b]_at_0xE000;指定text數(shù)組從0E000H開(kāi)始(xdata區(qū))

提示:如果外部絕對(duì)變量是I/O端口等可自行變化數(shù)據(jù),需要使用

volatile關(guān)鍵字進(jìn)行描述,請(qǐng)參考absacc.h。

一般C語(yǔ)言只定義變量,不給具體的地址。以上都是給變量規(guī)定了絕對(duì)地

址。

5.3.連接定位控制

此法是利用連接控制指令codexdatapdatadatabdata對(duì)“段"地址

進(jìn)行,如要指定某具體變量地址,則很有局限性,不作詳細(xì)討論。

八、函數(shù)遞歸

1.棧

棧是一個(gè)后進(jìn)先出的壓入(push)和彈出(pop)式數(shù)據(jù)結(jié)構(gòu)。

程序員經(jīng)常利用棧這種數(shù)據(jù)結(jié)構(gòu)來(lái)處理那些最適合用進(jìn)先后出邏輯來(lái)描述

的編程問(wèn)題。這里討論的程序中的棧在每個(gè)程序中都是存在的,它不需要程序員

編寫(xiě)代碼去維護(hù),而是由運(yùn)行是系統(tǒng)自動(dòng)處理。所謂的系統(tǒng)自動(dòng)維護(hù),實(shí)際上就

是編譯器所產(chǎn)生的程序代碼。盡管在源代碼中看不到它們,但程序員應(yīng)該對(duì)此有

所了解(轉(zhuǎn)成匯編語(yǔ)言看的見(jiàn))。

當(dāng)一個(gè)函數(shù)(調(diào)用者)調(diào)用另一個(gè)函數(shù)(被調(diào)用者)時(shí),運(yùn)行時(shí)系統(tǒng)將把調(diào)用者

的所有實(shí)參和返回地址壓入到棧中,棧指針將移到合適的位置來(lái)容納這些數(shù)據(jù)。

最后進(jìn)棧的是調(diào)用者的返回地址。當(dāng)被調(diào)用者開(kāi)始執(zhí)行時(shí),系統(tǒng)把被調(diào)用者的自

變量壓入到棧中,并把棧指針再向下移,以保證有足夠的空間存儲(chǔ)被調(diào)用者聲明

的所有自變量。當(dāng)調(diào)用者把實(shí)參壓入棧后,被調(diào)用者就在棧中以自變量的形式建

立了形參。被調(diào)用者內(nèi)部的其他自變量也是存放在棧中的。由于這些進(jìn)棧操作,

棧指針已經(jīng)移動(dòng)所有這些局部變量之下。但是被調(diào)用者記錄了它剛開(kāi)始執(zhí)行時(shí)的

初始棧指針,以他為參考,用正或負(fù)的偏移值來(lái)訪問(wèn)棧中的變量。當(dāng)被調(diào)用者準(zhǔn)

備返回時(shí),系統(tǒng)彈出棧中所有的自變量,這時(shí)棧指針移動(dòng)了被調(diào)用者剛開(kāi)始執(zhí)行

時(shí)的位置。接著被調(diào)用者返回,系統(tǒng)從棧中彈出返回地址,調(diào)用者就可以繼續(xù)執(zhí)

行了。當(dāng)調(diào)用者繼續(xù)執(zhí)行時(shí),系統(tǒng)還將從棧中彈出調(diào)用者的實(shí)參,于是棧指針回

到了調(diào)用發(fā)生前的位置。

注釋?zhuān)壕褪钦f(shuō)主調(diào)函數(shù)的實(shí)參都?jí)喝攵褩?,其它的變量仍然保存在原?nèi)存中,

被調(diào)函數(shù)的變量和形參都進(jìn)棧,在棧中進(jìn)行實(shí)參和形參之間的傳遞。

2、遞歸

遞歸的意思就是函數(shù)自己調(diào)用自己本身,或者在自己函數(shù)調(diào)用的下級(jí)函數(shù)中

調(diào)用自己。

遞歸之所以能實(shí)現(xiàn),是因?yàn)楹瘮?shù)的每個(gè)執(zhí)行過(guò)程都在棧中有自己的形參和局

部變量的拷貝,這些拷貝和函數(shù)的其他執(zhí)行過(guò)程毫不相干。這種機(jī)制是當(dāng)代大多

數(shù)程序設(shè)計(jì)語(yǔ)言實(shí)現(xiàn)子程序結(jié)構(gòu)的基礎(chǔ),是使得遞歸成為可能。

程序員需保證遞歸函數(shù)不會(huì)隨意改變靜態(tài)變量和全局變量的值,以避免在遞

歸下降過(guò)程中的上層函數(shù)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論