# 2.C语言指针变量
变量的指针是变量的地址。 存储变量地址的变量是指针变量。 这意味着c语言允许用一个称为指针变量的变量存储指针。 因此,指针变量的值是变量的地址或称为变量的指针。
为了表示指针变量与其指向的变量之间的关系,程序中用“*”符号表示“指向”。 例如,i_pointer表示指针变量,*i_pointer是i_pointer指向的变量。 因此,以下两个语句的作用相同。
~~~
i=3;
*i_pointer=3;
~~~
第二条语句的含义是将3指派给指针变量i_pointer指向的变量。
#定义指针变量
指针变量的定义有以下三种。
1 .指针类型说明,即定义变量是指针变量;
2 .指针变量名
3 .变量值(指针)指向的变量的数据类型。
其一般形式如下
类型描述符*变量名称
其中*表示这是指针变量,变量名是定义的指针变量名,类型说明符表示本指针变量所指变量的数据类型。
例如:
~~~
int *p1;
~~~
p1是指针变量,表示其值是整数变量的地址。 或者,p1指向整数变量。 应该由给予p1的地址确定p1指向哪个整数变量。
另外,例如:
~~~
int *p2; /*p2是整数变量的指针变量*/
float *p3; /*p3是指向浮点变量的指针变量*/
char *p4; /*p4是指向字符变量的指针变量*/
~~~
应该注意的是,一个指针变量只指向同一类型的变量。 例如,P3只能指向浮点变量,不能指向一个浮点变量,也不能指向字符变量。
##指针变量引用
指针变量和普通变量一样,不仅要在使用前定义说明,而且要给出具体的值。 无法使用未分配的指针变量。 如果不使用,系统会混乱或死机。 指针变量的代入只能赋予地址,不能赋予其他数据。 否则,会发生错误。 在C语言中,变量的地址由编译系统分配,对用户完全透明,用户不知道变量的具体地址。
两个相关运算符:
* :取地址运算符;
* *指针运算符(或“间接访问”运算符)。
c语言提供了表示变量地址的地址运算符。 其一般形式如下
变量名;
例如,a表示变量a的地址,b表示变量b的地址。 变量本身必须事先说明。
存在指向整数变量的指针变量p。 将整数变量a的地址赋予p有以下两种方法。
1 .如何初始化指针变量:
~~~
int a;
int *p=a;
~~~
2 .赋值语句的方法:
~~~
int a;
int *p;
p=a;
~~~
以下赋值是错误的,因为无法为指针变量指派一个数。
~~~
int *p;
p=1000;
~~~
不能在赋值的指针变量之前加上“*”说明符。 *写*p=a也是错误的。 假设:
~~~
int i=200,x;
int *ip;
~~~
我们定义了两个整数变量I,x,还定义了一个整数的指针变量ip。 I、x可以存储整数,但ip只能存储整数变量的地址。 我们可以把I的地址分配给ip :
~~~
ip=i;
~~~
此时,指针变量ip指向整数变量I,假设变量I的地址为1800,则该代入可以想象为下图所示的联系。
! [ ] 65http://www.LV Tao.net/content/uploadfile/201404/08b 21619 F4 BD 7b 69 d 41 CBF FEA 3344 dcb 20140421043835.gif ]
稍后可以通过指针变量ip间接访问变量I。 示例:
~~~
x=*ip;
~~~
运算符*访问以ip为地址的存储。 ip中存储了变量I的地址。 因此,*ip访问地址为1800的存储区(因为是整数,实际上是1800到2字节)。 因为这是I占用的存储空间,所以上述赋值表达式等效于以下内容。
~~~
x=i;
~~~
另外,指针变量和一般变量一样,可以改变存储在它们中的值。 也就是说,你可以改变它们的方向。 假设
~~~
int i,j,*p1,*p2;
i='a ';
j='b ';
p1=i;
p2=j;
~~~
/p>则建立如下图所示的联系。
![](http://www.lvtao.net/content/uploadfile/201404/0d94205245f5a705718cec93f9d4e19920140421043835.gif)
这时赋值表达式:
~~~
p2=p1;
~~~
就使p2与p1指向同一对象i,此时*p2就等价于i,而不是j,图所示。
![](http://www.lvtao.net/content/uploadfile/201404/41a82d267d56a20c24baff12ead080be20140421043836.gif)
如果执行如下表达式:
~~~
*p2=*p1;
~~~
则表示把p1指向的内容赋给p2所指的区域,此时就变成下图所示。
![](http://www.lvtao.net/cpp/uploads/allimg/120129/qwr345fsfds.gif)
通过指针访问它所指向的一个变量是以间接访问的形式进行的,所以比直接访问一个变量要费时间,而且不直观,因为通过指针要访问哪一个变量,取决于指针的值(即指向),例如"*p2=*p1;"实际上就是"j=i;",前者不仅速度慢而且目的不明。但由于指针是变量,我们可以通过改变它们的指向,以间接访问不同的变量,这给程序员带来灵活性,也使程序代码编写得更为简洁和有效。
指针变量可出现在表达式中,设
~~~
int x, y, *px=&x;
~~~
指针变量px指向整数x,则*px可出现在x能出现的任何地方。例如:
~~~
y=*px+5; /*表示把x的内容加5并赋给y*/
y=++*px; /*px的内容加上1之后赋给y,++*px相当于++(*px)*/
y=*px++; /*相当于y=*px; px++*/
~~~
【例10-1】
~~~
main(){
int a,b;
int *pointer_1, *pointer_2;
a=100;b=10;
pointer_1=&a;
pointer_2=&b;
printf("%d,%dn",a,b);
printf("%d,%dn",*pointer_1, *pointer_2);
}
~~~
对程序的说明:
1. 在开头处虽然定义了两个指针变量pointer_1和pointer_2,担它们并未指向任何一个整型变量。只是提供两个指针变量,规定它们可以指向整型变量。程序第4、5行的作用就是使pointer_1指向a,pointer_2指向b。
2. 最后一行的*pointer_1和*pointer_2就是变量a和b。最后两个printf函数作用是相同的。
3. 程序中有两处出现*pointer_1和*pointer_2,请区分它们的不同含义。
4. 程序第4、5行的“pointer_1=&a”和 “pointer_2=&b”不能写成“*pointer_1=&a”和 “*pointer_2=&b”。
请对下面再的关于“&”和“*”的问题进行考虑:
1. 如果已经执行了“pointer_1=&a;”语句,则&*pointer_1是什么含义?
2. *&a含义是什么?
3. (pointer_1)++和pointer_1++的区别?
【例10-2】输入a和b两个整数,按先大后小的顺序输出a和b。
~~~
main(){
int *p1,*p2,*p,a,b;
scanf("%d,%d",&a,&b);
p1=&a;p2=&b;
if(a
p=p1;
p1=p2;
p2=p;
}
printf("na=%d,b=%dn",a,b);
printf("max=%d,min=%dn",*p1, *p2);
}
~~~