当前位置:天才代写 > tutorial > C语言/C++ 教程 > 再谈C语言中数组和指针之间的互操纵

再谈C语言中数组和指针之间的互操纵

2017-11-03 08:00 星期五 所属: C语言/C++ 教程 浏览:812

副标题#e#

我曾说过,在C语言中只有一维的数组(这是我对数组的观点),并且数组元素可以是任何范例的数据(或工具),自然也可以是别的的一个数组(因为数组也是一种数据范例)。所以假如你僵持要说有多维数组,那也不是不行能的工作。我们只要把一个数组赋值给另一个数组的元素就可以了。虽然了,我们必需担保在措施编译期数组的巨细是一个牢靠的常数。

其实,数组的操纵很简朴的。只要我们确定一个数组的巨细和指向该数组下标为0的元素的指针,其他的任何一个数组下标的运算都等同于一个对应的指针运算,所以我们说“数组和指针是可以彼此操纵的”。两者的本质是一样的。甚至我们还可以把数组看作是一个“指针”的荟萃。

我可以通过如下的方法声明一个数组:

char name[10];

这个语句声明白name是一个拥有10个字符型元素的数组。雷同的

struct student{
int tid[4];
char name[10];
char sex;
char address[25];
} std[100];

这里声明白std是一个拥有100个元素的数组,并且std中的每一个元素都界说了一名学生的根基信息,每一个元素都是一个布局,个中包罗一个拥有4个整形元素的数组(tid[4]),用来记录学生的学好;尚有一个拥有10个字符型元素的数组(name[10]),用来记录学生的名字;一个用来记录学生性此外字符(sex);尚有一个记录学生住址,拥有25个字符型元素的数组(address[25])。数组是一个很机动的布局。

所谓的“二维数组”或“矩阵”是很容易声明的,譬喻:

int week[7][24];

这里把声明week声明为一个拥有7个数组元素的数组(这样表明,不会感受奇观吧),个中每一个元素都是拥有24个整数型元素的数组。留意了不能把week领略为一个拥有24个数组元素的数组,个中每一个元素是一个拥有7个整形元素的数组。 尚有,假如week不是用于sizeof的操纵数,那么它老是被一个指向week数组起始地点的指针。这里又和指针磨合了。 假如一个指向的是一个数组的一个元素,那么我们只需给这个指针加上一个自然数i(0=<i <数组的上界线的值),那么就可以获得一个指向该数组的弟i个元素的指针。假如在此基本上减去1,那么就获得了一个指向前一个元素的指针。这样的操纵很简朴很机动的。可是这儿也有一个误区:许多几何人都认为“给一个指针加一个整数,就等同于给该指针的二进制数暗示加上一个同样的整数”。其实,这是一个很容易犯的错误了,至少在初学C语言的时候,我就犯过这个错误,并且不只一次。其实,这两者的寄义是截然差异的。假设我们有一个这样的指针声明语句:

int *p;

那么p自然是一个指向整数指针了,那么p+1指向的是计较机内存的下一个整数,而不是指向指向地点的下一个内存位置。也就是说措施的逻辑地点一般都差异于实际的物理地点。

假如有两个指向同一个数组的元素,那么我们可以通过这两个指针之间的算术运算获得一些有意义的表达式。 好比,

int *pointer;
int *ip=pointer + i;


#p#副标题#e#

那么我们可以通过指ip-pointer获得i的值。假如ip和ponter指向的不是同一个元素,那么我们就无法担保这个操纵的正确性,固然他们在内存地点上相差一个整数倍。

让我们通过下面的一个例子来看看数组和指针操纵的等效性和机动度:

假如我们在措施中声明白以下两个语句,

int a[12];
int *p;

那么我们可以对数组和指针举办相应的操纵了:

(1) p=a;

因为a = a[0],所以这里就有p=a[0]了,即p和a都指向数组的第一个元素;

(2) p=p + 1;

这也是正确的。它等效于p=a[1];

(3) p++;

这个语句等效于 p=a[2];

尚有:

p=&a; 这样的语句ANSI C中是错误的,这一点在前一篇文章我已经声明过,因为这两个操纵数的范例很显然是不匹配的,即&a是一个指向数组的指针而p是一个整型指针。所以此类操纵是犯科的。有时大概会荣幸的通过(因为有些编译器提供商不必然严格的凭据ANSI C的保准来开拓本身的编译器),可是我们不倡导这种做法。

数组元素的引用

这是一个足够让人糊涂的问题。先看一看下面这个语句是否正确:

a + i=a + i;

也许你会说很显然是正确的,因为它出格象一个两元加法运算。固然谜底的前一半是正确的,可是问题的实质可不是这样的。为了答复之一个 问题我们需要从数组元素的引用说起。

#p#分页标题#e#

在前面我们声明白a为一个拥有12个整型元素的数组,并且我们知道a是一个指向该数组的第一个(0位元素)元素的指针,所以凭据指针的性质我们可以知道*a就是对数组的第一个元素的引用。你可以通过如下的方法给数组的第一个元素赋值:

*a=2005;

大白了这一点,那么其他元素的赋值和引用也是雷同的。*(a+3)是对数组的弟3个元素的引用,而其赋值可以是:

*(a+3)=2006;

然而,由加法的互换律,可以知道1+a=a+1,所以a+i=i+a;

因为 *(a+i)=*(i+a)。

#p#副标题#e#

此刻让我们想一想如何用指针来操纵我们的二维数组吧。

前面我们声明白一个二维数组week,那么week[2]代表什么意思呢?我想假如大白了前面的讲授,那么这个问题就一如反掌了。week[2]代表的无非就是week数组的弟3个元素(数组下标从0开始),即一个拥有24个整型元素的数组。假如你还想知道week[2]的内存巨细,那么你可以通过sizeof操纵来实现:

int mem;
mem=sizeof(week[2]);

其实,sizeof(week[2])=24 * sozeof(int)。

假如你想通过指针来会见week[2]的元素(这里假设会见弟3个元素),那也是很简朴的。请看下面的表达式:

int value;
p=week[3];
value=*(p+3);

也可以是:

value=week[2][2];

可能

value=*(week[2]+3);

还可以是:

value=*(*(week+2)+3);

由此我们可以看出来,数组和指针不是两个彼此独立的布局,而是细密细密互不行分的整体。两者之间的互操纵是最美的团结。我们倡导只在措施设计中才用数组和指针之间的互操纵的实现要领。到这里我们的路程也该竣事了,假如说尚有一些技能没有提及,我想那自然是数组和指针别离作为函数返回值范例和函数参数的景象而已。其操纵和上面提到的相当,在此就不提了。一般我们习惯于把指针看成函数返回值范例和函数参数来处理惩罚的,而不是处理惩罚数组,因为在这种景象下,对数组的操纵显得很鸠拙很底效。

 

    关键字:

天才代写-代写联系方式