第六章 指针、引用和动态空间管理 6.1 指针的概念 指针的概念 指针变量的定义和初始化

Slides:



Advertisements
Similar presentations
C++语言程序设计教程 第5章 构造数据类型 第6章 C++程序的结构.
Advertisements

电子成绩单项目实现.
C语言程序设计教程 单位:德州学院计算机系.
第九章 字串 (String).
第8章 指针 ● 8.1 指针简介 ● 8.2 指针变量的操作 ● 8.3 数组与指针 ● 8.4 二维数组与指针 ●本章小结 ●本章练习.
C语言基础——指针的高级应用 Week 05.
第5章 指 针 教学目标: 掌握指针定义、初始化方法和基本运算; 掌握利用指针访问一维数组、二维数组的方法;
高级语言程序设计 C++程序设计教程(下) 2006年春季学期 与一些教材的区别 偏重理论,不去讨论某个系统的具体使用方法,但会涉及实现技术
VC++系统开发 第二章 C++语言基础 河北经贸大学信息技术学院.
第六讲 指针与字符串 —— 为什么指针 —— 持久动态内存分配 —— 字符串(字符数组).
第九章 指针 目录 指针与指针变量的概念 变量的指针和指向变量的指针变量 数组的指针和指向数组的指针变量
第8章 字元與字串處理 8-1 C語言的字元檢查函數 8-2 C語言的字串 8-3 字串的輸入與輸出 8-4 指標與字串
第5章 函数与模块化设计 学习目的与要求: 掌握函数的定义及调用方法 理解并掌握参数的传递方法 理解函数的嵌套与递归调用
复习与总结.
由C程序结构所知,一个完整的C语言程序是由一个且只能有一个main()函数(又称主函数)和若干个其他函数组合而成的。而前面各章仅学习main()函数的编程,本章将介绍其他函数的编程,包括其他函数的定义、调用、参数传递及变量的作用域等。
函數 授課:ANT 日期:2009/3/24.
内容提要 对象的生命周期 构造函数 析构函数 拷贝构造函数. 常宝宝 北京大学计算机科学与技术系
Introduction to the C Programming Language
C 程式設計— 指標.
函數 授課:ANT 日期:2011/3/28.
项目六 用指针优化学生成绩排名 项目要求 项目分析
结构体和共用体 2 梁春燕 华电信息管理教研室.
C 程式設計— 指標 台大資訊工程學系 資訊系統訓練班.
新世纪计算机专业系列教材 数据结构 C++实现 第一章 缪淮扣 顾训穰 沈 俊 编著 科 学 出 版 社.
Object-Oriented Programming in C++ 第一章 C++的初步知识
程序设计期末复习 黎金宁
第三章 C++中的C 面向对象程序设计(C++).
Chap 8 指针 8.1 寻找保险箱密码 8.2 角色互换 8.3 冒泡排序 8.4 电码加密 8.5 任意个整数求和*
第八章 函数.
第五章 指针 5.1 指针的概念和定义 5.2 指针运算 5.3 指针和数组 5.4 字符串指针 5.5 指针数组 5.6 指向指针的指针
第二章 C++对C 在非面向对象方面的改进 更简洁,更安全.
C语言 程序设计基础与试验 刘新国、2012年秋.
第3讲 C++程序控制结构 3.1 顺序结构 3.2 分支结构 3.3 循环结构 3.4 转向控制 3.5 综合案例分析.
第八章 使用指针.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
第十章 指针.
第2章 C++流程控制语句 if 语句 switch语句 for语句 while语句 do - while语句 break语句
数组 梁春燕 华电信息管理教研室.
C++大学基础教程 第5章 数组 北京科技大学 信息基础科学系.
第十章 用户自定义数据类型 目录 学生信息管理系统的开发 结构体数据类型的概述 结构体变量的使用 结构体数组
C语言大学实用教程 第5章 函数与程序结构 西南财经大学经济信息工程学院 刘家芬
C++语言程序设计 第六章 数组 指针与字符串.
C语言复习3----指针.
第一章 程序设计和C语言 主讲人:高晓娟 计算机学院.
C++语言程序设计 C++语言程序设计 第三章 控制语句 第十一组 C++语言程序设计.
第10讲 构造函数和析构函数 构造函数 析构函数 This 指针.
C语言大学实用教程 第6章 数组 西南财经大学经济信息工程学院 刘家芬
函数 概述 模块化程序设计 基本思想:将一个大的程序按功能分割成一些小模块, 特点: 开发方法: 自上向下,逐步分解,分而治之
函式庫補充資料.
Oop8 function函式.
第八章 指標 (Pointer).
第六章 指针 C++程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
第11章 從C到C++語言 11-1 C++語言的基礎 11-2 C++語言的資料型態與運算子 11-3 C++語言的輸出與輸入
第十章 指针 指针是C语言的重要概念,是C语言的特色,是C语言的精华。 10.1 地址和指针的概念 内存中的每一个字节都有一个地址。
第二章 基本数据类型 ——数据的表示.
第二讲 基本数据类 型及数组等 此为封面页,需列出课程编码、课程名称和课程开发室名称。
第 9 章 建構函式與解構函式.
C程序设计.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
挑戰C++程式語言 ──第9章 函數.
第四章 函数 丘志杰 电子科技大学 计算机学院 软件学院.
《数据结构与算法设计》第一部分 面向对象的C++程序设计基础.
第三章 高级函数特性.
基本資料型態 變數與常數 運算子 基本的資料處理 授課:ANT 日期:2014/03/03.
第九章 指针 C程序设计中使用指针可以: 使程序简洁、紧凑、高效 有效地表示复杂的数据结构 动态分配内存 得到多于一个的函数返回值.
第9章 C++程序设计初步 9.1 C++的特点 9.2 最简单的C++程序 9.3 C++的输入输出 9.4 函数的重载
資料!你家住哪裏? --談指標 綠園.
第六章 复合数据类型 指针的声明与使用 数组的声明与使用 指针与数组的相互引用 字符串及相关库函数 new与delete
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
Presentation transcript:

第六章 指针、引用和动态空间管理 6.1 指针的概念 6.1.1 指针的概念 6.1.2 指针变量的定义和初始化   6.1 指针的概念   6.1.1 指针的概念 6.1.2 指针变量的定义和初始化 1.指针表示内存空间的地址。指针类型定义以*标识。  例:int* //整型指针    char* //字符指针    double*//double型指针 

第六章 指针、引用和动态空间管理 2.指针变量定义  例:int* ip;    char* cptr;    int* iptr1,*iptr2;  

第六章 指针、引用和动态空间管理 3.建立指针  (1)建立指针包含指针变量定义和给指针赋初值(地址)。  (2)&操作符可取变量地址,指针变量用于存放地址。   

第六章 指针、引用和动态空间管理 例:int* iptr;    int icount=18;    iptr=&icount;//指针赋值    该例等价与  

第六章 指针、引用和动态空间管理 例:int icount=18;    int* iptr=&icount;//指针的初始化    内存表示:    

第六章 指针、引用和动态空间管理 4.间接引用指针   操作符*可取指针变量所指单元内容,称为间接引用指针。 

第六章 指针、引用和动态空间管理 例:#include<iostream.h> void main() { {  int * iptr;  int icount=18;  iptr=&icount;  cout<<*iptr<<endl;  *iptr=58;  }  结果:18     58 

第六章 指针、引用和动态空间管理 5.指针变量地址:指针变量也具有内存地址。 例:#include<iostream.h>   5.指针变量地址:指针变量也具有内存地址。  例:#include<iostream.h>    void main()    {     int icount=18;     int* iptr=&icount;     *iptr=58;     cout<<icount<<endl;     cout<<iptr<<endl;     cout<<&icount<<endl;     cout<<*iptr<<endl;     cout<<&iptr<<endl;    } 

第六章 指针、引用和动态空间管理 结果:58     0x0067fe00     58     0x0067fefc  内存表示: 

第六章 指针、引用和动态空间管理   例:int icount=58;    int* iptr=&icount;    则    icount //整型变量    iptr //指针变量    &icount //整型变量icount地址     

第六章 指针、引用和动态空间管理   &iptr //指针变量iptr地址    *icount //错误    *iptr //指针变量iptr所指单元内容  6.*(取内容)和&(取地址)为互逆操作。   

第六章 指针、引用和动态空间管理 6.1.3 const指针  1.指向常量的指针:在指针定义语句的类型前加const,表示指针指向的数据为常量。 

第六章 指针、引用和动态空间管理 例:const int a=78; const int b=28; int c=18;   const int * pi=&a; //int const * pi=&a;    *pi=58; //错误,*pi为常量      pi=&b;   *pi=68; //错误,*pi为常量 

第六章 指针、引用和动态空间管理 pi=&c;  *pi=88; //错误,*pi为常量  c=98;    结论:const int * pi=&a;(或int const * pi=&a;)中,*pi为常量,pi为变量,故*pi不能为左值。 

第六章 指针、引用和动态空间管理   2.指针常量:在指针定义语句的指针名前加const,表指针本身为常量。 

第六章 指针、引用和动态空间管理 例:char * const pc="asdf"; pc=“dfgh”;//错误,pc为常量   *pc='b';    *(pc+1)='c';    *pc++=‘y’; //错误,pc为常量     结论: int * const pi=&a;中,*pi为变量,pi为常量,故pi不能为左值。 

第六章 指针、引用和动态空间管理 3.指向常量的指针常量     结论: const int * const pi=&a;中,*pi、pi均为常量,故均不能作为左值。 

第六章 指针、引用和动态空间管理 例:const int ci=7; int ai; const int * const cpc=&ci;   const int * const cpc=&ai;   cpi=&ai; //错误,cpi为常量   *cpi=39; //错误,*cpi为常量   ai=39;    

第六章 指针、引用和动态空间管理 6.2 指针运算 6.2.1 赋值(=) 同类型指针之间可相互赋值。 任何类型的指针可赋值给void指针,反之不行。 例:char c=‘x’,*s=&c; void * p1,* p2=Null; p1=s;//对 s=p2;//错

第六章 指针、引用和动态空间管理 6.2.2 取地址(&) 单目运算符&可取变量的地址。 例:int k,*p; p=&k; k p

第六章 指针、引用和动态空间管理 6.2.3 取内容(*) 单目运算符*可取指针所指的内存单元内容。 例:int *pd,d; pd=&d; cout<<*pd<<‘ ‘<<endl; d pd 99

第六章 指针、引用和动态空间管理 6.2.4 判断一指针是否为空指针(==或!=)。 例:如果p是空指针,则… if(p==0)… if(p==Null)… if(!p)… 例:如果p不是空指针,则… if(p!=0)… if(p!=Null)… if(p)…

一般将高地址指针作被减数,且其数据不计算在内。 例:int n,m[12],*p1=&m[5],*p2=&m[10]; 第六章 指针、引用和动态空间管理 6.2.5 计算两地址间数据单元的个数(-)。 计算两地址间存储单元的个数。 一般将高地址指针作被减数,且其数据不计算在内。 例:int n,m[12],*p1=&m[5],*p2=&m[10]; n=p2-p1;//n==5 低地址 高地址 p1 p2

第六章 指针、引用和动态空间管理 6.2.6 指针移动 1. 移动n个单位:操作符+、 -、 +=和 -=。 指针向后(高地址)移动n个单位:指针表达式+n或指针表达式+=n。 指针向前(低地址)移动n个单位:指针表达式-n或指针表达式-=n。 例:见书。

第六章 指针、引用和动态空间管理 2. 移动1个单位:操作符++(前增1)、 ++(后增1) -- (前减1)和-- (后减1) 。 指针向后(高地址)移动1个单位:指针变量++或++指针变量。 指针向前(低地址)移动1个单位:指针变量--或--指针变量。

第六章 指针、引用和动态空间管理 例:int k,*pk=&k; cout<<endl<<++pk; 结果是两个相同的地址。 cout<<endl<<pk++; 结果是两个不相同的地址。

第六章 指针、引用和动态空间管理 6.2.7 指针表达式的副作用 1.表达式的副作用:表达式计算过程中,若参与运算的变量的值发生了改变,称此表达式具有副作用。如i+j++。 2.表达式的副作用产生的原因是使用了具有副作用的操作符,包括: (1)赋值(=) (2)复合赋值(+=,-=,*=,/=等等) (3)前增1和前减1(++,--) (4)后增1和后减1(++,--)

第六章 指针、引用和动态空间管理 3.对指针表达式 具有副作用的操作符,包括: (1)赋值(=) (2)复合赋值(+=,-=,*=,/=等等) (3)前增1和前减1(++,--) (4)后增1和后减1(++,--) 无副作用的操作符,包括: (1)取地址(&) (2)间接引用(*) (3)其它如+,-,==等

第六章 指针、引用和动态空间管理 4.对指针表达式,设p为指针变量。 (1)前增量++p,前减量—p,间接引用*p,赋值及复合赋值的结果仍为左值。 (2)后增量p++,后减p--,取地址&k及由p构成的算术表达式和关系表达式的结果不能作为左值。

第六章 指针、引用和动态空间管理 例:设p为指针变量。 ++(++p) //对 (p++)++ //错 --p+=&k //对 p--+=&k //错 ++p++ //错 (++p)++ //对 ++(p++) //错 p++-=3 //错 (p+3)++ //错 ++(p+3) //错 ++++p //对 p++++ //错

第六章 指针、引用和动态空间管理 6.2.8 指针类型的强制转换 (类型修饰符*) 指针表达式 6.2.9 指针操作符的综合运用 例:见书。

第六章 指针、引用和动态空间管理 6.3 指针与数组 6.3.1 一维指针与数组 1.指针的加减运算即指针的移动操作(以内存单元为单位)。  2.一维数组名是首元素地址。 

第六章 指针、引用和动态空间管理 例:int a[5]; a[0] a[4] a[1] a[2] a[3] a a+4 a+1 a+2

int* pa=a;//int* pa=&a[0]; 第六章 指针、引用和动态空间管理 例:int a[10]; int* pa=a;//int* pa=&a[0]; a[0] a[1] a[2] … a[9] … a pa

第六章 指针、引用和动态空间管理 第i个元素(四种表示): a[i] *(a+i) p [i] *(p+i) 第i个元素地址(四种表示) :

第六章 指针、引用和动态空间管理 例:#include<iostream.h> void main() {   {      int iArray[10];      int sum=0;      int* iptr=iArray;// 数组名是首元素地址    for(int i=0;i<10;i++) iArray[i]=i*2;     for(int index=0;index<10;index++)     {      sum+=*iptr;      iptr++;     }     cout<<”sum is”<<sum<<endl; 

第六章 指针、引用和动态空间管理 上例内存表示:

第六章 指针、引用和动态空间管理    3.一维数组名是首元素地址,但数组名是指针常量,不能作为左值。  例:见书。 4.数组指针:指向数组且与数组名等价的指针。 

第六章 指针、引用和动态空间管理 例:int a[100]; int* iptr=a; iptr称为数组指针。     此时iptr++ //正确,因iptr为指针变量    a++ //错误,因a为指针常量 

第六章 指针、引用和动态空间管理 例:对数组的求和运算,有以下5种方法。    #include<iostream.h>    int s1,s2,s3,s4,s5;    int a[]={1,4,7,10,13,16,19,22,25};    int* iptr; 

第六章 指针、引用和动态空间管理 void main()  {   int size,n;   size=sizeof(a)/sizeof(*a);   //size=sizeof(a)/sizeof(a[0]);  

第六章 指针、引用和动态空间管理 for(n=0;n<size;n++) s1+=a[n];//方法1  iptr=a;  for(n=0;n<size;n++) s2+=*iptr++;//方法2  for(n=0;n<size;n++) s3+=*(iptr+n);//方法3 

第六章 指针、引用和动态空间管理 iptr=a;  for(n=0;n<size;n++) s4+=iptr[n];//方法4  for(n=0;n<size;n++)s5+=*(iArray+n);//方法5  

第六章 指针、引用和动态空间管理 cout<<s1<<endl  <<s2<<endl  <<s3<<endl  <<s4<<endl  <<s5<<endl;  } 

第六章 指针、引用和动态空间管理 6.3.2 多维数组与指针 1.二维数组的数组名是首行地址。 例:int b[5][2]; int (*pb)[2]=b; 此时,pb与数组名b等价,称pb是与数组b等价的数组指针。 

第六章 指针、引用和动态空间管理 内存表示: b b+1 b+2 b+3 b+4 b[0][0] b[1][0] b[2][0]

第六章 指针、引用和动态空间管理 数组b的第i行第j列元素可表示为: pb[i][j] b[i][j] *(b[i]+j) *(*(b+i)+j) *(pb[i]+j) *(*(pb+i)+j) 相应地,有数组b的第i行第j列元素地址的表示方法。 以上转换要点:a[i]等价与*(a+i)

第六章 指针、引用和动态空间管理 由于b[0]可看成具有2个元素的一维整形数组,故其数组名b[0]即首元素地址&b[0][0],b[0]+1即&b[0][1]。 同理 b[1]即&b[1][0],b[1]+1即&b[1][1]。 b[2]即&b[2][0],b[2]+1即&b[2][1]。   b[3]即&b[3][0],b[3]+1即&b[3][1]。 ……

第六章 指针、引用和动态空间管理 内存表示: b[0] b[0]+1 b[1] b[1]+1 b b+1 b+2 b+3 b+4

第六章 指针、引用和动态空间管理 例:设计函数show_matrix,它显示参数传来的任意规格的整形二维数组。 #include<iomanip.h> void show_matrix(int* array,int row,int col,int width) { for(int i=0;i<row;i++) { cout<<endl; for(int j=0;j<col;j++) cout<<setw(width)<<*(array+i*col+j); } void main() { int s[][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}}; show_matrix(s[0],4,3,5); //&s[0][0]或(int*)s cout<<endl;

第六章 指针、引用和动态空间管理 6.3.3 数组指针 1.数组指针:指向数组且与数组名等价的指针。 例(指向一维数组的指针) int a[10]; int* pa=a; 称pa为数组指针。  

第六章 指针、引用和动态空间管理 例(指向二维数组的指针) int b[3][4]; int (*pb)[4]=b; 称pb为数组指针。  

第六章 指针、引用和动态空间管理 2.函数的形参为数组参数时,形式上是数组,本质上是指针,是与该数组名等价的数组指针。 例: int sum (int array[] ,int n);等价于 int sum (int*array , int n);

第六章 指针、引用和动态空间管理 6.3.4 字符指针与字符串 1.字符串:分为字符数组与字符串常量两种。  (1)字符数组是用来初始化字符数组的字符串。  (2)字符串常量是该字符串首字符地址,类型为char*。 

第六章 指针、引用和动态空间管理 例:char buffer[]=“hello”;//字符数组    cout<<“good”<<endl;//字符串常量 

第六章 指针、引用和动态空间管理 2.字符串常量存放在data区中的const区中。   2.字符串常量存放在data区中的const区中。   由于字符串常量是该字符串首字符地址,如字符串常量“hello”值为0000:0100(因存放它的首单元地址是0000:0100),另有字符串常量“hello”值为0238:045d(因存放它的首单元地址是0238:045d),故两个同样字符组成的字符串常量是不相等的。见图。  

第六章 指针、引用和动态空间管理 3.字符指针  (1)字符串常量、字符数组名和字符指针的类型均为char*。  (2)输出字符指针就是输出字符串。  (3)输出字符指针的间接引用就是输出单个字符。 

第六章 指针、引用和动态空间管理 例:#include<iostream.h> void main() {   {     char buffer[10]="ABC";     char* pc;     pc="hello";     cout<<pc<<endl;//输出字符指针    pc++;     cout<<pc<<endl;//输出字符指针     cout<<*pc<<endl;//输出字符指针的间接引用     pc=buffer;     cout<<pc;//输出字符指针    } 

第六章 指针、引用和动态空间管理 结果:hello     ello     e     ABC   

第六章 指针、引用和动态空间管理 4.字符串比较    (1)两个字符串常量的比较是地址的比较。  (2)两个数组名的比较也是地址的比较。 

第六章 指针、引用和动态空间管理 例:#include<iostream.h> void main() {   {     char buffer1[10]="hello";     char buffer2[10]="hello";  if(buffer1==buffer2)    //实质上是地址的比较    cout<<"equal\n";  else  cout<<"not equal\n";  }   结果:not equal  

第六章 指针、引用和动态空间管理   (3)真正要从字面上比较两个字符串可用标准库函数strcmp()进行。   标准库函数strcmp(),在头文件string.h中,函数原型如下:   int strcmp(const char* s1,const char* s2); 

第六章 指针、引用和动态空间管理   函数值如下:    0 s1值等于s2值    正值 s1值大于s2值    负值 s1值小于s2值   

第六章 指针、引用和动态空间管理 例:#include<iostream.h> #include<string.h>   void main()    {     char buffer1[10]= "hello";    char buffer2[10]="hello";     if(strcmp(buffer1,buffer2)==0)        cout<<"equal\n";    else      cout<<"not equal\n";     }    结果:equal   

第六章 指针、引用和动态空间管理 5.字符串赋值   (1)因字符数组名是指针常量,故不能直接给字符数组名赋值。   例:char buffer[10];     buffer=“hello”;//错误,此为赋值 

第六章 指针、引用和动态空间管理  例:char buffer[11]= “I am a boy”;//正确,此为初始化    (2)可通过for循环给字符数组赋值。   例:char buffer[11];     for (int i =0; i <10; i ++) cin>>a[i];     a[10]=’\0’; 

第六章 指针、引用和动态空间管理   (3)字符指针可初始化或赋值。  例:char *string=“I love china”;//正确,此为初始化   例:char *string;     string=“ I love china”;//正确,此为赋值 

第六章 指针、引用和动态空间管理 (4)可调用标准库函数strcpy()给字符数组赋值。   (4)可调用标准库函数strcpy()给字符数组赋值。   标准库函数strcpy(),在头文件string.h中,函数原型如下:    char* strcpy( char* dest,const char* src);   功能:将src的内容拷贝到dest中,并将dest的值作为函数值返回。 

第六章 指针、引用和动态空间管理   例:char s[]="12345";    cout<<s<<" ";    cout<<strcpy(s, "ABCD")<<" ";    cout<<s;  结果:12345 ABCD ABCD 

第六章 指针、引用和动态空间管理   例:char buffer1[10];    char buffer2[10];    strcpy(buffer1, "hello");    strcpy(buffer2, buffer1);  注:strcpy()仅能对以‘\0’作结束符的字符数组进行操作。若要对其它类型的数组赋值可调用函数memcpy()。 

第六章 指针、引用和动态空间管理 (5) 标准库函数memcpy(),在头文件mem.h中,函数原型如下:  void* memcpy( void* d,void* s,size_t n);   功能:从源s中拷贝n个字节到目标d。    例:int intarray1[5]={1,3,5,7,9};    int intarray2[5];    memcpy(intarray2,intarray1,5*sizeof(int)) 例6.2 例6.3见书。 

第六章 指针、引用和动态空间管理 6.3.5 指针数组和命令行参数 1.指针数组:数组元素值为指针的数组称之指针数组。 6.3.5 指针数组和命令行参数  1.指针数组:数组元素值为指针的数组称之指针数组。  例:char* proname[]={"fortran","c","c++"};    2.指针数组与二维数组  例:char* proname[]={“fortran”,“c”,“c++”};//指针数组 

第六章 指针、引用和动态空间管理  数组proname占2字节*3=6字节,所指向的字符串占8+2+4=14个字节,故该指针数组共占20个字节的存储空间。     例:char name[3][8]={“fortran”,“c”,“c++”};//二维数组   数组name共占8字节*3=24个字节的存储空间。   故二维数组一般比指针数组多浪费存储空间。 

第六章 指针、引用和动态空间管理   3.二级指针:指向指针的指针。  数组名表示首元素地址,是一级指针。  指针数组名是指向指针的指针,即二级指针。 

第六章 指针、引用和动态空间管理  例:int a=3;    int* pa=&a;//pa是一级指针    int** ppa=&pa;//ppa是二级指针    该例内存示意图 

第六章 指针、引用和动态空间管理 例:char* pc[]={"a","b","c"}; char** ppc; ppc=pc;//ok  第六章 指针、引用和动态空间管理 例:char* pc[]={"a","b","c"};    char** ppc;    ppc=pc;//ok  4.Null指针    Null指针又称零指针或空指针值。 

第六章 指针、引用和动态空间管理  指针数组的主要应用是命令行参数。 5.命令行参数:DOS命令中,程序命令及键入的参数称为命令行参数。  例: c>copy filea fileb//三个命令行参数   c>type c:autoexec.bat//二个命令行参数 

第六章 指针、引用和动态空间管理 命令行参数通过主函数main()的参数描述。 主函数main()的参数有三个:  int argc//描述命令行参数个数  char* argv[]//描述命令行参数的指针数组  char* env[]//描述环境变量的指针数组 

第六章 指针、引用和动态空间管理   例:void main()    void main(int argc)    void main(int argc, char* argv[])//该形式较常用    void main(int argc, char* argv[],char* env[]) 

第六章 指针、引用和动态空间管理 6.打印命令行参数 例://ch6-22.cpp #include<iostream.h> 6.打印命令行参数   例://ch6-22.cpp     #include<iostream.h>     void main(int argc, char* argv[])     {      int icount=0;  while(icount<argc)  {      cout<<"arg"<<icount<<":“      <<argv[icount]<<endl;   icount++;  } 

第六章 指针、引用和动态空间管理   c>ch6_22 aBcD eFg hIjKl  arg0:ch6_22  arg1: aBcD  arg2: eFg   arg3: hIjKl 

第六章 指针、引用和动态空间管理 例://该例功能同上例 #include<iostream.h>  例://该例功能同上例   #include<iostream.h>   void main(int argc, char* argv[])   {   int i=0;   while(*argv!=Null)    cout<<"arg"<<i++<<":"<<*argv++<<endl;   } 

第六章 指针、引用和动态空间管理 7.命令行参数使用形式 (1)void main() void main(int argc)   7.命令行参数使用形式  (1)void main()   void main(int argc)   void main(int argc, char* argv[])//该形式较常用   void main(int argc, char* argv[],char* env[]) 

第六章 指针、引用和动态空间管理 (2)操作系统以空格区分不同参数,若参数中含有空格,可用引号括起来。 (2)操作系统以空格区分不同参数,若参数中含有空格,可用引号括起来。  例:c>ch6_22 Hello how are you  arg0:ch6_22  arg1: Hello  arg2: how  arg3: are  arg4:you 

第六章 指针、引用和动态空间管理 例:c>ch6_22 "Hello how are you" arg0:ch6_22   例:c>ch6_22 "Hello how are you"  arg0:ch6_22  arg1: Hello how are you  6.3.6 数组参数实际上是指针

第六章 指针、引用和动态空间管理 6.4 指针与函数  6.4.1 指针参数 1.数组作为函数形参时,形式上是数组,实际上是指针。  例:void sum(int array[],int n);    //等价与void sum(int * array,int n); 

第六章 指针、引用和动态空间管理 例:#include<iostream.h>   void sum(int array[],int n)   { int sum=0;    for(int i=0;i<n;i++)    {    sum+=*array;     array++;    }    cout<<sum<<endl;     void main()     { int a[10]={1,2,3,4,5,6,7,8,9,10};     sum(a,10);     } 

第六章 指针、引用和动态空间管理   2.形参和实参结合规则  (1)形参为简单变量时,结合规则:形参=实参的值 

第六章 指针、引用和动态空间管理 例:(形参为简单变量) #include<iostream.h> 例:(形参为简单变量)    #include<iostream.h>    double time2(double n)    {      n=n*2;      return n;    }    void main()      double m=7.0;      cout<<endl<<m;      cout<<endl<<time2(m);   

第六章 指针、引用和动态空间管理 运行结果: a=3,b=8 after swapping… a=3,b=8 例:(形参为普通变量) 例:(形参为普通变量)    #include<iostream.h>    void swap(int,int);    void main()    { int a=3,b=8;     cout<<"a="<<a<<",b"<<b<<endl;    swap(a,b);      cout<<"after swapping…\n";     cout<<"a="<<a<<",b"<<b<<endl;  }    void swap(int x,int y)    { int temp=x;      x=y;      y=temp;    }  运行结果: a=3,b=8     after swapping…     a=3,b=8 

第六章 指针、引用和动态空间管理   (2)形参为指针变量时,结合规则:形参指针=实参指针的值(地址值) 

第六章 指针、引用和动态空间管理 例:(形参为指针变量) #include<iostream.h> 例:(形参为指针变量)    #include<iostream.h>    void swap(int*,int*);    void main()    { int a=3,b=8;     cout<<"a="<<a<<",b"<<b<<endl;     swap(&a,&b);      cout<<"after swapping…\n";     cout<<"a="<<a<<",b"<<b<<endl;    }   void swap(int* x,int* y)    { int temp=*x;     *x=*y;     *y=temp;    }  运行结果: a=3,b=8    after swapping…  a=8,b=3 

第六章 指针、引用和动态空间管理 3.指针函数:返回指针值的函数。 定义格式:类型修饰符* 函数名(形参表) 函数体 3.指针函数:返回指针值的函数。  定义格式:类型修饰符* 函数名(形参表)     函数体  (1)指针函数不能把在它内部说明的具有局部作用域的数据地址作为返回值。  (2)可以返回堆地址,可以返回全局或静态变量的地址。   

第六章 指针、引用和动态空间管理 例:有若干个学生的成绩,要求在用户输入学生序号以后,能输出该学生的全部成绩。 例:有若干个学生的成绩,要求在用户输入学生序号以后,能输出该学生的全部成绩。   #include<iostream.h>   void main()   {    static float score[][4]={60,70,80,90,65,76,      87,69,88,66,79,80}; 

第六章 指针、引用和动态空间管理 float* search(float (* pointer )[4] , int n); 行数   float* search(float (* pointer )[4] , int n);    float* p;    int i, m;    cin>>m;    p=search(score,m);    for(i=0; i<4; i++)     cout<<*(p+ i)<< " ";   } 

第六章 指针、引用和动态空间管理 float* search(float (* pointer )[4] , int n) {   {     float* pt;     pt= *( pointer + n);     return (pt);    }   

第六章 指针、引用和动态空间管理 例:char* trim(char* s ) { char * p=s+strlen(s)-1;   {     char * p=s+strlen(s)-1;     while(p-s>=0&&*p==‘ ‘) p--;     *(p+1)=‘\0’; return s;    }   

第六章 指针、引用和动态空间管理 4.void指针(即void*)   void指针,又称空类型指针。不能进行指针运算,也不能进行间接引用。可将其它类型指针赋给void指针,反之不行,除非进行显示转换。   

第六章 指针、引用和动态空间管理 例:void* p; p++;//error *p=20.5;//error int a=20;   int* pr=&a;    void* p=pr;//ok    pr=p;//error    pr=(int*)p;//ok   

第六章 指针、引用和动态空间管理 6.4.3 函数指针:指向函数且与函数名等价的指针。 1.函数名是指向函数的指针常量。 2.函数指针定义   6.4.3 函数指针:指向函数且与函数名等价的指针。 1.函数名是指向函数的指针常量。 2.函数指针定义   (1)若函数原型为:类型 函数名(形参表);   则相应函数指针定义为:   类型 (*变量名)(形参表)〖=函数名〗; 

第六章 指针、引用和动态空间管理 (2)若函数原型为:类型* 函数名(形参表); 则相应函数指针定义为:   (2)若函数原型为:类型* 函数名(形参表);   则相应函数指针定义为:   类型* (*变量名)(形参表)〖=函数名〗;  例:int f1(int n);     int (*pf1)(int n);     pf1=f1;//pf1是与f1等价的函数指针 

第六章 指针、引用和动态空间管理 例:int f1(int n);   int (*pf1)(int n)=f1;//pf1是与f1等价的函数指针    例:char* f2(int n,char* s);//指针函数    char* (*pf2)(int n,char* s);    pf2=f2;//pf2是与f2等价的函数指针 

第六章 指针、引用和动态空间管理   例:char* f2(int n,char* s);//指针函数    char* (*pf2)(int n,char* s)=f2;//pf2是与f2等价的函数指针  3.通过函数指针来调用函数 

第六章 指针、引用和动态空间管理 例:#include<iostream.h>   int add(int a,int b){return a+b};    void main()    {    int (*p)(int,int);    p=add; //p是与add等价的函数指针   cout<<add(3,5);   cout<<(*p)(3,5);   四种调用形式效果等价   cout<<p(3,5);    cout<<(*add)(3,5);    }   结果:8888 

第六章 指针、引用和动态空间管理 4.函数指针作函数形参 例:计算以0.10为步长,特定范围内的三角函数之和。  4.函数指针作函数形参    例:计算以0.10为步长,特定范围内的三角函数之和。   #include<iostream.h>   #include<math.h>  double sigma(double(*func)(double),double dl,double du)  { double dt=0.0; for(double d=dl;d<du;d+=0.1) dt+=func(d);  return dt;  } 

第六章 指针、引用和动态空间管理 void main() { double dsum; dsum=sigma(sin,0.1,1.0); cout<<"the sum of sin from       0.1 to 1.0 is"<<dsum<<endl; dsum=sigma(cos,0.5,3.0);   cout<<"the sum of cos from       0.5 to 3.0 is"<<dsum<<endl; } 

第六章 指针、引用和动态空间管理  6.5 引用(reference)的概念    1.引用:为一个变量、函数等对象规定一个别名,该别名称为引用。此后,对别名的操作即是对别名所代表的对象的操作。 

第六章 指针、引用和动态空间管理   2.声明引用:声明引用与定义指针类似,只不过将*换成&。引用只有声明,没有定义。因为引用不占存储空间,而定义要分配存储空间。 

第六章 指针、引用和动态空间管理   3.引用若不是作为函数参数的,则必须初始化。   声明引用格式如下:   格式:类型& 别名〖=别名所代表的对象〗; 

第六章 指针、引用和动态空间管理  例:  int i=0;   int& ir=i;//定义引用ir作为对象i的别名  ir=2;//形式上向ir赋值,实际上是向i赋值,等同于i=2;   int* p=&ir;//形式上取ir 的地址,实际上是取i 的地址,等同于int* p=&i; 

第六章 指针、引用和动态空间管理 例:  int a[10], *p=a;  int& ra1=a[6];//ra1代表数组元素a[6]  int (&ra2)[10]=a;//ra2代表数组a  int* & rp1=p;//rp1代表指针变量p  int& rp2=*p;//rp2代表p所指向的那个对象,即数组元素a[0] 

第六章 指针、引用和动态空间管理 例: #include<iostream.h> void main() { {  int intone;  int& rint=intone;  intone=5;  cout<<"intone:"<<intone<<endl;  cout<<"rint:"<<rint<<endl;  rint=7;  }  运行结果:intone:5       rint:5       intone:7       rint:7 

第六章 指针、引用和动态空间管理 4. 引用作为函数的形参 函数形参为引用时,形参和实参结合规则。   4. 引用作为函数的形参  函数形参为引用时,形参和实参结合规则。  形参为引用时,形参(引用)接收实参(对象)的地址,每当使用引用时,c++就去求该引用所含地址中的变量值。 

第六章 指针、引用和动态空间管理 或表述为:  形参为引用时,函数调用期间,凡遇到形参(引用)的地方,全部用实参(对象)来代替。 

第六章 指针、引用和动态空间管理 例:#include<iostream.h>   void swap(int& x,int& y);    void main()    { int x=5;    int y=6;  cout<<"before swap,x:"<<x<<",y:"<<y<<endl;  swap(x,y);  cout<<"after    swap,x:"<<x<<",y:"<<y<<endl;  }  void swap(int& rx,int& ry)  { int temp=rx;  rx=ry;  ry=temp; 

第六章 指针、引用和动态空间管理 结果:before swap,x:5,y:6     after swap,x:6,y:5    例:见书。

第六章 指针、引用和动态空间管理 6.6 动态空间管理(堆内存管理)  1.堆内存(heap):堆是一块内存区域,堆允许程序在运行时(而不是编译时),申请某个大小的内存空间。堆内存又称为动态内存。    

第六章 指针、引用和动态空间管理 2.获得堆内存 2.获得堆内存   c中用函数malloc()(在头文件alloc.h中)来获得堆内存;c++中用操作符new来获得堆内存。  3.释放堆内存   c中用函数free()(在头文件alloc.h中)来释放堆内存;c++中用操作符delete来释放堆内存。   

第六章 指针、引用和动态空间管理 4.new和delete操作符  (1)对非数组空间   new 类型[(表达式)]   delete 指针表达式[,指针表达式] 

第六章 指针、引用和动态空间管理 例:int* p1,**p2; p1=new int(5); p2=new (int *);   cout<<endl<<*p1<<' '<<**p2;    delete p1,*p2,p2;   

第六章 指针、引用和动态空间管理   上例的内存表示:  注:new操作符若申请成功,返回首单元地址;否则返回Null值。 

第六章 指针、引用和动态空间管理  (2)对数组空间  new 类型[元素个数] //申请一维数组空间  delete[] 指针表达式[,指针表达式] 

第六章 指针、引用和动态空间管理 例:int* ap=new int[10];    delete[] ap;   

第六章 指针、引用和动态空间管理 例:double (*matrix)[4]=new double[4][4]; delete[] matrix;    matrix