我当一日班长心得体会:指针与字符数组(相当精辟)

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 10:00:47

5.3 指针变量的使用

5.3.1 指向的指针变量的使用

  当已使指针变量指向了某个变量后,就可以使用指针变量来引用这个变量。
  指针变量的引用主要有两种:一是赋值,二是引用所指向的变量。

1.给指针变量赋值(指针变量=地址表达式)


  要注意指针变量的数据类型和地址对应的数据类型应一致。例如,定义了整型变量a、型指针变量p_a和实型变量b、实型指针变量p_b,则p_a=&a、p_b=&b都是正确的;而p_a=&b、p_b=&a则是错误的,因为他们的数据类型不匹配。

2.引用所指向的变量(*指针变量)


  “*指针变量”所代表所指向的变量。使用时要注意该指针变量必须已赋过值,即已指向某个变量。例如,定义整型变量a和整型指针变量p,并且p已指向a,则*p就代表变量a。

5.3.2 指向一维数组的指针变量的使用

  当定义了一维数组和同类的指针变量后,可以用赋初值或直接赋值的方式将指针变量指向数组首地址,也可以将指针变量指向数组中某个元素。
  如果要将指针变量指向数组首地址,可以用赋初值方式“*指针变量=数组名”;也可以在程序中用赋初值“指针变量=数组名”。如果将指针变量指向某数组元素,可以用赋初值方式“*指针变量=&数组名[下标]”;也可以在程序中用赋值方式“指针变量=&数组名[下标]”。

1. 用指向一维数组的指针变量处理数组元素

  当指针变量已指向数组后,就可以用指针变量来处理数组中的每个元素。处理数组元素的关键是引用数组元素,引用数组元素的方法与指针指向数组的方式有关:当指针变量指向数组首地址时,引用数组元素方法如下:
    引用“数组元素[0]” *(指针变量+0) 或 *指针变量
    引用“数组元素[i]” *(指针变量+i)

  当指针变量指向下标为i的数组元素时,引用数组元素的方法如下:
    引用“数组元素[i]” *(指针变量+0) 或 *指针变量
    引用“数组元素[i-k] *(指针变量-k)
    引用“数组元素[i+k] *(指针变量+k)

  比较上述两种方式可以看出,采用指针变量指向数组首地址的方式比较简单,是通常采用的方式。
  当指针变量指向数组首地址后,对下标为i的数组元素引用一共有下列四种方法:
      *(指针变量+i)   *(数组名+i)   指针变量[i]   数组名[i]
   前两种引用数组元素的方法使用了“指针运算符”,称为“指针法”;后两种引用数组元素的方法使用了“下标运算符([])”,称为“下标法”。
  虽然从书写格式来看,指向数组首地址的指针变量和数组名可以互换,但是它们是完全不同的概念。指针变量是存放地址这种数据类型的变量,可以按照变量的处理方式对其进行运算;而数组名仅仅是一个地址常量,只能按照常量的方式进行处理。

2. 指向一维数组的指针变量的运算

  当指针变量已指向数组后,对指针变量可以进行算术和关系运算。
  (1)指针变量和整数的算术运算。
  对指针变量进行算术运算的规则如下:
    指针变量+整数  “指针变量中的地址+整数*指针变量类型占用单元数”对应的地址
    指针变量-整数   “指针变量中的地址-整数*指针变量类型占用单元数”对应的地址
    ++指针变量     “指针变量中的地址+指针变量类型占用单元数”对应的地址
               此后,指针变量将指向下一个数组元素
    --指针变量     “指针变量中的地址-指针变量类型占用单元数”对应的地址
               此后,指针变量将指向上一个数组元素
    指针变量++    “指针变量中的地址”对应的地址(因为是后缀减1运算符)
               此后,指针变量将指向下一个数组元素
    指针变量--    “指针变量中的地址”对应的地址(因为是后缀减1运算符)
               此后,指针变量将指向上一个数组元素
  从运算结果来看,值仍为地址型数据,我们也把上述运算规则组成的式子称为表达式,这种表达式的类型是“地址型”,所以上述规则组成的表达式常称为“地址型表达式”或“指针型表达式”,简称为“指针表达式”。
  要特别注意对指向数组的指针进行算术运算时,所加减的整数不是指绝对的地址整数值,而是该指针变量向后或向前跳过的同类型数据的数目。
  例如,设定义了整型数组a[10],整型指针变量pa,切执行了pa=a。假定数组a的首地址为2000。请看下列的表达式及运算结果:
  执行pa=pa+5后   pa指向数组元素a[5],pa的地址值将为2000+5*2=2010,
             其中的“2”是整型 数据占用的单元数;
  再执行pa--后    pa将指向数组元素a[4],pa的地址值将为2010-1*2=2008。
  还要注意指针变量和地址常量的区别。当某指针已指向某数组首地址后,对指针变量可以进行增1减1的算术运算,也可以对其进行加减整数的算术运算并可以存回指针变量。但是对代表地址常量的数组名不能进行增1减1的算术运算,虽然可以对其进行加减整数的运算,但是不能存回数组名。例如,指针变量pa指向数组a的首地址,++pa,pa++,--pa,pa--,pa=pa+5.pa=pa-5都是正确的;而 ++a,a++--a,a--,a=a+5,a=a-5都是错误的。但其中a+5和a-5是正确的,因为它们是地址常量组成的表达式。
  (2)指针变量和指针变量的减法运算。
  指针变量和指针变量的减法运算规则如下:
    指针变量1-指针变量2
  要求这两个指针变量必须指向同一个数组,否则不能进行减法运算。运算结果为它们所指向的是数组元素下标相差的整数。
  (3)指针变量的关系运算。
  对指针变量进行关系运算的规则如下:
     指针变量1 关系运算符 指针变量2
  当两个指针变量的值(地址值)满足关系运算时,结果为1(真);否则为0(假)。所以来年各个指针变量进行关系运算的结果也是逻辑值。
  关系运算符还可以用于两个地址常量之间的比较,或一个地址常量和一个地址变量之间的比较。更为一般的是用于两个地址型表达式之间的比较。例如,定义了数组a和同类型的指针变量p1,p2;使p1指向数组元素a[2];p2指向数组元素a[3]。请看下列的关系表达式及其运算结果:
      p1      p1++==p2   结果为0, 注意++是后缀
      --p2==p1   结果为1, 注意--是前缀
      p1      p1<&a[9]   结果为1, &a[9]上地址常量。
      p2<=a+3   结果为1, a+3是地址表达式,代表a[3]的地址


3. 关于使用“指针法”处理一维数组元素的下标越界问题


  在第四章中曾提到过。采取“下标法”引用数组元素时不检查下标是否越界。同样,用“指针法”引用数组元素时,对下标是否越界也不作检查,即允许下标越界。

5.3.3 指向字符串的指针变量的使用

  当程序中需要用指针变量来处理字符串时,可以定义字符型指针变量,并用赋初值或赋值方式将该字符型指针变量指向对应的字符串。以后就可以使用该指针变量来处理字符串或字符串中的单个字符了。

  如果字符串是存放在某个字符数组中,可以用赋初值或赋值方式将指针变量指向该字符数组,以后可以用指针变量来处理字符数组中存放的字符串,也可以使用指针变量来处理其中的单个字符,处理方法类似于一维数组。
  在C语言中允许直接使用字符串常量,并不一定要求字符串存放在字符数组中。这样的字符串常量可以用字符型指针变量指向它,以后也可以用字符型指针变量来处理这个字符串或字符串中的单个字符。


1.如何将指针变量指向字符串常量


  将指针变量指向字符串常量的方法有两种:第一种方法是给指针变量赋初值的方式,格式为“*指针变量=字符串常量”;第二种方法是先定义一个字符型指针变量,然后通过赋值方式,其格式为“指针变量=字符串常量”。
  假定要求字符型指针变量p指向字符串常量'abc";可以采用下列两种方式:
    方法一 char *p="abcd";
    方法二 char *p;
        p="abcd";

注意可以用赋值方式使指针变量指向字符串常量,但是不允许将字符串常量赋值给字符串数组。例如,下列的程序段是错误的:
         char a[10];
         a="abcd";
  C语言允许在同一个程序中,使用一个字符型指针变量先后指向不同字符串常量。


2.指向字符串常量的指针变量的使用


  当一个字符型指针变量已指向某个字符串常量,就可以利用指针变量来处理这个字符串。处理方式有主要有两种:
  (1)处理整个字符串。
      输出字符串 prinf("%s".指针变量);
      输出新的字符串代替原字符串 scanf("%s",指针变量);
  (2)处理字符串中的单个字符
      第i个字符的表示方法 *(指针变量+i)


3.指向存放字符串的字符数组的指针变量的使用


  当一个字符串已经存放一个字符型数组中,并且用指针变量指向这个字符数组,处理字符串中的单个字符就是处理一维数组的元素,处理方法和前面介绍的处理一维数组完全相同,唯一需要注意的是,数组元素的类型是字符型。
  下面通过一个例子,说明如何用指针变量来处理字符串常量和存放在字符数组中的字符串。

5.3.4 指向二维数组的指针变量的使用

  当定义了二维数组和同类型的指针变量后,可以使这个指针变量指向二维数组的首地址,也可以使这个指针变量指向二维数组中的某个一维数组(前面提到过,二维数组可以看承若干个一维数组),还可以使这个指针变量指向二维数组的某个数组元素。
  由于二维数组的地址表达方式比一维数组复杂,所以,使用指向二维数组的指针变量来处理二维数组元素比处理一维数组要复杂一些。下面我们就分几种情况来讨论。

1. 指针变量指向二维数组的某个元素


  当指针变量指向二维数组的某个元素时,利用指针变量来处理该数组元素和处理一维数组元素的方法相同。
  (1) 让指针变量指向二维数组的某个元素的方法。
    使用赋初值或赋值都可以使指针变量指向二维数组繁荣某个元素。
    用赋初值方式的格式为: *指针变量=&数组名[下标1][下标2]
    用赋值方式的格式为: 指针变量=&数组名[下标1][下标2]

  (2) 二维数组元素的引用方法。
    当指针边来年感已指向二维数组元素后,引用该数组元素的方法是:*指针变量。


2. 指针变量指向二维数组的首地址


  当指针变量指向二维数组的首地址时,也可以处理数组中的任何一个元素。其关键在于如何让指针变量指向某个具体的数组元素。
  (1) 让指针变量指向二维数组首地址的方法。
    使用赋初值或赋值方式都可以使指针变量指向二维数组的首地址。
    用赋初值方式的格式有两种:
      *指针变量=二维数组名
      *指针变量=&二维数组名[0][0] (0行0列元素的地址就是二维数组首地址)
    用赋值方式的格式也有两种:
      指针变量=二维数组名
      指针变量=&二维数组名[0][0]
  (2) 二维数组元素的引用方法
    当指针变量已指向二维数组的首地址后,引用该数组第i行第j列的元素的方法是:
      *(指针变量+i*列数+j)


3. 指针变量指向二维数组中某个一维数组


  在数组一章中曾介绍过二维数组可以看成若干个一维数组。因此,我们可以定义一个指针变量,专门用来指向二维数组中的一维数组,然后利用这样的指针变量来处理对应二维数组中的某个一维数组元素。
  (1) 让指针变量指向二维数组中某个一维数组的方法。
  如果你希望将指针变量指向二维数组中的某个一维数组,首先要按下列格式定义一个指针变量:
     (*指针变量)[m] 其中的m是对应二维数组的列长度。
  然后再用赋初值或赋值方式将该指针变量指向二维数组的首地址,方法和前面介绍的方法完全相同:
     (*指针变量)[m]=二维数组名 赋初值
     指针变量=二维数组名 赋值
  完成上述两项工作后,二维数组中第i行对应的一维数组首地址可以用下列表达式来
获得:
     *(指针变量+i)
  使用这种指针变量,需要注意以下几点:
  a.定义这种指针变量时,圆括号不能丢。
  b.定义这种指针变量时,m必须是整型常量表达式,并且其值要等于希望指向的二维数组的列长度。
  c.定义这种指针变量后,赋初值或赋值时应该赋予列长度为m的二维数组首地址,然后用表达方 式来获  得二维数组中某个一维数组的首地址。
  (2) 二维数组元素的引用方法
  当某个指向一维数组的指针变量已指向对应二维数组的首地址后,就可以用像处理一维数组元素的方式来处理这个二维数组中已指向的一维数组元素。具体格式如下:
     数组元素地址 *(指针变量+行下标)+列下标
     数组元素引用 *(*(指针边来年感+行下标)+列下标)
其中“*(指针变量+行下标)”是行下标对应的一维数组首地址。
  例如语句“int a[2][5],(*p)[5];”定义了二维数组a[2][5]和指向具有5个元素的一维数组指针变量p,并且使p指向二维数组a的首地址。则对应二维数组中2个一维数组的首地址如下:
    二维数组中的一维数组 用指针变量表示对应一维数组的首地址
          a[0] *(p+0)
          a[1] *(p+1)
    二维数组元素的引用格式如下:
    数组元素  a[0][0]   a[0][1]   a[0][3]    a[0][4]
    引用格式  *(*(p+0)+0) *(*(p+0)+2) *(*(p+0)+3)  *(*(p+0)+4)
    数组元素  a[1][0]   a[1][1]   a[1][2]    a[1][3]    a[1][4]
    引用格式  *(*(p+1)+0) *(*(p+1)+1) *(*(p+1)+2)  *(*(p+1)+3)  *(*(p+1)+4)