指针为C语言编程提供了强大的支持——如果你能正确而灵活地利用指针,你就可以直接切入问题的核心,或者将程序分割成一个个片断。一个很好地利用了指针的程序会非常高效、简洁和精致。

利用指针你可以将数据写入内存中的任意位置,但是,一旦你的程序中有一个野指针("wild”pointer),即指向一个错误位置的指针,你的数据就危险了——存放在堆中的数据可能会被破坏,用来管理堆的数据结构也可能会被破坏,甚至操作系统的数据也可能会被修改,有时,上述三种破坏情况会同时发生。

此后可能发生的事情取决于这样两点:第一,内存中的数据被破坏的程度有多大;第二,内存中的被破坏的部分还要被使用多少次。在有些情况下,一些函数(可能是内存分配函数、自定义函数或标准库函数)将立即(也可能稍晚一点)无法正常工作。在另外一些情况下,程序可能会终止运行并报告一条出错消息;或者程序可能会挂起;或者程序可能会陷入死循环;或者程序可能会产生错误的结果;或者程序看上去仍在正常运行,因为程序没有遭到本质的破坏。

值得注意的是,即使程序中已经发生了根本性的错误,程序有可能还会运行很长一段时间,然后才有明显的失常表现;或者,在调试时,程序的运行完全正常,只有在用户使用时,它才会失常。

在C语言程序中,任何野指针或越界的数组下标(out-of-bounds array subscript)都可能使系统崩溃。两次释放内存的操作也会导致这种结果。你可能见过一些C程序员编写的程序中有严重的错误,现在你能知道其中的部分原因了。

有些内存分配工具能帮助你发现内存分配中存在的问题,例如漏洞(leak,见7.21),两次释放一个指针,野指针,越界下标,等等。但这些工具都是不通用的,它们只能在特定的操作系统中使用,甚至只能在特定版本的编译程序中使用。如果你找到了这样一种工具,试试看能不能用,因为它能为你节省许多时间,并能提高你的软件的质量。

指针的算术运算是C语言(以及它的衍生体,例如C++)独有的功能。汇编语言允许你对地址进行运算,但这种运算不涉及数据类型。大多数高级语言根本就不允许你对指针进行任何操作,你只能看一看指针指向哪里。

C指针的算术运算类似于街道地址的运算。假设你生活在一个城市中,那里的每一个街区的所有街道都有地址。街道的一侧用连续的偶数作为地址,另一侧用连续的奇数作为地址。如果你想知道River Rd.街道158号北边第5家的地址,你不会把158和5相加,去找163号;你会先将5(你要往前数5家)乘以2(每家之间的地址间距),再和158相加,去找River Rd.街道的168号。同样,如果一个指针指向地址158(十进制数)中的一个两字节短整型值,将该指针加3=5,结 果将是一个指向地址168(十进制数)中的短整型值的指针(见7.7和7.8中对指针加减运算的详细描述)。

街道地址的运算只能在一个特定的街区中进行,同样,指针的算术运算也只能在一个特定的数组中进行。实际上,这并不是一种限制,因为指针的算术运算只有在一个特定的数组中进行才有意义。对指针的算术运算来说,一个数组并不必须是一个数组变量,例如函数malloc()或calloc()的返回值是一个指针,它指向一个在堆中申请到的数组。

指针的说明看起来有些使人感到费解,请看下例:

char *p;

上例中的说明表示,p是一个字符。符号“*”是指针运算符,也称间接引用运算符。当程序间接引用一个指针时,实际上是引用指针所指向的数据。

在大多数计算机中,指针只有一种,但在有些计算机中,指向数据和指向函数的指针可以是不同的,或者指向字节(如char。指针和void *指针)和指向字的指针可以是不同的。这一点对sizeof运算符没有什么影响。但是,有些C程序或程序员认为任何指针都会被存为一个int型的值,或者至少会被存为一个long型的值,这就无法保证了,尤其是在IBM PC兼容机上。

注意:以下讨论与Macintosh或UNIX程序员无关;

最初的IBM PC兼容机使用的处理器无法有效地处理超过16位的指针(人们对这种结论仍有争议。16位指针是偏移量,见9.3中对基地址和偏移量的讨论)。尽管最初的IBM PC机最终也能使用20位指针,但颇费周折。因此,从一开始,基于IBM兼容机的各种各样的软件就试图冲破这种限制。

为了使20位指针能指向数据,你需要指示编译程序使用正确的存储模式,例如紧缩存储模式。在中存储模式下,你可以用20位指针指向函数。在大和巨存储模式下,用20位指针既可以指向数据,也可以指向函数。在任何一种存储模式下,你都可能需要用到far指针(见7.18和7.19)。

基于286的系统可以冲破20位指针的限制,但实现起来有些困难。从386开始,IBM兼容机就可以使用真正的32位地址了,例如象MS-Windows和OS/2这样一些操作系统就实现了这一点,但MS—DOS仍未实现。

如果你的MS—DOS程序用完了基本内存,你可能需要从扩充内存或扩展内存中分配更多的内存。许多版本的编译程序和函数库都提供了这种技术,但彼此之间有所差别。这些技术基本上是不通用的,有些能在绝大多数MS-DOS和MS-WindowsC编译程序中使用,有些只能在少数特定的编译程序中使用,还有一些只能在特定的附加函数库的支持下使用。如果你手头有能提供这种技术的软件,你看一下它的文档,以了解更详细的信息。

7.1 什么是间接引用(indirection)?

对已说明的变量来说,变量名就是对变量值的直接引用。对指向变量或内存中的任何对象的指针来说,指针就是对对象值的间接引用。如果p是一个指针,p的值就是其对象的地址;*p表示“使间接引用运算符作用于p”,*p的值就是p所指向的对象的值。

*p是一个左值,和变量一样,只要在*p的右边加上赋值运算符,就可改变*p的值。如果p是一个指向常量的指针,*p就是一个不能修改的左值,即它不能被放到赋值运算符的左边,请看下例:

例 7.1 一个间接引用的例子

#include int

main()

{

int i;

int * p ;

i = 5;

p = & i; / * now * p = = i * /

/ * %Pis described in FAQ VII. 28 * /

printf("i=%d, p=%P, * p= %d\n" , i, P, *p);

* p = 6; / * same as i = 6 * /

printf("i=%d, p=%P, * p= %d\n" , i, P, *P);

return 0; / * see FAQ XVI. 4 * / }

}

上例说明,如果p是一个指向变量i的指针,那么在i能出现的任何一个地方,你都可以用*p代替i。在上例中,使p指向i(p=&i)后,打印i或*p的结果是相同的;你甚至可以给*p赋值,其结果就象你给i赋值一样。

C语言编程常见问题解答之指针和内存分配.doc

下载Word文档到电脑,方便收藏和打印[全文共2694字]

编辑推荐:

下载Word文档

c语言中指针往内存写值,C语言编程常见问题解答之指针和内存分配相关推荐

  1. C语言中不同类型的取值范围

    C语言中的不同类型的取值范围 前言 C语言中,我们知道最基本的数据类型有int整型,float和double浮点型,char字符型,在计算机里,他们的取值并不是任意和无限的,都有相应的取值范围,那么计 ...

  2. c语言中存贮班级学生的变量,C语言----变量教案.docx

    C语言----变量教案 课 题 2.2 常量和变量----变量 课型 理实一体化 授课班级 高二计算机(升学班) 课时 2 教学目标 复习巩固C语言中常量的应用: 掌握C语言中变量的命名规则及应用. ...

  3. Gox语言中使用Sciter库进行GUI图形界面编程-GX23.1

    Sciter是非常优秀的跨平台GUI图形界面编程库,只需附带一个动态链接库文件,就可以实现基于HTML/CSS/TiScript的图形界面,并且已经经过很多公司和商用产品的实际检验,稳定可靠.我们常见 ...

  4. c语言中removeDir的相反函数,C语言编程常见问题解答之常用函数的包括文件.doc

    C语言编程常见问题解答之常用函数的包括文件 C语言编程常见问题解答之常用函数的包含文件(1) 作者:unknown 更新时间: 2005-05-10 函数 包含 类别 功能 _atold math.h ...

  5. c语言中减号算一个字符吗,C语言中指针的加减运算

    char arr[3]; printf("arr:\n%d\n%d\n%d\n", arr, arr + 1, arr + 2); char *parr[3]; printf(&q ...

  6. c++ 结构体中不同类型的初始值_Golang语言基础教程:结构体

    1.1 什么是结构体 Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型.结构体是由一系列具有相同类型或不同类型的数据构成的数据集合. 1.2 结构体的定义和初始化 ...

  7. C语言中 以追加只写方式打开文本文件,C语言文件操作

    语言中对文件进行操作必须首先打开文件,打开文件主要涉及到fopen函数.fopen函数的原型为 FILE* fopen(const char *path,const char *mode) 其中pat ...

  8. 对c语言的认知报告怎么写,对C语言指针的认识的认知实习报告.doc

    对C语言指针的认识的认知实习报告 认知实习报告 题目:对C语言指针的认识 学生姓名: 学号: 班级: 所属学院: 指导教师: 2013年7月 对C语言指针的认识 学生姓名: 学号: 班级: 指导教师: ...

  9. C语言中头文件怎么写?(本文来源网络,由黑乌鸦进一步完善)

    c语言头文件怎么写?我一直有这样的疑问,但是也一直没去问问到底咋回事:所以今天一定要把它弄明白! 其实学会写头文件之后可以为我们省去不少事情,可以避免书写大量的重复代码.有利于整理思路.使代码脉络更加 ...

最新文章

  1. cmake 注意事项
  2. F - 等式(1/x + 1/y = 1/n)
  3. AJAX跨域请访问的问题
  4. 33/100. Product of Array Except Self
  5. 预定义异常 - PHP手册笔记
  6. javafx中的tree_JavaFX中的塔防(2)
  7. 深度学习二(Pytorch物体检测实战)
  8. 百度竞价开户优化的细节到底是哪些
  9. XMOS 最新 USB 专业录音声卡解决方案
  10. 澳洲电源和电池充电器对应标准的公告将强制执行2022年6月15日起
  11. 原生js实现星级评分
  12. Linux之LVM篇
  13. spring session Session().removeAttribute 异常
  14. 坚鹏:苏州银行《银行数字化运营之行动篇》课程培训圆满结束
  15. 什么是无监督、监督、半监督学习
  16. 支付必测--使用fiddler篡改支付金额
  17. 我的Android进阶之旅------四种呼叫转移场景
  18. Arch Linux 安装Go
  19. electron的基本教程
  20. CCRC信息安全服务资质认证给企业带来的好处

热门文章

  1. 2020年,人工智能如何走向高质量发展?
  2. “妈妈打工,爸爸是盲人”小学生记错开学时间独自上学,原因心酸
  3. Fedora 30系统下,用g++编译opencv项目
  4. pelco-d协议数据解析示例
  5. Labview 属性节点讲解
  6. matlab与音频处理
  7. 2020年华科计算机考研机试题答案(没弄懂题目的意思)
  8. 域的基本管理:创建部门和用户
  9. java百度云推送demo_百度云推送java服务端maven安装完整demo
  10. ios linux时间戳转时间,将UNIX时间戳转换为数据 – iOS