c++小结
考试
一、选择
1.面向对象程序设计将数据与对数据的操作放在一起,组成一个类
2.要求通过函数来实现一种不太复杂的功能,并且要求加快执行速度,选用内联函数(inline)
内联函数:以空间换时间,通过内存膨胀来减少函数跳转的时间,没有入栈出栈
3.类模板在程序执行的时候,编译器会将类模板转成一个模板类
4.c++中的3类有两种用法:
(1)一种是类的实例化,即生成类的对象,并参与系统的运行
(2)另一种是通过继承,派生出新的类
5.已定义了一个类A,并有语句
(1) A* p=new A[5];意思是:
该语句会创建A类的5个对象,且他们的地址是连续的
(2) A* p1=new A(5);意思是:
该语句会创建A类的一个对象,且将对象的地址赋值给p1
6.建立一个有成员对象的派生类对象,各构造函数的执行顺序为:
基类->成员对象类->派生类
7.关于对类A的私有数据成员的访问:
(1)类A的友元函数可以访问类A的私有成员
(2)类A中的非静态成员函数可以访问类A的私有成员(静态成员函数只能访问静态成员数据)
(3)类A的友元类中的非静态成员函数可以访问类A的私有成员
(4)类A的嵌套类中的非静态成员函数不可以访问类A的私有成员
class A
{
int x;
class B
{
void fun()
{
//x,这是访问不了的
}
}
}
8.数组指针
数组指针指向的,最少是二维数组,指向一维数组的话不方便操作
#include<iostream>
using namespace std;
int main()
{
int n[][3]={10,20,30,40,50,60};
int(*p)[3];
p=n;
cout<<p[0][0]<<","<<*(p[0]+1)<<","<<(*p)[2]<<endl;
//输出时:10,20,30
return 0;
}
10.返回值
在C语言中:会有很多优化的地方
#include<stdio.h>
fun()//默认返回值是int
{
printf("1111 ");
return 666;
}
int main()
{
printf("%d",fun());
//输出1111 666;
return 0;
}
11.使用#include和#include"xxx"包含头文件的区别
(1)#include
(2)#include"xxx",是到当前项目下去查找头文件,找不到就去系统目录下面查找
12.定义类的动态对象数组时,系统只能够自动调用该类的无参构造函数或者是默认构造函数对其进行初始化。
13.基类的公有成员在派生类中的访问权限有继承方式决定
14.this指针始终指向调用成员函数的对象
15.A类中把B类声明为了自己的友元类,那么在B类中,如果存在A类对象,是可以访问到A类的所有成员的
使用友元类:
#include<iostream>
using namespace std;
class A
{
void sleep()
{
cout << "一起睡觉" << endl;
}
public:
void speak()
{
cout << "一起说话" << endl;
}
friend class B;
};
class B
{
A* p;
public:
B(A* p)
{
this->p = p;
}
void sport()
{
p->sleep();
p->speak();
}
~B()
{
if (p != NULL)
{
delete p;
p = NULL;
}
}
};
int main()
{
B b(new A);
b.sport();
system("pause");
return 0;
}
16.建立一个有成员对象的多态派生类对象时,各构造函数体的执行顺序为:基类->成员对象类->派生类
17.在c++类中,const关键字可以修饰对象和函数,const修饰对象可以保护对象里的数据不被修改,const修饰函数可以保护数据。
18.值传递,址传递,引用传递
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
//值传递
void fun(char* p)//将str传过来,相当于值传递,是给形参p申请了内存,而str还是为空,(只是将str的值赋给了p)
{
p = (char*)malloc(100);
}
//引用传递
void fun1(char*& p1)//用引用传递就可以给str申请内存了
{
p1=(char*)malloc(100);
}
//址传递
void fun2(char** p)//要使用二级指针,fun2(&str),取str的地址传进来,才能给str申请内存
{
*p=(char*)malloc(100);
}
//取一级指针的地址,要用二级指针来保存一级指针的地址,二级指针解引用得到一级指针,再给这个一级指针申请内存
int main()
{
char* str = NULL;
fun(str);//错误的是值传递
strcpy(str, "hello world");
printf("%s\n", str);//没有输出
delete str;
str = NULL;
return 0;
}
局部变量的作用域
#include<stdio.h>
char* fun()
{
char p[] = "hello world";//计算大小,要算'\o'。这个p是局部变量,出了fun函数就被释放
return p;
}
int main()
{
char* str = NULL;
str = fun();
printf("%s", str);//输出为烫烫烫
return 0;
}
19.void reverse(int* parr,int len);
现有函数声明,实现此函数完成对一维整型数组的倒转
#include<iostream>
using namespace std;
void reverse(int* parr, int len)//方法一
{
int temp=0;
for (int i = 0, j = len - 1; i < j; i++, j--)
{
temp = parr[i];//先用一个中间变量,接收要被交换的值,用以赋给数组后面的元素
parr[i] = parr[j];//将数组后面的赋给前面的
parr[j] = temp;
}
}
void reverse1(int* parr1, int len1)//方法二
{
int temp=0;
for (int i = 0; i < len1/2; i++)
{
temp = parr1[i];
parr1[i] = parr1[len1 - 1 - i];
parr1[len1 - 1 - i] = temp;
}
}
//位运算交换两个值,按位异或
void reverse(int* parr, int len)//方法三
{
int temp=0;
for (int i = 0, j = len - 1; i < j; i++, j--)
{
parr[i]=parr[i]^parr[j];
parr[j]=parr[i]^parr[j];
parr[i]=parr[i]^parr[j];
}
}
int main()
{
int arr[] = { 1,2,3,4,5,6 };
reverse1(arr, 6);
for (int i = 0; i < 6; i++)
{
cout << arr[i] << " ";
}
return 0;
}
20.定义一个函数模板,能完成int,double,float,char类型的一维数组排序
//冒泡排序
template<typename T>
void fun(T* parr, int len)//parr是用来接收数组的,len是数组长度
{
T temp;//定义一个中间变量,来交换两个变量的值
int i = 0;
int j = 0;//要用两层循环,数组元素有多少个,就将数组遍历元素个数-1次
for (i = 0; i < len - 1; i++)
{
for (j = 0; j < len - 1 - i; j++)//防止越界
{
if (parr[j] > parr[j + 1])//大的数往后面排
{
temp = parr[j];
parr[j] = parr[j + 1];
parr[j + 1] = temp;
/*
parr[j] = parr[j] ^ parr[j + 1];
parr[j+1] = parr[j] ^ parr[j + 1];
parr[j] = parr[j] ^ parr[j + 1];
*/
}
}
}
for (int i = 0; i < len; i++)
{
cout << parr[i] << " ";
}
cout << endl;
}
int main()
{
int arr[6] = { 5,6,3,8,2,4 };
fun(arr, 6);
char str[6] = { 'a','e','s','a','v','r' };
fun(str, 6);
return 0;
}
21.定义一个抽象类shape,并由他派生出3个类,square(正方形),trapezoid(梯形)和triangle(三角形)。用虚函数分别计算几种图形的面积,并求他们的和。要求用基类指针数组,使它每一个元素指向一个派生类对象
#include<iostream>
using namespace std;
class shape
{
protected:
double a, b,h;
public:
//求面积
virtual double area() = 0;
};
class square:public shape//正方形
{
public:
square(double a)
{
this->a = a;
}
virtual double area()
{
return a * a;
}
};
class trapezoid :public shape//梯形
{
public:
trapezoid(double a, double b, double h)
{
this->a = a;
this->b = b;
this->h = h;
}
virtual double area()
{
return (a + b)*h / 2;
}
};
class triangle :public shape//三角形
{
public:
triangle(double a, double h)
{
this->a = a;
this->h = h;
}
virtual double area()
{
return a * h / 2;
}
};
int main()
{
shape* p[2];
p[0] = new square(2.65);
p[1] = new trapezoid(5.6, 6.3, 30);
p[2] = new triangle(10, 20);
double sum = 0;
sum = p[0]->area() + p[1]->area() + p[2]->area();
printf("%lf\n", sum);//285.522500
cout << sum << endl;//285.522
system("pause");
return 0;
}