二维数组指针定义,C语言如何定义指针指向字符型二维数组
二维数组指针定义,C语言如何定义指针指向字符型二维数组详细介绍
本文目录一览: C语言中“二维数组行指针”是什么意思
指向二维数据的一行的指针,比如说:
int array1[2][5]={
{0,1,2,3,4},
{ 4,5,6,7,8}
};
二维数组行指针
array1[0]
array1[1]
都是行指针
先从存储的角度对二维数组作一个全面的了解。二维数组在内存中的存储,是按照先行后列依次存放的。从内存的角度看,可以这样说,二维数组其实就是一个一维数组,在内存中没有二维的概念。如果把二维数组的每一行看成一个整体,即看成一个数组中的一个元素,那么整个二维数组就是一个一维数组,它以每一行作为它的元素,这个应该很好理解。
第一,来详细介绍二维数组与指针的关系。-
首先定义个二维数组 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语言如何定义指针指向字符型二维数组
在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*,也即每个元素为指针。
定义字符型二维数组:char
str[3][10];
定义指针型数组
:
char
*p[5]
=
{str[0],str[1],str[2]};
C语言如何定义指针指向字符型二维数组
在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*,也即每个元素为指针。
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]); // 输出结果
定义字符型二维数组:char str[3][10];
定义指针型数组 : char *p[5] = {str[0],str[1],str[2]};
如定义:int a[3][4];
int *p; p=a[0];此时p就指向0行0列元素
char c[4][5];
char (*pc)[5];
pc=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函数逐个对数组元素赋值。
参考资料:
百度百科-数组
指向二维数组的指针如何定义?
方案一:
int arrayA[2][3] = { {1, 2 ,3},{11,22,33}};
int arrayB[2][5] = {{5,6,7,8,9},{55,66,77,88,99} };
int *array = NULL;
if (A条件成立)
{
array = &arrayA[0][0];
}
else
{
array = &arrayB[0][0];
}
方案二:
这种方式是定义指向二维数组的行的数组指针,列必须相同,行可以不同,所以这里要定义两个数组指针变量!
int arrayA[2][3] = { {1, 2 ,3},{11,22,33}};
int arrayB[2][5] = {{5,6,7,8,9},{55,66,77,88,99}};
int (*array1)[3] = NULL;
int (*array2)[5] = NULL;
if (A条件成立)
{
array1 = arrayA;
}
else
{
array2 = arrayB;
}
如果你定义的两数组列一样, 即:
int arrayA[2][5] = { {1, 2 ,3},{11,22,33}};
int arrayB[2][5] = {{5,6,7,8,9},{55,66,77,88,99}};
那么就可以:
int (*array)[5] = NULL;
if (A条件成立)
{
array = arrayA;
}
else
{
array = arrayB;
}
二维数组的指针,某一行的指针,某一元素的指针各代表什么含义?
举例说明:
int a[3][4];
&a[0][0]的类型是int *
&a[0]的类型是指向一个4个元素的一维int类型数组
以二维数组 int a[2][2];为例
既知表达式 a 的值即&a[0]或者是a+0的值
类型是int**
a[0]的值即&a[0][0]
某一个行的指针,以a[0],即第一行的指针为例,其含义是a[0][0]的地址值
某 一元素 的地址的表达式,&a[0][0], 为第一行第一个元素的地址,&a[1][1]是第二行第二个元素的地址
某一行(以第x行为例)元素的指针是该行第一个元素的地址值,表达式是&a[x-1][0]或者a[x-1]
int a[5][6];
int (*p)[6]=a;
int * p1= a[0];
int * p2= &a[0][0];
首先,数组首地址值=行首地址值=第一个元素地址值,注意只是值相等,重要的是类型不同.记住:地址类型很重要.
1)int (*)[n]
数组地址类型,其中n为列宽,表示一行中包含n个int元素,此处为6,即6个int元素组成一行,并将其看成一个整体,int的数据宽度是4字节,因此一行(整体)有4*6=24个字节.此类指针每次递增1即递增24个字节
指针值都是4字节的,区分不同类型的目的就是为了指示:指针指向的内存的数据宽度,即该指针指向的地址开始存放的数据是多少字节的,进而实现数据对齐.
a是个数组,"a"这个标识符映射为常量指针,其类型为 int (*)[6],指向数组首地址,因此可以直接赋值给p.
注意p的数据宽度也是4*6=24,如果p++,那么递增的是24个字节.所以这种类型的指针也称为行指针,因为以行为基本单位.
因此,二维数组指针就是行指针.
2)int *
单个int类型元素的指针,也可以作为一维数组的指针,同样原因:数据宽度一致,都是4字节.
因此a[0]表示数组首行,而行数据是个int型的一维数组,因此其类型为 int *,所以可以直接赋值.
同样 a[0][0]表示数组首行首元素,因此取地址后也可以直接赋值给int *类型指针.
最后再次重申,解读指针定义或者分析右值类型时,数据宽度是关键所在.
附图显示数组首地址值=行首地址值=第一个元素地址值,但是类型是不同的.
C语言 二维数组 指针
a是数组第一行地址,代表一行,偏移量是2*4.
*(a+2)是数组第二行第一列地址,偏移量是4
*(*(a+2)+1)代表a[2][1]的值
*(a+2)+1和*(*(a+2)+1)
这完全是两个东西。第二个代表a[2][1]
二维数组名代表的是这个数组首元素的地址或者可以看作二维数组第一行的地址,a+2是指向第三行的,二维数组可以看作是以行为数组名的一维数组比如
int a[2][2]
数组名是a[2]
在这里*(a+2)代表的是第三行首元素的地址,然后加1的话就是第3行第二元素的地址了。所以*(*(a+2)+1)代表a[2][1]
C语言二维数组指针变量是什么,int (p)[2]什么意思
int
*p[2]:
指针数组,首先它是一个数组,数组的元素都是指针(int
*),数组占多少个字节由数组本身决定.它是"存储指针的数组"的简称;
int
(*p)[2]:
数组指针.首先它是一个指针,指向一个数组,在32为系统下永远占4个字节,它是"指向数组的指针"的简称;
二维数组指针变量:
指向一个二维数组的的指针。
int
(*p)[2]:一个含有两个
指向int
型数据
的指针元素的i数组.
指针形成的数组,int
(*p)[2]指两个指针变量构成的数组,这两个指针值得地址指向整形数据
二维数组指针变量形式如下:
类型名
(*数组名)[数组行数][数组列数]
如:int
(*p)[2][3];
//
定义一个int类型的二维数组指针变量,数组中每个元素都是一个指针
int
(*p)[2]表示定义一个数组指针,只是是一个一维的数组指针,数组中每个元素(共2个元素)都是一个int类型的指针变量,指针指向的地址就需要后续程序给出,不然会变为野指针。
二维数组与指针、指针数组、数组指针的用法
二维数组和指针⑴ 用指针表示二维数组元素。 要用指针处理二维数组,首先要解决从存储的角度对二维数组的认识问题。我们知道,一个二维数组在计算机中存储时,是按照先行后列的顺序依次存储的,当把每一行看作一个整体,即视为一个大的数组元素时,这个存储的二维数组也就变成了一个一维数组了。而每个大数组元素对应二维数组的一行,我们就称之为行数组元素,显然每个行数组元素都是一个一维数组
下面我们讨论指针和二维数组元素的对应关系,清楚了二者之间的关系,就能用指针处理二维数组了。 设p是指向二维数组a[m][n]的指针变量,则有:
int* p=a[0];//此时P是指向一维数组的指针。P++后,p指向 a[0][1]。
如果定义int (*p1)[n];p1=a;p1++后,p1指向a[1][0];
则p+j将指向a[0]数组中的元素a[0][j]。 由于a[0]、a[1]┅a[M-1]等各个行数组依次连续存储,则对于a数组中的任一元素a[i][j],指针的一般形式如下: p+i N+j 相应的如果用p1来表示,则为 (p1+i)+j 元素a[i][j]相应的指针表示为: ( p+i N+j) 相应的如果用p1来表示,则为 ( (p1+i)+j) 同样,a[i][j]也可使用指针下标法表示,如下: p[i N+j] 例如,有如下定义: int a[3][4]={{10,20,30,40,},{50,60,70,80},{90,91,92,93}}; 则数组a有3个元素,分别为a[0]、a[1]、a[2]。而每个元素都是一个一维数组,各包含4个元素,如a[1]的4个元素是a[1][0]、a[1][1]、a[1]2]、a[1][3]。 若有: int p=a[0]; 则数组a的元素a[1][2]对应的指针为:p+1 4+2 元素a[1][2]也就可以表示为:( p+1 4+2) 用下标表示法,a[1][2]表示为:p[1 4+2] 特别说明: 对上述二维数组a,虽然a[0]、a都是数组首地址,但二者指向的对象不同,a[0]是一维数组的名字,它指向的是a[0]数组的首元素,对其进行“ ”运算,得到的是一个数组元素值,即a[0]数组首元素值,因此, a[0]与a[0][0]是同一个值;而a是一个二维数组的名字,它指向的是它所属元素的首元素,它的每一个元素都是一个行数组,因此,它的指针移动单位是“行”,所以a+i指向的是第i个行数组,即指向a[i]。对a进行“ ”运算,得到的是一维数组a[0]的首地址,即 a与a[0]是同一个值。当用int p;定义指针p时,p的指向是一个int型数据,而不是一个地址,因此,用a[0]对p赋值是正确的,而用a对p赋值是错误的。这一点请读者务必注意。 ⑵ 用二维数组名作地址表示数组元素。 另外,由上述说明,我们还可以得到二维数组元素的一种表示方法: 对于二维数组a,其a[0]数组由a指向,a[1]数组则由a+1指向,a[2]数组由a+2指向,以此类推。因此, a与a[0]等价、 (a+1)与a[1]等价、 (a+2)与a[2]等价,┅,即对于a[i]数组,由*(a+i)指向。由此,对于数组元素a[i][j],用数组名a的表示形式为: ( (a+i)+j) 指向该元素的指针为: *(a+i)+j 数组名虽然是数组的地址,但它和指向数组的指针变量不完全相同。
第一,指针变量的值可以改变,即它可以随时指向不同的数组或同类型变量,而数组名自它定义时起就确定下来,不能通过赋值的方式使该数组名指向另外一个数组。
第二,数组名是指针,类型是指向元素类型的指针,但值是指针常量,声明数组时编译器会为声明所指定的元素数量保留内存空间。数组指针是指向数组的指针,声明指针变量时编译器只为指针本身保留内存空间。
例4 求二维数组元素的最大值。
该问题只需对数组元素遍历,即可求解。因此,可以通过顺序移动数组指针的方法实现。 main() { int a[3][4]={{3,17,8,11},{66,7,8,19},{12,88,7,16}}; int p,max; for(p=a[0],max= p;p
max) max= p; printf("MAX=%d/n",max); } 执行结果: MAX=88 这个程序的主要算法都是在for语句中实现的:p是一个int型指针变量;p=a[0]是置数组的首元素地址为指针初值;max= p将数组的首元素值a[0][0]作为最大值初值;p
<a[0]+12是将指针的变化范围限制在12个元素的位置内;p++使得每比较一个元素后,指针后移一个元素位置。 例5 求二维数组元素的最大值,并确定最大值元素所在的行和列。 本例较之上例有更进一步的要求,需要在比较的过程中,把较大值元素的位置记录下来,显然仅用上述指针移动方法是不行的,需要使用能提供行列数据的指针表示方法。 main() { int a[3][4]="{{3,17,8,11},{66,7,8,19},{12,88,7,16}};" p="a[0],max,i,j,row,col;" max="a[0][0];" row="col=0;" for(i="0;i<3;i++)" for(j="0;j
max) { max= (p+i 4+j); row=i; col=j; } printf("a[%d][%d]=%d/n",row,col,max); } 程序运行结果: a[2][1]=88 ⑶ 行数组指针 在上面的说明中我们已经知道,二维数组名是指向行的,它不能对如下说明的指针变量p直接赋值: int a[3][4]={{10,11,12,13},{20,21,22,23},{30,31,32,33}}, p; 其原因就是p与a的对象性质不同,或者说二者不是同一级指针。C语言可以通过定义行数组指针的方法,使得一个指针变量与二维数组名具有相同的性质。行数组指针的定义方法如下: 数据类型 ( 指针变量名)[二维数组列数]; 例如,对上述a数组,行数组指针定义如下: int ( p)[4]; 它表示,数组 p有4个int型元素,分别为( p)[0]、( p)[1]、( p)[2]、( p)[3] ,亦即p指向的是有4个int型元素的一维数组,即p为行指针
此时,可用如下方式对指针p赋值:
p=a;
(4)指针数组的定义
指针数组是指每个元素中存放的是指针。定义为 int *p[4];sizeof(p)=16,返回的是数组的总空间