数组与指针


在C语言中,数组是用来存储相同数据类型的数据的一种数据类型,它常用来存储int、flota、double、char等类型的数据,而数组名,则相当于元素的首地址,我们可以通过数组名来获得数组的是地址,特别对于char类型的数组,我们可以用数组名就对它进行输入输出等操作。

指针其实就是地址,我们常说的指针变量,其实就是一个存储地址的变量。

对于一个变量,我们可以使用一个指针来指向它,那么对于一个数组呢?数组包含若干个相同元素,它在内存中同样占据相应的内存空间,也就拥有相应的地址。此时我们就可以使用指针变量来指向数组,并通过指针来对数组进行操作。

 

1.    使用指针变量指向数组。

一般形式:

int a[5];

int *p;

p = a;

int *p = a;

注意到,上面指针的类型为int,数组的类型也为int。

与指针的一般用法相同,即指针类型必须声明为和所指向的数据类型一致,即此时若将数组声明为一个float类型的数组,那么指向数组的指针也必须声明为float 类型。

由于在C语言中首地址与数组第一个元素的地址相同,上面对指针的定义也就等价于:

int *p;

p = &a[0];

int *p =&a[0];

这两种声明的作用是将数组的地址赋值给指针p,方便我们直接用指针对数组进行操作。

注意:数组名只是数组在内存空间中的首地址,并不代表整个数组。

 

2.    使用指针操作数组

C语言中规定,如果指针变量p指向一个数组元素,那么,对于p+1并不是仅仅将指针变量p的地址加上1,而是指向了数组的下一个元素。如果指针变量p指向的数组是双精度类型的数组,数组的单个元素在内存中占用8个字节,那么p+1就相当于将指针变量p加上8,使p+1指向数组的下一个元素。

对于

int *p =&a[0];

的情况下:

 

(1)    p+i和a+i都相当于a[i]的地址,它们都指向数组a的第i个元素。

 

(2)    *(p+i)和*(a+i)的值都为a[i]。(由于数组名即数组在内存中的首地址,那么数组名也就可以当做一个指针来用,但是数组名并不能被赋值为新的地址,其值是不变的。)

此处和指向单个常量的用法一致,使用*加上指针变量名,就得到所指向变量的值。

如*(p+3) == *(a+3) == a[3]。

 

(3)    *(p+i)等同于p[i]。

即指向数组的指针变量也可以看做是数组名来使用。

使用示例:

 

输出数组的值,方法一:

<span style="font-size:14px;">#include <stdio.h>

void main()
{
       int a[5];

       printf("请输入五个数字:\n");

       int i;

       for(i = 0; i<5; i++)

       {
              scanf("%d",&a[i]);

       }
 
       int *p;

       p = a;

       for(i = 0; i<5; i++)

       {
              printf("%d,",*(p+i));
       }
}
</span>

方法二:

<span style="font-size:14px;">#include<stdio.h>

void main()

{
       int a[5];

       printf("请输入五个数字:\n");

       int i;

       for(i = 0; i<5; i++)

       {
              scanf("%d",&a[i]);
       }

       int *p;

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

       {
              printf("%d,",p);
       }
}</span>

对比两种方法,方法二的执行效率是远高于方法一的,因为方法一中每次都会令i加上1,然后从数组中找第i个元素,计算地址,最后才输出,第二种方法直接令地址做出计算,得出第i个元素的地址,输出a[i]的值。

3.      数组名作函数参数

使用形式:


<span style="font-size:14px;">#include<stdio.h>

void main()

{
       void s(int a[],int n);

       int array[10];

       void s(array,5);

}

void s(int a[],intn)

{

}</span>

在这种情况下使用数组名,数组名是当做指针型数据来使用的,即给函数所传递的数据是一个指针型数据,可以用下面的代码来验证。

<span style="font-size:14px;">#include<stdio.h>

void main()

{
       int s1(int a1[]);

       int s2(double a2[]);

       int array1[10];

       double array2[10];

       int size1 = s1(array1);

       int size2 = s2(array2);

       printf("size1=%d,size2=%d\n",size1,size2);
}

int s1(int a1[])
{
       return sizeof(a1);
}

int s2(doublea2[])
{
       return sizeof(a2);
}</span>

最终输出结果,size1 = 4,size2 = 4。

即无论数组存储的是什么类型的数据,在把数组名作为函数参数时,数组名都默认为指针型数据,其在内存中占用四个字节的存储空间。


学习资料:C程序设计   第三版  谭浩强 著、黑马程序员入学基础视频

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值