数据内存中的地址也称为指针,如果一个变量存储了一份数据的指针,我们就称它为指针变量。
定义指针变量
定义指针变量与定义普通变量非常相似,不过要在变量名前加星号 * ,格式为:
datatype *name ; 或者dataype *name = value;
* 表示一个指针变量,datatype表示该指针变量所指向的数据的类型。例如:
int *p1;
p1 是一个指向int 类型数据的指针变量,至于p1究竟指向哪一份数据,应该赋予它的值决定。再如:
int a = 100;
int *p_a = &a;
在定义指针变量p_a 的同时对他进行初始化,并将变量a的地址赋予它,此时p_a就指向了a。值得注意的是,p_a需要的一个地址,a前面必须要加取地址&,否则是不对的;
和普通变量一样,指针也可以被多次写入,只要你想,随时能够改变指针变量的值:
//定义普通变量 float a = 99.5,b = 10.6; char c = '@' ,d = '#'; //定义指针变量 float *p1 = &a; chat *p2 = &c; //修改指针变量 p1 = &b; p2 = &d;
* 是一个特殊符号,表明一个变量是一个指针,定义p1/p2必须带 * ,而给p1.p2赋值时,因为已经知道它时一个指针变量,就没必要多此一举再带上 * 号,后面可以像使用普通变量一样使用指针。
通过指针变量取得数据
指针变脸存储了数据的地址,通过指针变量能够获得该地址上的数据,格式为:
*pointer;
这里的 * 称为指针运算符,用来取得某个地址上的数据,请看以下代码:
#include <stdio.h> int main() { int a = 15; int *p = &a; printf("%d,%d\n",a,*p); retrun 0; }
使用指针可以间接获取数据,使用变量名时直接获取数据,前者比后者的代价要高
指针除可以获取内存的数据,也可以修改,也可以修内存上的数据,例如:
#include <stdio.h> int main() { int a = 15,b = 99,c = 222; int *p = &a; //定义指针变量 *p = b; // 通过指针变量修改内存上的数据 c = *p; //通过指针变量获取内存上的数据 printf("%d,%d,%d,%d \n",a,b,c,d); retrun 0; }
运行的结果全为99;
*p代表的是a中的数据,它等价于a,可以将另外一份数据赋值给它,也可以将它赋值给另外一个变量
* 在不同的场景下有不同的作用:*可以用在指针变量的定义中,表明是一个指针变量,以和普通变量区分开;使用指针变量时在前面加 * 表示获取指针指向的数据,或者说表示的是指针指向的数据本身
也就是说,定义指针变量时的 * 和使用指针时的 * 意义完全不同,例如以下代码:
int *p = &a; //指明p是一个指针变量 *p = 100; // 用来获取指针指向的变量
需要注意的是,给指针变量本身赋值时不能加 * , 修改上面的代码:
int *p; p = &a; //不能再p的前面加 * *p = 100;
指针变量也可以出现在普通变量能出现的任何表达式中,例如:
int x,y,*px = &x,*py = &y; y = *px + 5; //表示把x的内容加5并赋值给y,*px + 5 相当于(*px) + 5 y = ++*px; // px的内容加上1之后赋值给y,++*px相当于++(*px) y = *px++; // 相当于 y = (*px)++ py = py; // 把一个指针的值赋给另一个指针
关于 * 和 & 的谜题
假设有一个 int 类型的变量a,pa是指向它的指针,那么*&a 和 &*pa分别是什么意思呢?
*&a可以理解为*(&a),&a表示取变量a的地址(等价于pa),*(&a)表示取这个地址上的数据(等价于*a),绕来绕去,又回到了原点,*&a仍然等价于a.
&*pa可以理解为&(*pa),*pa表示取得pa指向的数据(等价于a),&(*pa)表示数据的地址(等价于&a),所以&*pa等价于pa。
对于星号 *的总结
星号的主要三种用途
1.表达乘法
2.表示定义一个指针的变量,以和普通变量区分开,例如 int a = 100;int *p = &a;
3.表示获取指针指向的数据,是一种间接操作,例如 int a,b,*p= &a;*p = 100;b = *p;