相同的生成代码 buf[2]='x'; | pbuf[2]='x' ->不同的生成代码 上面这两个程序有区别吗? 答案是: (1"/> 相同的生成代码"/>

CC 指针和数组的异同

2017-11-30 3页 doc 14KB 12阅读

用户头像

is_594886

暂无简介

举报
CC 指针和数组的异同CC 指针和数组的异同 这个是C/C++中最容易混淆,最容易头晕的一个话题。 我们先从一个简单的例子看起(一维数组) void f(char* buf); | void f(char* buf); int main(...){ | int main(...){ char buf="abc"; | char* pbuf="abc"; f(buf); | f(pbuf); ->相同的生成代码 buf[2]='x'; | pbuf[2]='x' ->不同的生成代码 上面这两个程序有区别吗? 答案是: (1)对于一维数...
CC  指针和数组的异同
CC 指针和数组的异同 这个是C/C++中最容易混淆,最容易头晕的一个话题。 我们先从一个简单的例子看起(一维数组) void f(char* buf); | void f(char* buf); int main(...){ | int main(...){ char buf="abc"; | char* pbuf="abc"; f(buf); | f(pbuf); ->相同的生成代码 buf[2]='x'; | pbuf[2]='x' ->不同的生成代码 上面这两个程序有区别吗? 是: (1)对于一维数组的处理,传递参数的地时候统统作为指针来看待,也就是f(buf)的调用被编译器等效成了 char* pbuf="abc",f(pbuf)这样的调用。 (2)对于寻址和赋值: buf[2] 是编译器计算(buf的地址+2),放入x pbuf[2]是编译器计算pbuf的地址,得到pbuf中的值,再以这个值为基地址,+2,放入x 也就是说,pbuf的赋值语句是2次跳转的,效率比不上buf[2]这样的语句。 -------------------------------------------------------------- 考虑复杂一点的情况,多维数组怎么办? int main(...){ int buf[2][3];//这个buf数组在内存中仍然是1维连续内存! 那么buf[10][10]=6;这样的语句是如何计算的呢? buf的结构被看成一个矩阵被拉直为行向量的表示,10行10列,buf[1][2]的地址就是: 第二行的起始(1*10)+第3个元素的偏移(2),等效于((int*)(buf))[12]。 这样说很清楚了吧,如果我们要把buf传递给一个函数作为参数,怎么办呢? 只需要保证编译器能看出,这个被拉直的,2维数组,每一行多少个元素: void f(int buf[][10]){ buf[1][2]=6;//编译器能够通过f的形式参数声明来决定buf[1][2]是从buf偏移多少。 ... 上面这个声明和void f(int buf[10][10])甚至void f(int buf[20][10])是等效的。因为我们只需要知道每行包括多少个元素,至于有多少行,(数组多大),不是编译器控制的,是程序元的责任。 -------------------------------------------------------------- 如果f的声明是f(int buf[][])呢? 它等效于f(int *buf[])或者f(int ** ppbuf)这样的声明,传入参数必须是一个真正的2维数组。像下面这样 int** buf=new int*[10]; for(int i=0;i<10;++i)buf[i]=new int[10]; f(buf); buf数组本身必须是一个指针数组,buf[1][2]这样的计算是: (a)计算buf[1]的值 (b)这个值是一个地址,指向一个数组,取这个数组的偏移量2中的值。 如果我混用f(int buf[][10])和f(int buf[][]),我就会得到一个编译警告或者错误: void f2(int ppi[][2]){} void f3(int *ppi[2]){} int p2[3][2]={ {1,2},{3,4}, }; f2(p2);正确的用法 f3(p2);警告:传递参数 1 (属于 ‘f3’)时在不兼容的指针类型间转换。 由于f3的生成代码是2次跳转,因此传入p2作为参数的时候,会把一个真正的数组元素的值作为地址看待,再次计算一个内存地址偏移量中的值,可能导致程序崩溃。 参考文献:《C专家编程》
/
本文档为【CC 指针和数组的异同】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索