c语言字符串二维数组的动态分配应,C语言中动态分配二维数组复习过程.doc

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、翻译下列句子,指出句式特点然则察此害亦何用生哉

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值