c语言 什么是行指针 求大神详细解释。

Python09

c语言 什么是行指针 求大神详细解释。,第1张

我们在使用c语言进行编写程序的时候,就一定会使用上指针,指针的操作是编写程序的一个点。

如何更好的使用指针,将是我们进行更好的书写程序的关键。

这里,小编就分享一下自己在使用c语言编程过程中,对于指针的理解:

1:指针是一个地址,指向的是个类型:

我们知道,c语言中的类型有int,char,bool(这个不常用),一般我们使用int,char就可以满足一般的类型需求的,如果对于变量的长度过大,就是用long ,float,double,关于各个类型使用的的长度问题,可以使用sizeof(int)或者sizeof(long)来查看各个类型,在系统中的小。

而指针就是一个8个字节(64系统)。

2:指针指向的是地址,地址指向的是内容:

我们需要一个变量,来存储地址,这个变量的值是地址,但是我们可以通过修改变量的值,来不断的改变地址,但是,我们如果需要改变该个地址的值的话,就需要,对地址的值进行修改,而不改变地址。

int a = 10;

int *p ;

p = &a;

*p =11;

a=?

这里我们看到,p 是一个变量,我们使用p来存储变量a的地址,这是,我们使用*p对于这个变量进行赋值,那么a的值最后,是多少呢,结果是11,因为我们使用*p赋值,就相当于a=11,赋值效果一样的。

3:指针的指针,是面对于指针的变量:

我们说,指针的指针的时候,就有点不清楚了,到底怎么区分指针和指针的指针呢。

char *p;

char **pr;

pr = &p;

我们这样看就清楚了一点,char *(*pr); *pr是一个存储的值为指针的变量,pr就是存储上个变量地址的变量。整合起来就是,pr是一个存储的值为指针的地址的变量。

这样,我们就基本,对于指针有一个直接的了解了。

int *arry[10] //指针数组

int (*arryp)[10] //数组指针,因为数组指针指向数组,而数组也可看做是个指针,那数组指针可以理解为一个二 级指针

int a[10]

arryp = &a //将数组地址个数组指针

arry[0] = *arryp //arry[0]是一级指针,要将数组指针赋给指针数组,就要取内容,实际就是 arry[0] = a

先从存储的角度对二维数组作一个全面的了解。二维数组在内存中的存储,是按照先行后列依次存放的。从内存的角度看,可以这样说,二维数组其实就是一个一维数组,在内存中没有二维的概念。如果把二维数组的每一行看成一个整体,即看成一个数组中的一个元素,那么整个二维数组就是一个一维数组,它以每一行作为它的元素,这个应该很好理解。

第一,来详细介绍二维数组与指针的关系。-

首先定义个二维数组 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])

……