嵌入式C编程01指针的使用.ppt_第1页
嵌入式C编程01指针的使用.ppt_第2页
嵌入式C编程01指针的使用.ppt_第3页
嵌入式C编程01指针的使用.ppt_第4页
嵌入式C编程01指针的使用.ppt_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

指针的使用,课程安排,指针的概念 指针数据类型 指针与其他数据类型 指针修饰符,一般的32位CPU都有硬件MMU单元,能将有限的硬件内存(如 512M)虚拟成一个较大(如2G)的虚拟内存 这样软件可以在一个非常大的范围里使用内存 每个内存单元(8bits组成一个内存单元byte)都有一个地址 地址是一个无符号的整数表示,通常与CPU字长相等(在32位 CPU上就是4byte的空间),内存与地址,1、变量是对程序中数据存储空间(地址和值)的抽象 int num = 100; printf(“num is %d, num addr is %pn”, num, 3、问题是,怎么通过addr简接获取该地址内保存的值(100)?,变量与地址,1、C定义了一种专门用于表示地址的变量指针 int* addr; /定义指针变量 2、将内存中数据的地址赋值给指针变量:表示将指针指向该数据 addr = ,指针的由来,用好指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值 直接操作地址造就了C/C+的强大 用不好指针造成: 非法内存访问,程序死机或异常 内存泄露,减低系统性能 指针属于间接访问,指来指去最终变得不可维护,指针是把双刃剑,课程安排,指针的概念 指针数据类型 指针与其他数据类型 指针修饰符,指针的定义,实例:int *pi; char *pc; double* pd; info_t *pinfo; static int *pi; static char *pc; static info_t *pinfo; 关键概念: 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 = ,指针运算,1、取值运算符 int num = 100; int* paddr = *paddr = ? paddr + 1 = ? *(int*)paddr = ? (int*)paddr + 1 = ?,通用(void)指针,指针变量的类型表示指针所指向对象的类型 能不能定义一种通用指针,将来根据需要再指向特定对象? void *point = NULL; /void指针,定义不指定指针指向哪种类型数据 sizeof (point) = ? point+ ? point- ? 使用时需要进行强制类型转换: int num = 100; char ch = a; void *point = NULL; point = ,课程安排,指针的概念 指针数据类型 指针与其他数据类型 指针修饰符,数组与指针,1、数组与指针的关系 数组名表示数组首地址,可以把数组名可作指针常量 int arr3 = 1, 2, 3; int *p = arr; p+ ? arr+ ? *p = ? *(p+1) = ? *(p + 2) = ? 数组下标操作符内部实现机制:通过指针取值运算符实现 arr2 相当于 *(arr+2) 数组作为函数参数,实际是转化为指针实现 str_cpy(char src, char des) = str_cpy(char *src, char *des) 数组作为函数返回值,必须通过指针实现 char *str_cpy(char *src, char *des),数组与指针,2、指针数组:即数组的元素为指针类型。 char* var10; /10个int型指针的数组 sizeof(var) = ? var + 1 ? 3、数组指针:即指针的类型为数组(指向数组的指针)。 char (*var)10; /指向10个int型数组的指针 sizeof(var) = ? var + 1 ? 4、字符串与指针 字符串是属于典型的字符数组,因而通常通过char型指针处理字符串,数组与指针,将字符串直接赋值给指针,表示指针指向字符串内存首地址 注意:字符串常量内存分配在只读数据区(RODATA) 实例:char *p = “xnf”; char arr = “xnf”; *p ? *p+ ? *+p ? *p = X ? arr0 = X ? strcpy(p, “XNF”) ? strcpy(arr, “XNF”) ?,数组与指针,通过指针数组表示字符串数组 char a16 = “welcome”, “to”, “xnf”; 主函数参数就是通过指针数组实现的: int main (int argc, char *argv),结构与指针,1、结构包含指针:结构体中包含指针域变量 如:学生信息中name与phone定义为指针 注意:在程序中动态修改学生信息表中的 name和phone域可行么?,结构与指针,2、指向结构体的指针 结构体变量域通过.访问,而结构体指针域通过-访问 sizeof(info) = ? sizeof(p) = ? 下面这段代码错在哪里?,结构与指针,通过结构体指针传递参数比直接传递结构体变量更高效 实参传递给形参时只拷贝了4个字节,指针与指针,1、指向指针变量的指针 int num = 100; int *p = 实现指针二级访问:,函数与指针,1、指针作为函数的参数 向函数传递数组、字符串、结构: 如strc_py、show_info 作为函数的输出参数 例如:实现交换两个整数的函数 void swap(int a, int b) 传值,形参值改变并不能带回给实参 传址,在函数内改变地址内保存的内容,函数与指针,问题: 要在函数能改变指针的值,怎么通过输出参数返回? 例如: void get_mem(char *pmem, int size) pmem = malloc(size); 动态分配的内存能通过pmem带回么? 不能!要将实参指针的地址传递给形参(二级指针)才能实现! 更直接的方法是通过函数返回值实现,函数与指针,2、指针作为函数的返回值 返回字符串、动态分配的内存等,如 *strcpy, *malloc 注意返回地址的有效性(函数执行完毕后该地址未被回收) 下面两个函数哪个是合法的?,函数与指针,3、指向函数的指针 函数存放在TEXT段,同样具有地址 函数名就是函数在TEXT段的入口地址 跟数组名一样,函数名也可以看作是一个指针常量 所以,函数名也可以赋值给指针变量,那么该指针变量类型呢? 函数指针类型!通过函数指针,也可以间接调用函数。,函数与指针,函数指针的应用: 1、作为函数参数实现回调函数 所谓回调函数是指通过调用其他函数反 过来调用某个函数 模拟面向对象的多态,在UI组件的大量使 用,函数与指针,2、作为结构体的动作域 模拟面向对象的类,在Linux内核中大量使用 作为一个现实中的对象,不但有数据属性,还需要有行为属性 使用对象行为,课程安排,指针的概念 指针数据类型 指针与其他数据类型 指针修饰符,const修饰符,1、const修饰符的作用:限定一个变量不允许被改变(只读) 如:const int num = 100; /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 = &num2 ?,const修饰符,3、指向const变量的指针: 指向只读变量的指针,而指针本身不是只读的 如: const int num1 = 100; const int num2 = 200; const int *p = *p = 200 ? p = &num2 ?,volatile修饰符,1、编译器总是试图优化编译使代码运行得更快 如果程序中变量未被改变,对变量的访问尽量用寄存器代替内存储存 寄存器属于CPU内部的存储单元,比起内存访问来得更快 2、但对于硬件驱动程序来说,这样做就存在风险 const unsigned int *paddr = 0x0012ff7c; /假定0x0012ff7c表示一个网卡内存地址 data = *paddr; /第一次取网卡数据 data = *paddr; /第二次取网卡数据 由于*paddr从未被程序改变,所以第二次取值从寄存器中进行,跟第一次值一样 但网卡内存数据会随时在通信中发生改变!,volatile修饰符,3、使用volatile修饰符 volatile告诉编译器,不要对其修饰的变量作优化 总是从内存进行读写,而不是仅仅在寄存器 volatile const unsigned int *p = 0x0012ff7c; /假定0x0012ff7c表示一个网卡内存地址,typedef修饰符,1、指针相关数据类型,typedef修饰符,2、更复杂的指针相关数据类型 从变量名括号开始解释,括号外面表示类型可以用typedef自定义类型来简化 int (*p3)(int); typedef int (func_t)(int); /定义返回整数的函数类型 funct_t *p3; /定义包含3个函数指针的数组 int *(*p3)(int); typedef int *(func_t)(int); /定义返回整数指针的函数类型 func_t *p3; /定义包含3个函数指针的数组,typedef修饰符,int (*p)3(int); /错误,不能声明函数的数组 如何定义指向包含3个返回整数函数指针数组的指针? typedef int (func_t)(int); /定义返回整型函数指针类型 typedef func_t *pfarr_t3; /定义包含3个函数指针数组类型 pfarr_t *p; /定义指向数组的指针,上机实验,1、指针应用 (1)用指针实现char* str_cpy(char *des, char *src)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论