指针-数组的基本概念与辨析

一、数组元素的指针的定义:


所谓数组元素的指针就是数组元素的地址。



我们可以这样理解,先前我们说到,指针就是变量的地址。


那么数组是可以包含多个元素的,每一个变量在内存中都会占用空间,就用有相应的地址。


所以,数组元素的指针,就是记录了数组中各个元素的地址。


当然,不可能一次性记录完,而是通过数据在内存中的存储规律,


通过给定义一个数组元素初始的地址,根据计算获得该数组中的其它地址


举例:


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


int *p;


p = &a[0];


p = a;


上面的例子中,我们定义了一个数组和一个指针


然后,我们将该数组中第一个元素的地址 赋值给指针变量p。


所以指针p就指向a[0] 这个地址。


在数组中,单独的数组变量名代表的数组第一个元素的地址


所以说 a = &a[0]


那么,我们也可以用 p = a 来获得一个数组元素的地址


当然,我们在定义指针的时候,可以进行初始化的。


如: int *p =a;  它的作用是a数组的首元素地址赋值给了指针变量p,而不是赋值给了 *p


总之,记住一点,指针是表示地址的,指针变量表示的是地址的值



二、在引用数组元素指针的运算


我们提到指针就是地址,对地址进行赋值运算时没有问题的,但是算数运算呢?


+ - * /


首先对地址的*、/ 是没有意义的,因为得到的东西是没有任何意义的。


那么 +、- 呢?


例:int a[10] = {1,2,3,4,5,6,7,8,9,0};


      int *p = a;


此时,p是 a[0]的地址 ,那么p+1 就是a[1]的地址了。


当然,它在真正编译的时候,p+1所代表的地址是 p+1*d  , d是一个数组元素所占的字节数


如下:

 

 

#include <stdio.h>
int main(){
	int a[10] = {1,2,3,4,5,6,7,8,9,0};
	int *p = a;
	printf("p的初始地址是%d:\n",p);
	printf("p的值是%d:\n",*p);
	
	p++;
    printf("p++的初始地址是%d:\n",p);
	printf("p++的值是%d:\n",*p);
	
    p = p+3;
    printf("p+3的初始地址是%d:\n",p);
	printf("p+3的值是%d:\n",*p);
}

 

 结果:

 

 

p的初始地址是2293520:
p的值是1:
p++的初始地址是2293524:
p++的值是2:
p+3的初始地址是2293536:
p+3的值是5:
请按任意键继续. . .

 


三、通过指针引用数组元素


(1)下标法:如a[i] 形式


(2)指针法: 如*(a+i) 或 *(p+i)。其中a是数组名,p是指向数组元素的指针的指针变量,其初值p=a。


举例说明:


例:有一个整型数组a,有10个元素,要求输出数组中的全部元素。


(1)下标法:

 

 

#include <stdio.h>
int main(){
   int a[10];
   int i;
   printf("please enter 10 integer numbers:");
   for(i=0;i<10;i++)
       scanf("%d",&a[i]);
   for(i=0;i<10;i++)
       printf("%d ",a[i]);

   printf("%\n");
   return 0;
}
 


(2)通过数组名计算数组元素地址,找出元素的值。

 

 

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

 


(3)用指针变量指向数组元素


 

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

 

 

在上述的三个例子中,我们分别用了下标法、指针法来控制输出的变量。


首先,下标法用的是我们最熟悉的数组下标,即a[i],前面 通过循环来改变i下标值的大小 ,并通过下标法来输出存放在数组中的变量。


指针法分别用了两种不用的形式,一个是直接用数组变量名,比如a,a代表数组的首地址,则*a是数组首地址的值,那么随着下标的递增,*(a+i) 就是 数组a的第i个值。


这里需要注意的是,数组a 是指针型常量,所以 如果用a++ 来移动指针,用*a来获得指针所指向的值,这种方法是不行的。


如下:


for(p=a;a<(p+10);a++)

     printf("%d",*a);


程序会报wrong type argument to increment  错误 ,


所以我们只要 记住 ,数组的变量是 指针型常量,它是无法通过自增 来改变 地址的位置的。



对于第三个例子,我们用一个指针变量指向 该数组,因为该指针变量不是常量,所以它可以递增。


当使用p=a ,p++;时 ,它的位置会指向下一个数组元素的位置。


所以,我们可以直接用 *p 来获取该指针所指向数组的 元素。



在第三个例子中,我们也用的数组下标地址的方式来存取需要输入的数字,


现在,我们将scanf方法也改成指针的方式:

 

 

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

 

 


下面,我们给出一个指针和 变量同时使用的例子


例:通过指针变量输出整型数组a的10个元素。

 

 

#include <stdio.h>
int main(){
     int *p,i,a[10];
     p = a;
     printf("please enter 10 integer numbers:");
     for(i=0;i<10;i++)
         scanf("%d",p++);

     for(i=0;i<10;i++,p++)
         printf("%d",*p);

     printf("\n");
     return 0;
}
 

 

上面的例子中,我们发现,结果并不是我们想要的数据,这其中主要原因就是,p所指向的地址不正确,


在第一个for循环体中,经过10轮循环,p指向的位置是数组第10个元素的地址,


所以 ,在第二个for循环中,p指向的是 数组第11-20的地址,当然,这些地址的值是不存在的,所以输出的结果也是不正确的。


那么我们如何解决这个问题的, 解决办法就是,在第二次for循环的开始,让p重新指向数组的初始位置


即p=a


我们看下面例子:

 

#include <stdio.h>
int main(){
     int *p,i,a[10];
     p = a;
     printf("please enter 10 integer numbers:");
     for(i=0;i<10;i++)
         scanf("%d",p++);
         
     p = a;
     for(i=0;i<10;i++,p++)
         printf("%d ",*p);

     printf("\n");
     return 0;
}
 

 

由于*p++  是右运算符,所以,上述的程序又可以改成

 

#include <stdio.h>
int main(){
     int *p,i,a[10];
     p = a;
     printf("please enter 10 integer numbers:");
     for(i=0;i<10;i++)
         scanf("%d",p++);
         
     p = a;
     for(i=0;i<10;i++,p)
         printf("%d ",*p++);

     printf("\n");
     return 0;
}
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值