第 六 章 数组、指针与字符串
6-1 数组a[10][5][15]一共有多少个元素? 解:10*5*15=750个元素
6-2 在数组a[20]中第一个元素和最后一个元素是哪一个? 解:第一个元素是a[0],最后一个是a[19]
6-3 用一条语句声明一个有5个元素的int型数组,并依次赋予1~5的初值。 解:int integerArray[5]={1,2,3,4,5}
6-4 已知有一个数组名叫oneArray,用一条语句求出其元素的个数。 解:int nArrayLength=sizeof(oneArray)/sizeof(oneArray[0]); 6-5 用一条语句声明一个有5×3个元素的二维int型数组,并依次赋予1~15的初值。 解:int theArray[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; 6-6 运算符“*”和 “&”的作用是什么?
解:*是指针运算符,是一元操作符,表示指针所指向的对象的值。&是取地址运算符,也是一个一元运算符,用来得到一个对象的地址。
6-7 什么叫做指针?指针中储存的地址和这个地址中的值有何区别?
解:指针是一种数据类型,具有指针类型的变量称为指针变量。指针变量存放的是另外一个对象的地址,这个地址中的值就是另一个对象的类容。
6-8 声明一个int型指针,用new语句为其分配包含10个元素的地址空间。 解:int pInteger=new int[10];
6-9 在字符串”Hello,world!”中结束符是什么? 解:\\0
6-10 声明一个有5个元素的int型数组,在程序中提示用户输入元素值,最后再在屏幕上显示出来。
解:#include 6-11 引用和指针有何区别?何时只能使用指针而不能使用引用? 解:引用是一个别名,不能为NULL值,不能被重新分配;指针是一个存放地址的变量。当需要对变量重新赋以另外的地址或赋值为NULL时只能使用指针。 6-12 声明下列指针:float类型变量的指针pfloat,char类型的指针pstr、struct Customer型的指针pcus。 解:float*pfloat; Char*pstr; Struct customer*pcus; 6-13 给定float类型的指针fp,写出显示fp所指向的值的输出流语句。 解:cout<<”Value==”<<*fp; 6-14 在程序中声明一个double类型变量的指针,分别显示指针占了多少字节和指针所指的变量占了多少字节。 解:#include double*counter; cout<<\cout< cout<<\return 0; } 6-15 const int * p1 和 int * const p2的区别是什么? 解:const int *p1声明了一个指向整形常量的指针p1,因此不能通过指针p1来改变它所指向的整型值;int*const p2声明了一个指针型常量,用于存放整形变量的地址,这个指针一旦初始化后,就不能被重新赋值。 6-16 声明一个int型变量a,一个int型指针p,一个引用r,通过p把a的值改为10,通过r把a的值改为5 解:int a; int*p=&a; int &r=a; *p=10; r=5; 6-17 下列程序有何问题,请仔细体会使用指针时应避免出现这个的问题。 #include cout << \ return 0; } 解:指针p没有初始化,也就是没有指向某个确定的内存单元,它指向内存中的一个随机地址,给这个随机地址赋值是非常危险的。 6-18 下列程序有何问题,请改正;仔细体会使用指针时应避免出现的这个问题。 #include using namespace std; int fn1(){ int * p = new int (5); return *p; } int main(){ int a = fn1(); cout << \return 0; } 解:#include int *fn1(){ int*p=new int(5); return p; } 6-19 声明一个参数为int型,返回值为long型的函数指针;声明类A的一个成员函数指针,其参数为int型,返回值long型。 解:long(*p_fn1)(int); Long(A::*p_fn2)(int); 6-20 实现一个名为SimpleCircle的简单圆类,其数据成员int*itsRadius为一个指向其半径值的指针,存放其半径值。设计对数据成员的各种操作,给出这个类的完整实现并测试这个类。 解:#include public: SimpleCircle(); SimpleCircle(int); SimpleCircle(const SimpleCircle &); ~SimpleCircle(){} void setRadius(int); int getRadius()const; private: int*itsRadius; }; SimpleCircle::SimpleCircle() { itsRadius=new int(5); } SimpleCircle::SimpleCircle(int Radius ) { itsRadius =new int(Radius); } SimpleCircle::SimpleCircle(const SimpleCircle & rhs) { int val=rhs.getRadius(); itsRadius=new int(val); } int SimpleCircle::getRadius()const { return*itsRadius; } int main(){ SimpleCircle CircleOne ,CircleTwo(9); cout<<\ cout<<\ return 0; } 6-21 编写一个函数,统计一条英文句子中字母的个数,在主程序中实现输入输出。 解:#include int main(){ char text[100]; cout<<\输入一个英语句子:\ gets(text); cout<<\这个句子里有\个字母。\} 6-22 编写函数void reverse(string &s),用递归算法使字符串s倒序。 解:#include string reverse(string & str){ if(str.length()>1){ string sub=str.substr(1,str.length() -2); return str.substr(str.length ()-1,1)+reverse(sub)+str.substr(0,1); }else return str; } int main(){ string str; cout<<\输入一个字符串:\ cin>>str; cout<<\原字符串为:\ cout<<\倒序反转后为:\ return 0; } 6-23 设学生人数N=8,提示用户输入N个人的考试成绩,然后计算出他们的平均成绩并显示出来。 解:#include 6-24 基于char*设计一个字符串类MyString,并且具有构造函数、析构函数、复制构造函数,重载运算符“+”、“=”、“+=”、“[]”,尽可能完善它,使之能满足各种需要。(运算符重载功能为选做,参见第8章) 解:#include private: MyString(unsigned short); char*itsMyString; unsigned short itsLen; }; MyString::MyString(){ itsMyString=new char[1]; itsMyString[0]='\\0'; itsLen=0; } MyString::MyString(unsigned short len){ itsMyString=new char[itsLen+1]; for(unsigned short i=0;i<=len;i++) itsMyString[i]='\\0'; itsLen=len; } MyString::MyString(const char*const cMyString){ itsLen=strlen(cMyString); itsMyString=new char[itsLen +1]; for (unsigned short i=0;i MyString::MyString(const MyString&rhs){ itsLen=rhs.getLen(); itsMyString=new char [itsLen +1]; for(unsigned short i=0;i MyString::~MyString(){ delete[]itsMyString; itsLen=0; } MyString&MyString::operator =(const MyString&rhs){ if(this==&rhs) return *this; delete[]itsMyString; itsLen=rhs.getLen(); itsMyString=new char[itsLen +1]; for(unsigned short i=0;i char&MyString::operator [](unsigned short offset){ if(offset>itsLen) return itsMyString[itsLen-1]; else return itsMyString[offset]; } char MyString::operator [](unsigned short offset )const { if(offset>itsLen) return itsMyString[itsLen-1]; else return itsMyString[offset]; } MyString MyString::operator +(const MyString&rhs){ unsigned short totalLen=itsLen+rhs.getLen (); MyString temp (totalLen); unsigned short i=0; for(i=0;i void MyString::operator +=(const MyString&rhs){ unsigned short rhsLen=rhs.getLen(); unsigned short totalLen=itsLen+rhsLen; MyString temp(totalLen); unsigned short i=0; for(i=0;i int main(){ MyString s1(\ cout<<\ char*temp=\ s1=temp; cout<<\ char tempTwo[20]; strcpy(tempTwo,\ s1+=tempTwo; } cout<<\cout<<\cout<<\s1[4]='x'; cout<<\cout<<\MyString s2(\MyString s3; s3=s1+s2; cout<<\MyString s4; s4=\ cout<<\return 0; 6-25 编写一个3×3矩阵转置的函数,在main()函数中输入数据。 解:#include { k=a[i][j]; a[i][j]=a[j][i]; a[j][i]=k; } } int main(){ int i,j; int data[3][3]; cout<<\输入矩阵的元素\ for(i=0;i<3;i++) for(j=0;j<3;j++) { cout<<\第\行第\个元素为:\ cin>>data[i][j]; } cout<<\输入的矩阵为:\ for(i=0;i<3;i++){ for (j=0;j<3;j++) cout< 6-26 编写一个矩阵转置的函数,矩阵的行数和列数在程序中由用户输入。 解: #include int main(){ int n,i,j; int*p; cout<<\请输入矩阵的行、列数:\ cin>>n; p=new int [n*n]; cout<<\输入矩阵的元素\ for(i=0;i } } cout<<\输入的矩阵为:\for(i=0;i move(p,n); cout<<\转置后的矩阵为:\for(i=0;i return 0; 6-27定义一个Employee类,其中包括表示姓名、街道地址、城市和邮编等属性,包括setName()和display()等函数;display()使用cout语句显示姓名、地址、城市和邮编等属性,函数setName()改变对象的姓名属性,实现并测试这个类。 解:#include private: char name[30]; char street[30]; char city[18]; char zip[6]; public: Employee(char*n,char*str,char*ct,char*z); void setName (char*n); void display(); }; Employee::Employee(char*n,char*str,char*ct,char*z) { strcpy(name,n); strcpy(street,str); strcpy(city,ct); strcpy(zip,z); } void Employee::setName (char*n) { strcpy(name,n); } void Employee ::display (){ cout< int main(){ Employee e1(\逗逼\马勒戈壁3号\葫芦岛\ e1.display (); cout< 6-28分别将例6-10程序和6-16程序中对指针的所有使用都改写为与之等价的引用形式,比较修改前后的程序,体会在哪些情况下使用指针更好,哪些情况下使用引用更好。 解:6-10 #include void splitFloat(float x,int&intPart ,float&fracPart){ intPart=static_cast int main(){ cout<<\ for(int i=0;i<3;i++){ float x,f; int n; cin>>x; splitFloat(x,n,f); cout<<\ } return 0; } 6-16 #include int main (){ cout<<\ Point &ptrl=*new Point; delete &ptrl; cout<<\ ptrl=*new Point(1,2); } delete &ptrl; return 0; 6-29运行下面的程序,观察执行结果,指出该程序是如何通过指针造成安全性隐患的,思考如何避免这种情况的发生。 #include int arr[]={1,2,3}; double*p=reinterpret_cast cout< 解:在32位平台下,一般int是4个字节,double 是8个字节,代码第5、6行强制转换后的赋值过程中修改了arr[0] , arr [1] , 的内存空间,因此导致arr[1]的非预期输出。 避免这种情况的措施:1、尽量避免使用类型转换;2、必须使用类型转换时,尽量开辟新的内存空间,在新内存空间中完成转换。3、必须使用原有内存空间时,要特别注意各种数据类型在不同平台下的内存占用大小。 6-30 static_cast,const_cast和reinterpret_cast各自应在哪些情况下使用? 解:static_cast运算符实现类型间的转换,但没有运行时类型检查来保证转换的安全性。 Cosnt_cast运算符用来修改类型的const或volatile属性。可以去除对象或者变量const或volatile属性。 Reinterpret_cast可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针。
相关推荐: