指针

 

 

---恢复内容开始---

       通过前面的学习,我们了解了什么是指针,怎样去定义指针变量,以及如何去运用指针来完成变量a与变量b的交换。接下来,我们来看看如何通过指针引用数组,再讲这个问题之前,我们先来回顾一下有关数组的知识。  

        数组是一组有序数据的集合,它分为一维数组,和二维数组。下面,我举几个例子,方便读者理解和接受这个概念。

#include <stdio.h>
int main()
{
   int i,a[10];
   for (i=0,i<=9;i++)
       a[i]=i;
    for(i=9;i>=0;i--)
         printf (“%d”,a[i]);
printf(“\n”);
return0;
}

其中,上面程序的a[10],就是定义了一个存放一个有十个整数元素的数组。可以看到用一个“int a[10]”就相当定于了10个简单的整型变量,显得便捷方便。

在一维数组的基础上,我们就容易去定义二维数组了,请看下面的例子:

#include <stdio.h>
int main()
    {int i,j,row=0;colum=0,max;
      int a[3][4]={{1,2,3,4},{9,8,7,6},{ -10,10,-5,2}};
       max =a[0][0];
        for(i=0;i<=2;i++)   
            for (j=0;j<=3;j++)
                if(a[i][j]>max)
                 {max=a[i][j];
                  row=i;
                   colum=j
          }
    printf (“max=%d\nrow=%d\ncolum=%d\n”,max,row,colum);
    return0;
}

回归到我们今天的话题,所谓的数组元素的指针就是数组元素的地址。

在c语言中,数组名,不包括形参数组名,形参数组名是不占用物理内存的,它代表的就是数组首元素的地址,也就是说

int  *p=&a[0];
  它等效于下面两行:
 int   *p;
  p=a;

如果我们想引用这个数组中的某个值时,怎么办?这时就可以进行指针的加或减法运算了,

假如我们定义了一个一维数组,用一个指针变量指向数组中的某个元素,则p+1指向下一个元素,同理,p-1指向上一个元素,但这时指针变量p的值未必增加一个或减少一个单位,这就要看定义的指针变量的数据类型,如:int型,p的值增加4(在vc++中运行),char型,p的值加1。

我始终认为例子能给读者更加深刻的理解,比起那些定义和理论,例子能让他们更易于接受和掌握。

#include <stdio.h>
int main()
  {int a[10];
    int i;
    printf(“please enter 10 integer number :”);
     for (i=0;i<=10;i++)
          scanf(“%d”,&a[i]);
     for (i=0;i<10;i++)
         printf (“%d”,a[i]);
     printf (“%d\n”);
     return0;
}
#include <stdio.h>
int main()
  {int a[10];
    int i;
    printf(“please enter 10 integer number :”);
     for (i=0;i<=10;i++)
          scanf(“%d”,&a[i]);
     for (i=0;i<10;i++)
         printf (“%d”,*(a+i));
     printf (“%d\n”);
     return0;
}

这两个程序的运行结果都是相同的,仔细观察,这两个程序还是有细微的不同的,第九行的(a+i)是a数组中序号为i的元素的地址,*(a+i)是该元素的值。第七行中&a[i]也是同样用法。

#include <stdio.h>
int main()
  {int a[10];
    int *p,i;
    printf(“please enter 10 integer number :”);
     for (i=0,p=a;i<=10;i++,p++)
          scanf(“%d”,p);
     for (p=a;p<a+10;p++)
         printf (“%d”,*p);
     printf (“%d\n”);
     return0;
}

这个程序是上面程序的一个改进,如果读者上机去运行一下的话,会发现,程序三会快于程序一,二。这就是指针变量的作用。即使是程序一,二,也要将a[i]转化为*(a+i)处理的,即先计算元素地址。

如果不用p变化的方法而改用数组名变化的方法行不行?假如将上述的第8 9行改为

for(p=a;a<=(p+10;a++)
  printf(“%d”;*);

请读者思考下。

下面来聊聊通过指针引用多维数组,其中最具代表性的就是二维数字了。

举一个小例

int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};

从二维数组的角度看,a代表二维数组首元素的地址,a+1代表下一行首元素的地址,a+2……便以此类推。

那么,如果想得到第二行第二个元素,那该如何用地址法表示吗?这里提供两种方法,①a[1]+2,②*(a+1)+2    

它们代表的值为取它们地址的*,即*(a[1]+2)或*(*(a+1)+2)。如:要a[i][j]的值,用地址法表示为*(a[i]+j),*(*(a+i)+j)。

不妨假设,a的地址为1998,变量a是整型变量,在vc++中,一个整型变量占据4个字节,那么a+1和*(a+1)都是2016。请读者思考一下这是为什么。

    指针在字符串方面的应用也是非常广泛的。

首先,我们来看看一个例题。

  定义一个字符数组,其中存放字符串“All  people are beautiful!”,输出该字符串和第8个字符。

#include  <stdio.h>
int  main()
         {char string[]=“All  people are beautiful!”};
          printf(“%s\n”,string);
          printf(“%c\n”,string[7]);
          return0:
}

实际上,string[7]就是*(string+7),string+7是一个地址,指向字符“C”。

它的另一种表示方法:

include  <stdio.h>
int  main()
         {char *string=“All  people are beautiful!”};
          printf(“%s\n”,string);
          return0:
}

对字符指针变量string初始化,实际上是把字符串第1个元素的地址赋给指针变量string,使string指向字符串的第一个字符。

 

posted @ 2017-10-29 20:33  TANGPANG  阅读(286)  评论(0编辑  收藏  举报