1. 内存是如何存放变量的.
通过变量名对变量进行访问和存储是为了方便程序员而设计的,其实内存中完全没有存取变量名的必要.因为编译器知道具体每一个变量名对应的存放地址,所以当你读取某一个变量名之后,编译器会找到变量名所在的地址,并根据变量的类型读取相应范围的数据.
2. 指针和指针变量
通常我们说指针就是地址的意思.C语言中有专门的指针变量存放指针,跟普通变量不同**,指针变量存放的是一个地址.**
指针变量也有类型,它的类型就是存放的地址指向的数据类型
在编译系统中,指针变量占四个字节的空间,也就是说一个地址占四个字节的空间.
3. 定义指针变量
定义指针变量和定义变量类似:
char *pa;
int *pb;
左侧的数据类型表示指针变量中存放的地址指向的内存单元的数据的类型.
因为不同数据类型所占的内存空间不同,如果指错了,那么在访问指针变量指向的数据时就会出错.
4. 取地址运算符和取值运算符
如果需要获取某个变量的地址,可以使用取地址运算符(&):
char *pa = &a;
int *pb = &f;
如果需要访问指针变量指向的数据,可以使用取值运算符(*):
printf("%c, %d\n", *pa, *pb);
这里要注意取值运算符和定义指针用的运算符都是星号(*),这属于符号重用,在不同的地方有不同的意义:在定义是表示定义指针变量;在其他地方表示获取指针变量指向的变量的数据值.
直接通过变量名来访问变量的值,我们称之为直接访问.
通过指针变量的形式来访问变量的值的方式叫间接访问.
所以取值运算符又叫间接运算符.
5. 避免访问未被初始化的指针
#include <stdio.h>
int main()
{
int *a;
*a = 123;
return 0;
}
类似这种代码很危险,因为指针a到底指向哪里我们没办法知道.这个道理就跟未初始化的变量一样,值是随机的.
这个指针变量很危险,因为后边代码对一个未知地址进行赋值,那么你可能覆盖到系统的关键代码.系统不允许你这么做,这个时候会终止报错.
更危险的是偶尔这个指针变量里面存放的是一个合法地址,那么在接下来的赋值就会导致这个地方的值莫名其妙的被修改.这种类型的bug非常难排查.
所以在用指针间接访问时,必须保证它们已经被正确的初始化.