- 1、本文档共3页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
二次指针与二维数组
首先我们需要知道,什么是二次指针?下面的代码就定义了一个二次指针变量p2。
char **p2;
还是通过图来说明变量、指针变量、二次指针变量的关系吧。
对于代码:
char c = ‘h’;
char *p1 = c;
char **p2 = p1;
其中c、p1、p2的关系如下图所示:
由于“指针生成”规则(参见教材P176)的存在,我们无法将一个数组传递给一个函数。一个折中的解决办法是传递这个数组的第一个元素的地址,以及数组的各个维数,然后在函数中计算得到要操作的数组元素的地址来操作该数组元素。例如:
void fun(char *p, int n, int m)//从传入指针指向元素开始,将m*n个元素赋值为5
{
for (int i = 0; i m; i++)
for (int j = 0; j n; j++)
*(p + i*n + j) = 5;
}
main()
{
char a[2][3];
fun(a[0][0], 2, 3);
return 0;
}
显然,其中的fun(a[0][0], 2, 3);对数组的操作相当于:
for (int i = 0; i m; i++)
for (int j = 0; j n; j++)
a[i][j] = 5;
在这段代码中,a[i][j]的形式显然更为浅显易懂,也*(p + i*n + j) = 5更为安全(不容易写错)。接下来我们要做的,就是希望实现这样的功能:函数能够以a[i][j]这样的下标处理一个维度变化的二维数组。
通过指针数组,我们可以实现一个一维长度不同的二维数组。当然,这也就意味着该二维数组的元素在内存中的位置不一定连续了。
什么在指针数组呢?看如下代码:
char *pp[7];
这就是一个指针数组,它表示一个长度为7的数组pp,而数组pp的每一个元素的类型,都是char *。也就是说,我们可以将数组pp的元素赋值给另一个指针变量,就像这样:
char *p = pp[3];
而联系到第一部分指针与一位数组之间的关系,我们可以有让数组pp的每个元素都指向不同的指针,比如说这样:
char a[13] = ustc, b[17] = 1958;
char *t = a + 2;
char *p[5] = {a, b, t};//VC 6.0中可以用变量对数组的值进行初始化
执行以上代码之后,p[0]就指向了a数组,p[1]就指向了b数组。而p[2]在这里的含义,也是指向一个数组。我们可以看到,通过指针是无法获知数组的长度的。这也就是为什么在C语言中,字符数组后面会跟一个’\0’来作为结束标致。而在操作其他类型的数组的时候,也是需要显示在代码中指定数组的长度。
printf(“%s\n”, p[2]);
上述代码执行后将输出
tc
因为printf函数在输出字符串的时候,会从传入的参数开始一直向外输出,直到遇到字符串结束标志’\0’。
好。接下来我们要问了,char a[5]中,a的数据类型可以看做是一个字符指针(char *),那么char *pp[7]中,pp又是什么数据类型呢?这里pp的数据类型,就是我们本部分开始时提到的二次指针了。我们可以通过如下代码来声明一个二次指针变量,并且并给它赋值:
char *pp[7];
char **p2p = pp;
而就像我们可以对一个指针变量char *p进行指针运算p[2]或*(p + 2)获取对应的值一样,我们也可以通过如下代码获取一个指针。
char *p1, *p2;
p1 = p2p[3];
p2 = p2p[5];
而对于上述定义的p1、p2,我们还是仍然使用类似p[2]、*(p + 2)的指针运算。于是,我们就能得到类似二维数组的使用方法了。
char a[13] = ustc, b[17] = 1958;
char *p[5] = {a, b};//VC 6.0中可以用变量对数组的值进行初始化
char **p2p = pp;
printf(“%c\n”, pp[0][2]);
上述代码将输出一个字符’t’,以及换行。
好了,到此为止我们完成了对二次指针的分析。在文章动态分配二维数组(或动态分配二维数组)当中,给出了利用二次指针动态分配二维数组的代码样例。以及内存分配的示意图。通过分析该文章的代码和配图,有助于我们更深入的理解二次指针。
而我们也需要在心中牢记的,是二次指针与二维数组名之间的区别。它们是完全不同的两种数据类型。在编程时,都可以通过类似*(*(p + 2) + 3)、p[2][3]的方式来访问一个具体的数组元素。但是他们在计算上述表达式以获取数据时,进
文档评论(0)