资讯动态

嵌入式Day12--指针

发布时间:2026/8/12 15:53:28 来源:尧图企业网站定制
1.特点让代码更加简洁高效指针传参通过指针直接操作数据避免不必要的数据拷贝提高程序运行效率。提供直接访问内存的操作指针存储的是内存地址可以直接读写该地址的数据灵活控制内存。利用指针可以直接操作硬件指针可以直接访问硬件寄存器或内存映射的硬件设备。2.概念内存存储运行时的数据。内存地址 计算机需要对物理内存进行管理。因为内存空间大给每个存储单元(1byte)分配一个编号。这个编号就是内存地址并且是线性连续的。指针就是指针变量是专门用来存储内存地址的变量。 在32bit操作系统下任意类型的指针大小为4byte0-0xffffffff。在64bit操作系统下任意类型的指针大小为8byte(0-0xffffffffffffffff)指针的类型是多种多样的。例如int*整形的,char* (字符指针),double*浮点类型指针任意类型的指针大小都是一致的用指针可以表示任意的数据。通过变量名访问内存的方式称为直接访问。 如果用指针方式访问称为间接访问。当定义变量后变量名会和对应的内存空间进行关联。变量名是内存的一个别名。内存地址是一个编号这个编号和int类型在c语言中是不同的两种类型支持的运算符和操作是不同。3.相关的运算符3.1取地址运算符获得变量在内存空间中的地址编号单目运算符从右向左结合。只有变量左值在内存中有明确位置的值才能使用常量和表达式不能进行操作int a 20; a; // 获得a 变量在内存中的地址。 输入需要输出通常使用%p来输出 取地址操作相当于升级操作 变量升级为对应类型的指针3.2 *解引用运算符获得指针指向的空间或者对应空间中的值通过指针间接访问它指向的数据。*运算符连接的内容必须为指针类型不能是普通变量类型如果直接使用*对应的表达式表达式值为该指针指向空间中的值int a 20; a; 指针类型 *a // 20 int 解引用操作相当于降级操作 指针降级为变量类型。 解引用操作的过程 1. 找到指针中存储的地址 2. 根据指针的基类型(int * 的基类型是int) 确定占用内存大小 3. 取出从地址开始的地方基类型的大小取出数据。 取地址操作和解引用操作互为反操作。4.定义不能使用未经初始化的指针int *p; //指向空间的范围为4字节 char *p; //指向空间的范围为1字节 float *p; //指向空间的范围为4字节 double *p; //指向空间的范围为8字节 int *p, *q;5.初始化指针变量定义好后一定要初始化。如果不初始化会存储随机地址。5.1野指针未经初始化的指针、指向已经被释放空间的指针、超出作用范围的指针称为野指针5.2空指针不明确指向任何有效对象或内存地址的指针、指向内存地址为0x0的指针称为空指针用NULL来表示它的值为 0内存地址0x0空间为只读空间不能赋值NULL指针不能执行*p value操作int *p_i; // 定义了一个整形指针 int* .只能存储整形变量的地址 char* p_c 0 ; // 都是8 个字节。 空指针 double* p_d ; // 野指针 short* p_s NULL; //空指针 逻辑上先指向0地址稍后再给一个合理的地址6.指针的访问变量的访问分为直接和间接访问// 初始化 int i_a 20; p_i i_a; // 正常初始化 // 20; 只能是变量执行取址操作 // (i_a 10); printf(a is addr %p\n,i_a); printf(p_i is %p\n,p_i); printf(a is %d\n,i_a); // 直接访问 printf(指针访问a is %d\n,*p_i); // 间接访问 i_a 30;// 直接访问 printf(i_a 30 ,a is %d\n,i_a); *p_i 50;// 间接访问 printf(*p_i 50, a is %d\n,*p_i);内存存储如下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); nt 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); }不同类型的指针的解引用操作如果执行 * 解引用操作话 。 假设指针存储的地址是0x2000 char* 取0x2000 开始的1个字节空间的数据 int* 取0x2000 开始的4个字节空间的数据 short* 取0x2000 开始的2个字节空间的数据 float* 取0x2000 开始的4个字节空间的数据 double* 取0x2000 开始的8个字节空间的数据不同类型的指针的 --如果执行 。 假设指针存储的地址是0x2000 char* 偏移量 1byte - 0x2001 int* 偏移量 4byte - 0x2004 short* 偏移量 2byte - 0x2002 float* 偏移量 4byte - 0x2004 double* 偏移量 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; }

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价