下面是一个简略的程序,没有按照标准格式写,大家只需要清楚黑色字体是写在主函数里的,绿色字体当做注释看便可。
int a = 1;
int b = 2;
int c = 3;
int* p = &a;
定义 P 为指针变量,保存的是 a 的地址。这里的 * 是为了说明该变量被定义为了指针变量,int说明该指针变量的类型是整型。整型的指针变量必须保存整型的地址值,即即指针变量的类型必须与被保存的地址值的类型一致。(& 为取地址符)
*p = 100;
这里的 * 是间接访问符,起“解引用”的作用。因为指针变量 p 在上个语句中保存了 a 的地址,然后该语句通过对 p 解引用指向了 a 的地址,同时把 100 放到了该地址处。简单来说该句其实是把 100 赋值给了 a
p = &b;
第一个语句我们知道 p 是保存 a 的地址,而这一句让指针变量 p 保存了 b 的地址。就如同 int t = 3; t = 5; 一样,最后 t 的值 不是 5 吗?至于为什么 p 不带星号?就像 t = 5 也没带 int 一样,变量的类型已经被定义了,不需要重复定义。
*p = 200;
该语句和第四句异曲同工,只不过这里的指针变量 p 保存的值不同,所以这句是把 200 赋值给了 b,在此不赘述。
int** t = &p;
这里是把 t 定义为了一个二级指针变量,其保存的值必须是相同类型的一级指针变量。(如果把 &p 写成 &a 就会报错,因为 a 只是个普通变量)那么什么叫二级指针?我们知道一级指针变量保存的是一个普通变量的地址,那么二级指针变量保存的就是那个一级指针变量的地址,这样说起来可能有些繁琐,如果不明白请继续看下一句。
*t = &c;
t ;二级指针变量
p : 一级指针变量
*t :对 t 解引用
*p: 对 p 解引用
&p : p 的地址
&c : c 的地址
这句的具体含义就是:*t —— &p —— p = &c
其实这句话的就是有让 一级指针变量 p 保存了 c 的地址值,
即把 c 的地址值赋给了 p。
如果后面跟一句 *p = 400,那么就会使 c = 400,没问题吧?
另外,这里还有一个知识点,二级指针是可以直接解两次引用的,如:
**t = 400,这个语句跟上面的结果一样,也是使 c = 400。
过程如下:**t———&p——p——*p——&c——c=400
另外,若平台确定,则指针大小固定。
因为指针实质上是一个内存地址,内存地址的长度跟CPU的寻址有关。
在32位系统上, CPU用32位表示一个内存地址。这样的系统上一个指针占据4个字节。
在64位系统上, CPU用64位表示一个内存地址。这样的系统上一个指针占据8个字节。
所以指针类型和指针大小 是没有关系的。
留个小问题,下面是一段程序,请思考其会输出什么,(后面有答案)
#include<stdio.h>
int main(){
int a = 1;
int b = 2;
int c = 3;
int* p = &a;
*p = 100;
printf("%d,%d,%d\n",a,b,c);
p = &b;
*p = 200;
printf("%d,%d,%d\n",a,b,c);
int** t = &p;
*p = 400;
printf("%d,%d,%d\n",a,b,c);
*t = &c;
*p = 400;
printf("%d,%d,%d\n",a,b,c);
*t = &a;
*p = 400;
printf("%d,%d,%d\n",a,b,c);
return 0;
}
答案是:
100,2,3
100,200,3
100,400,3
100,400,400
400,400,400