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
對高等數學教學的一些思考
主站蜘蛛池模板: 国产精品不卡永久免费| 小13箩利洗澡无码视频免费网站| 成人免费午夜视频| 日韩免费中文字幕| 91精品视频在线播放| 欧美成人区| jizz亚洲高清在线观看| 午夜国产在线观看| 精品国产三级在线观看| 97精品国产高清久久久久蜜芽| 国产一区二区三区在线观看视频| 97精品久久久大香线焦| 国产91视频免费| 国产成人一区免费观看| 久久综合成人| 欧美曰批视频免费播放免费| P尤物久久99国产综合精品| 欧美另类一区| 国产真实乱人视频| 欧美va亚洲va香蕉在线| 久久人妻系列无码一区| a级毛片一区二区免费视频| 欧美在线视频不卡第一页| 狠狠色狠狠色综合久久第一次| 免费一级毛片完整版在线看| 九九免费观看全部免费视频| 亚洲综合日韩精品| 人妻丰满熟妇AV无码区| 亚洲无码高清视频在线观看| 99热最新网址| 国产三区二区| 日本AⅤ精品一区二区三区日| 色综合久久久久8天国| 天天婬欲婬香婬色婬视频播放| 国产美女无遮挡免费视频| 久久亚洲中文字幕精品一区| 无码'专区第一页| 精品三级网站| 毛片大全免费观看| 国产拍在线| 亚洲第一精品福利| 五月婷婷中文字幕| 国产在线98福利播放视频免费| 久久窝窝国产精品午夜看片| 亚洲福利视频一区二区| 青草国产在线视频| 国产精品成人观看视频国产 | 久久这里只有精品66| 亚洲欧美精品在线| 97在线国产视频| 丰满人妻被猛烈进入无码| 欧美性猛交xxxx乱大交极品| 亚洲精品桃花岛av在线| 亚洲大学生视频在线播放| 97在线视频免费观看| 成年人午夜免费视频| 亚洲精品大秀视频| 成人免费网站久久久| 日本成人在线不卡视频| www.91在线播放| 欧美一级黄色影院| 国产在线精品香蕉麻豆| 国产超薄肉色丝袜网站| 亚洲黄色高清| 污网站在线观看视频| 久久精品人妻中文系列| 四虎成人免费毛片| 一本大道无码日韩精品影视| 性色生活片在线观看| 国产毛片网站| a亚洲视频| 91精品国产一区自在线拍| 四虎精品国产AV二区| 国产午夜无码片在线观看网站 | 在线a视频免费观看| 亚洲一区波多野结衣二区三区| 99人体免费视频| 五月天香蕉视频国产亚| 亚洲国产综合精品中文第一| 亚洲精品人成网线在线| 99视频在线免费观看| 97视频精品全国在线观看|