资源预览内容
第1页 / 共38页
第2页 / 共38页
第3页 / 共38页
第4页 / 共38页
第5页 / 共38页
第6页 / 共38页
第7页 / 共38页
第8页 / 共38页
第9页 / 共38页
第10页 / 共38页
亲,该文档总共38页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第四章 数组和指针 1 数组与vector类型相似,也可以保存某种类型的一组对象。区别在于数组的长度是固定的。数组一经创建,就不允许添加元素。程序员无法知道一个给定数组的长度。 指针可以像迭代器一样用于遍历和检查数组中的元素。使用指针很容易出错。与容器和迭代器相比,依赖于数组和指针的程序更容易出错。现代C+程序更多使用vector代替数组。数组被严格限制使用,只有当测试性能表明用vector达不到性能要求时,才使用数组。4.1 数组的定义和初始化 2数组是由类型名、标识符和维数组成的复合数据类型。类型名规定了存放在数组中的元素的类型维数指定了数组中包含的元素的个数。必须用值大于等于1的常量表达式定义。const unsigned buf_size=512,max_files=20;int staff_size=27; /conconstconst unsigned sz=get_size(); /const value not known / untile run timechar input_bufferbuf_size; /ok,const variablestring fileTalbemax_files+1; /ok,constant expressiondouble salariesstaff_size; /error,non const variableint test_scoresget_size(); /error;non const expressionint test_scoresget_size(); /error;non const expressionint valssz; /error; size not known untiol run time数组初始化 31.显式初始化数组元素 const unsigned arr_size=3; int iaarray_size=0,1,2 若无显式初始化,则: 在函数体外定义的内置数组,无素均为0. 函数体内定义的内置数组,元素无初始化若元素为类类型,无论在那里定义,则自动调用该类的默认构造函数进行初始化。如果该类没有默认构造函数,则必须为该数组的元素提供显式初始化。 4Int ia=0,1,2; /an array of dimension 3Const unsigned array_size=5;Int iaarray_size=0,1,2; /ia=0,1,2,0,0String str_arrarr_size=“hi”,”bye”; /str_arr=“hi”,”bye”,”,”,”特殊的字符数组 5char ca1=C,+,+; /no nullChar ca2=C,+,+,0; /explicit nullChar ca3=“C+”; /null added automaticlConst char ca36=“Daniel”; /error, is /7 elements数组不能直接复制和赋值 6与vector不同,一个数组不能用另外一个数组初始化,也不能将一个数组赋值给另一个数组。Int ia=0,1,2; /ok,array of intsInt ia2 (ia); /error,cannot initialize any /array with anotherInt main() const unsigned array_size=3; int ia3array_size; /ok,but ele are unintialize ia3=ia; /error,cannot assign one aray to another return 0;数组操作 7数组元素可用下标操作符访问。从0开始。Vector的下标类型为vector:size_type,数组的下标类型为size_tInt main() const size_t array_size=10; int iaarray_size; /10 ints for(size_t ix=0; ix!=array_size;+ix) iaix=ix; return 0;8Int main() const size_t array_size=7; int ia1=0,1,2,3,4,5,6; int ia2array_size; /local , el uninitial /copy element form ia1 to ia2 for(size_t ix=0; ix!=array_size; +ix) ia2ix=ia1ix; return 0;4.2 指针的引入 9指针是指向某种类型对象的复合数据类型,是用于数组的迭代器:指向数组中的一个元素。可使用解引用操作符*和自增操作符。指针用于指向对象。指针保存的是另一个对象的地址: string s(“hello world”); string *sp=&s; /sp holds the addres of s建议:尽量避免使用指针和数组 10由于指针和数组容易产生不可预料的错误,其中一部分是概念上的问题,指针用于低纵级操作,容易产生与繁琐细节相关的错误。其他错误则源于使用指针的语法规则,特别是声明指针的语法。 许多有用的程序都可不使用指针和数组实现。现代C+程序采用vector类和迭代器取代一般数组、采用string类取代C风格字符串。指针的定义和初始化 11vector *pvec; /pvec can point to a / vectorint *ip1, *ip2; /ip1 and ip2 can point to intstring *pstring; /pstring can point to a stridouble *dp; /dp can point to a douledouble dp,*dp2; /dp2 is a pointer另一种风格的指针:string* ps; /legal but can be misleadingString* ps1,ps2; /ps1 is pointer to str, ps2 is stiString* ps1,*ps2; /both ps1 and ps2 are pointer指针可能的取值 12指针的状态: 保存一个特定对象的地址; 指向某个对象后面的另一个对象; 或者是0值,表示不指向任何对象。int ival=1024;int *pi=0; /pi initialized to address no objint *pi2=& ival; /pi2 ini to address of ivalint *pi3; /ok,but dangerous,pi3 is uninitialpi=pi2; /pi and pi2 address same obje, ivalpi2=0; /pi2 not address to no object指针初始化和赋值操作的约束 13对指针进行初始化或赋值只能用以下四种1.0值常量表达式。如在编译时可获得0值的整形const对象或字面值常量0.2.类型匹配的对象的地址。3.另一个对象之后的下一地址。4.同类型的另一个有效指针。14int ival;int zero=0;const int c_ival=0;int *pi=ival;/error, initial from int valuePi=zero; /error,pi assigned int value of 0Pi=c_ival; /ok,c_ival is a const with comple-time value of 0pi=0; /ok,directly with liteal constant 0Int *pi=NULL;Double dval;Double *pd=&dval; /ok, initilaixe with a address of a doubleDouble *pd2=pd; /ok,initilize is a pointer to doubeInt *pi=pd; /error, type of pi and pd differPi=&dval; /error, void * 指针 15void* 指针可以保存任何类型的对象地址。double obj=3.14;double *pd=&obj; /ok,void *pv=&obj; /obj can be of any typepv=pd; /pd can be a pointer to any typeVoid*指针支持的操作:与另一指针比较向函数传递void*指针或从函数返回void*指针给另一个void*指针赋值4.2.3 指针操作 16指针提供间接操纵其所指对象的功能。stirng s(“hello world”);string *sp=&s; /sp holds the addres of scout*sp; /prints hello world给指针赋值或通过指针赋值 17如果对左操作数进行解引用,则修改的是指针所指对象的值。如果没有使用解引用,则修改的是指针本身的值。string s1(“some value”);string *sp1=&s1;string s2(“another”);string *sp2=&s2;*sp1=“a new value”; /s1 been chanedsp1=sp2; /sp1point to a different ofjbect指针和引用的比较 18引用总是指向某个对象,定义引用时没有初始化是错误的。指针可以指向不同的对象。赋值行为的差异:给引用赋值修改的是该引用所关联的对象的值。指针赋值使指针指向另一个对象。19int ival=1024,ival2=2048;int *pi=&ival,*pi2=&ival2;pi=pi2; /pi poin to ival2int &ri=ival,&ri2=ival2;ri=ri2; /asigns ival2 to ival指向指针的指针 20int ival=1024;int *pi=&ival; /pi points to an intint *ppi=π /ppi points to a point to intInt *pi2=*ppi; /ppi points to apinterCout“the value of ivaln”“direct value:”ival“n”“indirect value:”*pi“n”“doubly indirect value:”*ppiia2int j=p1; /p1=*(p+1),p1=ia3int k=p-2; /ok,p-2=ia0数组的超出末端指针 23const size_t arr_size=5;int arrarr_size=1,2,3,4,5;int *p=arr; /ok,p point to arr0int *p2=p+arr_size; /p2 point to one past / the end用指针遍历数组元素 24Const size_t arr_sz=5;Int int_arrarr_sz=0,1,2,3,4;for(int *pbegin=int_arr,*pend= int_arr+arr(sz; pbegin!=pend;+pbegin) cout*pbegin ; 指向const对象的指针和const指针25指向const对象的指针必须具有const特性const double *cptr; /cptr point to a / double that is constConst double pi=3.14;Cptr=π /okDouble *ptr=π /error*cptr=33; /errorconst void *cpv=&universe;void *pv=&universe; /error, Double dval=3.14; /dval is a double, its value can be chanCptr=&dval; /ok,but cant change dval through cptrconst指针 26const指针是指本身的值不能被修改的指针int errNumb=0;int *const curErr=&errNumb; 与任何const量一样,const指针必须在定义时初始化指向const对象的const指我const double pi=3.14159const double *const pi_ptr=π指针和typedef 27typedef string * pstringconst pstring cstr;问:cstr是什么类型?const string *cstr; /errorstring *const cstr; /correct!4.3 C风格字符串 28字符串字面值类型其实是const char类型的数组。而是以空字符null结束的字符数组。char ca1=C,+,+; /not null,not c stylchar ca2=C,+,+,0;/explicit nullchar ca3=“C+”; /null added automaticchar *cp1=ca1;char *cp2=ca2;C风格字符串的标准库函数 29#include 标准库函数总是假定每个字符串是以null结束的。4.3.1 创建动态数组 30数组长度固定,在编译时必须知道其长度,只在定义它的块语句内存在。动态分配的数组不必在编译时知道其长度,可以在运行时才确定数组长度。动态分配的数组将一直存在,直到程序显式释放它为止。C语言用一对标准库函数malloc和free在自由存储区中分配存储空间,C+用new和delete实现相同的功能。动态数组的定义 31动态分配数组时,只需指定类型和长度,不必为数组对象命名。int *pia=new int10; /array of 10 ints初始化动态分配的数组 32string *psa=new string10; /arr of 10 emint *pia=new int10; /arr of 10 uniniti intsInt *pia2=new int10();const对象的动态数组 33/error, unitilized const arrayConst int *pci_bad=new const int100;/ok, value-initialized const arrayconst int *pci_ok=new const int100();/ok, array of 100 empty stringsConst string *pcs=new const string100;允许动态分配空数组 34size_t n=get_size();int * p=new intn;for (int * q=p; q!=p+n; +q) cout*qendl;Char arr0; /error, cant define 0-lenth arChar *cp=new char0; /ok,but cp cant / be dereferenced动态空间的释放 35如果不再需要使用动态创建的数组,程序员必须显式地将其占用的存储空间返还给程序的自由存储区。C+为指针提供delete释放指针所指向的数组空间。char *cp=new char10;Delete cp;4.4 多维数组 36如果数组的元素又是数组,称为多维数组int ia34=0,1,2,3,4,5,6,7,8,9,10,11; int ia34=0,1,2,3,4,5,6,7,8,9,10,11;Int ia34=0,4,8;指针和多维数组 37由于多维数组其实是数组的数组,由多维数组转换成的指针类型应是指向第一个内层数组的指针。int ia34;int (*ip)4=ia; /ip points to an array of /4intsip=&ia2; /ia2 is an array of 4 intsint *ip4; /array of pointers to int作业4.5, 4.7, 4.16
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号