第七章 指针
1.指针的特点
-
编写代码更加简洁高效
-
可以直接访问内存。要访问合法的内存地址(不要越界)。
-
指针可以直接操作硬件。(操作 51,arm开发板,)
2.基本概念
-
内存,memory 。 程序运行起来后的一个 数据暂存场所。32bit 0-4G 。c语言中,操作内存的时候,最小单位 是1byte(字节)。 code(代码段),data(数据段),heap(堆,),map/share( c库函数),stack(栈,局部变量,函数参数,返回地址)
-
地址,由于地址空间比较大,c 语言中,最小操作单位 是1byte。为了方便 访问内存,给每个内存都分配了一个编号。 叫内存的地址。
-
指针,指针变量。 专门存储地址的变量。
3. 指针相关运算符
1.& 取地址运算符, 获得变量在内存空间中的地址
-
只能给左值取地址
-
int a; &a; &a 是一个表达式。 值,表示的是a这个变量在内存空间的首地址。 类型 int *
-
double num = 0 ; # // 0x123456 doulbe *
-
2. 解引用
只能是指针类型才能解引用。 先找到对应的内存地址 ,获得内存地址空间中的内容。
int a = 20;
int * p = &a; // int * 类型说明符
a; //20 直接访问
*p; //20 解引用 值:对应内存空间中的数据, 类型 int
*p =10; // 给a 写入数据 , 左值
int b = *p;// 右值 , 读取a 中的数据
*&a; =20; * 和 & 运算符 ,相反操作的运算符。
int p;
int *p ; // p int -> int*
*p; // int * --> int
4 指针的定义
基类型 * 指针名;
int* p1; // * 不是解引用 类型说明符 int *
char *p2; // char*
double * p3; //double *
float* p4; //float *
5指针的初始化
指针需要初始化后,才可以使用。指针必须和某个内存区域关联后,才可使用。
野指针: 未经初始化的指针或指针指向的内存空间是一个已经被释放的空间的指针;
int *p; // 野指针, p中存储的地址,是一个随机值。 从逻辑上说,这个指针不能对,也不能。
空指针: NULL(宏定义) ,在stdio.h.
int *p1 = NULL; // 空指针。 NULL == ((void*)0) 指针已经初始化,稍后,才会关联一个变量的地址。 在未关联变量地址前,也不能读写。
int a =10;
printf("a %p
",&a);
int* p1; // * 不是解引用 类型说明符 int *
char *p2; // char*
double * p3; //double *
float* p4; //float *
// 这个地方的代码,有崩溃的风险
//printf("p1 %d
",*p1); //p1 野指针
//*p1 = 20;
int *p5 = NULL; // ((void*) 0) 空指针
int * p6 = &a;
printf("p6 addr %p
",p6);
printf("a addr %p
",&a);
printf("a value:%d
",*p6); // 通过指针,间接读取 a 变量的值, 右值
*p6 = 50; // 左值,修改变量
printf("修改后 a value:%d
",*p6); // 通过指针,间接读取 a 变量的值
printf("a value:%d
",a); // 直接访问 a 变量的值
6 .指针的算术运算
+ - * / % ++ --
int a =20;
int *p= &a;
int *p2 = p1+1;
+ ,p+1 , 在p指针指向的地址的基础上 在一个 sizeof(基类型) 个字节的偏移量。那么p指针就指向当前元素的下一个元素。如果指针需要+1,-1, 一般和数组操作的时候,才会使用。
7 指针和数组
-
数组的数组名 ,是一个指向数组中第一元素的指针常量。 a中储存的地址,不能发生变化。 数组名的本质,就是一个指针常量(加了一些限制, 指针中存储的地址,不能改变).
-
sizeof 不同
sizeof 是数组 int a[50]; sizeof(a) == sizeof(int) * 50
int * p ; sizeof(p) == 8 byte ,任意指针都是8个字节(64bit)
int a[10]={1,2,3,4}; //2000
int b[10]={2,3,4,5,6,7}; //3000
a =b;// 错误 ,a中存储的地址,不能改变 。指针常量

3.使用指针访问,数组的元素
int a[5]={1,2,3,4,5};
printf("arrray addr %p
",a); //a就是一个指针。 存储的是 a[0]地址
printf("a[0] %p
",&a[0]);
printf("a[1] %p
",&a[1]);
int *p =a ; // p指针和 数组进行关联 , p 中存储了a[0]的地址。
printf("a[0] %d
",a[0]);
printf("point *(p+0) %d
",*(p+0));
printf("*(a+0) %d
",*(a+0));
printf("point p[0] %d
",p[0]);
printf("a[0] addr %p
",&a[0]);
printf("point addr *(p+0) %p
",&(*(p+0)));
printf("*(a+0) addr %p
",&(*(a+0)));
printf("point addr p[0] %p
",&p[0]);
/*
printf("a[1] %d
",a[1]);
printf("point a[0] %d
",*(p+1));
访问方式
a[n] ---> *(p+n) -->*(a+n)---> p[n]







