在C语言中,我们平时所说的指针,其实就是指的是变量的地址。地址指向变量单元,一个形象的例子:就像一个房间号“指向”某一个房间。然后,通过地址,可以找到与之对应的内存单元。
为了更清楚什么是指针,必须弄清楚数据在内存中是如何存储、读取的。
一、数据存储介绍
程序中定义一个变量,在对程序进行编译时,系统就会这个变量分配内存单元。编译系统根据程序中定义的变量类型(一般整型分配2个字节,单精度浮点型分配4个字节),分配一定长度的空间。内存区的每一个字节有一个编号,这个编号便是“地址”,它就相当于房间号。在地址所标志的内存单元中存放数据,这相当于房间中居住的旅客一样。
二、指针变量的引用
在指针变量中只能存放地址,不能将其他非地址类型的数据赋给一个指针变量。
有两个运算符:
&:取地址运算符; &a为变量a的地址。
*:指针运算符,取指针所指向的对象的内容;*p为指针变量p所指向的存储单元的内容(p所指向的变量的值)
下面用排序的例子来理解下:
int main()
{
int *p1,*p2,*p,intA,intB;
scanf("%d,%d",intA,intB);
p1=&intA;
p2=&intB;
if(intA<intB)
{
p1=&intB;
p2=&intA;
}
printf("intA=%d,intB=%d\n",intA,intB);
printf("max=%d,min=&d\n",*p1,*p2);
return 0;
}
在这个程序中,intA、intB的值其实没有交换,而p1和p2的值却交换了。在这个算法中,不交换整型变量的值,而是交换两个指针变量的值(即intA和intB的地址)
同样的例子,我们也可以用函数的形式来调用,具体看注释:
#include <stdio.h>
void main()
{
void swap(int *p1,int *p2); /*声明交换函数*/
int intA,intB;/*声明整型变量*/
int *pointerOne, *pointerTwo;/*声明两个指针变量*/
scanf("%d, %d", &intA, &intB);
pointerOne=&intA;/*intA的地址赋给指针变量pointerA,使pointerA指向intA*/
pointerTwo=&intB;/*intA的地址赋给指针变量pointerB,使pointerB指向intB*/
if (intA>intB) /*比较intA和intB的大小*/
swap(pointerOne,pointerTwo);/**/
printf("\n%d,%d\n",intA,intB);/*输出结果*/
}
/*交换函数*/
void swap(int *p1,int *p2)
{
int intTemp;/*声明整型临时变量*/
intTemp=*p1;/*将*p1的值赋给intTemp*/
*p1=*p2;
*p2=intTemp;
}
上面的代码中,在函数调用的时候,将实参变量的值传送给形参变量,采用的依然是“值传递”方式,因此虚实结合后形参p1的值为&intA,p2的值为&intB,这是p1和pointerOne都指向变量intA,p2和pointerTwo都指向intB。函数调用结束后,形参p1和p2将释放。
再来看swap交换函数,如果把"intTemp=*p1"写成"*intTemp=*p1",就有问题了。*p1就是intA,而*temp是指针变量intTemp所指向的变量。但是intTemp中并没有确定的值。所以,对*intTemp赋值有可能给一个存储着重要的存储单元赋值,这样会破坏系统的正常工作状况。应该将*p1的值赋给一个整型变量,本例中就是用整型变量intTemp作为临时辅助变量来实现*p1和*p2交换的。
本例中算法是交换intA和intB的值,而p1和p2的值不变,与第一个例子相反。
下面再来看指针在数组中的用法
指针引用数组元素:如果指针变量p已指向数组中一个元素,则p+1指向同一数组中的下一个元素,而不是将p的值简单的加1。p+1所代表的地址实际是p+1xd,d表示一个数组元素所占的字节数。
下面来看三级网络中的一个小例子,该例子实现所有字符串左移动一个位置,第一个字符串移动到最后一个位置:
void chg(char *chrS)
{
int intI;
char chrFirst,*p=chrS;/*定义字符串变量chrFirst,和字符串指针变量*p,并使p指向chrS*/
chrFirst=*chrS;/*把字符串chrS的第一个字符赋给chrFirst*/
for(intI=0;intI<(int)strlen(chrS)-1;intI++)
*(p+intI)=*(p+intI+1);/*字符串向左移动一位*/
p[strlen(chrS)-1]=chrFirst;/*将第一个字符串移动到字符串chrS的最后位置*/
}