指针的作用
※处理大量数据:编写大型软件时,函数与函数之间经常会传送大批量的数据。比如一个班有50个学生,有一个子函数的作用就是将这50个学生的成绩进行排序,再返回给父函数。如果用之前学过的“参数复制”方式,我们就要定义一个有50个参数的子函数,并且子函数只能有一个返回值,不能实现这个功能。
这时候父函数可以将第一个同学的座位号(指针)传给子函数,一个参数就能搞定。
※改变父函数中变量的值。
※高手用来提高程序运行速度。
内存和地址
※许多馆子店在管理房间时,会给每个房间编号,同时会给房间取个名字,比如“水云阁”,“碧玉居”等等。那么名字就是我们平时所说的“变量名”,编号就是我们所说的“指针”,俗称“内存地址”。
※指针也是变量,它也要占用内存,它不存储“整数”,“实数”这种普通数据,它存的是其它变量的“地址”,占用4字节内存。
指针的定义和使用
普通变量定义时,前面加个*就是指针的定义。一般来说,我们都会在指针类型的变量名前面加p,表示pointer(指针)的意思。
指针也是变量,它也要占用内存,只是它不是存“整数”,“实数”,它存的是其它同种类型变量的“地址”。就像一个抽屉A,里面什么也不放,只放着另一个抽屉B的钥匙,若想拿到抽屉B中的物品,必须先从抽屉A中取钥匙。
下面我们来看一个指针的执行情况:
int i=15,j=0; /*定义2个普通变量*/
int *pi,*pj=0; /*这行定义2个指针,pj初始化为空指针*/
pi=&i; /*用&运算符将i的地址赋给指针pi*/
注意:
※可以将地址0赋给指针,如pi=0时,系统会自动将0转成空地址赋给pi。
※等号左边只允许是容器,右边只允许是数值。如果右边是容器,它会自动取出容器里的数值。
※ * 在定义时出现表示定义指针,在表达式中出现表示取值。它还有个作用就是做乘号,这时它是个双目运算符。
如:
int i=5,j=0,*pi; /*定义指针*/
pi=&i;
int *pj=pi; /*定义指针*/
j=*pi; /*取值*/
*pi=50;
j=i*5; /*作为乘号*/
提问:
int i;
int *pi=&i;
这个*是定义变量还是取值?
实际上系统看见“变量定义”与“表达式”合成的语句,会自动分解。如上式会被分解为:
int *pi;
pi=&i;
int *p1=&a,*p2=p1;会被分解为:
int *p1,*p2;
p1=&a;
p2=p1;
思考一下:int *p=p1;和*p=*p1;的含义各是什么?
程序1
用指针间接操作2个变量
// 25-1用指针操作两个变量.c #include <stdio.h> void fun1() { int a = 0, b = 0; //定义两个普通变量 int *p; // 定义指针变量 p = &a; //取变量a的内存地址,(&是取址运算符)赋值给指针p *p = 30; //把30赋给指针p指向的变量中(*是取变量运算符,与&相反) // p 指向 a p = &b; //取变量b的内存地址,(&是取址运算符)赋值给指针p *p = 50; //把50赋给指针p指向的变量中 // p 指向 b printf("a = %d,b = %d", a, b); } void fun2() { int a = 10, b, *p1, *p2; //定义普通变量 指针变量 p1 = &a; //取变量a内存地址赋值给p1 b = *p1; // *p1取值 赋值给 变量b //若b = p1的 值就是: p1里面存的a的内存地址 赋值给变量 b printf("%d,%d ", a, b); //result : a = 10 b = 10 p2 = p1; //指针赋值 p2指针也指向变量a的内存地址 //如果 p2 = *p1 相当于 *p1取值里面是:10 赋值给p2 //如果 *p2 = p1 报错 b = 20; p1 = &b; *p2 = *p1; //取p1的内容赋给p2指向的变量 printf("a=%d,b= %d ", a, b); } main() { fun2(); }
※指针就相当于存放着各变量的钥匙,得到变量的钥匙用&i,从指针中拿钥匙取值就用*pi
※指针不能指向不同类型的变量。
如:
float f=3.14;
int *pi=&f; /*错误*/
※指针在定义时*号可以靠着类型,也可以靠着变量,但中间一定要有空格。通常定义函数返回值时靠着类型,定义变量时靠着变量。为什么呢?
如:
int* pi,pj;
/*此写法容易误认为定义了2个指针,实际上pj是整型变量*/
int *p,pj; /*立刻就看出第二个不是指针*/
因为函数不可能定义多个返回值,所以*号可以靠着类型。
int* fun(){…} /*表示此函数返回一个整型指针*/
int *fun(){…}
/*此写法容易误认为定义了指向函数的指针*/