999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

C語言教學中的幾個常見問題

2009-06-20 08:45:46
計算機教育 2009年10期
關鍵詞:教學

黃 宇

文章編號:1672-5913(2009)10-0096-03

摘要:作者在多年的C語言教學過程中,對學生中經常遇到的問題進行了一些總結。本文就學生中經常遇到的5個帶有普遍性的問題,通過C程序示例進行了分析,指出了出現錯誤的原因,給出了改正的方法。

關鍵詞:C語言;程序設計;教學

中圖分類號:G642

文獻標識碼:B

1引言

隨著計算機應用技術的普及,大學中很多專業都開設了計算機編程課程。在非計算機專業中,大多以教授C語言編程為主。本人長期從事對非計算機專業學生的C語言編程課的教學工作,在長期的教學實踐中,發現了一些學生在編程中經常會遇到的問題。在此,就幾個典型的常見問題,展開一些探討。這些問題的解決,對于更深入的理解C語言,將起到一定的幫助作用。

2幾個常見問題

2.1無符號數運算問題

大家知道,在C語言中,不同類型的數據一起運算時是按照隱式類型轉換的規則進行的,也就是將兩個類型不一致的數據首先轉換成一致的,然后再進行運算。其轉換的基本原則有兩點,一是小數據類型向大數據類型轉換,二是有符號類型向無符號類型轉換。比如,當一個float類型數據和一個double類型的數據進行運算時,就是首先將float類型的數據轉換成double類型的數據,然后再進行運算;而當一個int類型的數據和一個unsigned int類型的數據進行運算時,則首先把int類型的數據轉換為unsigned int類型的數據,然后再進行運算。對于第一種情況,一般不會遇到問題,但是對于第二種情況,初學者往往注意不到這種轉換中可能會隱含的問題,導致程序運行結果出現與自己設想不一致的情況。

下面給一個具體的例子:

#include

int main()

{

unsigned int n = 1;

int m = -1;

if (m < n)printf("m < n");

else printf("m >= n");

return 1;

}

在這段程序中,n = 1,m = -1,顯然應該是m= n。初學者遇到這種情況,往往百思不得其解,最終往往會歸咎于是不是系統出現了問題。

為什么會出現這種情況呢?這是因為n是unsigned int類型的,而m是int類型的,在m和n進行比較運算時,由于二者的類型不一致,首先要進行類型轉換。按照C語言隱式類型轉換規則,有符號類型的int轉換為無符號類型的unsigned int。這樣,m(=-1)中的符號位被當成了“數字”進行轉換,有符號的-1成為了無符號的4294967295(四字節的情況下。如果是二字節的則是65535)。而4294967295當然要大于1了,所以就有了以上的運行結果。

不單單是在比較運算中會出現這種情況,在其他運算中,比如加減乘除等,也一樣會有類似的情況出現。所以,當有符號和無符號的數據混合運算時,一定要注意這個問題,除非特殊情況,應盡量避免有符號和無符號的混合運算。

2.2計算數組的長度

在C語言中,操作符sizeof( )可以計算一個類型或者一個變量所占用的字節數。比如:sizeof(int)或者sizeof(x)(假定x是int類型的),當一個整數占用4個字節時,就可以得到4的結果。

再比如,一個整數數組:int a[8];

可以通過sizeof(a)/sizeof(int)得到數組a的元素個數。因為sizeof(a)得到的是a數組占用的總字節數,除以每個int所占用的字節數sizeof(int),就是該數組的長度。

由于很多情況下需要知道一個數組的長度,比如在對一個數組排序時,因此,有些初學者就利用sizeof在函數中計算數組的長度。舉例如下:

mysort(int a[])

{

int len;

len = sizeof(a)/sizeof(int); //得到數組a的長度

//以下對a進行排序

}

但是往往會發現,這樣的結果并不正確,len經常得到的是1(假定是32位系統,一個整數占4個字節)。這又是為什么呢?

這個問題,與C語言中數組參數的傳遞方式有關。在C語言中,當一個數組當作參數傳遞時,數組被轉換為指針。在上面的例子中,無論你在函數定義是mysort(int a[])還是mysort(int a[100]),在函數內部,a均被轉換成int *a類型,與定義mysort(int *a)是一致的。因此,在函數內部,當計算sizeof(a)時,實際上計算的是sizeof(int *)。因此,當作為形參時,無論你的mysort(int a[N])定義中,有無N,或者N是多大,sizeof(a)得到的都是4(假定在32位系統中)。

因此,在一個函數內部,是無法得到一個數組參數的長度的,其長度只能通過參數進行傳遞。所以,上述的排序函數應該定義成如下的形式:

mysort(int a[], int len)

{

//以下對a進行排序

}

2.3常量字符串問題

在學習完字符串的操作之后,同學們往往會編寫一些簡單的練習程序,這時經常會遇到一些“莫名其妙”的情況,使得程序不能正確運行。

比如下面這個程序,非常簡單,就是把字符串"abcde"中的'a'換成'A':

int main()

{

char *p = "abcde";

p[0] = 'A';

return 1;

}

程序編譯沒有問題,一運行就出現錯誤。這是為什么呢?

在這個程序中,字符串"abcde"是一個常量,指針p指向了這個常量。而“常量”顧名思義是不能修改的,而該程序試圖通過指針p修改一個常量字符串,導致運行錯誤。

把程序修改如下,就沒有問題了:

int main()

{

char p[] = "abcde";

p[0] = 'A';

return 1;

}

這是因為p是一個字符數組,并通過初始化的方法對該數組進行了賦值。雖然字符數組p也是一個字符串,但是p不是常量,可以修改,因此就不會出現運行錯誤了。

同樣,如果是這樣,也不會出現錯誤:

int main()

{

char p[] = "abcde";

char *q = p;

q[0] = 'A';

return 1;

}

因為在這里q指向是字符數組p,而不是字符串常量"abcde"。

2.4文件結束判斷問題

在C語言中,函數feof( )可以判斷文件結束,但是初學者在使用feof( )時,經常會犯錯誤。請看下面這個例子,該程序實現將文件a.txt拷貝到b.txt的功能,通過feof判斷a.txt是否結束,在結束之前,每次讀一個字符,并寫到b.txt中。程序如下:

int main()

{

FILE *pi, *po;

char c;

pi = fopen("a.txt", "rb");

po = fopen("b.txt", "wb");

while (!feof(pi))

{

c = fgetc(pi);

fputc(c, po);

}

fclose(pi);

fclose(po);

return 1;

}

程序很簡單,看似沒有什么錯誤。但是這里卻隱含了一個初學者經常會犯的錯誤。運行一下該程序,就會發現在b.txt的最后,會“奇怪”地多出了一個字符。

問題出現在什么地方呢?主要是對feof的認識有誤造成的。

仔細看一下feof的功能,會發現當讀完了最后一個字符后,feof還是保持“假”,只有當讀完了最后一個字符再試圖讀文件時,feof才為真。也就是說,feof判斷是否到達文件尾比實際情況要“晚”一步。按照上面的程序,當fgetc從a.txt中讀完了最后一個字符后,feof并不馬上為真,還要循環再讀一次a.txt,并通過fputc函數將這次得到的結果(在字符c中)寫入到b.txt中,造成了b.txt中多了一個字符。而這時,feof才變成了真,程序退出循環結束。

明白了這一點,程序按照如下方式增加一個if語句就可以了:

int main()

{

FILE *pi, *po;

char c;

pi = fopen("a.txt", "rb");

po = fopen("b.txt", "wb");

while (!feof(pi))

{

c = fgetc(pi);

if (feof(pi)) break;//新增加的一個判斷

fputc(c, po);

}

fclose(pi);

fclose(po);

return 1;

}

2.5結構體的大小問題

通過sizeof可以計算一個結構體占用的字節數,比如下面一段程序是計算結構體S所占的字節數。程序的輸出應該是多少呢?

int main()

{

struct S

{

char a;

int n;

};

int n;

n = sizeof(struct S);

printf("%d", n);

return 1;

}

char占1個字節,int占4個字節,初學者往往會回答S長度是5。但是一運行程序,發現輸出的結果卻是8。見到這樣的結果,初學者往往又不得其解,不知為什么會這樣。

這里涉及的就是所謂的地址對齊的問題,編譯程序,在默認的情況下,會按照一定的原則,比如讓寬度為2的基本數據類型(short等)都位于能被2整除的地址上,讓寬度為4的基本數據類型(int等)都位于能被4整除的地址上等等,這樣做的原因是為了加快程序的運行速度。也就是說,對結構體進行了一定的填充,使得它的成員的地址滿足一定的要求。關于如何對齊問題涉及的內容比較多,這里就不詳細解釋了,有興趣的讀者可以參考有關計算機組成原理方面的書。

3結束語

我們在C語言教學過程中,經常會遇到學生提出的各種問題,有些問題是個別性的,有些問題則是普遍性的,從學生遇到的最多的問題中,整理出了這5個具有普遍性的問題,希望對有關C語言的教與學能起到一定的幫助。

參考文獻:

[1] 薛勝軍. 計算機組成原理[M]. 武漢:華中科技大學出版社,2000.

[2] 王誠, 劉衛東,宋佳興. 計算機組成與設計[M]. 3版. 北京:清華大學出版社,2008.

[3] 嚴蔚敏,吳偉民.數據結構(C語言版)[M].北京:清華大學出版社,2006.

[4] 譚浩強. C程序設計[M]. 北京:清華大學出版社,2006.

[5] David J. Kruglinski. Visual. C++技術內幕[M]. 4版. 北京:清華大學出版社,2001.

[6] H.M.Deitel,P.J.Deitel. C程序設計教程[M]. 北京:機械工業出版社,2001.

猜你喜歡
教學
微課讓高中數學教學更高效
甘肅教育(2020年14期)2020-09-11 07:57:50
「微寫作」教學實踐的思考
“以讀促寫”在初中寫作教學中的應用
如何讓高中生物教學變得生動有趣
甘肅教育(2020年12期)2020-04-13 06:25:34
談高中音樂欣賞教學中的“聽、看、想、說、動”
“自我診斷表”在高中數學教學中的應用
東方教育(2017年19期)2017-12-05 15:14:48
對外漢語教學中“想”和“要”的比較
唐山文學(2016年2期)2017-01-15 14:03:59
對識譜教學的認識與思考
《可以預約的雪》教學探索與思考
中學語文(2015年6期)2015-03-01 03:51:42
對高等數學教學的一些思考
主站蜘蛛池模板: 日韩欧美中文| 中文毛片无遮挡播放免费| 国产99精品视频| 欧美性精品不卡在线观看| 欧美一道本| 欧美成人影院亚洲综合图| 无码丝袜人妻| 另类综合视频| 国产人妖视频一区在线观看| 午夜国产精品视频| 国产福利影院在线观看| 无码一区中文字幕| 午夜色综合| 亚洲Av综合日韩精品久久久| 国产99免费视频| 亚洲成a人在线播放www| 国产一区二区免费播放| 婷婷综合在线观看丁香| 成人精品免费视频| 成人免费一级片| 国产乱子伦一区二区=| 国产精品99久久久| 亚洲第一成年人网站| 天天干伊人| 一区二区理伦视频| 欧类av怡春院| 亚洲最大情网站在线观看| 97se亚洲| 日本a级免费| 国产一级毛片在线| 日韩高清成人| a毛片在线免费观看| 国产97视频在线| 欧美一级特黄aaaaaa在线看片| 色天天综合| 91在线一9|永久视频在线| 99伊人精品| 日韩不卡高清视频| 亚洲人成网站色7777| 久久免费视频播放| 国产免费观看av大片的网站| 98精品全国免费观看视频| 久操中文在线| 无码专区国产精品一区| 亚洲第一区欧美国产综合| a天堂视频| 亚洲国产日韩欧美在线| 无码中文字幕乱码免费2| 国产91无码福利在线| 国产欧美在线观看视频| a级毛片免费在线观看| 中文国产成人久久精品小说| 丰满人妻一区二区三区视频| 在线国产综合一区二区三区| 亚洲精选无码久久久| 久久99热66这里只有精品一| 国产成人麻豆精品| 欧美在线中文字幕| 欧美一区二区三区欧美日韩亚洲 | 国产三级视频网站| 欧美啪啪视频免码| 国内丰满少妇猛烈精品播| 国产99精品视频| 中文字幕在线永久在线视频2020| 国产精品久久久久鬼色| 999精品色在线观看| 欧美一级爱操视频| 欧美在线导航| 国内精品视频在线| 亚洲中文字幕精品| 国产视频自拍一区| 国产欧美日韩va另类在线播放| 久久人搡人人玩人妻精品| 污污网站在线观看| 深夜福利视频一区二区| 成人国内精品久久久久影院| 欧美亚洲国产精品第一页| 色综合国产| 这里只有精品在线播放| 在线高清亚洲精品二区| 99久久精彩视频| 一本一道波多野结衣一区二区 |