嵌入式c编程01指针的使用

上传人:shaoy****1971 文档编号:112017209 上传时间:2019-11-04 格式:PPT 页数:36 大小:1.22MB
返回 下载 相关 举报
嵌入式c编程01指针的使用_第1页
第1页 / 共36页
嵌入式c编程01指针的使用_第2页
第2页 / 共36页
嵌入式c编程01指针的使用_第3页
第3页 / 共36页
嵌入式c编程01指针的使用_第4页
第4页 / 共36页
嵌入式c编程01指针的使用_第5页
第5页 / 共36页
点击查看更多>>
资源描述

《嵌入式c编程01指针的使用》由会员分享,可在线阅读,更多相关《嵌入式c编程01指针的使用(36页珍藏版)》请在金锄头文库上搜索。

1、指针的使用 课程安排 n指针的概念 n指针数据类型 n指针与其他数据类型 n指针修饰符 一般的32位CPU都有硬件MMU单元,能将有限的硬件内存(如 512M)虚拟成一个较大(如2G)的虚拟内存 这样软件可以在一个非常大的范围里使用内存 每个内存单元(8bits组成一个内存单元byte)都有一个地址 地址是一个无符号的整数表示,通常与CPU字长相等(在32位 CPU上就是4byte的空间) 内存与地址 1、变量是对程序中数据存储空间(地址和值)的抽象 int num = 100; printf(“num is %d, num addr is %pn”, num, 2、可以将变量的地址保存在一个

2、整型变量中 unsigned int addr = 0; addr = printf(“addr is %#xn”, addr); 3、问题是,怎么通过addr简接获取该地址内保存的值(100)? 变量与地址 1、C定义了一种专门用于表示地址的变量指针 int* addr; /定义指针变量 2、将内存中数据的地址赋值给指针变量:表示将指针指向该数据 addr = /指针变量addr指向num变量 3、通过指针变量可以间接访问被指向的数据 printf(“num is %dn”, *addr); /通过addr获取num *addr = 200; /通过addr修改num printf(“num

3、 is %dn”, num); 指针的由来 用好指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值 直接操作地址造就了C/C+的强大 用不好指针造成: 非法内存访问,程序死机或异常 内存泄露,减低系统性能 指针属于间接访问,指来指去最终变得不可维护 指针是把双刃剑 课程安排 n指针的概念 n指针数据类型 n指针与其他数据类型 n指针修饰符 指针的定义 实例:int *pi; char *pc; double* pd; info_t *pinfo; static int *pi; static char *pc; static info_t *p

4、info; 关键概念: 1、指针类型与指针指向对象类型 2、指针的值与指针指向对象的值 指针内存大小 指针变量用来表示内存地址,32位CPU上用4byte空间表示地址 int *pi; char *pc; double *pd; info_t *pinfo; sizeof(pi) = ? sizeof(pc) = ? sizeof(pd) = ? sizeof(pinfo) = ? 指针初始化与赋值 1、初始化为指向对象的地址 int num = 100; int paddr = /paddr指向num 2、初始化为空指针 int *paddr = NULL; /NULL为0,表示空地址 3、

5、指针变量定义后可以随时改变所指向的变量 int num1 = 100, num2 = 200; int paddr = NULL; paddr = paddr = 指针运算 1、取值运算符 int num = 100; int* paddr = 通过paddr间接取num值: *paddr 2、取址运算符 char *paddr = *paddr = ? paddr + 1 = ? *(int*)paddr = ? (int*)paddr + 1 = ? 通用(void)指针 指针变量的类型表示指针所指向对象的类型 能不能定义一种通用指针,将来根据需要再指向特定对象? void *point

6、= NULL; /void指针,定义不指定指针指向哪种类型数据 sizeof (point) = ? point+ ? point- ? 使用时需要进行强制类型转换: int num = 100; char ch = a; void *point = NULL; point = printf(“num is %dn”, *(int*)point); point = printf(“ch is %cn”, *(char*)ch); 课程安排 n指针的概念 n指针数据类型 n指针与其他数据类型 n指针修饰符 数组与指针 1、数组与指针的关系 l数组名表示数组首地址,可以把数组名可作指针常量 int

7、 arr3 = 1, 2, 3; int *p = arr; p+ ? arr+ ? *p = ? *(p+1) = ? *(p + 2) = ? l数组下标操作符内部实现机制:通过指针取值运算符实现 arr2 相当于 *(arr+2) l数组作为函数参数,实际是转化为指针实现 str_cpy(char src, char des) = str_cpy(char *src, char *des) l数组作为函数返回值,必须通过指针实现 char *str_cpy(char *src, char *des) 数组与指针 2、指针数组:即数组的元素为指针类型。 char* var10; /10个i

8、nt型指针的数组 sizeof(var) = ? var + 1 ? 3、数组指针:即指针的类型为数组(指向数组的指针)。 char (*var)10; /指向10个int型数组的指针 sizeof(var) = ? var + 1 ? 4、字符串与指针 l字符串是属于典型的字符数组,因而通常通过char型指针处理字符串 数组与指针 l将字符串直接赋值给指针,表示指针指向字符串内存首地址 注意:字符串常量内存分配在只读数据区(RODATA) 实例:char *p = “xnf”; char arr = “xnf”; *p ? *p+ ? *+p ? *p = X ? arr0 = X ? st

9、rcpy(p, “XNF”) ? strcpy(arr, “XNF”) ? 数组与指针 l通过指针数组表示字符串数组 char a16 = “welcome”, “to”, “xnf”; 主函数参数就是通过指针数组实现的: int main (int argc, char *argv) 结构与指针 1、结构包含指针:结构体中包含指针域变量 如:学生信息中name与phone定义为指针 注意:在程序中动态修改学生信息表中的 name和phone域可行么? 结构与指针 2、指向结构体的指针 结构体变量域通过.访问,而结构体指针域通过-访问 sizeof(info) = ? sizeof(p) =

10、? 下面这段代码错在哪里? 结构与指针 通过结构体指针传递参数比直接传递结构体变量更高效 实参传递给形参时只拷贝了4个字节 指针与指针 1、指向指针变量的指针 int num = 100; int *p = int *pp = 实现指针二级访问: 函数与指针 1、指针作为函数的参数 l向函数传递数组、字符串、结构: 如strc_py、show_info l作为函数的输出参数 例如:实现交换两个整数的函数 void swap(int a, int b) 传值,形参值改变并不能带回给实参 传址,在函数内改变地址内保存的内容 函数与指针 问题: 要在函数能改变指针的值,怎么通过输出参数返回? 例如:

11、 void get_mem(char *pmem, int size) pmem = malloc(size); 动态分配的内存能通过pmem带回么? 不能!要将实参指针的地址传递给形参(二级指针)才能实现! 更直接的方法是通过函数返回值实现 函数与指针 2、指针作为函数的返回值 返回字符串、动态分配的内存等,如 *strcpy, *malloc 注意返回地址的有效性(函数执行完毕后该地址未被回收) 下面两个函数哪个是合法的? 函数与指针 3、指向函数的指针 函数存放在TEXT段,同样具有地址 函数名就是函数在TEXT段的入口地址 跟数组名一样,函数名也可以看作是一个指针常量 所以,函数名也可

12、以赋值给指针变量,那么该指针变量类型呢? 函数指针类型!通过函数指针,也可以间接调用函数。 函数与指针 函数指针的应用: 1、作为函数参数实现回调函数 所谓回调函数是指通过调用其他函数反 过来调用某个函数 模拟面向对象的多态,在UI组件的大量使 用 函数与指针 2、作为结构体的动作域 模拟面向对象的类,在Linux内核中大量使用 作为一个现实中的对象,不但有数据属性,还需要有行为属性 使用对象行为 课程安排 n指针的概念 n指针数据类型 n指针与其他数据类型 n指针修饰符 const修饰符 1、const修饰符的作用:限定一个变量不允许被改变(只读) 如:const int num = 100

13、; /num是只读整型变量 const int arr3 = 10, 20, 30; /arr是只读整型数组 num = 200 ? arr0 = 100 ? arr1 = 200? 2、const指针: 指向变量的只读指针,指针本身只读,但指向的对象非只读 如:int num1 = 100; int num2 = 200; int* const p = *p = 200 ? p = const int num2 = 200; const int *p = *p = 200 ? p = int const *p = const int num2 = 200; const int* const

14、p = *p = 200 ? p = /假定0x0012ff7c表示一个网卡内存地址 data = *paddr; /第一次取网卡数据 data = *paddr; /第二次取网卡数据 由于*paddr从未被程序改变,所以第二次取值从寄存器中进行,跟第一次值一样 但网卡内存数据会随时在通信中发生改变! volatile修饰符 3、使用volatile修饰符 volatile告诉编译器,不要对其修饰的变量作优化 总是从内存进行读写,而不是仅仅在寄存器 volatile const unsigned int *p = 0x0012ff7c; /假定0x0012ff7c表示一个网卡内存地址 type

15、def修饰符 1、指针相关数据类型 定义含义 int i; int *p; int an; int *pn; int (*p)n; int f(); int *p(); int (*p)(); int *p; 定义整型变量i p为指向整型数据的指针变量 定义含n个元素的整型数组a n个指向整型数据的指针变量组成的指针数组p p为指向含n个元素的一维整型数组的指针变量 f为返回整型数的函数 p为返回指针的函数,该指针指向一个整型数据 p为指向函数的指针变量,该函数返回整型数 p为指针变量,它指向一个指向整型数据的指针变量 typedef修饰符 2、更复杂的指针相关数据类型 从变量名括号开始解释,括号外面表示类型可以用typedef自定义类型来简化 lint (*p3)(int); typedef int (func_t)(int); /定义返回整数的函数类型 funct_t *p3; /定义包含3个函数指针的数组 lint *(*p3)(int); typedef int *(func_t)(int); /定义返回整数指针的函数类型 func_t *p3; /定义包含3个函数指针的数组 typedef修饰符 lint (*p)3(int); /错误,不能声明函数的数组 如何定义指向包含3个返回整数函数指针数组的指针? ty

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 中学教育 > 职业教育

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号