1 指针
1.1 内存
定义int i,j,k=c;
编译时系统分配1000、1001、1002、1003这4个字节给变量 i。变量的“地址”是指其占用存储区中由小到大的第1个字节地址。如变量 i的地址是1000。
说明:
1)内存最基本单元是字节,一般内存地址用十六进制数来表示。
1.2 内存访问方式
(1)直接访问
printf("%d\n",i);
直接指出变量名,无需知道这个变量的内存具体位置,通过C编译系统来管理每个变量和具体地址。
(2)间接访问
内存单元间接访问就是将变量i的地址放到另一个变量p中。也就是说,这个变量p的值是变量i的地址,系统也要为变量p本身分配内存单元。
1.3 指针变量
说明:
1)指针型变量是用来存储内存地址的,它本身也有个地址。
2) 区分“变量的指针”和“指向变量的指针变量”。变量的“指针”就是变量的“地址”。在 C语言中,“指针”和“地址”是两个等价的概念。“指针变量”是存放变量指针(地址)的变量,用来指向另一个变量。
1.4 指针变量的定义
类型名 *指针变量名1,*指针变量名2,…;
如:int *p,*q;
1.5 给指针变量赋值
1.5.1 通过&
1)
int a=3,*p;
p=&a; /*给指针变量p赋值*/
或
2)
int a=3,*p=&a; /*给指针变量初始化*/
说明:p与a数据类型一致,如这里指针变量p只能存储int类型变量的的地址。
1.5.2 通过指针变量赋值
把一个指针变量中的地址值赋给另一个同类型的指针变量,从而使两个指针指向同一地址。
int a=3,*p=&a,*q;q=p;
1.6 指针运算
间接存取”就是通过指针变量p间接得到变量a的地址,然后存取变量a的值的方式。C语言提供了一个称作“间接访问运算符”的单目运算符:“”。“”出现在程序中的不同位置,其含义是不同的。
如在指针变量说明中,“”是类型说明符,表示其后的变量是指针类型。表达式中出现的“”则是一个运算符,用以表示指针变量所指的变量,取值。
1)对指针变量的使用必须是先使指针变量有固定的指向然后才可以使用,即先赋值后使用。
int a,*p;
*p=5; /*这种写法是错误的,因为此时指针变量p还没有固定指向,这样使用容易造成重要数据的破坏*/
2)运算符“&”和“*”的优先级相同,结合性是从右到左
3)q=&p;
4) *、++、–的优先级是相同的,结合性为从右到左
(*p)++ /*等价于a++*/
*p++ /*等价于*(p++)*/
++*p /*等价于++a*/
*++p /*等价于*(++p)*/
5)p+n,p-n
p是一个指针变量,p+1表示将指针向后移动1个数据长度。
数据长度就是对应基类型所占的字节数,如是int型,p+1就是p向后移动4个字节(1个步长)。
说明:这样看,指针与数组有很相似的关系了。
#include <stdio.h>
int main()
{
int var = 20;
int* p;
p = &var;
printf("var 变量的地址: %p\n", &var);
printf("p 变量存储的地址: %p\n", p);
printf("p 变量的地址: %p\n", &p);
printf("*p 变量的值: %d\n", *p);
printf("p++变量存储的地址: %p\n", ++p);
return 0;
/*var 变量的地址: 0000006AEED0FB04
p 变量存储的地址: 0000006AEED0FB04
p 变量的地址: 0000006AEED0FB28
*p 变量的值: 20
p++变量存储的地址: 0000006AEED0FB08*/
}
1.7 其他指针
1)空指针
int *p1=0; //0是唯一不必转换就可以赋值给指针的数据
int *p2=NULL; //NULL是一个宏定义,其作用与0相同
//在ASCII码中,编号为0的字符就是空
编程时,
int x=10;
int *p=NULL; //使指针指向空
p=&x;
2)无类型指针
无类型指针使用void*修饰,这种指针指向一块内存,但其类型不定。程序无法分配空间,因此使用时使用强制转换。
void *p=NULL, *q=NULL; //定义一个无类型的指针变量
int *m=(int*)p; //将无类型的指针变量p强制转换为int类型再赋值
int a=10;
q=&a; //空指针q接收其他类型的指针时不必强转
3)野指针
总结:上面3张图最重要!!!
2. 多级指针
称为指向指针的指针