一.概述:
直接引用:
char a; a = 10;
我们通过变量名来直接引用变量,然后进行赋值.
看似简单,但是系统会自动将变量名a转换为变量的存储地址,根据地址找到变量a的存储空间,然后再将数据 10 以二进制的形式放入变量a的存储空间中。
通过变量名引用变量,由系统自动完成变量名和存储地址之间的转换,称为变量的“直接引用".
二.什么是指针
一.间接引用:
存放变量地址的变量,我们称之为"指针变量", 变量p中存储的是变量a的地址,那么p就可以称为是指针变量,或者说p指向a。
根据"直接引用"的理解,当我们通过p取得a的时候首先把p转换成p对应的存储地址,再根据这个地址找到对应的存储空间中拿到存储内容,p存储的内容就是a的地址,然后根据这个地址到对应的存储空间中取得对应的数据,这个数据就是a的值.
这种通过p找到a对应地址再取值的方式称为“间接引用”.
二.指针的定义:
2.1 类名标识符 *指针变量名
int *p; double *q;
2.前面的类型标识符表示指针变量所指向的变量的类型,而且只能指向这种类型的变量
2.2指针的初始化
// 定义int类型的变量a int a = 10; // 定义一个指针变量p int *p; // 将变量a的地址赋值给指针变量p,所以指针变量p指向变量a p = &a;
&取地址符号
//也可以这样 int *p = &a;
注意:不能给指针变量赋值常数
int *p; //错误 p = 200;
2.3.给指针指向的变量赋值(修改)
int a = 10; printf("修改前,a的值:%d\n",a); //10 int *p =&a; //通过指针变量的p间接修改变量a的值 *p = 9; printf("修改后的,a的值:%d",a); // 9*p =9 *p(取值):取出p存储的a的变量的地址访问对应的存储空间,也就是a的存储空间。
可以发现,我们通过变量p间接修改了变量a的值
注意:
在指针变量没有指向确定地址之前,不要对它所指的内容赋值。
int *p; //错误,没有指向确定的地址 *p = 10;
正确的写法:
int a = 7,b; int *p = &b; *p = a;
三.关于指针的疑问.
1.一个指针变量占用多少个字节的内存空间?占用的空间是否会跟随所指向变量的类型而改变?
在同一种的编译器环境下,一个指针变量所占用的内存空间是固定的.
2.既然每个指针变量所占用的内存空间是一样的,而且存储的都是地址,为何指针变量还要分类型?而且只能指向一种类型的变量?比如指向int类型的指针、指向char类型的指针。
例子:
int i =2; char c = 1; //定义一个指向char类型的指针 char *p = &c; //取出 printf("%d",*p); //打印1
如果改了 char *p = &c 为 int *p = &c;
输出的值为:513;
wtf什么回事?
假设在16位编译器下,指针字节为2
由于局部变量的是存储在栈里面,先存储 i 再存储 c 、p.
其中,指针变量p和int类型变量i各占2个字节,char类型的c占一个字节,p指向c,因此p值就是c的地址.
1.最初的时候,我们用char *p指向变量c。当利用*p来获取变量c的值时,由于指针p知道变量c是char类型的,所以会从ffc3这个地址开始读取1个字节的数据:0000 0001,转为10进制就是1
2. 后来,我们用int *p指向变量c。当利用*p获取变量c的值时,由于指针p认为变量c是int类型的,所以会从ffc3这个地址开始读取2个字节的数据:0000 0010 0000 0001,转为10进制就是513
可见,给指针分类是多么重要的一件事,而且一种指针最好只指向一种类型的变量,那是最安全的。