版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C语言_ch08_6_指针数组与多重指针动态内存分配第一页,共38页。指针数组指针数组
指针组成的数组例如:int*p[4]由于[]比*优先级高,因此p首先与[]结合,即p是数组,4个元素分别为p[0]、p[1]、p[2]、p[3]。数组每个元素的类型是int*,即去掉标识符和[]后的部分。2023/4/152第二页,共38页。指针数组举例例如,图书馆有若干本书(图a),
要求对这些书目进行排序和查询。表示多个字符串的两种数据结构二维字符数组,图bcharnames[5][150];字符指针数组,图cchar*names[5];2023/4/153第三页,共38页。#include<stdio.h>intmain(){inti;char*arr[4]={"C","C++","Java","VBA"};for(i=0;i<4;i++)printf("AddressofString%d:%u\n",i+1,arr[i]);return0;}VBA\0Java\0C++\0C\003C04304204104003F03E03D04404B04A04904804704604504F04E04D04C第四页,共38页。0x0042204C0x004220480x004220400x0042203Carrchar*arr[4]={"C","C++","Java","VBA"};C\0C++\0VBA\0Java\02023/4/155第五页,共38页。例8.27将多个字符串按字母顺序(由小到大)输出。#include<stdio.h>#include<string.h>voidsort(char*names[],intn);voidprint(char*names[],intn);intmain(){
char*names[]={
"Followme", "BASIC", "GreatWall", "FORTRAN", "ComputerDesign" };
intn=sizeof(names)/sizeof(names[0]);sort(names,n);print(names,n); }2023/4/156第六页,共38页。\0\0\0\0\0第七页,共38页。voidsort(char*names[],intn)//选择法排序{
char*temp;
inti,j,k;
for(i=0;i<n-1;i++){k=i;
for(j=i+1;j<n;j++)
//k为当前排序子表最小串的下标{
if(strcmp(names[k],names[j])>0)
k=j;}
if(k!=i){temp=names[i];names[i]=names[k];names[k]=temp;}}}2023/4/158第八页,共38页。voidprint(char*names[],intn){
inti;
for(i=0;i<n;i++)printf("%s\n",names[i]);}
运行结果为:
BASICComputerDesignFORTRANFollowmeGreatWall2023/4/159第九页,共38页。8.7.2指向指针的指针指向指针变量的指针变量,简称为指向指针的指针。2023/4/1510第十页,共38页。指向指针的指针的定义char**p;*运算符的结合性是从右到左,因此**p相当于*(*p)(*p)前面部分是char*,表明p是指向char*(即一个字符指针变量)的指针变量。指向指针的指针常用在二维数组中2023/4/1511第十一页,共38页。*p就是p所指向的那个指针变量,例p=name+2;printf("%x\n",*p);printf("%s\n",*p);2023/4/1512第十二页,共38页。例8.28使用指向指针的指针输出各字符串。intmain(){
char*name[]={"Followme","BASIC","GreatWall","FORTRAN","ComputerDesign"};
char**p;
inti;
for(i=0;i<5;i++){p=name+i;printf("%s\n",*p);}}2023/4/1513第十三页,共38页。例8.29一个指针数组的元素指向整型数据的简单例子intmain(){
inta[5]={1,3,5,7,9};
int*num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]};
int**p,i;p=num;
for(i=0;i<5;i++){ printf("%d\t",**p); p++; }}运行结果为:135792023/4/1514第十四页,共38页。图8.39*pnum[2],是a[2]的地址**p即*num[2],也就是a[2]的值52023/4/1515第十五页,共38页。8.7.3指针数组作main函数的形参在cmd命令行,可通过输入可执行文件名来执行。常见dos命令举例dircdtypeipconfigping…2023/4/1516第十六页,共38页。main()函数的形参intmain(intargc,char*argv[])argc:命令行参数个数,包括命令字(可执行文件名)
argv:是一个指针数组,用来存放命令行中各个参数和命令字的字符串,并且规定:
argv[0]存放命令字
argv[1]存放命令行中第一个参数
argv[2]存放命令行中第二个参数
……形参不一定命名为argc和argv2023/4/1517第十七页,共38页。//输出第2到最后一个参数字符串intmain(intargc,char*argv[]){
while(argc>1) { ++argv;//程序名被跳过 printf("%s\n",*argv); --argc; }
return0;}3argcargv“mainpara”“a.txt”“b.txt”2023/4/1518第十八页,共38页。上面程序可以改写为intmain(intargc,char*argv[]){
while(argc-->1) printf("%s\n",*++argv);
return0;}2023/4/1519第十九页,共38页。为什么使用动态内存分配数组静态数组inta[10];动态数组数组长度动态指定2023/4/1520第二十页,共38页。动态分配内存在<stdlib.h>和<malloc.h>中均定义了下面的函数void*malloc(size_tsize);size_t是在<stddef.h>中定义的数据类型,就是一个unsigned
int向系统申请大小为size的内存块,把指向首地址的指针返回。如果申请不成功(如空间不足),返回NULL如malloc(100);voidfree(void*block);释放由malloc()申请的内存块。block是指向此块的指针2023/4/1521第二十一页,共38页。int*pi,i;...pi=(int*)malloc(100*sizeof(int));//intpi[100];if(pi==NULL){printf("Outofmemory!\n");exit(1);}...for(i=0;i<100;++i){ pi[i]=0;}...free(pi);pi=NULL;22第二十二页,共38页。例8.30建立动态数组,输入n(n由用户输入)个学生的成绩,另外用一个函数输出不合格的成绩。#include<stdio.h>#include<malloc.h>//<stdlib.h>voidprintfailinggrade(int*,int);voidprintfailinggrade(int*p,intn){inti;printf("\nThefailinggrade:");for(i=0;i<n;i++){if(p[i]<60)printf("%d",p[i]);}printf("\n");}23第二十三页,共38页。intmain(){
int*pscore,i,n;printf("请输入学生人数:");scanf("%d",&n);pscore=(int*)malloc(n*sizeof(int));
if(NULL==pscore) { printf(“Error:Outofmemory!\n"); exit(1); }printf("请输入%d个成绩,用空格隔开:",n);
for(i=0;i<n;i++)scanf("%d",pscore+i);printfailinggrade(pscore,n);free(pscore);pscore=NULL;
return0;}24第二十四页,共38页。防止内存泄露之道在需要的时候才malloc,并尽量减少malloc的次数能用自动变量解决的问题,就不要用malloc来解决malloc一般在大块内存分配和动态内存分配时使用malloc本身的执行效率就不高,所以过多的malloc会使程序性能下降可以重复利用malloc申请到的内存尽量让malloc和与之配套的free在一个函数内尽量把malloc集中在函数的入口处,free集中在函数的出口处以上做法只能尽量降低产生泄露的概率。完全杜绝内存泄露,关键要靠程序员的细心与责任感2023/4/1525第二十五页,共38页。8.8.3void指针类型void*则为"无类型指针",可以指向任何类型的数据。float*p1;
int*p2;
p1=p2;
其中p1=p2语句会编译出错,提示"'=':cannotconvertfrom'int*'to'float*'"必须改为:
p1=(float*)p2;2023/4/1526第二十六页,共38页。而void*则不同,任何类型的指针都可以直接赋值给它,无需进行强制类型转换:
void*p1;
int*p2;
p1=p2;下面的语句编译出错:
void*p1;
int*p2;
p2=p1;
提示"'=':cannotconvertfrom'void*'to'int*'"。2023/4/1527第二十七页,共38页。void的使用规则一:如果函数没有返回值,那么应声明为void类型
规则二:如果函数无参数,那么应声明其参数为void规则三:小心使用void指针类型规则四:如果函数的参数可以是任意类型指针,那么应声明其参数为void*2023/4/1528第二十八页,共38页。关于野指针(悬挂指针)悬挂指针:既不为空,也没有被设置为与另一个对象有链接关系的指针。野指针是非常危险的,所以要"杜绝"野指针。参见《高质量C++/C编程指南》--第7章内存管理(2)
2023/4/1529第二十九页,共38页。"野指针"的成因主要有两种:(1)指针变量没有被初始化。未被初始化的指针变量的缺省值是随机的。所以,指针变量在定义的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如
char*p=NULL; char*str=(char*)malloc(100);(2)指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。2023/4/1530第三十页,共38页。(3)指针操作超越了变量的作用范围。这种情况让人防不胜防,示例程序如下:classA{ public: voidFunc(void){cout<<"FuncofclassA"<<endl;}};voidTest(void){
A*p; { Aa; p=&a; //注意a的生命期
} p->Func(); //p是"野指针"}函数Test在执行语句p->Func()时,对象a已经消失,而p是指向a的,所以p就成了"野指针"。但奇怪的是我运行这个程序时居然没有出错,这可能与编译器有关。2023/4/1531第三十一页,共38页。与指针相关的编程规则减少出错的根本是彻底理解指针。与指针相关的编程规则
1)
未使用的指针初始化为NULL。
2)
在给指针分配空间前、分配后均应作判断。
3)
指针所指向的内容删除后也要清除指针本身。2023/4/1532第三十二页,共38页。遵循这些规则可以有效地减少指针出错,我们来看下面的例子:
#include<stdio.h>#include<stdlib.h>intmain(void){
char*str=(char*)malloc(100);strcpy(str,"hello");free(str);
if(str!=NULL){ strcpy(str,"world"); printf(str);}}
请问运行Test函数可能会有什么样的结果?33第三十三页,共38页。篡改动态内存区的内容,后果难以预料,非常危险。因为free(str);之后,str成为野指针,if(str!=NULL)语句不起作用。如果我们牢记规则3
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 农村建房包工包料施工合同
- 2024年度工程廉政协议书签订法律责任3篇
- 股东持股协议书范本
- 贴牌加工合同范本
- 医院劳务合同
- 食品原材料采购合同
- 手电动车转让协议书范例
- 二零二四年网络安全评估合同3篇
- 《打印机和仪的选购》课件
- 幼儿园转让合同书3篇
- 采矿08-1设计花园煤矿说明书
- SB/T 11137-2015代驾经营服务规范
- GB/T 5237.3-2017铝合金建筑型材第3部分:电泳涂漆型材
- GB/T 3798-2021汽车大修竣工出厂技术条件
- GB/T 2899-2017工业沉淀硫酸钡
- GB/T 18705-2002装饰用焊接不锈钢管
- 2023年贵州省普通高中学业水平考试历史试卷
- 培智学校启智教育人教版生活数学第四册认识人民币课件
- 小学数学六年级《外方内圆和外圆内方》优秀教学设计
- 压实度试验检测报告
- 急性中毒现场急救
评论
0/150
提交评论