C語言中動態分配二維數組復習過程.doc
C語言中動態分配二維數組在C中動態分配內存的,對于單個變量,字符串,一維數組等,都是很容易的。C中動態分配二維數組的方法,很少有C語言書中描述,我查找了有的C語言書中提到了一個方法假定二維數組的維數為MN分配是可以這樣 int ptrnew int*M;這是先動態分配一個包含有M個指針的數組,即指先分配一個針數組/指針數組的首地址保存在ptr中 forint i0;iM;i ptrinew intN;為指針數組的每個元素賦一個地址,這個地址是指向一維數組的地址,也即是為針元數組的每個元素分配一個數組一個源代碼的例子為int pMatrix new int*row;forint i 0; i row; i pMatrixi new intcolumn; forint j 0; j column; j pMatrixij ij; /簡單的初始化 這樣創建一個數組有個嚴重的問題,就是它的內存不連續,行與行之間的內存不連續,雖然可以用ij下標訪問,無法滿足用指向二維數組元素型別的指針變量來訪問整個數組的要求. 例如不能如下訪問每個二維數組元素 int * p NULL;forp pMatrix0; p pMatrix0column * row; p int fff *pme;而這種訪問方式對于真正的二維數組是完全可以的。出現這種原因就是因為行與行之間的內存不連續造成的。所以,這中方式創建的動態二維數組,不是真正意義上的二維數組。那么什么是真正的二維數組呢C語言中的二維數組在內存組織形式是按行存儲的連續的內存區域。所以,必須保證數組元素是按行存儲的,而且也是最重要的是內存要連續。所以,我寫出了如下的一個方法假定二維數組的元素變量類型是MyType;可以是C語言接受的除void之外的任何類型,因為編譯器不曉得void類型的大小;例如int,float,double等等類型;int row 2;/暫假定行數是2,這個可以在運行時刻決定;int column 3;/暫假定列數是2,這個可以在運行時刻決定; void ptdhead NULL;在后面說明為什么要用void類型 void ptdBody NULL;在后面說明為什么要用void類型 ptdhead void mallocsizeofvoid**row sizeofMyType*row*column; ifptdhead return FALSE; ptdBody ptdhead row ; forint ncount 0; ncount row; ncount ptdheadncount ptdBody ncount * column* sizeofMyType/sizeofvoid*; MyTypeptdheadRealse; ptdheadRealse MyTypeptdhead;/強制轉換為自己程序需要的二維數組元素類型的指針 ptdhead NULL; forint i 0; i row; i forint j 0; j column; j ptdheadRealseij ij;進行簡單的初始化; 這樣的一種方法動態分配的二維數組,內存是連續的,是真正意義的C語言二維數組,滿足所有二維數組訪問的方法,而且內存利用效率高,程序性能好。這樣一種分配方法要理解的是一下一點概念體會,只要是指針都可以帶,不管使直接指針,還是間接指針,都可以用下標,只要使指針就可以了,這個很關鍵;另外就是要明白void*的指針是不能夠用于加減法的,因為系統不曉得一個void型的大小,但是void指針卻是可以進行加減法,進行指針偏移的,因為void*型大小使知道的,所以,編譯器使可以計算出偏移地址的。由于void型,系統不曉得大小,所以,void *p void*malloc3; 編譯器無法通過如 void *q p3;我們知道假設一個整型變量nCont在32位機器上是4個字節,q是指向nCont的指針變量,q的值,也就是nCont的地址是0 x00032ec0,那么q1的值為0 x0 x00032ec01*4,這是C語言中計算指針表達式值的方法。即q1的值為q1*sizeofint;從這里,我們可以理解為什么我們用void作為動態分配內存函數返回的類型,因為,如果返回的是void*類型,我們無法計算地址的偏移量,即無法計算出數組首元素的地址,也就是數組的地址。當然,我們可以不用void,可以用除了void*的任何C中內嵌的簡單類型,不過如果考慮使用起來簡單,方便,那么我覺得還是懸著用void,或者char*;選擇char*類型方便的是,char類型的大小是1,那么元素的個數,即等于地址的偏移量。構建實例一維include stdio.h include stdlib.h int main int n1,i; int *array; puts輸入一維長度; scanfd,n1; arrayint*mallocn1*sizeofint;第一維 fori0;in1;i arrayii1; printfdt,arrayi; freearray;釋放第一維指針 return 0; 二維include stdlib.h include stdio.h int main int n1,n2; int array,i,j; puts輸入一維長度; scanfd,n1; puts輸入二維長度; scanfd,n2; arrayintmallocn1*sizeofint*; 第一維 fori0;in1; i arrayiint*mallocn2* sizeofint;第二維 forj0;jn2;j arrayijij1; printfdt,arrayij; puts; fori0;in1;i freearrayi;釋放第二維指針 freearray;釋放第一維指針 return 0; 三維include stdlib.h include stdio.h int main int n1,n2,n3; int *array; int i,j,k; puts輸入一維長度; scanfd,n1; puts輸入二維長度; scanfd,n2; puts輸入三維長度; scanfd,n3; arrayint*mallocn1*sizeofint;第一維 fori0; in1; i arrayiintmallocn2*sizeofint*; 第二維 forj0;jn2;j arrayijint*mallocn3*sizeofint; 第三維 fork0;kn3;k arrayijkijk1;printfdt,arrayijk; puts; puts; fori0;in1;i forj0;jn2;j freearrayij;釋放第三維指針 fori0;in1;i freearrayi;釋放第二維指針 freearray;釋放第一維指針 return 0; 四維include stdlib.h include stdio.h int main int n1,n2,n3,n4; int array; int i,j,k,m; puts輸入一維長度; scanfd,n1; puts輸入二維長度; scanfd,n2; puts輸入三維長度; scanfd,n3; puts輸入四維長度; scanfd,n4; arrayintmallocn1*sizeofint*;第一維fori0; in1; i arrayiint*mallocn2*sizeofint; 第二維 forj0;jn2;j arrayijintmallocn3*sizeofint*; 第三維 fork0;kn3;k arrayijkint*mallocn4*sizeofint;第四維 form0;mn4;m arrayijkmijkm1; printfdt,arrayijkm; puts; puts; puts; fori0;in1;i forj0;jn2;j fork0;kn3;k freearrayijk;釋放第四維指針 fori0;in1;i forj0;jn2;j freearrayij;釋放第三維指針 fori0;in1;i freearrayi;釋放第二維指針 freearray;釋放第一維指針 return 0; 以三維整型數組arrayn1n2n3為例。 先遵循從外層到里層,逐層申請的原則 最外層指針是array,它是個三維指針,所指向的是array,其為二維指針。所以給array(三維指針) 申請內存應 arrayint*callocn1,sizeofint; 次層指針是array,它是個二維指針,所指向的是array,其為一維指針。所以給array(二維指針)申請內存應 fori0;in1;i arrayiintcallocn2,sizeofint*; 最內層指針是array,它是個一維指針,所指向的是array,其是個整型常量。所以給array(一維指針)申請內存應 fori0;in1;i forj0;jn2;j arrayijint*callocn3,sizeofint; array(整型常量) 當然,你可以把它們整合在一起為 int i,j,k; int n1,n2,n3; int *array; scanfddd,n1,n2,n3; arrayint*callocn1,sizeofint; fori0;in1;i arrayiintcallocn2,sizeofint*; forj0;jn2;j arrayijint*callocn3,sizeofint; fork0;kn3;k arrayijkijk1; 最后不要忘了釋放這些內存,這要遵循釋放的時候從里層往外層,逐層釋放的原則。 分析過程可參考上面的解答,這里不再贅述。只給出代碼吧 fori0;in1;i forj0;jn2;j freearrayij;釋放第一維指針 fori0;in1;i freearrayi;釋放第二維指針 freearray;釋放第三維指針 其余維的如四維創建過程大同小異,這里不再贅述。【學習目標】1、積累文中實詞、虛詞和句式知識。 2能夠運用所學的實詞、虛詞及句式方面的知識,去閱讀淺易的文言文。 3情感目標 體會“兼愛”思想內涵,進一步思考其對現代社會的意義。 教學重難點 多義詞義項的歸納和墨子思想的理解、說理方法。【預習案】1、梳理課文中的文言知識。 11、作者介紹墨子,名翟(注音 ),魯人。墨子是我國 時期著名的 、 、科學家、軍事家、社會活動家。 的創始人,并有 一書傳世。他的基本思想主張是 、 、 、尚同、節用、節葬、非樂、天志、明鬼、非命等項,其核心是 。 墨子精通手工技藝,可與當時的巧匠公輸班(俗稱魯班)相比。他自稱是“鄙人”,被人稱為“布衣之士”。墨子曾做過宋國大夫,自詡說“上無君上之事,下無耕農之難”,是一個同情“農與工肆之人”的士人。墨子曾經從師與儒者,學習孔子之術,稱道堯舜大禹,學習詩、書、春秋等儒家典籍。但后來逐漸對儒家繁瑣禮樂感到厭煩,最終舍掉了儒學,形成自己的墨家學派。墨家是一個宣揚仁政的學派。在代表新型地主階級利益的法家崛起以前,墨家是先秦和儒家相對立的最大一個學派,并列“顯學”。墨子的學說思想主要包括以下幾點兼愛非攻。所謂“兼愛”是要求君臣、父子、兄弟都要不分親疏遠近地互相愛,“愛人若愛其身”,并認為社會上出現強執弱、富侮貧、貴傲賤的現象,是因為天下人不相愛所致。天志明鬼。宜揚天命鬼神的迷信思想是墨家的大特點。尚同尚賢。尚同是要求百姓上同于天子。墨子認為,國君是國中賢者,百姓應以君上之是非為是非。他還認為上面了解下情也很重要,因為只有這樣才能賞善罰暴。尚賢是要求君上任用賢者而廢抑不肖者。節用。節用是墨家非常強調的一種觀點,他們抨擊君主、貴族的奢侈浪費,尤其反對儒家看重的久喪厚葬之欲。認為君主、貴族都應像古代大禹一樣,過著極為儉樸的生活。兼愛導學案2、讀準字音并注音家之與家之相篡 ( ) 不憚 ( ) 富必侮貧 ( ) 牂羊之裘 ( )可使毋起者( ) 練帛之冠( )惡人者( ) 蹈火而死者( )朝有黧黑之色( )3、 找出通假字并解釋既以非之( ) 天下之難物于故也 ( ) 昔者楚靈王好士細要 ( ) 教馴其臣 ( ) 破碎亂行 ( ) 貴必敖賤( )辯其故也( )茍君說之( )4、 找出下列句子中的古今異義詞并解釋以不相愛生 夫愛人者者,人亦從而愛之 破碎亂行 5、詞類活用強必執弱,富必侮貧,貴必敖賤,詐必欺愚 利人者,人亦從而利之 脅息然后帶 越王親自鼓其士而進之 越王擊金而退之 是故諸侯不相愛則必野戰以兼相愛、交相利之法易之6 【探究案】1、翻譯下列句子,指出句式特點然則察此害亦何用生哉