linuxC中指针的使用.ppt

上传人:sh****n 文档编号:7422837 上传时间:2020-03-21 格式:PPT 页数:26 大小:373.84KB
返回 下载 相关 举报
linuxC中指针的使用.ppt_第1页
第1页 / 共26页
linuxC中指针的使用.ppt_第2页
第2页 / 共26页
linuxC中指针的使用.ppt_第3页
第3页 / 共26页
点击查看更多>>
资源描述
linuxC中指针的使用 学号 姓名 1 指针的概念指针是一个特殊的变量 它里面存储的数值被解释成为内存里的一个地址 把一个变量所在的内存单元的地址保存在另外一个内存单元中 保存地址的这个内存单元称为指针 重点 指针的四方面的内容 指针的类型 指针所指向的类型 指针的值 或者叫指针所指向的内存区 指针本身所占据的内存区 1 指针的类型判断指针类型的方法 把指针声明语句里的指针名字去掉 剩下的部分就是这个指针的类型 如 int ptr 指针的类型是int char ptr 指针的类型是char int ptr 指针的类型是int int ptr 3 指针的类型是int 3 int ptr 4 指针的类型是int 4 2 指针所指向的类型把指针声明语句中的指针名字和名字左边的指针声明符 去掉 剩下的就是指针所指向的类型 int ptr 指针所指向的类型是intchar ptr 指针所指向的的类型是charint ptr 指针所指向的的类型是int int ptr 3 指针所指向的的类型是int 3 int ptr 4 指针所指向的的类型是int 4 3 指针的值 或者叫指针所指向的内存区或地址指针的值是指针本身存储的数值 这个值将被编译器当作一个地址 而不是一个一般的数值 在32位程序里 所有类型的指针的值都是一个32位整数 因为32位程序里内存地址全都是32位长 指针所指向的内存区就是从指针的值所代表的那个内存地址开始 长度为sizeof 指针所指向的类型 的一片内存区 4 指针本身所占据的内存区只要用函数sizeof 指针的类型 测一下就可以知道 在32位平台里 指针本身占据了4个字节的长度 在64位平台上指针变量都占8个字节 注意 sizeof 指针的名称 测到的是指针自身类型的大小 2 指针中 和 是取地址运算符 号是指针间接寻址运算符 i表示取变量i的地址 pi表示取指针pi所指向的变量的值 运算符的操作数必须是左值 因为只有左值才表示一个内存单元 才会有地址 运算结果是指针类型 运算符的操作数必须是指针类型 运算结果可以做左值 3 指针类型转换指针之间可以相互赋值 也可以用一个指针初始化另一个指针 例如 int ptri pi 或者 int ptri ptri pi 本质上就是把变量pi所保存的地址值赋给变量ptri 用一个指针给另一个指针赋值时要注意 两个指针必须是同一类型的 不是同一类型时可以进行强制类型转换然后赋值 例如 floatf 12 3 float fptr 不对 因为指针p的类型是int 它指向的类型是int 表达式 f的结果是一个指针 指针的类型是float 它指向的类型是float 强制类型转换 p int 如果有一个指针p 我们需要把它的类型和所指向的类型改为TYPE TYPE 那么语法格式是 TYPE p 这样强制类型转换的结果是一个新指针 该新指针的类型是TYPE 它指向的类型是TYPE 它指向的地址就是原指针指向的地址 而原来的指针p的一切属性都没有被修改 4 算数运算指针可以加上或减去一个整数 指针的这种运算的意义和通常的数值的加减运算的意义是不一样的 以单元为单位 例1 chara 20 int ptr int a 强制类型转换并不会改变a的类型ptr 第3句中 指针ptr被加了1 编译器是这样处理的 它把指针ptr的值加上了sizeof int 在32位程序中 是被加上了4 因为在32位程序中 int占4个字节 由于地址是用字节做单位的 故ptr所指向的地址由原来的变量a的地址向高地址方向增加了4个字节 由于char类型的长度是一个字节 所以 原来ptr是指向数组a的第0号单元开始的四个字节 此时指向了数组a中从第4号单元开始的四个字节 一个指针ptrold加 减 一个整数n后 结果是一个新的指针ptrnew ptrnew的类型和ptrold的类型相同 ptrnew所指向的类型和ptrold所指向的类型也相同 ptrnew的值将比ptrold的值增加 减少 了n乘sizeof ptrold所指向的类型 个字节 两个指针不能进行加法运算 这是非法操作 没意义 两个指针可以进行减法操作 但必须类型相同 指针之间的进行比较运算比的是地址 5 指针表达式一个表达式的结果如果是一个指针 那么这个表达式就叫指针表式 由于指针表达式的结果是一个指针 所以指针表达式也具有指针所具有的四个要素 指针的类型 指针所指向的类型 指针指向的内存区 指针自身占据的内存 当一个指针表达式的结果指针已经明确地具有了指针自身占据的内存的话 这个指针表达式就是一个左值 否则就不是一个左值 6 数组和指针的关系数组的数组名其实可以看作一个指针 声明了一个数组TYPEarray n 则数组名称array就有了两重含义 第一 它代表整个数组 它的类型是TYPE n 第二 它是一个常量指针 该指针的类型是TYPE 该指针指向的类型是TYPE 也就是数组单元的类型 该指针指向的内存区就是数组第0号单元 该指针自己占有单独的内存区 注意它和数组第0号单元占据的内存区是不同的 该指针的值是不能修改的 即类似array 的表达式是错误的 例 intarray 10 0 1 2 3 4 5 6 7 8 9 value value array 0 也可写成 value array value array 3 也可写成 value array 3 value array 4 也可写成 value array 4 上例中 一般而言数组名array代表数组本身 类型是int 10 但如果把array看做指针的话 它指向数组的第0个单元 类型是int 所指向的类型是数组单元的类型即int array 3是一个指向数组第3个单元的指针 所以 array 3 等于3 字符串相当于是一个数组 在内存中以数组的形式储存 只不过字符串是一个数组常量 内容不可改变 且只能是右值 如果看成指针的话 他即是常量指针 也是指针常量 7 指针和结构类型的关系可以声明一个指向结构类型对象的指针 例子如下 structMyStruct inta intb intc structMyStructss 20 30 40 声明了结构对象ss 并把ss的成员初始化为20 30和40 structMyStruct ptr 声明了一个指向结构对象ss的指针 它的类型是MyStruct 它指向的类型是MyStruct 通过指针p访问结构体成员可以写成 ptr a ptr b和 ptr c 为了书写方便 C语言提供了 运算符 也可以写成ptr a和ptr b ptr b 8 指针与函数的关系可以把一个指针声明成为一个指向函数的指针 函数指针存放的就是函数的入口地址 intfun1 char int int pfun1 char int pfun1 fun1 inta pfun1 abcdefg 7 通过函数指针调用函数 可以把指针作为函数的形参 在函数调用语句中 可以用指针表达式来作为实参 一个函数如果使用了指针作为形参 那么在函数调用语句的实参和形参的结合过程中 必须保证类型一致 否则需要强制转换 分析一下变量f的类型声明int pfun1 char int pfun1首先跟 号结合在一起 因此是一个指针 pfun1 外面是一个函数原型的格式 参数是char 和int 返回值是int 所以pfun1是指向这种函数的指针 9 指针的安全问题 1 意外改写数据例子 chara int ptr 该例子完全可以通过编译 并能执行 但是 第3句对指针ptr进行自加1运算后 ptr指向了和整形变量a相邻的高地址方向的一块存储区 这块存储区里是什么 我们不知道 有可能它是一个非常重要的数据 甚至可能是一条代码 而第4句竟然往这片存储区里写入一个数据 这是严重的错误 为了避免这种情况可以使用const限定符 constint a intconst a 这两种写法是一样的 a是一个指向constint型的指针 a所指向的内存单元不可改写 所以 a 是不允许的 但a可以改写 所以a 是允许的 int consta a是一个指向int型的const指针 a是可以改写的 但a不允许改写 intconst consta a是一个指向constint型的const指针 因此 a和a都不允许改写 指向非const变量的指针或者非const变量的地址可以传给指向const变量的指针 编译器可以做隐式类型转换 例如 charc a constchar pc 但是 指向const变量的指针或者const变量的地址不可以传给指向非const变量的指针 以免透过后者意外改写了前者所指向的内存单元 2 出现 野指令 有一种情况需要特别注意 定义一个指针类型的局部变量而没有初始化 intmain void int p p 0 在堆栈上分配的变量初始值是不确定的 也就是说指针p所指向的内存地址是不确定的 后面用 p访问不确定的地址就会导致不确定的后果 于是很容易出现 野指令 我们常把指向不确定地址的指针称为 野指针 UnboundPointer 为避免出现野指针 在定义指针变量时就应该给它明确的初值 或者把它初始化为NULL intmain void int p NULL p 0 NULL在C标准库的头文件stddef h中定义 defineNULL void 0 就是把地址0转换成指针类型 称为空指针 它的特殊之处在于 操作系统不会把任何数据保存在地址0及其附近 也不会把地址0 0 xfff的页面映射到物理内存 所以任何对地址0的访问都会立刻导致段错误 p 0 会导致段错误 错误明显容易发现 相比之下 野指针的错误难以发现和排除 3 在指针的强制类型转换 ptr1 TYPE ptr2中 如sizeof ptr2的类型 大于sizeof ptr1的类型 那么在使用指针ptr1来访问ptr2所指向的存储区时是安全的 如果sizeof ptr2的类型 小于sizeof ptr1的类型 那么在使用指针ptr1来访问ptr2所指向的存储区时是不安全的 谢谢
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!