C语言 指向二维数组的指针

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言 指向二维数组的指针相关的知识,希望对你有一定的参考价值。

#include "stdafx.h"
#include "stdio.h"

int main(int argc, char* argv[])


int a[3][4]=1,3,5,7,9,11,13,15,17,19,21,23;
int* p=a;
/*error C2440:
'initializing' : cannot convert from 'int [3][4]' to 'int *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Error executing cl.exe. */

int i;

for(i=0;i<12;i++)

if(i%4==0)printf("\n");
printf("%4d",*(p+i));


printf("\n");

return 0;


int* p=a; 若改为int* p=a[0]; 就不会报错了,二维数组名不就是指针么?为什么上面的程序要报错?

a是指针,不过是行指针,p的基类型int,而 a 的基类型是一个包含4个整形元素的一类数组.
int (*p)[4] = a;这样定义p也会编译过去的,因为这时p的基类型也是一个包含4个整形元素的一类数组。
至于int* p = a[0];编译正确,是因为a[0]也是指针,基类型也是int。追问

int* p=a;
哪里错了呢?
是不是就是因为,p的类型是指向int变量的指针,而a 的类型是指向一维数组的行指针?

追答

cannot convert from 'int [3][4]' to 'int *'
不能 从int[3][4]转化到int*
很显然,p的类型是int* ,而a的类型是int [][4],所以,转换不了。
你不妨试试这段代码,体会一下:
int a[3][4]=1,3,5,7,9,11,13,15,17,19,21,23;
int *p = (int*)a;
int (*q)[4] = a;
int i;
for(i=0;i<12;i++)

if(i%4==0)printf("\n");
printf("%4d",p[i]);

printf("\n");
for(i = 0;i < 3;i++)

for(j = 0;j < 4;j++)
printf("%4d",q[i][j]);
printf("\n");

printf("\n");
printf("%4d",p[i]);

参考技术A 表示一个指向二维数组的指针变量
------------------
这东西说的不完整.跟二维数组有关的知识,只有数组指针和行指针这两种.如果是单个指针变量,那么和一维数组有关.绝对扯不到二维数组.
实参是一维数组,形参是指针.
实参是二维数组,形参是行指针.
实参是数组指针,形参是指向指针的指针.
参考技术B 先用一个指针类型把这个返回值进行接受,然后再向你的那个二维数组赋值,记得要把那个指针free掉
char*
temp;
temp
=
returnpointer();
strcpy(a[i],
temp);
free(temp):
参考技术C 那个*(p+i)表示的是指向二维 数组第i组的第一个元素,当然会有错了.有错调试器会显示.追问

int* p=a;
哪里错了呢?

追答

a是数值,而p是指针当然错了

参考技术D 先从存储的角度对二维数组作一个全面的了解。二维数组在内存中的存储,是按照先行后列依次存放的。从内存的角度看,可以这样说,二维数组其实就是一个一维数组,在内存中没有二维的概念。如果把二维数组的每一行看成一个整体,即看成一个数组中的一个元素,那么整个二维数组就是一个一维数组,它以每一行作为它的元素,这个应该很好理解。
第一,来详细介绍二维数组与指针的关系。-
首先定义个二维数组 array[3][4],p 为指向数组的指针。
若p=array[0],此时p指向的是二维数组第一行的首地址,则 p+i 将指向array[0]数组中的元素array[0][i]。由以上所介绍的二维数组在内存中的存储方式可知,对数组中的任一元素array[i][j] ,其指针的形式为:p+i*N+j (N为每一行的长度)。 元素相应的指针表示法为:*(p+i*N+j) ,下标表示法为:p[i*N+j] 。
For Example:
array[4][3]=1,2,3,4,5,6,7,8,9,10,11,12;
int * p=array[0];
数组array有四个元素,分别为array[0],array[1],array[2],array[3],每个元素为包含3个元素的一维数组,
如array[0]的3个元素为 array[0][0],array[0][1],array[0][2]。
元素array[2][2]对应指针为:array+2*3+2,
指针表示法为:*(array+2*3+2) ,
下标表示法为:array[2*3+2] 。
特别注意:虽然 array[0] 与 array 都是数组首地址,但两者指向的对象不同,这点要非常明确。array[0] 是一维数组的名字,它指向的是一维数组array[0]的首地址,所以 *array[0]与array[0][0]为同个值。而 array 是二维数组的名字,它指向的是所属元素的首地址,其每个元素为一个行数组。它是以‘行’来作为指针移动单位的,如array+i 指向的是第 i 行。对 array 进行 * 运算,得到的是一维数组 array[0] 的首地址,所以 *array 与 array[0] 为同个值。如果定义 int* p,p为指int类型的指针,指向int 类型,而不是地址。故以下操作 :p=array[0] (正确) ,p=array (错误) 。这点要非常注意。
第二,看看如何用数组名作地址表示其中元素。
对二维数组array ,array[0] 由 array指向,故*array 与array[0] 是相同的,依次类推可得 array[i] 由array+i 指向,*(array+i) 与array[i]是相同的。 因此,对于数组元素 array[i][j] ,用数组名表示为 *(*(array+i)+j) ,指向该元素的指针为 *(array+i)+j 。
注意:数组名虽然是地址,但与指向数组的指针性质不同。指针变量可以随时改变其所指向对象,而数组名不可以,一旦被定义,就不能通过赋值使其指向另外一个数组,但是在Java中则可以。
第三,顺便了解一下不太常用的‘行数组指针’。
对于二维数组array[4][3],与int* p 。二维数组名array 不能直接赋值给p。原因前面已讲过,两只的对象性质不同。 在C语言中,可以通过定义一个行数组指针,使得这个指针与二维数组名具有同样的性质,实现它们之间可以直接赋值。行数组指针定义如下:
int (*p)[3]; 它表示,数组 *p 具有三个int类型元素,分别为 (*p)[0] , (*p)[1] , (*p)[2] ,即 p指向的是具有三个int类型的一维数组,也就是说,p为行指针。此时,以下运算 p=array 是正确的。
第四,二维数组作为函数参数。
二维数组作为函数参数一般有两种方式:(1) void func(int **array)... (2) void func(int array[ ][N])
注意第二种方式一定要指明二维数组的列数
当二维数组名作为函数实参时,对应的形参必须是一个行指针变量。
和一维数组一样,数组名传送给变量的是一个地址值,因此,对应的形参也必须是一个类型相同的指针变量,在函数中引用的将是主函数中的数组元素,系统只为形参开辟一个存放地址的存储单元,而不可能在调用函数时为形参开辟一系列存放数组的存储单元。
int main()
double a[3][4];
……
fun(a);
……
fun(double (*a)[n])
……

C语言如何定义指针指向字符型二维数组

使用指针变量访问二维数组的任意一个元素的方法:

1.使用列指针:定义一个列指针p,让它指向二维数组的第0个元素

int a[3][4];

int *p;

p=&a[0][0];   

//因为a[0]是第0行的数组名,所以p=&a[0][0]相当于p=a[0],因为a[i][j]前面共有i*4+j个元素

该二维数组的任意i行j列元素可表示为*(p+i*4+j)。

2.使用行指针:定义一个行指针p,让它指向二维数组的第0行

int a[3][4];

int (*p)[4];

p=a;   //也可以为p=&a[0];   

其中* ( *(p+i)+j)表示任意一个i行j列的元素。

扩展资料:

数组的使用规则:

1.可以只给部分元素赋初值。当 中值的个数少于元素个数时,只给前面部分元素赋值。例如:static int a[10]=0,1,2,3,4;表示只给a[0]~a[4]5个元素赋值,而后5个元素自动赋0值。

2.只能给元素逐个赋值,不能给数组整体赋值。例如给十个元素全部赋1值,只能写为:static int a[10]=1,1,1,1,1,1,1,1,1,1;而不能写为:static int a[10]=1;请注意:在C、C#语言中是这样,但并非在所有涉及数组的地方都这样,数据库是从1开始。

3.如不给可初始化的数组赋初值,则全部元素均为0值。

4.如给全部元素赋值,则在数组说明中, 可以不给出数组元素的个数。例如:static int a[5]=1,2,3,4,5;可写为:static int a[]=1,2,3,4,5;动态赋值可以在程序执行过程中,对数组作动态赋值。这时可用循环语句配合scanf函数逐个对数组元素赋值。

参考资料:

百度百科-数组

参考技术A

在C语言中,可以通过如下方式来定义指向字符型二维数组的指针:

char c[4][5];  // 定义一个4行5列的字符型二维数组
char (*pc)[5]; // 定义一个含5个元素的数组指针
pc=c;  // 将数组指针pc指向二维字符数组c


注:

char (*pc)[5] 不能写为 char *pc[5]

char (*pc)[5] 表示数组指针,数组中每个元素为char型;

char *pc[5] 表示指针数组,数组中每个元素为char*,也即每个元素为指针。

参考技术B

1、定义二维指针数组与定义一维指针数组差不多,只是矩阵的维度增加了一维而已。

2、下面通过具体的实例来说明如何定义一个二维数组:

int *p[2][3];  // 定义一个二维数组,只是定义,并没有分配地址空间
int i,j;  // 数组的行数和列数
// 下面的2个for循环是用来对二维指针数组进行初始化的,也即分配地址。如果不进行初始化操作,就会使指针变为野指针(即指向不明)。
for(i=0; i<2; i++)
    for(j=0; j<3; j++)
        p[i][j] = (int *)malloc(sizeof(int));
*p[0][1] = 2; // 对指针数组中指针所指向的内存单元进行赋值操作
printf("%d\\n", *p[0][1]);  // 输出结果

参考技术C 定义字符型二维数组:char str[3][10];
定义指针型数组 : char *p[5] = str[0],str[1],str[2];
参考技术D 如定义:int a[3][4];
int *p; p=a[0];此时p就指向0行0列元素

以上是关于C语言 指向二维数组的指针的主要内容,如果未能解决你的问题,请参考以下文章

C语言指针指向一维数组与二维数组?

C语言指向二维数组的指针

C语言中二维数组行指针是啥

C语言中怎样区分一维指针和二维指针?

C语言:定义指向二维数组的指针变量

C语言 如何定义一个二维指针数组?