C语言指针变量的定义和使用(精华)
"数据"在内存中的"地址"也成为"指针",如果一个变量存储了一份数据的"指针",我们就称它为"指针变量"。
在C语言中,允许用一个 变量 来存放 指针,这个变量我们称它为指针变量。
"指针变量的值"就是某份数据的"地址",这样一份的数据可以是"数组、字符串、函数,页可以是另外的一个普通变量或者指针变量"
现在我们假设有一个"char类型的变量c"它存储了一个字符'K'(ASCII码为 十进制的75),并占用了地址为OX11A的内存(地址通常用十六进制表示)
另外有一个"指针变量p"它的值为OX11A,正好等于"变量c的地址",这种情况下就称"p指向了c"或者说"p是指针变量c的指针"。
一、定义指针变量
它与普通变量的定义非常相似,不过要在"变量名"前面加个 星号 *
格式为:
datatype *kangkang;
或者:
datatype *kangkang = 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 = 'q',d = '#'
//定义指针变量
float *p1 = &a;
char *p2 = &c;
//修改指针变量的值
p1 = &b;
p2 = &d;
//注意!!
1. *是一个特殊的符号,表明一个变量是指针,定义p1、p2时必须带上 * 。
2. 而给p1、p2 "赋值"时,因为编译器已经知道它是一个指针变量,所以就不用再多此一举了,就可以跟使用普通变量一样来使用指针变量。
3. 也就是说,定义指针变量时必须带*,给指针变量赋值时不能带*。
指针变量也可以连续定义噢!
例如:
int *a,*b,*c; //指针a b c的类型都为int*
注意每个变量前面都要带*。如果写称下面的形式,那么只有a是指针变量,bc都是int类型的普通变量。
int *a,b,c; //只有a是 int*
二、通过指针变量取得数据
指针变量存储了"数据的地址",通过指针变量能够获取到"该地址上的数据"。
格式为:
*kangkang;
* 称为"指针运算符",用来取得某个地址上的数据。
//举个程序例子吧
#include<stdio.h>
int main()
{
int a = 15;
int *p = &a;
printf("%d,%d\n",a,*p);
return 0;
}
结果:
15,15
假设 a 的地址是 0X1000,p 指向 a 后,p 本身的值也会变为 0X1000,*p 表示获取地址 0X1000 上的数据,也即变量 a 的值。从运行结果看,*p 和 a 是等价的。
//指针除了可以获取内存上的数据,也可以修改内存上的数据,
例如:
#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,*p);
return 0;
}
结果为:
99,99,99,99
*p 代表的是 a 中的数据,它等价于 a,可以将另外的一份数据赋值给它,也可以将它赋值给另外的一个变量。
* 在不同的场景下有不同的作用:
1. *可以在指针变量的定义中,表明这是一个指针变量(让大家可以将它与普通变量区别开)
2. 是用"指针变量"时在 前面加* 表示"获取指针指向的数据",或者说 表示的是"指针指向的数据本身"。
也就是说,"定义指针变量时的*"与 "使用指针变量时的*" 意义完全不同。
具体如下:
int *p = &a;
*p = 100;
第一个 代码中 * 用来指明p是一个指针变量
第二个带啊吗中 * 是用来获取指针指向的数据
"需要注意的是":给指针变量本身"赋值"时 不能加 *
如下:
int *p;
p = &a; //给指针变量本身 赋值!!!
*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 = px; //把一个指针的值赋给另一个指针
为了让大家更易理解,下面再举个程序例子吧!
//eg通过指针交换两个变量的值。
#include<stdio.h>
int main()
{
int a = 100,b = 999,temp;
int *pa = &a;
int *Pb = &b;
printf("a=%d,b=%d",a,b);
//进入交换!!!
temp = *pa; //将a的值先保存到temp上
*pa = *pb; //将b的值交给a;
*pb = temp;//最后将保存起来的a值交给b
//结束交换,输出最终结果
printf("a=%d,b=%d\n",a,b);
return 0;
}
结果:
a=100, b=999
a=999, b=100
从运行结果可以看出,a、b 的值已经发生了交换。需要注意的是临时变量 temp,它的作用特别重要,因为执行*pa = *pb;语句后 a 的值会被 b 的值覆盖,如果不先将 a 的值保存起来以后就找不到了。
三、关于 * 和 & 的谜题
假设有一个int类型的a, pa是指向他们的指针, 那么 *&a 和*&pa 分别是什么意思呢?
*&a可以理解为 *(&a), &a表示"取变量a的地址",等价于(pa),所以*(&a)表示取这个地址上的数据(等价于*pa),绕来绕去,又回到原点,*&a仍然等于a。
&*pa可以理解为 &(*pa), *pa表示"取得pa指向得数据(等价于a)", &(*pa)表示数据的地址(等价于&a),所以&*pa等价于 pa。
四、对 星号* 的总结
在我们目前所学到的语法中,星号*主要有三种用途:
表示乘法,例如int a = 3, b = 5, c; c = a * b;,这是最容易理解的。
表示定义一个指针变量,以和普通变量区分开,例如int a = 100; int *p = &a;。
表示获取指针指向的数据,是一种间接操作,例如int a, b, *p = &a; *p = 100; b = *p;。