2005-4-27 1 C++大学基础教程 第6章 指针和引用 北京邮电大学电信工程学院 计算机技术中心 指针(Pointer)是C++和C的一 种数据类型。很多其他高级语言 也有类似的数据类型。引用 (Reference)则是C++所特有的 一种数据类型。指针和引用在概 念上和使用上都有相似之处,但 是也有重要的差别。 第六章 指针和引用 6.1 指针的概念 6.2 指针的运算 6.3 指针和函数 6.4 指针和字符串 6.5 通过指针访问数组 6.6 指针访问动态内存 6.7 引用概念 6.1 指针的概念 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -5- 6.1.1 指针和指针变量 指针是变量的地址。或者说是在内存中,存放 某种类型变量的地址。 例如,定义了整型变量a,a的地址就是一个指 针。 也可以不定义任何变量,只是指定内存某个地 址开始(如0x00430100)的4个字节存放整型 变量,这样的地址也是指针。 存放指针的变量就是指针变量。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -6- 6.1.1 指针和指针变量 当声明了一个指针变量后,确定了三件事: ? 变量本身在内存中所分配的地址和字节数,指针变 量总是占有4个字节; ? 系统允许的地址范围,以及地址单元内可以存放的 内容; ? 指针变量可以进行的运算。 访问指针变量时,只能看到地址。只有通过这 个地址,才能访问地址单元中的内容。这样的 访问称为对于内存单元的 间接访问 。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -7- 6.1.2 指针变量的声明和初始化 指针变量声明的格式是: <类型名> *变量名1, *变量名2 ; 例如: int *va1, *va2; char *ch1, *ch2; 指针变量在声明后,变量的值(地址)是随机 的。 这样的指针变量是不能安全的使用的 。因 为其中的随机地址完全可能不是有效的数据地 址。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -8- 6.1.2 指针变量的声明和初始化 在声明指针变量时的 “*”,有两个含义: ? 声明变量va1、va2、ch1、ch2都是指针变量; ? 说明变量va1和va2的类型是(int *)型,即 指向 整型变量的指针 。va1和va2所指定的地址单元中, 只能存放整型数据。类似地,ch1和ch2的类型是 (char *)型,它们所指定的地址单元中,只能存 放字符。 指针变量都是有类型的. 指针变量的类型就是 它所指定的地址单元中存放的数据的类型 。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -9- 6.1.2 指针变量的声明和初始化 指针变量的初始化有两种方法:在声明时的初 始化和声明后的初始化。 声明指针变量时就进行初始化的格式是: <类型名> *指针变量名=&变量名; ? 其中的变量名应该是已经声明或定义的同类型变量 名。例如: ? char ch1=’Y’, ch2=’A’; ? char *pch1=&ch1, *pch2=&ch2; 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -10- 6.1.2 指针变量的声明和初始化 也可以在声明指针变量后,用赋值的方式对它 们进行初始化。例如: ? int i1=’Y’, i2=’A’; ? int *pi1, *pi2; ? pi1=&i1; ? pi2=&i2; 没有初始化指针变量是不可以使用的。编译带 有这样的指针变量的程序,编译系统会给出警 告,而运行时会出现错误。 6.2 指针的运算 6.2 指针的运算 表6.1 指针的运算 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -13- 6.2.1 指针的赋值运算 指针的赋值运算一定是地址的赋值。用来对指针变量 赋值的可以是: ? 同类型变量的地址; ? 同类型的已经初始化的指针变量; ? 其他同类型的指针。 此外,也可以用0或者NULL对指针变量赋值。使得变量 包含的是 “空指针 ”,即不指向任何的内存物理地址。 必须注意:不同类型的指针是不可以互相赋值的。在 指针赋值时,不存在类型自动转换的机制。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -14- 例6.1 观察以下指针赋值运算的结果。如果将注释去 掉,结果将如何? #include <iostream> using namespace std; void main() {int va1=100,*pva1; float vf1='A',*pvf1,*pvf2; int *pva2=NULL; cout<<"value of pva1 is "<<pva2<<endl; pva1=&va1; pvf1=pvf2=&vf1; cout<<pva1<<" "<<&va1<<endl; cout<<pvf1<<" "<<pvf2<<endl; //pvf1=pva1; } value of pva1 is 0x00000000 0x0012FF7C 0x0012FF7C 0x0012FF74 0x0012FF74 注释去掉会出现编译错误 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -15- 6.2.2 间接引用运算 间接引用运算符 “*”是一种一元算符,它和指 针变量连用,对指针所指向的内存地址单元进 行间接访问。使用的格式是: *指针变量 如果指针变量iptr指向整型变量va,*iptr就 是变量va的内容 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -16- 例6.2 对变量的直接访问和间接访问:写出以下程序 运行结果。 #include <iostream> using namespace std; void main() {char ch1='a',*ch; int k1=100; ch=&ch1; //指针ch指向变量ch1 cout<<"*ch="<<*ch<<endl; //间接访问 *ch='B'; cout<<"ch1="<<ch1<<endl; //直接访问 ch1=k1; cout<<"*ch="<<*ch<<endl; //间接访问 } 运行结果 : *ch=a ch1=B *ch=d 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -17- 例6.3 定义指向指针的指针变量。观察对这种指针变量 间接访问的结果。 #include <iostream> using namespace std; void main() { int va=100,*pva,**ppva; //ppva是指向指针的指针 int k1=100; pva=&va; cout<<"*pva="<<*pva<<endl; //间接访问结果是整型数 ppva=&pva; cout<<"*ppva="<<*ppva<<endl; //间接访问结果是地址 cout<<"pva="<<pva<<endl; //就是指针pva的内容 } 运行结果 : *pva=100 *ppva=0x0012FF7C pva=0x0012FF7C 6.2 面向过程的程序设计 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -19- 6.2 面向过程的程序设计 不足: 1、结构化编程将数据和过程相分离; 2、结构化编程对代码重用支持不够。 可重用思想就是创建一些已知属性的组件, 然后插入到自己的程序中。 6.3 面向过程的程序设计 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -21- 6.3 面向过程的程序设计 面向对象的程序设计将数据和处理数据的 过程当成一个整体 ——对象。 1)封装 由对象的概念支持。只需知道外部接口, 不需知道内部实现,就可以使用的特性。 2)继承 由类的概念支持。利用已有的成果进行扩 展,充分体现了代码重用。 3)多态 运行时特性。 6.4 C++的诞生 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -23- 6.4 C++的诞生 C++语言从C语言的基础上发展起来的 C语言 历史: 1、贝尔实验室的 Dennis Ritchie开发 2、在 B语言 的基础 3、作为 Unix操作系统的开发语言 优点: 1、与 硬件 无关 2、设计严谨 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -24- 6.4 C++的诞生 1978年, Brian Kernighan与 Dennis Ritchie 出版了 《 The C Programming Language》 是最 早的经典 传统 C语言 的书,很薄,只有两百多 页,所以这本 C语言的圣经又称 `K&R“。 当时很快出现了多个不兼容的 C语言版 本,因此需要制订一种标准 C。所以 1988年, 第二版 《 The C Programming Language》 ,是 最经典的标准 C的书籍。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -25- 6.4 C++的诞生 C语言之父 dennis Ritchie The C Programming Language 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -26- 6.4 C++的诞生 C语言是一门面向过程的程序语言 优点: 1、可直接访问内存 2、程序运行效率高 3、可移植性好 缺点: 1、类型检查机制较弱 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -27- 6.4 C++的诞生 C++语言的 优点: 1、 简化 程序复杂性 2、促进 代码重用 3、使用先进的 面向对象技术 Bjarne出版了的经典 C++著作 《 The C ++ Programming Language 》 , 1991年第 2版, 1997年第 3版, 2000年特别版,他被 誉为 C++之 父。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -28- 6.4 C++的诞生 C++之父 Bjarne stroustrup The C ++ Programming Language 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -29- 6.4 C++的诞生 C++语言是从 C语言发展演变而来。 C++包 含了整个 C, C是建立 C++的基础。 C++包含 C 的所有特征、属性、优缺点,并添加了 面向对 象 的支持。 C++语言 C语言 面向对象 6.5 程序开发过程 6.5 程序开发过程 源程序: .cpp compile(Ctrl+F7) 目标程序: .obj Build(F7) 可执行程序: .exe 6.6 简单的C++程序 6.6 简单的C++程序 /*************************************** 程序文件: ch1_6.cpp 程序功能:在屏幕上输出 hello world! 作者 :XXX 创建时间: XX年 XX月 XX日 ***************************************/ #include <iostream> using namespace std; void main() { cout<<"Welcome to Bupt!“<<endl; } 注释 编译预处理 程序主体 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -34- 6.6 简单的C++程序 “注释 ” 是程序员为读者作的说明,用来提 高程序的可读性, C++程序在编译过程中 忽略 注释。 1、 “//” 用来注释一行说明,在 “//”之后的文字直到 换行都为注释。一 般用来对于程序中难懂的代 码进行说明。 2、 “/*”和 “*/” 用来注释一段说明,在 “/*”和 “*/”之间的部 分,不管多长都为注释。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -35- 6.6 简单的C++程序 所有以 “#”开头的代码,称为编译预处理。 #include <iostream> 每次启动编译器时,先运行预处理器,预处 理器找到所有以 “#”开头的代码行进行处理。 include是一条预处理指令,意思是 “后面跟的是一 个文件名,请找到该文件并将其加入。 ” iostream是系统定义的一个 “头文件 ”,它设置 了 C++的 I/O相关环境,并定义了输入输出流对象 cout和 cin等。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -36- 6.6 简单的C++程序 using namespace std; 1998年批准的标准 C++使用 namespace命名 空间标准。 iostream是一个标准函数库, cout是 标准库函数提供的一个对象,标准库函数在 namespace说明书中被指定为 “std”。因此这句 代码的意思是使用标准命名空间 std中的函数。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -37- 6.6 简单的C++程序 正式的程序从代码 “void main()”开始,它 包含一个名为 main()的函数,也称为主函数。 每个 C++程序有且仅有一个 main()函 数,程序在 开始运行时会自动调用 main()函数。 main()前面的 void表示函数的返回值的类 型,意味着程序执 行结束后无需向操作系统返 回 。 函数:是指能实现一个或多个功能的代码 块。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -38- 6.6 简单的C++程序 所有的函数都以左大括号 {开始,右大括号 } 结束,在大括号 {}之间的部分称为函数体。 cout<<” Hello World!”<<endl; 1、 cout:标准输出流对象, 2、 <<: 插 入操作符可以连续使用 3、 endl:代表换行符 意思是使用 cout将 “<<”后面的内容打印在屏 幕上。 在 函 数 体 的 每 一句代码后面都有一个分号 “;” 表示一个 C++语句的结束。 2005-4-27 北京邮电大学电信工程学院计算机技术中心 -39- 6.6 简单的C++程序 操作步骤 1、新建一个工程 1) 启动 VC++ 6.0 2) 新建一个 console工程 3) 编写源程序 2、编译和连接 编译: compile(Ctrl+F7) 链接: Build(F7) 3、运行 使用的命令: Ctrl+F5 总结 1、 程序设计语言的发展过程 机器语言、汇编语言和高级语言。 2、C和C++的关系 3、如何编写、编译、运行一个C++程序 作业 熟悉 VC++ 6.0的环境。