1.5 指针变量
懂得C语言的人都知道,C语言之所以强大且具有自由性,主要体现在对指针的灵活运用上。因此,说指针是C语言的灵魂一点都不为过。既然指针如此重要,那么指针究竟是什么呢?在回答这个问题之前,我们先通过下面一段代码来看看指针的使用。
include<stdio.h>
int main()
{
int a=2;
int*pa;
char b='t';
char*pb;
pa=&a;
pb=&b;
printf("整型指针pa占用内存大小为:%d字节\n",sizeof(pa));
printf("整型指针pb占用内存大小为:%d字节\n",sizeof(pb));
printf("整型变量a的地址为:\t%d\n",&a);
printf("整型变量b的地址为:\t%d\n",&b);
printf("整型指针pa的值为:\t%d\n",pa);
printf("整型指针pb的值为:\t%d\n",pb);
printf("整型指针pa+1的值为:\t%d\n",pa+1);
printf("整型指针pb+1的值为:\t%d\n",pb+1);
return 0;
}
运行结果:
整型指针pa占用内存大小为:4字节
整型指针pb占用内存大小为:4字节
整型变量a的地址为:1245056
整型变量b的地址为:1245055
整型指针pa的值为:1245056
整型指针pb的值为:1245055
整型指针pa+1的值为:1245060
整型指针pb+1的值为:1245056
现在逐一分析上面的运行结果,为什么指针变量的大小都是4字节呢?这是因为我们使用的是32位的计算机,内存地址都是32位的整数,而指针变量的实质就是内存地址。再看看整型指针变量pa和字符型指针变量pb,它们分别用于存放整型变量a和字符型变量b的地址,在之后使用printf打印语句打印出来的结果中也可以看出,pa和pb中存放的分别是整型变量a和字符型变量b的地址。那么,什么是指针变量呢?存放地址的变量称为指针变量。指针变量是一种特殊的变量,它不同于一般的变量,一般变量存放的是数据本身,而指针变量存放的是地址。再看两种类型的指针的运算结果,对比运算前后的结果发现,两种类型指针加1后的变化值并不相同,如果按照一般的加法来理解,加1以后它们的值都应该增加1,为什么整型指针的值增加的是4,而字符型指针增加的是1呢?下面用图1-4来展示不同类型的变量在内存中是如何分配存储区域的。
在图1-4中,字符变量在内存中占用一个字节的大小,而整型变量在内存中占用4个字节的大小,但是我们发现,指针变量pa指向变量a的地址时取的是存储变量a在内存中的最小存储地址,而所指向的却是占用4个字节大小的内存区域,所以从这里可以看出,我们不能简简单单地将指针理解为地址,而应该把指针理解为指向一块内存区域的起始地址,指向区域的大小视所指变量的类型而定。而指针变量与一般变量的区别就在于,指针变量存放的是地址,看看下面一段代码。
图 1-4 不同类型的指针变量在内存中的存储区域分配
include<stdio.h>
void main(int argc,char*argv[])
{
int a[10];
printf("a的值为:\t%d\n",a);
printf("&a的值为:\t%d\n\n",&a);
printf("a+1的值为:\t%d\n",a+1);
printf("&a+1的值为:\t%d\n",&a+1);
return;
}
运行结果:
a的值为:1245020
&a的值为:1245020
a+1的值为:1245024
&a+1的值为:1245060
很多读者看了上面的运行结果会觉得不可思议,a和&a都表示数组a的起始地址,打印出来的结果相同是显而易见的,为什么a+1和&a+1打印出来的结果却相差如此之大呢?回想前面讲述的内容,出现这种情况的原因是它们是不同类型的指针变量。代码中的a其实相当于一个整型指针变量,所以它加1的结果就和之前的分析一样,那么&a又意味着什么呢?别急,我们先把“int a[10];”变形为“int*(&a)[10];”,这样就可以很直观地看出来,&a就相当于指向一个int[10]类型的指针变量,于是上面的运行结果就很容易理解了,a到a+1的变化就是它指向的变量所占用的内存单元的大小4字节,而&a到&a+1的变化就是它指向的变量所占用的内存单元的大小4×10字节=40字节。
通过前面两段代码的分析,读者对指针变量应该有了更进一步的认识,但是我们不可能就用这么一点内容来讲解指针,后面我们会通过一章的内容来具体讲解指针,这里只是想让读者对于指针变量有一个初步的认识。