指针1.用途高效的访问数据传递参数2.特征高效简洁相对于普通变量而言指针可以直接访问物理内存或者直接操作硬件单片机开发3.概念内存存储运行时的数据内存地址计算机需要对物理内存进行管理。因为内存空间大给每个存储单元(1byte)分配一个编号。这个编号就叫内存地址。并且编号是线性连续的指针就是指针变量。专门用来存储内存地址的变量。在32bit任意类型的指针4byte0 -0xffffffff。64bit任意类型的指针8byte.(0-0xffffffffffffffff) .指针的类型是多种多样。int *整形的,char* (字符指针),double*浮点类型指针。任意类型的指针大小都是一致。 用指针可以表示任意的数据通过变量名访问内存称为直接访问。 如果同指针方式访问称为间接访问当定义变量后变量名会和对应的内存空间进行关联。变量名是内存的一个别名内存地址是一个编号。这个编号和int类型在c语言中是不同的两种类型支持的运算符和操作是不同4.相关的运算符取地址运算符。获得变量在内存空间中的地址编号。单目运算符从右向左结合。被操作对象只能是变量(左值赋值运算符中的左值)。不能是常量或这表达式。int a 20; a; // 获得a 变量在内存中的地址。 输入需要输出。 %p 。 //取地址操作相当于 升级操作 //变量升级 - 对应类型的指针* 解引用运算符通过内存地址获得变量的数据(内容)。被操作的对象必须是指针变量。int a 20 ; a; /指针类型 *a // 20 int //解引用操作相当于降级操作 //指针的降级- 变量类型。解引用操作的过程找到指针中存储的地址根据指针的基类型 (int * -- 基类型是int .) 的占用内存大小取出从地址开始的地方 基类型的大小 取出数据。取地址操作和解引用操作互为反操作5.指针的定义存储类型 数据类型 * 变量名 int* pa; //定义一个指针。 开辟8 byte 准备存储变量的地址。 pa 类型 int* 6.初始化指针变量定义好后一定要初始化。如果不初始化会存储随机地址。野指针定义后非全局指针未给初值的。指针存储的地址对应的变量已经释放的。不能读写操作。空指针指针变量定义好后存储0地址的指针。NULL。int *p_i; // 定义了一个整形直指针 int* .只能存储整形变量的地址 char* p_c 0 ; // 都是8 个字节。 空指针 double* p_d ; // 野指针 short* p_s NULL; //空指针 逻辑上先指向0地址。 稍后在给一个合理的地址7.指针的算术运算算术运算(整形) - * / % --指针的算术运算 - -- (一般对数组进行访问的时候会使用算术运算符)指针的加法 int a 20 ; // 0x2000 int int *p a; // 0x2000 a- int * printf(a is addr %p\n ,a); printf(p is addr %p\n ,p); pp1; // p 中存储的地址值变大。 p中原来的地址 sizeof(基类型4byte) 0xebbc 0xebc0 printf(p1 is addr %p\n ,p);#include stdio .h int main() { int a 20 ; // 0x2000 int int *p a; // 0x2000 a- int * printf(a is addr %p\n ,a); printf(p is addr %p\n ,p); #if 0 // 减法 pp-1; printf(p-1 is addr %p\n ,p); 先获得p 指针中存储的地址 和sizeof(基类型)的大小进行相减操作。 // p p*2; // 乘法没有意义 // p p/2; // 没有意义 // p p%4; //没有意义 // 加法 先获得p 指针中存储的地址 和sizeof(基类型)的大小进行相加操作。 p; // p p1; printf(p1 is addr %p\n ,p); #endif // 先获得p 指针中存储的地址 和sizeof(基类型)的大小进行相减操作。 p--; printf(p-1 is addr %p\n ,p); int b 20 ; int *pb b ; //ppb ; 两个指向不同变量的指针进行相加没有意义。 // p - pb; 两个指向不同变量的指针进行相减没有意义。 //如果这两个指针指向数组的开头 和数组的结尾。 int i_a [8]{0}; int * p_start i_a [0]; int *p_end i_a [7]; int ret p_end - p_start ; //int* -int * 结果类型int 有意义相差了几个数据元素。 (0x2000 -x201c) / sizeof(int) printf(ret is %d\n ,ret); }不同类型的指针的解引用操作如果执行 * 解引用操作话。 假设指针存储的地址是0x2000char*取0x2000 开始的1个字节空间的数据int*取0x2000 开始的4个字节空间的数据short*取0x2000 开始的2个字节空间的数据float*取0x2000 开始的4个字节空间的数据double*取0x2000 开始的8个字节空间的数据不同类型的指针的--如果执行。 假设指针存储的地址是0x2000char*偏移量1byte - 0x2001int*偏移量4byte - 0x2004short*偏移量2byte - 0x2002float*偏移量4byte - 0x2004double*偏移量8byte - 0x20088.内存大小段对于多字节(大于1字节以上的基本数据类型)的数据。在内存中数据存储字节序。大小段存储方式是由CPU决定。51单片机,网络设备都使用大端方式储存数据。AMDintelARM都是采取小端存储。小端储存数据的低位在内存的低地址数据的高位在内存的高地址大端储存数据的低位在内存的高地址数据的高位在内存的低地址#include stdio .h int main() { int a 0x12345678 ; // 强制类型转换 char* p (char*)a; // char* int * // *p 从p指向的首地址开始偏移量1byte ,取出数据 //printf(val : 0x%x\n ,*p); if( 0x78 *p) { printf(小端存储\n); } else { printf(大端存储\n); } return 0 ; } //结果输出小端存储