二级指针与二维数组
2015-11-01 11:17
169 查看
先看一道笔试题:
#include<stdio.h>
void func1(int **a)
{
printf("a[0][1]=%d\n",a[0][0]);//
printf("a[0][1]=%d\n",a[0][1]);//
printf("a[0][1]=%d\n",a[1][0]);//
printf("a[0][1]=%d\n",a[1][1]);//
}
void func2(int *a)
{
printf("a[0][1]=%d\n",a[0]);//
printf("a[0][1]=%d\n",a[1]);//
printf("a[0][1]=%d\n",a[2]);//
printf("a[0][1]=%d\n",a[3]);//
}
int main()
{
int a[2][2] = {0, 1, 2, 3};
func1(a);
printf("\n");
func2(a);
return 0;
}
程序能正常输出吗?输出多少?
实际上放到IDE中运行一下可知,编译可以通过(尽管有警告),但运行出错,这又是为何呢?
要回答这道题,我们首先得明确什么是二级指针:即指向指针变量的指针;
示例如下:
#include<stdio.h>
int main()
{
int a=5;
int *p=&a;
int **pp=&p;//此为二级指针
printf("a=%d\n\n",a);
printf("*p=%d\n",*p);
printf("p=%d\n\n",(int)p);
printf("**pp=%d\n",**pp);
printf("*pp=%d\n",(int)*pp);
printf("pp=%d\n",(int)pp);
return 0;
}运行结果如下:
其次是对二维数组概念的掌握:
例如对于二维数组a[3][4],应注意的是用矩阵表示二维数组是逻辑上的概念,能形象的地表示出行列关系。而在内存中,各元素是连续存放的,地址不是二维的,而是线性的。
如下图所示:
因此二维数组并不能等同于二级指针,由定义可知反而可以当成一维数组对待。此时再回过头来看那道笔试题;
当把二维数组名a作为实参传入func1时,传进去的只不过是二维数组元素的首地址(结合上图加以体会);此时指针实则已经退化成一级指针了,即二维数组被当成了一维数组对待(因为二维数组地址本身是线性的,要想当成矩阵来使用,必须知道数组的列元素个数,但列信息并没有传入给func1);所以此时想按照二维数组的方式输出原数组的内容是不可能的,因为列信息丢失了,但如果按照一维数组输出就是可以的:
#include<stdio.h>
void func1(int **a)
{
printf("a[0][1]=%d\n",a[0]);//
printf("a[0][1]=%d\n",a[1]);//
printf("a[0][1]=%d\n",a[2]);//
printf("a[0][1]=%d\n",a[3]);//
}
void func2(int *a)
{
printf("a[0][1]=%d\n",a[0]);//
printf("a[0][1]=%d\n",a[1]);//
printf("a[0][1]=%d\n",a[2]);//
printf("a[0][1]=%d\n",a[3]);//
}
int main()
{
int a[2][2] = {0, 1, 2, 3};
func1(a);
printf("\n");
func2(a);
return 0;
}那么如果我仍希望可以按照二维数组输出呢?由上述分析可知,只需传入带有列元素信息的指针即可,此时需要用到指向一维数组的指针变量,这才是二维数组对应的指针形式,而不是二级指针。
#include<stdio.h>
void func1(int (*a)[2])
{
printf("a[0][1]=%d\n",a[0][0]);//
printf("a[0][1]=%d\n",a[0][1]);//
printf("a[0][1]=%d\n",a[1][0]);//
printf("a[0][1]=%d\n",a[1][1]);//
}
void func2(int *a)
{
printf("a[0][1]=%d\n",a[0]);//
printf("a[0][1]=%d\n",a[1]);//
printf("a[0][1]=%d\n",a[2]);//
printf("a[0][1]=%d\n",a[3]);//
}
int main()
{
int a[2][2] = {0, 1, 2, 3};
func1(a);
printf("\n");
func2(a);
return 0;
}
运行结果如下:
#include<stdio.h>
void func1(int **a)
{
printf("a[0][1]=%d\n",a[0][0]);//
printf("a[0][1]=%d\n",a[0][1]);//
printf("a[0][1]=%d\n",a[1][0]);//
printf("a[0][1]=%d\n",a[1][1]);//
}
void func2(int *a)
{
printf("a[0][1]=%d\n",a[0]);//
printf("a[0][1]=%d\n",a[1]);//
printf("a[0][1]=%d\n",a[2]);//
printf("a[0][1]=%d\n",a[3]);//
}
int main()
{
int a[2][2] = {0, 1, 2, 3};
func1(a);
printf("\n");
func2(a);
return 0;
}
程序能正常输出吗?输出多少?
实际上放到IDE中运行一下可知,编译可以通过(尽管有警告),但运行出错,这又是为何呢?
要回答这道题,我们首先得明确什么是二级指针:即指向指针变量的指针;
示例如下:
#include<stdio.h>
int main()
{
int a=5;
int *p=&a;
int **pp=&p;//此为二级指针
printf("a=%d\n\n",a);
printf("*p=%d\n",*p);
printf("p=%d\n\n",(int)p);
printf("**pp=%d\n",**pp);
printf("*pp=%d\n",(int)*pp);
printf("pp=%d\n",(int)pp);
return 0;
}运行结果如下:
其次是对二维数组概念的掌握:
例如对于二维数组a[3][4],应注意的是用矩阵表示二维数组是逻辑上的概念,能形象的地表示出行列关系。而在内存中,各元素是连续存放的,地址不是二维的,而是线性的。
如下图所示:
因此二维数组并不能等同于二级指针,由定义可知反而可以当成一维数组对待。此时再回过头来看那道笔试题;
当把二维数组名a作为实参传入func1时,传进去的只不过是二维数组元素的首地址(结合上图加以体会);此时指针实则已经退化成一级指针了,即二维数组被当成了一维数组对待(因为二维数组地址本身是线性的,要想当成矩阵来使用,必须知道数组的列元素个数,但列信息并没有传入给func1);所以此时想按照二维数组的方式输出原数组的内容是不可能的,因为列信息丢失了,但如果按照一维数组输出就是可以的:
#include<stdio.h>
void func1(int **a)
{
printf("a[0][1]=%d\n",a[0]);//
printf("a[0][1]=%d\n",a[1]);//
printf("a[0][1]=%d\n",a[2]);//
printf("a[0][1]=%d\n",a[3]);//
}
void func2(int *a)
{
printf("a[0][1]=%d\n",a[0]);//
printf("a[0][1]=%d\n",a[1]);//
printf("a[0][1]=%d\n",a[2]);//
printf("a[0][1]=%d\n",a[3]);//
}
int main()
{
int a[2][2] = {0, 1, 2, 3};
func1(a);
printf("\n");
func2(a);
return 0;
}那么如果我仍希望可以按照二维数组输出呢?由上述分析可知,只需传入带有列元素信息的指针即可,此时需要用到指向一维数组的指针变量,这才是二维数组对应的指针形式,而不是二级指针。
#include<stdio.h>
void func1(int (*a)[2])
{
printf("a[0][1]=%d\n",a[0][0]);//
printf("a[0][1]=%d\n",a[0][1]);//
printf("a[0][1]=%d\n",a[1][0]);//
printf("a[0][1]=%d\n",a[1][1]);//
}
void func2(int *a)
{
printf("a[0][1]=%d\n",a[0]);//
printf("a[0][1]=%d\n",a[1]);//
printf("a[0][1]=%d\n",a[2]);//
printf("a[0][1]=%d\n",a[3]);//
}
int main()
{
int a[2][2] = {0, 1, 2, 3};
func1(a);
printf("\n");
func2(a);
return 0;
}
运行结果如下:
相关文章推荐
- Lua中使用二维数组实例
- C#使用二维数组模拟斗地主
- C#二维数组基本用法实例
- javascript的日期对象、数组对象、二维数组使用说明
- PHP 如何获取二维数组中某个key的集合
- 改写函数实现PHP二维/三维数组转字符串
- java 二维数组矩阵乘法的实现方法
- Swift中定义二维数组的方法及遍历方法示例
- C#和Java中二维数组区别分析
- php对二维数组按指定键值key排序示例代码
- js二维数组定义和初始化的三种方法总结
- C语言中二维数组指针的简要说明
- php实例分享之二维数组排序
- php中二维数组排序问题方法详解
- js sort 二维数组排序的用法小结
- JS二维数组的定义说明
- Java编程中二维数组的初始化和基本操作实例
- C++中const修饰二级指针(从类型‘int**’到类型‘const int**’的转换无效)
- 黑马程序员-Java二维数组的几种定义方法