在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程序设计 第三版 谭浩强 著、黑马程序员入学基础视频