赞
踩
在计算机中所有数据都存放在存储器中。
把主存储器中的一个字节称为一个内存单元 ,通过内存单元的编号能正确地访问内存单 元,内存单元的编号也称为地址。
&:取地址运算符。
*: 指针运算符。
int a; //定义一个整型变量a
&a则可以获取到变量a的地址(编号)
可以想象它是:6422020,或者任意数字,总之它是个编号,是个常量
如果要把a的地址,放到一个变量p存起来,则把a的地址赋给p,即:p = &a。
但,有个重要的前提是:定义p是一个指针变量,还得是整型指针变量,因为变量a是整型的
这个是C语言的法则。
如何让p成为一个整型指针变量呢?
可以这么做: int *p; //在定义p的时候,前面加个*号,这个*号就告诉了编译器任命变量p为一个指针变量,专门用于存放地址的,地址一定是一个常量。而写在更前面的类型说明符 int 则是要求变量p存的这个地址它对应的变量是整型变量
那么如何取到a的值呢?
两种方法:可以用*p,也可以直接用a 来取。*p和a是等价的。听起来有点拗口?用程序+图来说明:
6466020是变量a的地址,此时a的“肚子”里有个值是100,变量p的“肚子”里有个值是6422020(&a取出来的a的地址)( 6666666是p的地址,这里没必要画出来,但是觉得画出来比较完整吧)*p这个针是扎进了这个地址对应的变量a的肚子里,取出来的是a的值100。对于*p,教科书上的解释是:p指向了变量a。 我觉得指来指去很难理解,于是我把指针理解成打针的针,一旦某个变量前面加了个*,这个变量就变成了个针筒,比如*p,这个针*p戳到哪,吸出来什么,是由它的变量肚子装的哪个地址决定的,就是往哪戳总要有个目标吧。比如这里的针 *p, 变量p肚子里的地址是6466020,于是它戳进了地址6466020对应变量a的肚子,吸出来了个值:100
简单来讲:*p 就是为了取变量p拿到的地址对应内存里的值 (从硬件方向去理解)
简单来讲:*p 就是为了取变量p拿到的地址对应变量里的值 (从软件方向去理解)
上面两句话是一个意思,总之硬件上就是一个“肚子”,一个“房间”,一个“空间”,软件上它总得有个名,变量a,b,c 什么的都行
如果这样定义p : int p,没有*号,那么p肚子里是装不了a的地址的,float *p也不行,float *p 定义后,p只能装float类型的变量的地址,比如以下这样定义才是合法的:
float *p;
float a;
a = 3.14159;
p=&a;
那么如何改变a的值呢?
同理也是两种办法:
a = 5.9999;
或者 *p = 5.9999
——————————————————————————————————————————
*p总结完了,**p呢?
我为什么把指针的针想象成打针的针,也是因为理解完**p后决定的。
如果定义了**p,那么给p赋值的时候,仍然要求是个地址,而且还得是指针变量的地址,不能是其他的值,比如值是整型的100之类的变量的地址是行不通的,不符合法则的
先上一段不符合法则的代码:
代码段①:
int **p;
int a;
a = 100;
p=&a;
第四行这里,编译器是不会通过的。
再上一段符合法则的代码:
代码段②:
int **p,*t;
int a;
a = 100;
t = &a;
p=&t;
**p 我认为可以按套娃的模式来理解了:
如果是定义的是int *p,只有一个*号,那就只有一针,一针戳到的肯定是整型变量的地址,不可能戳到的是其他类型的,因为*p要吸出来的值肯定得是个整型。
如果定义的是int **p,有两个*号,那用**p取值的时候就得是两针,一针下去戳到的得是整型指针变量的肚子,图上的变量t就是个整型指针变量,如果是别的类型的地址,则不合法,所以代码段①这里把&a直接给到p的话编译器不会通过,因为第二针都还没打,戳一针就到头了。代码段②里把整型指针变量的地址给到p才是正确的,p=&t; 这个语句,使得*p一针戳到整型指针变量t的肚子里,吸出了个变量a的地址4444444, 使得**p这第二针下去戳到了变量a的肚子,吸出来值100, 还有,*t也是可以吸出100的
**p 和 *(*p)是等价的,毕竟是从右到左的运算规则,不管定义了*p 和 **p,在给p赋值的时候都得给的是地址,只不过定义*p的话一针就要到头了,而定义**p是需要两针才到头 ,多少*就戳多少针,最后一针吸出来的值类型要和定义时的类型说明符一致。
定义int **p ,*p一针取出来的是地址,**p两针后取出来的就得是int类型的值。
定义int *p,那么*p一针取出来的就得是int类型的值,没有**p,因为没有两针,预约的是一针。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。