国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

國(guó)內(nèi)C語(yǔ)言教材中幾種值得商榷的說(shuō)法

2021-08-14 07:34巨同升
科學(xué)咨詢 2021年29期
關(guān)鍵詞:二進(jìn)制C語(yǔ)言整數(shù)

巨同升

(山東理工大學(xué) 山東淄博 255049)

“C語(yǔ)言程序設(shè)計(jì)”這門課程在國(guó)內(nèi)高校普遍開(kāi)設(shè)已有近三十年,課程的建設(shè)和研究取得了長(zhǎng)足的進(jìn)步,涌現(xiàn)出了數(shù)量眾多、各具特色的C語(yǔ)言教材。盡管如此,在許多C語(yǔ)言教材中還或多或少地存在著一些不準(zhǔn)確甚至是值得商榷的說(shuō)法。下面將對(duì)國(guó)內(nèi)教材中常見(jiàn)的幾種說(shuō)法進(jìn)行辨析,并期望與廣大同行商榷。

一、關(guān)于C語(yǔ)言的輸入輸出語(yǔ)句

有的教材中說(shuō):“C語(yǔ)言中沒(méi)有輸入輸出語(yǔ)句,只有輸入輸出函數(shù)。”果真如此嗎?

完整的C語(yǔ)言是由語(yǔ)言標(biāo)準(zhǔn)和標(biāo)準(zhǔn)庫(kù)兩部分組成的[1]。語(yǔ)言標(biāo)準(zhǔn)相當(dāng)于C語(yǔ)言的內(nèi)核,標(biāo)準(zhǔn)庫(kù)(主體是庫(kù)函數(shù))相當(dāng)于C語(yǔ)言的擴(kuò)展部分。這種設(shè)計(jì)極大地增強(qiáng)了C語(yǔ)言實(shí)現(xiàn)的靈活性和程序的可移植性,因?yàn)榭梢愿鶕?jù)某類計(jì)算機(jī)的硬件特點(diǎn)而單獨(dú)修改C語(yǔ)言標(biāo)準(zhǔn)庫(kù)部分的實(shí)現(xiàn)。

在C語(yǔ)言的語(yǔ)言標(biāo)準(zhǔn)部分的確沒(méi)有輸入輸出語(yǔ)句,也沒(méi)有輸入輸出函數(shù)。不過(guò)在C語(yǔ)言的標(biāo)準(zhǔn)庫(kù)部分,明確地定義了各種輸入輸出函數(shù),從而可以在C語(yǔ)言程序中以語(yǔ)句的形式來(lái)調(diào)用這些輸入輸出函數(shù)。

既然這種函數(shù)調(diào)用語(yǔ)句可以實(shí)現(xiàn)輸入輸出的功能,將它們稱為“輸入輸出語(yǔ)句”(而不必稱為輸入輸出函數(shù)調(diào)用語(yǔ)句)也是順理成章的。

因此正確的說(shuō)法是:在C語(yǔ)言的語(yǔ)言標(biāo)準(zhǔn)部分沒(méi)有輸入輸出語(yǔ)句,但在C語(yǔ)言的標(biāo)準(zhǔn)庫(kù)部分有輸入輸出函數(shù),從而在完整的C語(yǔ)言中有輸入輸出語(yǔ)句。

二、關(guān)于八進(jìn)制和十六進(jìn)制負(fù)整數(shù)

有的教材中說(shuō):“在C語(yǔ)言中,八進(jìn)制和十六進(jìn)制整數(shù)只有正數(shù),沒(méi)有負(fù)數(shù)?!边@種說(shuō)法是有問(wèn)題的。實(shí)際上,在C語(yǔ)言中,八進(jìn)制和十六進(jìn)制整數(shù)既可以使用正數(shù),也可以使用負(fù)數(shù)。下面的程序就是一個(gè)很好的證據(jù)。

#include <stdio.h>

int main(void)

{int a,b,c,d;

a=0127;

b=-0127;

c=0x1af;

d=-0x1af;

printf("a=%d,b=%d,c=%d,d=%d ",a,b,c,d);

printf("a=%o,b=%o,c=%x,d=%x ",a,b,c,d);

return 0;

}

該程序的運(yùn)行結(jié)果如下圖所示。

從該程序的運(yùn)行結(jié)果可以發(fā)現(xiàn),程序中可以使用八進(jìn)制和十六進(jìn)制的負(fù)整數(shù),但是不能以負(fù)數(shù)形式輸出八進(jìn)制和十六進(jìn)制的整數(shù)。

因此正確的說(shuō)法是:在C語(yǔ)言中,以八進(jìn)制和十六進(jìn)制形式輸出整數(shù)時(shí),只能輸出正數(shù)和0,不能輸出負(fù)數(shù)。

三、關(guān)于整數(shù)在內(nèi)存中的表示形式

有的教材中說(shuō):“在C語(yǔ)言中,整數(shù)是以二進(jìn)制補(bǔ)碼的形式在內(nèi)存中存儲(chǔ)的。”其實(shí),這種說(shuō)法是不準(zhǔn)確的。在C語(yǔ)言中,有符號(hào)整數(shù)的確是以二進(jìn)制補(bǔ)碼形式在內(nèi)存中存儲(chǔ)的,其最高位為符號(hào)位,用以表示該整數(shù)的正負(fù)。但是對(duì)于無(wú)符號(hào)整數(shù)來(lái)說(shuō),由于不存在負(fù)數(shù),并不需要表示正負(fù)的符號(hào)位,因而它的每一位都是數(shù)值位,這種表示形式應(yīng)稱為“無(wú)符號(hào)二進(jìn)制形式”。

因此正確的說(shuō)法是:在C語(yǔ)言中,有符號(hào)整數(shù)是以二進(jìn)制補(bǔ)碼形式在內(nèi)存中存儲(chǔ)的,無(wú)符號(hào)整數(shù)是以無(wú)符號(hào)二進(jìn)制形式在內(nèi)存中存儲(chǔ)的。

四、關(guān)于后自增(減)運(yùn)算符的優(yōu)先級(jí)

國(guó)內(nèi)絕大多數(shù)的C語(yǔ)言教材都說(shuō):“在C語(yǔ)言中,后自增(減)運(yùn)算符的優(yōu)先級(jí)與前自增(減)運(yùn)算符相同?!逼鋵?shí),這種說(shuō)法是有問(wèn)題的。

在傳統(tǒng)C語(yǔ)言(即C89標(biāo)準(zhǔn)之前的C語(yǔ)言)規(guī)范中,后自增(減)的優(yōu)先級(jí)的確是與前自增(減)相同的,都是2級(jí)。但是,從C89標(biāo)準(zhǔn)開(kāi)始,已經(jīng)將后自增(減)的優(yōu)先級(jí)調(diào)整為1級(jí),而前自增(減)的優(yōu)先級(jí)依然為2級(jí),從而使得后自增(減)的優(yōu)先級(jí)高于前自增(減)[1-2]。遺憾的是,這種調(diào)整并未在國(guó)內(nèi)的絕大多數(shù)C語(yǔ)言教材中反映出來(lái)。

五、關(guān)于scanf函數(shù)中的第二個(gè)參數(shù)

為什么scanf函數(shù)中的第二個(gè)參數(shù)只能是變量的地址,而不能是變量名本身呢?大多數(shù)教材中并未給出解釋,而有的教材則認(rèn)為是為了提高編程的靈活性,使得scanf函數(shù)中的第二個(gè)參數(shù)既可以是若干個(gè)變量的地址,也可以是指向某些內(nèi)存單元的指針。其實(shí),真正的原因在于C語(yǔ)言中函數(shù)參數(shù)的單向傳遞規(guī)則,即只能將實(shí)參的值傳遞給對(duì)應(yīng)的形參,而不能將形參的值傳遞給對(duì)應(yīng)的實(shí)參[3]。

在程序中調(diào)用scanf函數(shù)完成數(shù)據(jù)的輸入,是通過(guò)執(zhí)行該函數(shù)的函數(shù)體語(yǔ)句實(shí)現(xiàn)的。不過(guò)在執(zhí)行該函數(shù)的函數(shù)體時(shí)所輸入的數(shù)據(jù),首先存放于函數(shù)體中定義的局部變量中。調(diào)用scanf函數(shù)時(shí),若直接以待存儲(chǔ)數(shù)據(jù)的變量名作為實(shí)參,則函數(shù)體中局部變量(包括形參)的值并不能直接傳遞給實(shí)參;若改用待存儲(chǔ)數(shù)據(jù)的變量的地址作為實(shí)參,就可以通過(guò)跨函數(shù)間接引用的方式,將函數(shù)體中局部變量的值傳遞給主調(diào)函數(shù)中的變量了。

六、關(guān)于malloc函數(shù)的返回值類型

在大多數(shù)教材中,在調(diào)用malloc函數(shù)時(shí),總是要對(duì)其返回值進(jìn)行強(qiáng)制類型轉(zhuǎn)換。例如:

int*p;

p=(int*)malloc(sizeof(int));

這些教材中認(rèn)為這種強(qiáng)制類型轉(zhuǎn)換是必不可少的,其實(shí)并非如此。在傳統(tǒng)C語(yǔ)言(即C89標(biāo)準(zhǔn)之前的C語(yǔ)言)規(guī)范中,malloc函數(shù)的返回值為char*類型,由于這種類型與其他的指針類型都不是賦值兼容的,因此不能直接進(jìn)行賦值運(yùn)算,而必須先進(jìn)行強(qiáng)制類型轉(zhuǎn)換,再進(jìn)行賦值運(yùn)算[2]。

不過(guò),從C89標(biāo)準(zhǔn)開(kāi)始,已經(jīng)將malloc函數(shù)的返回值類型改為void*類型。void*是C89標(biāo)準(zhǔn)中定義的通用指針類型,通用指針與所有其他類型的指針都是賦值兼容的,即可以不經(jīng)過(guò)強(qiáng)制類型轉(zhuǎn)換而直接相互賦值[2]。例如:

int*p;

p=malloc(sizeof(int));

此外,calloc函數(shù)和realloc函數(shù)的用法與malloc函數(shù)是類似的。

七、關(guān)于文本打開(kāi)方式與二進(jìn)制打開(kāi)方式

C語(yǔ)言中的各類文件打開(kāi)方式均包括兩種,如讀方式包括“r”和“rb”,寫方式包括“w”和“wb”。在大多數(shù)C語(yǔ)言教材中,將文件的這兩種打開(kāi)方式稱為“打開(kāi)文本文件”與“打開(kāi)二進(jìn)制文件”。

這種叫法很容易使人誤解為用第一種打開(kāi)方式創(chuàng)建的就是文本文件,用第二種打開(kāi)方式創(chuàng)建的就是二進(jìn)制文件。其實(shí)一個(gè)新創(chuàng)建的文件是文本文件還是二進(jìn)制文件的決定因素,是向文件中寫入數(shù)據(jù)的函數(shù),而不是文件的打開(kāi)方式[3]。一般而言,使用fprintf、fputc和fputs等函數(shù)創(chuàng)建的文件,是文本文件;而使用fwrite函數(shù)創(chuàng)建的文件,則是二進(jìn)制文件。相應(yīng)地,fscanf、fgetc和fgets等函數(shù)用于讀取文本文件;而fread函數(shù)則用于讀取二進(jìn)制文件。

既然如此,為什么還要將文件的打開(kāi)方式區(qū)分為這兩種方式呢?其實(shí),這源于兩類操作系統(tǒng)對(duì)于回車換行的不同處理方式。在第一類操作系統(tǒng)(如UNIX和Linux)的文本編輯軟件中,采用與C語(yǔ)言相同的處理方式,只需用一個(gè)換行符,即可實(shí)現(xiàn)回車換行。而在第二類操作系統(tǒng)(如DOS和Windows)的文本編輯軟件中,則采用與C語(yǔ)言不同的處理方式,需要用一個(gè)回車符和一個(gè)換行符的組合,方可實(shí)現(xiàn)回車換行。

因此,在第二類操作系統(tǒng)中,當(dāng)用第一種方式打開(kāi)文件并對(duì)文件進(jìn)行寫入操作時(shí),將會(huì)把每一個(gè)換行符替換為一個(gè)回車符和一個(gè)換行符的組合;當(dāng)用第一種方式打開(kāi)文件并對(duì)文件進(jìn)行讀出操作時(shí),將會(huì)進(jìn)行相反的替換。然而,當(dāng)用第二種方式打開(kāi)文件并對(duì)文件進(jìn)行寫入和讀出操作時(shí),將不會(huì)對(duì)字符進(jìn)行任何替換。

而在第一類操作系統(tǒng)中,第一種打開(kāi)方式與第二種打開(kāi)方式是沒(méi)有區(qū)別的。不論用哪種方式打開(kāi)文件,在對(duì)文件進(jìn)行寫入和讀出操作時(shí),都不會(huì)對(duì)字符進(jìn)行任何替換??梢?jiàn),這兩種打開(kāi)方式均是既可以打開(kāi)文本文件,也可以打開(kāi)二進(jìn)制文件,區(qū)別在于對(duì)回車換行的處理方式不同。因此,正確叫法應(yīng)該是“文本打開(kāi)方式”與“二進(jìn)制打開(kāi)方式”[3]。

猜你喜歡
二進(jìn)制C語(yǔ)言整數(shù)
用二進(jìn)制解一道高中數(shù)學(xué)聯(lián)賽數(shù)論題
有用的二進(jìn)制
基于Visual Studio Code的C語(yǔ)言程序設(shè)計(jì)實(shí)踐教學(xué)探索
有趣的進(jìn)度
51單片機(jī)C語(yǔ)言入門方法
基于C語(yǔ)言的計(jì)算機(jī)軟件編程
一類整數(shù)遞推數(shù)列的周期性
高職高專院校C語(yǔ)言程序設(shè)計(jì)教學(xué)改革探索
答案
求整數(shù)解的策略