精华内容
下载资源
问答
  • C++复试宝典.pdf

    2021-02-28 21:29:20
    C++复试宝典.pdf
  • 复试科目是553 C/C++程序设计,推荐参考书1.清华大学出版社,郑莉,《C++语言程序设计》或2.清华大学出版社,钱能,《C++程序设计教程(第二版)》或3.清华大学出版社,H.M.Deitel,P.J.Deitel,《C++程序设计教程》(第六版...
  • 考研C++复试题目整理

    千次阅读 多人点赞 2020-05-13 10:20:55
    C++复试题目自整理 大家觉得有用点点赞啊可以升级升到3级我就可以自定义标签了谢谢~ 说复试题目过于牵强,只是自己整理的一些知识点而已,为了便于理解和背诵,有些部分定义和说明尽量简明扼要,如有错误请多多指教...

    C++复试题目自整理

    大家觉得有用点点赞啊可以升级升到3级我就可以自定义标签了谢谢~

    说复试题目过于牵强,只是自己整理的一些知识点而已,为了便于理解和背诵,有些部分定义和说明尽量简明扼要,如有错误请多多指教!(不可转载)

    1.面向对象的三个基本特征

    封装:通常认为封装是把数据和方法隐藏起来,对数据和方法的访问只能通过已定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自治、封闭的对象。我们在类中编写的方法就是对实现细节的一种封装;我们编写一个类就是对数据和数据操作的封装。可以说,封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口
    继承:在现有类的基础上扩展新的类的过程,子类可以共享原有类的属性和方法,还可以添加新的特征。可提高代码的可重用性;
    多态:不同的对象对同一信息会产生不同的结果;所谓消息是指对类的成员函数的调用,不同的行为是指不同的实现,也就调用不同的函数。换言之,多态指的就是用同样的接口访问功能不同的函数,从而实现“一个接口,多种方法”。
    抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么;

    2.C++如何实现多态性

    C++实现多态性:
    静态多态性:是通过函数的重载来实现的,由函数重载和运算符重载形成的多态性属于静态多态性,在系统编译时系统就知道要调用哪个函数,又称编译时的多态性。
    动态多态性:在编译时不确定调用的是哪个函数,而是在程序运行过程中动态地确定操作所针对的对象,又称运行时的多态性(通过虚函数实现)
    Java实现运行时多态性主要通过重写、重载和接口三种主要实现方式。
    多态的优点:1.增强了代码的重用性和灵活性;2.同一参数类型;3.同一功能调用;4.降低耦合性。

    3.构造函数与析构函数

    构造函数:主要用于定义对象时进行初始化工作;与类名相同没有返回值,可以没有参数也可以带有多个参数
    析构函数:用于在对象的生命周期结束时,进行善后工作。
    拷贝构造函数:用一个已有的对象对新对象进行初始化时,会调用拷贝构造函数。主要用于当类中有指针数据成员时,需要自己定义拷贝构造函数解决复制过程中段错误的产生。

    4.什么是const,作用是什么?

    Const修饰,实际上就是将对应的可读写性改成了只读性。靠近谁就修饰谁。
    1.定义变量
    变量的值在其生命周期内不能改变,用multable修饰变量就能改变。
    2.定义指针
    主要分为三种情况:不能修改指针指向的值,不能修改指针的值,两者皆不能修改。
    3.定义函数形参
    形参在函数中不会被改变
    4.定义对象
    在定义对象,对象中所有数据成员的值不能改变;
    在定义数据成员,则该数据成员不能被改变;
    定义成员函数,则只能引用本类中的数据成员,不能修改它们。
    对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左
    值”。

    5.const与define的区别

    宏定义只是对值进行简单的替换,不进行类型检查;而const有具体的类型,在编译阶段会进行类型检查。
    #define宏是在预处理阶段展开,而const常量在编译运行阶段 。
    const定义的常量在程序的运行过程中只有一份拷贝;而#define定义的常量在内存中有若干个拷贝 。
    const效率高,因为编译器通常不为普通const常量分配内存,而是保存在符号表中,没有了存储与读取的操作,效率很高。

    6.static作用有以下两个:

    Static:用static修饰的内容在内存中独立存储,优先于对象产生,属于类而不属于任何一个对象,可以被类中的对象所共享。
    1.规定内容的作用区域,就是内容所在的函数或类,只有在该函数/类才能调用。
    2.规定内容的生命周期,内容在函数/类执行完毕后不会被回收,会一直保留,直至程序结束

    7.静态数据成员与静态成员函数

    静态数据成员:静态数据成员是可以被类中所有对象共享的数据成员,静态数据成员只能在类体外进行初始化,在所有对象之外单独开辟空间,在编译时为其分配空间,在结束时释放空间,既可以通过对象名引用,也可以通过类名引用。
    静态成员函数:在类定义中,有static修饰的成员函数称为静态成员函数,它不属于任何一个特定的对象,一般来说静态成员函数访问的一般是静态数据成员或全局变量,不能访问普通数据成员。可以通过类名或对象名两种方法访问。可以用它在建立任何对象之前处理静态数据成员。
    对象成员:一个类中的数据成员是其他的对象,称为对象成员。首先它是一个类,其次是另一个类的成员

    封闭类:有其他类的对象作为 成员对象的类叫封闭类。
    封闭类对象生成时,先执行所有对象成员的构造函数,然后才执行封闭类的构造函数。

    8.静态数据成员与全局变量的不同

    全局变量可以被任意的类或函数调用,静态数据成员只能在其所用范围(类中)被调用。

    9.为什么引入友元的概念?

    类中的私有成员只能通过它的成员函数来访问,有时候需要在类的外部访问类的私有成员,所以就需要一种途径,在不放弃私有成员安全性的情况下,使得类外部的函数或类能够访问类中的私有成员,就引入了友元的概念,友元是一扇通向私有成员的后门。

    10.什么是友元函数?

    友元函数:由friend关键字修饰,不是当前类的成员函数,而是独立于当前类的外部函数,它可以访问该类的所有对象的成员,包括公有成员和私有成员。友元函数一般是带有一个该类的入口参数,因为友元函数不是类的成员函数,不能直接引用对象成员名,必须通过入口参数传递进来的参数名或对象指针来引用该对象的成员。
    友元函数通过直接访问对象的私有成员提高了程序运行的效率,但是破坏了数据的隐蔽性,降低了程序的可维护性,与面向对象思想不符。

    11.友元成员函数

    除了一般的函数可以作为某个类的友元外,一个类的成员函数也可以作为另外一个类的友元,这个成员函数不仅可以访问自己所在类对象中的私有成员和公有成员,还可以访问friend声明语句所在类对象中的私有成员和公有成员。

    12.友元类

    一个类可以成为另外一个类的友元。当一个类被声明为另一个类的友元时,它的所有成员函数都成为另外一个类的友元函数,这意味着友元的类中所有成员函数都可以访问另一个类中的私有成员。

    13.函数重载

    函数重载:对一个已有的函数赋予其新的含义,使其具有新的功能。简单来说就是一名多用(函数名相同参数不同)。

    14.运算符重载

    运算符重载的方法是定义一个重载运算符的函数,使制定的运算符不仅能实现原有的功能,还能够在其基础上进行了扩展。也就是说,运算符重载是通过定义函数来实现的,运算符重载实质上是函数的重载。
    Operator+运算符名称

    15.运算符重载函数的使用

    1.一种是作为类的友元函数进行使用
    2. 一种是作为类的成员函数进行使用

    16.重载运算符的规则

    1.C++不允许用户自己定义新的运算符,只能对已有的进行重载;
    2.C++不能对 .(成员访问运算符), *(指针访问运算符), ::(域运算符),sizeof(长度运算符),?:(条件运算符)共5个;
    3.重载不能够改变运算符的目数
    4.重载不能改变运算符的优先级
    5.重载不能改变运算符的结合性
    6.重载运算符的函数不能有默认的参数

    17.为什么要使用继承

    设计一个新类的时候可以继承父类的成员,减少设计类的冗余开发,从而较好地解决代码重用的问题。继承,派生指的是传递关系,继承是站在子类的角度说的,派生是站在父类的角度说的。
    从继承方式分:
    public(公有的):父类中私有成员子类不可访问,公有及保护成员在子类中保持原有访问状态。
    private(私有的):父类中私有成员子类不可访问,公有及保护成员为子类中的私有成员(即只能通过子类内的成员函数访问)。
    protect(保护的):父类中的私有成员子类不可访问,公有及保护成员为子类中的保护成员。

    18.保护成员的作用

    (1)在不涉及到派生的时候,私有成员和保护成员地位一样,在类内可以访问,类外不可以访问。
    (2)在涉及到派生时,父类中的私有成员无论怎么样的派生方式,在子类中都是不可见的,有时我们想让父类中的私有成员在子类的成员函数中使用,可以将父类中的私有成员声明为保护成员,父类中的保护成员在子类中是可见的可用的。

    19.多重继承

    多重继承:一个派生类有两个或多个基类。多重继承要注意防止出现二义性。
    多重继承中,派生类的构造函数只负责对其直接基类初始化,再由其直接基类对间接基类初始化。当存在虚基类时,在最后的派生类中还需要对虚基类初始化。

    20.虚基类及其作用

    引入虚基类的原因:如果一个派生类有多个直接基类,而这些直接基类又有一个共同基类,则最后的派生类中会保留其直接基类所继承的共同基类的多份同名成员,而引用这些同名的成员时,必须在派生类对象名后增加直接基类名以免产生二义性。占用大量的存储空间,易出错。
    将共同基类设置为虚基类,这样从不同派生类继承来的同名数据成员在内存中就只有一个拷贝,同名函数也只有一种映射。
    为了保证虚基类在派生时只被继承一次,应当在该基类的所有直接派生类中声明为虚基类,否则仍然会出现对基类的多次继承。

    21.派生类的构造函数和析构函数的构造规则

    (1)当基类的构造函数没有参数或没有显示的定义构造函数是,那么派生类可以不向基类传递参数,可以不定义构造函数。
    (2)当基类含有带参数的构造函数时,派生类必须定义构造函数,一提供把参数传递给基类构造函数的途径
    当派生类中有对象成员时,执行派生类构造函数的顺序是:
    1.调用基类构造函数,对基类数据成员初始化
    2.调用对象成员构造函数,对对象数据成员初始化
    3.调用派生类构造函数,对派生类数据成员进行初始化
    执行析构函数顺序与之相反

    22.组合与继承

    类的组合:在一个类中以另外一个类作为数据成员,称为类的组合。
    继承是纵向的,组合是横向的。通过继承建立了派生类和基类之间的关系,是一种“是”的关系,比如“白猫是猫”;派生类是基类的具体化实现,是基类中的一种。组合是“有”的关系,比如“老师有生日这个属性”。

    23.多态

    不同的对象对同一消息会产生不同的行为结果。所谓消息是指对类的成员函数的调用,不同的行为是指不同的实现,也就调用不同的函数。换言之,多态指的就是用同样的接口访问功能不同的函数,从而实现“一个接口,多种方法”。

    24.多态的实现

    从系统实现的角度看,多态性可分为两类:动态多态性,静态多态性。
    静态多态性:是通过函数的重载来实现的,由函数重载和运算符重载形成的多态性属于静态多态性;在系统编译时系统就知道要调用哪个函数,又称编译时的多态性。
    动态多态性:不在编译时确定调用的是哪个函数,而是在程序运行过程中动态地确定操作所针对的对象,又称运行时的多态性(通过虚函数实现)

    25.虚函数及其作用

    虚函数:用virtual修饰的函数称为虚函数,在基类中声明函数是虚拟的,并不是实际存在的函数,然后在派生类中才正式使用该函数。在其派生类中对该函数重新定义,赋予它新的功能,并且能够通过指向基类的指针指向同一类族中不同类的对象,从而调用其中的同名函数。
    虚函数的作用:是在程序的运行阶段动态地选择合适的成员函数。实现动态多态性。
    虚函数的实质:指向基类的指针在指向派生类对象时,自动进行指针类型转换,将派生类的对象的指针先转换为基类的指针,这样基类指针指向的是派生类对象中的基类部分。
    在派生类中重新定义的函数应与虚函数具有相同的形参个数,形参类型和形参顺序。如果在派生类中没有重新定义虚函数,则它继承基类的虚函数。

    26.静态关联和动态关联

    确定调用的具体对象的过程称为关联,
    函数重载和通过对象名调用的虚函数,在编译时即可确定其调用的虚函数属于哪一个类,其过程称为静态关联,由于是在运行前进行关联的,所以又称为早期关联,函数重载属静态关联。

    虚函数就是通过基类指针与虚函数的结合来实现多态性的。先定义一个指向基类的指针变量指向对应类的对象,再通过基类指针去调用虚函数。这样的调用方式编译系统在编译时是不能确定调用了哪一个类对象的虚函数的, 当在编译系统在运行阶段确定关联关系时,指针可以先后指向不同的类对象,从而调用同族中不同类的虚函数,这种方式就是动态关联。

    27.函数重载与虚函数的不同

    1 重载函数要求函数具有相同的返回值类型和函数名称,并具有不同的参数序列,而虚函数则要求这三项(函数名,返回值类型,参数序列)完全相同
    2 重载函数可以是成员函数或非成员函数 而虚函数只能是成员函数
    3 函数重载可用于构造函数,而虚函数不能用于构造函数
    4 重载函数是根据不同参数作为调用不同函数的依据,而虚函数根据对象的不同的调用不同类的虚函数
    5 虚函数在运行期间表现出多态功能,这是c++的精髓,而重载函数则在编译时表现出多态
    一般来讲,虚函数是一种特殊的重载,即必须被重载的函数,一般函数可以不被重载。一个函数被声明为虚函数,目的就是实现多态,若派生类不进行重定义则失去了原来的意图
    6 函数重载是在程序编译阶段确定操作的对象的,属于静态关联。虚函数是在程序运行阶段确定操作对象的,属于动态关联。

    28.虚析构函数

    在析构函数面前加上关键字virtual进行声明,称析构函数为虚析构函数。
    虚析构函数的作用:当父类的析构函数声明成虚析构函数的时候,当子类继承父类,子类中的析构函数也是虚函数,父类的指针指向子类对象时,delete掉父类的指针,先调动子类的析构函数,再调用父类的析构函数。

    29.纯虚函数

    纯虚函数是在声明虚函数时被“初始化”为0的函数,纯虚函数没有函数体。

    30.抽象类

    一个类中如果有纯虚函数,那么该类为抽象类。抽象类是不允许实例化对象的,作用:作为一个类族的共同基类,主要用来派生子类。纯虚函数在派生类中一定要实现,如果派生类中不实现基类中的纯虚函数,派生类就变成抽象类。

    31.抽象类与接口的区别

    抽象类的目的是为了延展类的继承结构,让继承结构整体更完整;
    接口是为了实现类注入新的特性、功能。

    32.输入输出流

    C语言通过函数实现输入输出(scanf,printf),C++通过类对象实现输入输出(cin,cout)
    C++的输入输出流是指由若干字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一个对象。
    在内存中为每一个对象开辟一个内存缓冲区用来存放流中的数据。输出数据时先将数据送到输出缓冲区中保存形成输入流,直到缓冲区满或者遇到endl,就讲缓冲区中的全部数据送到显示器显示出来;输入数据时,数据先送到输入缓冲区中形成输入流,再从中提取数据。
    缓冲区中的数据就是流

    33.标准的输出流对象有哪些

    标准的输入输出:即从键盘输入数据,输出到显示屏幕;
    标准输入输出流:
    Cout流对象:向控制台输出;
    Cerr流对象:(标准出错流)向终端显示器输出错误信息;
    Clog流对象:(标准出错流)同Cerr,两者区别:cerr是不经过缓冲区直接向显示器上显示出错信息,clog中的信息存放在缓冲区中,缓冲区满或者遇到endl时向显示器输出。
    流成员函数put:专用于输出单个字符

    34.标准的输入流对象有哪些

    Cin流:
    用于字符输入的流成员函数:
    Get函数:
    1.不带参数 从指定的输入流中提取一个字符
    2.带一个参数,从输入流中提取一个字符,赋给某个变量
    3.带三个参数,从输入流中读取n-1(或遇到指定的终止字符)个字符给指定的字符数组
    Get与getline不同之处:用getline函数从输入流读字符,一次一行,或遇到终止字符提前结束,指针移到该终止字符之后,下一个getline函数将从终止字符的下一个字符继续读入。
    而get遇到终止字符指针不向后移动

    35.文件流类与文件流对象

    文件流对象是以外存为对象的输入输出流对象。
    文件流类是专门用于磁盘文件的输入输出操作。
    要以磁盘文件为对象进行输入输出,必须定义一个文件流类的对象,通过文件流对象将数据从内存输出到磁盘文件,或者通过文件流对象从磁盘文件将数据输入到内存。
    打开文件open,关闭文件close

    整理不易,请多点点关注和收藏谢谢啦!

    展开全文
  • C++复试题目.zip

    2021-03-12 15:34:44
    C++复试题目.zip
  • 1 给一个三行四列的矩阵按列优先随机赋值(1~9的范围),寻找矩阵的鞍点(行最大值,列最小值)。 2 用递归实现对数组元素的二分查找。 3 实现一个selfString类,构造函数从文件中读取一个以空格为分隔符的英文句子...

    1 给一个三行四列的矩阵按列优先随机赋值(1~9的范围),寻找矩阵的鞍点(行最大值,列最小值)。

    2 用递归查找数组中的最小值 。
    3 用递归实现对数组元素的二分查找。
    4 实现一个selfString类,构造函数从文件中读取一个以空格为分隔符的英文句子。实现一个函数(不一定是成员函数)来找出两个句子的最长公共单词。(不会写)

    1 代码:

    //给一个三行四列的矩阵按列优先随机赋值(1~9的范围),寻找矩阵的鞍点(行最大值,列最小值)。
    #include <iostream>
    #include <ctime>
    using namespace std;
    int main(){
    	int a[3][4];
    	srand(time(0));
    	for(int i = 0; i < 3; i++) { //输入随机数组 
    		for(int j = 0; j < 3; j++) {
    			a[i][j] = rand();
    		}
    	}
    	for(int i = 0; i < 3; i++) { //输出数组 
    		for(int j = 0; j < 3; j++) {
    			cout << a[i][j] << " ";
    		}
    		cout << endl;
    	}
    	
    	int max[3], min[4];
    	for(int i = 0; i < 3; i++) {
    		max[i] = a[i][0]; //第一列的第一个元素赋为该行的最大值 
    		for(int j = 0; j < 4; j++) {
    			if(a[i][j] > max[i])
                	max[i] = a[i][j];
    		}
    	} 
    	for(int j = 0; j < 4; j++) {
            min[j] = a[0][j]; //第一行的第一个元素赋为该列的最小值 
            for(int i = 1; i < 3; i++ ) {
            	if(a[i][j] < min[j])
                    min[j] = a[i][j];
    		}      
        }
    
    	bool flag = false;
    	for(int i = 0;i < 3; i++) { //遍历数组寻找鞍点 
    		for(int j = 0; j < 4; j++) {
    			if(a[i][j] == max[i] && a[i][j] == min[j]) {
                    cout << "a[" << i << "][" << j << "] = " << a[i][j] << endl;
                    flag = true;
    			}
                
            }
    	} 
            
        if(flag == false)
            cout << "鞍点不存在!" << endl;
    	return 0;
    }
    

    结果:

    2 代码:

    //用递归查找数组中的最小值 
    #include <iostream>
    using namespace std;
    template <class T>
    
    int find_Min(const T a[], int len) {
    	static int small = a[0];
    	if(len == 0) //递归出口 
    		return small;
    	if(small > a[len-1])
    		small = a[len-1];
    	small = find_Min(a, len-1); 
    	return small;
    } 
    
    int main(){
    	int n;
    	cout << "请输入数组大小:";
    	cin >> n;
    	cout << "\n请输入数组元素:"; 
    	int a[n];
    	for(int i = 0; i < n; i++)
    		cin >> a[i];
    	cout << find_Min(a,n);
    	return 0;
    }
    

    结果:

    3 代码:

    //用递归实现对数组元素的二分查找。
    #include <iostream>
    using namespace std;
    
    int binary_Search(int a[], int left, int right, int searchnum) {
    	int mid = (left + right);
    	if(left <= right) {
    		if(searchnum == a[mid])
    			return mid; //返回要查找值的数组下标 
    		else if(searchnum > a[mid])
    			return binary_Search(a, mid+1, right, searchnum);
    		else 
    			return binary_Search(a, left, mid-1, searchnum);
    	} 
    	else {
    		return -999;
    	}
    } 
    
    int main(){
    	int a[20] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 };
        int num;
        cout << "请输入要查找的元素:";
        cin >> num;
    	cout << endl;
        cout << "该元素的数组下标为:" << binary_Search(a, 0, 19, num) << endl;
    	return 0;
    }
    

    结果:

    展开全文
  • 算法c++助力复试上机

    2021-01-04 16:17:33
    文件包含算法笔记和上机实战训练指南,对于考研复试上机还是挺有帮助的,加油考研人
  • C++复试常见题集结

    千次阅读 2020-05-11 10:04:18
    我们在进行C++程序编写的时候,不可避免的会使用面向对象的方式,但是对于我们自己编写的类来说,我们通常称之为非内部的数据结构类型,此时对于free/malloc这种标准的C/C++库函数来说,是不可能完成执行构造函数和...

    1.delete,malloc,new,free四者之间的关系
    我们在进行C++程序编写的时候,不可避免的会使用面向对象的方式,但是对于我们自己编写的类来说,我们通常称之为非内部的数据结构类型,此时对于free/malloc这种标准的C/C++库函数来说,是不可能完成执行构造函数和析构函数的作用的,而C++的标准运算符new和delete可以完成此项工作,new用于进行动态的内存分配和初始化工作,delete可以完成对象的清理和释放工作。
    2.delete和delete[ ]的区别
    我们在进行面向对象的程序设计时,会自建数据类型,但是对于我们通过new出来的自建数据类型的释放有需要注意的地方。简而言之就是用new分配的,需要通过delete来进行相应的释放,而通过new[ ]分配的内存,需要通过delete [ ]来进行释放,但是对于内部已有的数据类型来说不存在此种限制。
    3.C++面向对象三大特性:封装 继承 多态
    4.子类的析构和基类的析构的调用情况
    一句话,基类和子类之间的构造或者析构函数可以通过洋葱圈模型类予以解释,调用构造函数时,会先调用基类的构造函数,然后深入子类,而析构正好与之相反,先调用子类的,再调用父类的。
    5.多态 虚函数 纯虚函数
    首先多态产生的条件便是继承,方法重写,父类引用指向子类对象。会通过父类来根据相同的指令调用子类不同的方法,而虚函数和纯虚函数之间是有区别的,虚函数需要定义加上代码的实现,而纯虚函数不需要,并且如果一个类中如果存在纯虚函数,那么此类不能进行实例化,只能继承,虚函数便没有此种限制。
    6.引用 以及需要注意的问题
    引用便是我们在操作某一个变量时所起的别名,引用在创建时本身就不是一个数据类型,并不占有存储单元,因此系统也不会为之分配内存,引用声明以后,就相当于存在两个名字指向一块地址,但是不能再为引用创建引用。
    7.将引用作为函数参数的特点是什么
    将目标变量的引用作为函数的参数和将指针作为函数的参数的效果相同,但是不同的是我们需要对指针作为的形参分配存储空间,而对引用作为的形参不需要分类存储空间。
    8.什么时候使用常引用
    如果我们需要提高程序的效率,又希望我们的程序变量在函数内部不进行改变,那我们可以通过常引用的方式来进行编写程序。
    9.全局变量和局部变量相关
    C++的内存区域可以分为堆区和栈区,以及静态存储区,局部变量存储在栈区,函数结束后自动进行释放,全局变量存储在静态存储区,程序退出后才进行释放,另外堆区存放的是由new,malloc开辟,需要通过程序员本身调用delete,free进行释放。
    10.基类的析构函数不是虚函数,会带来什么问题
    在面向对象程序设计中,我们经常会见到虚函数,但是并不是每一个类的析构函数都是虚函数,如果某一个类为基类并且产生继承和多态时,一般将析构函数设置为虚函数,如果不这样做的话,那么在父类指针指向子类对象的时候,父类指针此时的析构函数并不是虚函数,在delete此指针的时候,只会调用父类的,而不会调用子类的,会导致内存泄漏。
    11.介绍内存的分配方式
    程序运行起来会产生3个区,主要的变量都会几种在这三区内。
    首先是静态存储区,程序运行开始便出现,其内的主要成员保罗全局变量等等,在程序运行结束后进行释放。
    其次是栈区,主要存储函数的局部变量,在函数内部有效,函数执行结束后会被自动释放掉。
    最后是栈区,主要通过new或者malloc方式来开辟内存,有程序员手动释放。
    12.const VS #define
    const常量与宏常量define之间使用方式类似,但是const应用时会进行安全类型检查,在程序的编译,运行时起作用,而define则在程序的预处理阶段,只进行简单的字符串转换。并且某些编译器可以对const进行调试,而不能对宏常量进行调试,使用const可以避免不必要的内存分配,节省空间。
    13.代码识别

    void * ( * (*fp1)(int))[10];   //1
    

    解释:首先fp1是一个指针,指向一个函数,这个函数的参数为int类型,函数的返回值也是一个指针,这个指针是一个数组,这个数组有10个元素,每一个元素是一个void*指针。

    float (*(* fp2)(int,int,int))(int); //2
    

    解释:fp2是一个指针,指向一个函数,这个函数有三个int类型的参数,函数返回值也为指针,指向一个函数,这个函数的参数为int类型,返回值为float类型。

    int (* ( * fp3)())[10]();    //3
    

    解释:fp3是一个指针,指向一个函数,这个函数的参数为空,函数的返回值也为一个指针,这个指针指向一个数组,这个数组有10个元素,每一个元素是一个指针,指向一个函数,函数的参数为空,返回值为int类型。

    int id[sizeof(unsigned long)];  //4
    

    解释:上面的代码正确,sizeof为编译时的元素符,编译时便确定了,可以看成与机器有关的常量。

     int (*s[10])(int);  //5
    

    解释:为一个函数指针数组,首先第一个int为返回值,而*s[10]为指针数组,s是含有10个指针的数组,第二个int是参数列表,(*p)(int)是一个函数指针,所以总计为一个函数指针数组。

        char str1[] = "abc";
      char str2[] = "abc";
    
      const char str3[] = "abc";
      const char str4[] = "abc";
    
      const char *str5 = "abc";
      const char *str6 = "abc";
    
      char *str7 = "abc";
      char *str8 = "abc";
    
      cout << ( str1 == str2 ) << endl;//0  分别指向各自的栈内存
      cout << ( str3 == str4 ) << endl;//0  分别指向各自的栈内存
      cout << ( str5 == str6 ) << endl;//1指向文字常量区地址相同
    
      cout << ( str7 == str8 ) << endl;//1指向文字常量区地址相同
    

    解释:str1到str4都是数组常量,他们都有自己的内存地址或者内存空间,但是str5到str8为指针,他们都指向相同的区域。

    int  a=4;
    
    int  &f(int  x)
    
    {    a=a+x;
    
          return  a;
    
    }
    
    int main(void)
    
    {    int   t=5;
    
         cout<<f(t)<<endl;    //a = 9
    
        f(t)=20;              //a = 20
    
        cout<<f(t)<<endl;     //t = 5,a = 20  a = 25
    
         t=f(t);               // a = 30 t = 30
    
        cout<<f(t)<<endl;  }   // t = 60
    
    }
    

    14.引用和指针的区别
    引用必须进行初始化,但是指针不需要,而且引用一旦初始化,便不可以更改其指向,更不可一指向空,但是指针不仅可以为一个空指针,而且可以更改指针的指向。
    15.结构和联合
    结构和联合都是由多个不同的数据类型成员组成,但在同一时刻,联合中值存放了一个被选中的成员,而结构的所有成员都存在。
    对于联合的不同成员赋值,将会对其他成员进行重写,原来成员的值就不存在了,对于结构的不同成员赋值是不影响的。
    16.重载和重写
    重载是指重新编写同名函数,但是必须满足函数的参数不同,参数个数或者类型不同的前提条件,并且,重载和多态无关,但是重写不同,多态发生时便发生了重写。
    另外关于地址绑定,重载是早绑定,在编译期间便绑定完毕,是静态的,但是重写是运行时绑定,属于晚绑定。
    17.全局对象的构造函数会在main函数之前执行,并且C++不是类型安全的,两个不同类型的指针可以进行转换,在这方面C#是安全的.关于initialization list,如果一个类所有成员都是public且没有默认的构造函数,就可以用initialization list对类的成员进行初始化;assignment为赋值
    18.UDP和TCP
    UDP为用户报文协议,TCP为传输控制协议,TCP与UDP相比较而言更加安全可靠,但是UDP更加快读,使用UDP还是TCP要取决于程序要求。
    19.消息映射
    程序员指定MFC类(有消息处理能力的类)处理某个消息,完成对处理函数的编写, 来完成消息处理的功能。
    20.windows消息系统由哪几部组成
    windows的消息系统由三部分组成,分别是消息队列, 消息循环以及消息处理。
    操作系统负责为进程准备一个消息队列,程序不断从消息队列中收取消息,接收消息。而应用程序也可以通过消息循环不断获取消息,处理消息。
    消息处理便是消息循环将消息放到关联的窗口上进行处理。
    21.将类的声明和实现分开的好处
    可以起到保护的作用,其实可以提高编译的效率。
    22.局部变量和全局变量
    局部变量和全局变量的名字可以相同,但是局部变量会屏蔽全局变量,如果需要在同名的情况下使用全局变量,需要使用域运算符(::)。
    23.assert()函数的使用
    assert函数是一个调用程序时经常使用的宏,在程序运行时用来计算括号内的表达式,其宏定义存放在<assert.h>中,其函数原型为void assert(int expression);类似于python中的assert,如果我们在打开文件时进行assert,会起到很好的作用。在程序运行时会计算括号内的表达式,如果出错,则会终止程序的进行。
    24.关于枚举类型
    首先何为枚举类型,所谓的枚举类型便是C++的一种派生类型,是用户定义的若干枚举常量的集合,其声明形式为enum 枚举名 {变量列表}。例如如果我们有一个需求那就是系统记录一周的变量的那便是enum Weekday{SUN,MON.TUE,WED,THU,FRI,SAT};
    值得注意的是:当我们需要一个变量,这个变量有好几种可能的取值的时候,我们可以将他定义为枚举类型。枚举类型有利于提高程序的可读性,从某种意义上来将,我们可以将其称之为一种“语法糖”。
    25.class和struct
    如果没有继承或者多态,那么class和struct两者的存储效率差不多相同,但是在C++中,class和struct是有着区别的,class成员默认为私有的,而struct默认为公有的。class和可以定义模板参数,但是struct不支持。
    26.static函数和普通函数的区别
    static静态函数默认的代码只限于本文件所有,而普通函数可以被其他代码文件所调用。
    总结来说就是,其他文件可以拥有同名静态函数,静态函数不可被其他文件所有。
    27.指针的几种情况
    int p[n]:指针数组,一共n个元素,每个元素均为指向整型数据的指针.
    int (
    )p[n]:p为一个指针,指向一维数组,这个数组有n个整形数据。
    int p():函数指针,p指向函数的返回值
    int (
    )p():p为指向函数的指针。
    28.Debug和Release版本的区别
    Debug是调试版本,Release是最终发送给用户的非调试的版本。
    29.函数指针和指针函数
    函数指针指的是指向一个函数入口的指针,而指针函数指的是函数的返回值是一个指针类型。
    30.指针常量和常量指针
    指针常量(int * const p),本质上是一个常量,指针用来说明常量的类型,在指针常量中,指针指向的值可以更改,但是指向的地址不可以更改。
    常量指针(const int * p),本质上是一个指针,指针指向一个常量,指针指向的内容不可以更改,但是指向可以更改。
    31.对指针的理解
    指针是一个变量,指向一块内存地址,指针的类型取决于指针指向的类型,其也可以访问其指向的内存地址。
    32.面向对象相关话语
    面向对象的程序设计思想便是将数据结构和对数据结构的操作的方法封装成一个个的对象,而类便是将一些具有共性的对象封装起来,对象所具有的特征包括静态特征和动态特征。静态特征指的是描述对象的一些属性,动态特征指的是对象表现出来的行为。
    类的定义与实现写在不同的文件上会提高编译的效率,因为分开的话只需要编译一次对应的obj文件,再次应用该类的地方就不会被编译,大大提高了效率。
    –》成员函数通过this指针指向对象的首地址来区分不同对象的成员数据。
    –》C++自动为类生成了四个缺省函数为:默认构造函数 拷贝构造函数 析构函数 赋值函数
    33.关于内置函数
    C++中类的成员函数定义可以分为几种实现方式,但是如果我们在类的内部实现了成员函数,我们默认实现的为较小规模的,但是系统在调用函数过程所花费的时间开销是巨大的。因此如果系统为了减少时间的开销,如果类内实现的成员函数不包括循环等控制结构,系统会默认将其编译为内置函数。默认inline定义,如果类内实现,那么便可以省略inline.
    34.拷贝构造函数调用时机
    ①当一个对象去初始化另一个类的对象的时候
    ②如果函数的形参是类的对象,调用函数进行实参和形参结合的时候。
    ③如果函数的返回值是类对象,函数调用完成返回时。
    关于构造函数,构造函数是类的一种特殊的成员函数,一般情况下,用来初始化对象成员变量,构造函数名字必须与类名相同,不具有任何类型,不具有返回值。
    35.重写拷贝构造函数
    通常情况下的一个原则是,如果我们在一个类中进行了new操作,我们便需要一个析构函数,同时我们也便需要一个拷贝构造函数。重写拷贝构造函数的原则便是包含动态分配成员或者包含指针成员的类都应该提供拷贝构造函数,同时提供拷贝构造函数的同时还应该考虑到重载“=”运算符。
    另外,构造函数的调用顺序为先调用基类的构造函数,然后顺序初始化成员,然后调用自己的拷贝构造函数。
    36.初始化成员列表的使用
    首先,类对象的构造顺序为,分配内存,调用构造函数,显示或者隐式的初始化数据成员。
    在以下三种情况下我们需要使用初始化列表:
    ①如果我们有一个类成员,本身就是一个类或者是一个结构,而且这个成员只有一个带参数的构造函数,而没有默认构造函数,如果要对此类进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,第一步将无法完成。
    ②当类成员中含有一个const对象的时候,或者是一个引用的时候,也必须通过初始化成员列表进行初始化,因为这两种对象在声明后需要马上进行初始化操作,而在构造函数中赋值会报错。
    ③子类初始化父类的成员,仅仅只能在初始化列表中进行初始化。
    37.静态成员函数
    当我们在一个类中定义了静态私有成员的时候,只能通过静态成员函数来进行访问。当类的构造函数是私有的时候,不能像普通的类那样实例化自己,只能通过静态成员函数来调用构造函数来初始化自己。另外,如果我们想要在类外访问类的私有成员,我们可以通过下面的三种方式来进行访问,分别是,友元,继承以及共有的成员函数。
    抽象类指的便是只能用来继承,而不能进行私有化的类。
    运算符重载的意义在于为了使得用户自定义的数据类型的操作和内定义的数据类型的操作想同,运算符重载的三种方式分为普通函数,友元函数以及类成员函数。* 、sizeof、.、s三目元算符以及域运算符都不可以进行重载。
    赋值运算符和拷贝构造函数之间的区别为都是将一个对象拷贝到另一个中去,不同的是拷贝构造函数需要建立一个新对象。
    构造函数可以被重载,析构函数有且只有一个,且没有参数,不可以被重载。
    全局对象的构造函数会在main之前执行。
    38.类A
    对一个类A不声明任何的成员函数和成员变量,但是Sizeof(A)仍不为0,举个反例,如果我们定一个class A[10]对象数组,如果为0,那么就无法区分A[0] A[1]…
    堆栈溢出的原因一般是没有回收垃圾资源。构造函数不能声明为虚函数。
    IP地址由两部分组成,分别为网络号和主机号。
    switch()内的不能为浮点型,必须为整型或者枚举型。
    一个函数频繁调用,C中为宏定义,C++为内联函数。
    C++不是安全的,因此两个不同类型的指针可以进行强制转换。
    C++值的传递方式:值传递 指针传递 引用传递
    引用的时候加上尖括号表示从标准库路径开始查找,不加则从用户的工作目录开始查找。
    39.static操作符
    ①static+局部变量 将一个变量声明为函数的局部变量,函数结束后变量不会被释放掉。
    ②static+全局变量 表示一个变量在当前文件的全局内科访问
    ③static+函数 表示一个函数在当前文件的全局内可访问
    ④static+类成员变量 表示这个成员为类所共有
    ⑤static+类成员函数 表示这个函数为全类所共有,而且只能访问静态成员变量
    其作用是static+局部变量表示变量的作用范围为该函数体,该变量的内存只被分配一次,在下次调用时还维护上次的值。
    static+全局变量或者函数指的是对整个模块可访问,其他模块不可访问。
    static+类相关,表示在类共有,且static+类函数只能访问静态成员,不接受this指针。
    40.const操作符
    const修饰常量,定义时就被初始化,以后不能更改。const修改形参,那么该形参在函数体内不能进行任何的改变。
    const修饰类成员函数,表示该函数只能对成员变量进行只读操作。
    const用来阻止一个变量被改变。

    展开全文
  • 1、输入 n 个十进制数转换成二进制写到文件,n 是随机得到的 2、写两个模板函数:插入排序法的迭代实现与递归实现 3、字符串的解析.文件中有类似的一行行字符串“(010)(15012345678)|123|(430070)”,按以下格式输出:...

    声明:一刷题目时借鉴了两位博主的代码,题目也来自这两位博主,附上他们的CSDN博客: Dcwjh的博客 GanonYou的博客

    1、输入 n 个十进制数转换成二进制写到文件,n 是随机得到的


    一刷代码:

    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <string>
    #include <stack>
    #include <cmath>
    
    using namespace std;
    
    template < typename T > void pushElements( T &stackRef, int);
    template < typename T > void popElements( T &stackRef);
    void toBinary( int );
    void toDemical( );
    static stack < int > intDequeStack;
    
    int main()
    {
    	int n;
    	int integer;
    	int choice;
    
    	cout << " 1. demical change to binary." << endl;
    	cout << " 2. binary change to demical." << endl;
    	cout << " 0 to quit" << endl;
    	cin >> choice;
    	
    	while ( choice )
    	{
    		switch (choice)
    		{
    		case 1:
    			cout << "Enter the number of integer: ";
    			cin >> n;
    			while ( n )
    			{
    				cout << "Enter the current integer:";
    				cin >> integer;
    				cout << "Binary: ";
    				toBinary( integer );
    				cout << endl;
    				--n;
    			}
    			break;
    		case 2:
    			cout << "\ndemical: " <<endl;
    			toDemical();
    			cout << endl;
    			break;
    		default:
    			break;
    		}
    		cout << " 1. demical change to binary." << endl;
    		cout << " 2. binary change to demical." << endl;
    		cout << " 0 to quit" << endl;
    		cin >> choice;
    	}
    
    
    }
    //十进制转换为二进制
    void toBinary( int inte )
    {
    	int reminder;
    	while ( inte > 0 )//全部压栈之后载出栈
    	{
    		reminder = inte % 2;
    		pushElements( intDequeStack, reminder );
    		inte /= 2;
    	}
    	popElements( intDequeStack );//出栈
    }
    //利用栈进行二进制到十进制的转换
    template< typename T> void pushElements( T &stackRef ,int inte )
    {
    	stackRef.push( inte );
    }
    template< typename T> void popElements( T &stackRef )
    {
    	ofstream outFile( "binary.txt", ios::out | ios::app );
    	if( !outFile )
    	{
    		cerr << "File could not be opened." << endl;
    		exit( 1 );
    	}
    
    	while( !stackRef.empty() )
    	{
    		cout << stackRef.top();
    		outFile << stackRef.top();
    		stackRef.pop();
    	}
    	outFile << endl;
    }
    //二进制转换为十进制
    void toDemical( )
    {
    	string binToDec;
    	int sum = 0;
    	int i = 0;
    	ifstream inFile("binary.txt");
    	if( !inFile )
    	{
    		cerr << "File cannot opened!" << endl;
    		exit( 1 );
    	}
    	while( inFile >> binToDec )
    	{
    		//整型流基数的转换只针对整型数据,
    		//文件中读入的是二进制数据,所以无法完成转换
    		while( i < binToDec.size() )
    		{
    			if( binToDec[i] == '1')//写成“1”有错
    				sum += static_cast<int>(pow( 2.0,binToDec.size() - i -1 ));
    			i++;
    		}
    		cout << sum << endl;
    		//计数值在一组循环结束时,要归零重新计数。
    		sum = 0;
    		i = 0;
    	}
    
    }
    

    二刷代码:

    #include <iostream>
    #include <fstream>
    #include <stack>
    using namespace std;
    
    void toBinary( int );
    int main()
    {
    	int n;
    	cout << "Please enter the number of integers:";
    	cin >> n;
    	cout << "Please enter " << n << " integers:" << endl;
    	while(n--)
    	{
    		int inte;
    		cin >> inte;
    		toBinary( inte );
    	}
    
    
    }
    void toBinary( int inte)
    {
    	stack<int> s;
    	int temp;
    	while(inte > 0)
    	{
    		temp = inte % 2;
    		s.push( temp );
    		inte /= 2;
    	}
    	ofstream outputFile("binary.txt",ios::app);
    	if(!outputFile)
    	{
    		cerr << "File can not be opened." << endl;
    		exit( 1 );
    	}
    	while (!s.empty())
    	{
    		cout << s.top();
    		outputFile << s.top();
    		s.pop();
    	}
    	outputFile << endl;
    	cout << endl;
    }
    

    2、写两个模板函数:插入排序法的迭代实现与递归实现


    这题综合了网上资源和自己写的,好几个版本都放上来了,正确版本和错误版本我都标注出来了,大家可以对比下。参考网上的当时没有标记具体来源,现在已经不太好找了,对原作者说声抱歉。

    #include <iostream>
    using namespace std;
    
    template < typename T > void insertSortIterator( T [], const int );
    template < typename T > void insertSortRecursive( T [], const int );
    template < typename T > void Insert( T [], const int );
    int main()
    {
    	int a []= {5,3,6,2,7,4,8,1,0,9};
    	double b[] = { 3.4, 1.1, 9.9, 0.3, 0.2, 5.4, 5.3, 5.5, 123, 3.39 };
    
    	insertSortIterator( a, sizeof( a ) / sizeof( *a ) -1 );
    	for( int item:a )
    		cout << item << " ";
    	cout <<endl;
    
    	insertSortRecursive( b, sizeof( b ) / sizeof( *b ) - 1 );
    	for( double item: b)
    		cout << item <<" ";
    	cout << endl;
    }
    //插入排序法的迭代实现
    template < typename T > 
    void insertSortIterator( T a[], const int size )
    {
    //法一 RIGHT
    	//自己改写*******************************************
    	//for( int i = 1; i < 10; i++ )
    	//{
    	//	int j;
    	//	if( a[ i - 1 ] > a[ i ] )
    	//	{
    	//		int temp = a[ i ];
    	//		for( j = i - 1; j >= 0; j -- )
    	//		{
    	//			if( a[ j ] > a[ j + 1 ] )
    	//				a[ j + 1 ] = a[ j ];
    	//			else
    	//				break;//如果前者不再大于后者,此次循环可以跳过。
    	//			a[ j ] = temp;
    	//		}	
    	//	}
    	//}
    	
    //法二 RIGHT
    	//网上最优*******************************************
    	for (int i = 1; i < 10; i++) 
    	{
    		//int temp = a[i];
    		//int j = i;
    		// //如果前面的元素小于temp,则向后移
    		//for (; j > 0 && a[j - 1] > temp; j--) 
    		//	a[j] = a[j - 1];
    		// //前一个元素(array[j - 1])和后一个元素(array[j])是相同的
    		// //在下一轮时,当array[j - 1]小于或等于temp时,将temp插入array[j](即上一轮的array[j - 1])
    		//a[j] = temp;
    		Insert( a, i );//与上述语句作用相同
    	}
    	
    //法三 RIGHT
    	//参考博客********************************************
    	//int i = 0;
    	//int temp;
    	//int j;
    	//for( i = 1; i < 10; i++ )
    	//{
    	//	j = i;
    	//	temp = a[ i ];
    	//	while( j > 0 && a[ j - 1 ] > temp )
    	//	{
    	//		a[ j ] = a[ j - 1 ];
    	//		j--;
    	//	}
    	//	a[ j ] = temp;
    	//}
    
    wrong 
    	//int i = 0;
    	//for( i = 1, i < size; i++ )
    	//{
    	//	if( a[ i - 1 ] > a[ i ] )
    	//	{
    	//		int j = i;
    	//		while( --j && a[ j ] > a[ j + 1 ] )
    	//			a[ j + 1 ] = a[ j ];
    	//		a[ j ] = a[ i ];
    	//	}
    	//}
    	//for( i = 0; i < 10; i++ )
    	//{
    	//	cout << a[ i ] << " ";
    	//}
    	//cout << endl;
    }
    
    //插入排序法的递归实现
    template < typename T > 
    void Insert( T a[], const int size)
    {
    	int j = size;
    	T temp = a[ size ];
    	for(; j >= 0 && a[ j -1 ] > temp; j-- )
    		a[ j ] = a[ j - 1 ];
    	a[ j ] = temp;
    }
    
    template < typename T > 
    void insertSortRecursive( T a[], const int size )
    {
    
    
    	if( size > 0 )
    	{
    		insertSortRecursive( a, size - 1 );//规模缩小
    		Insert( a, size );					//缩小后排序
    	}
    	else 
    		return;
    }
    
    
    //自己写的初始版本,WRONG!!!
    //template < typename T > 
    //void insertSortRecursive( T a, const int size )
    //{
    //	if( size == 1 )
    //		return array;
    //	else if( size == 2 )
    //	{
    //		if( a[ 0 ] > a[ 1 ] )
    //			swap( a[ 0 ], a[ 1 ] );
    //		return array;
    //	}
    //	else
    //		return insertSortRecursive( array, size - 1 );
    //}
    

    3、字符串的解析.


    文件中有类似的一行行字符串“(010)(15012345678)|123|(430070)”,按以下格式输出: “区号| 电话号码| 城市编号| 邮编
    一刷代码:
    这个代码就是参考 GanonYou的这篇博客。

    //文件中有类似的一行行字符串“(010)(15012345678)|123|(430070)”,
    //按以下格式输出:“区号| 电话号码| 城市编号| 邮编”
    
    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <string>
    using namespace std;
    
    void outputLine( string, string, string, string );
    
    int main()
    {
    	ifstream inputFile("teleNumber.txt" ,ios::in );
    	if( !inputFile )
    	{
    		cerr << "File can notopened!" << endl;
    		exit( 1 );
    	}
    
    	cout << "area" << setw( 18 ) << "telephone number" << setw( 9 ) 
    		<< "NO.city" << setw( 13 ) << "mail number" << endl; 
    	
    	string info;
    	string area,tele,city,mail;
    	while( inputFile >> info)
    	{
    		//area = info.substr( 1, 3 );
    		//tele = info.substr( 6, 11);
    		//city = info.substr( 19, 3);
    		//mail = info.substr( 24, 6);
    		
    		//区号
    		//参数:指定子串位置;子串长度
    		area = info.substr( info.find("(") + 1, info.find(")") - info.find("(") - 1);
    		
    		info.erase(info.find("("), info.find(")") - info.find("(") + 1);
    
    		tele = info.substr( info.find("(") + 1, info.find(")") - info.find("(") - 1);
    		info.erase(info.find("("), info.find(")") - info.find("(") + 1);
    
    		info.erase(info.find("|"), 1);
    		city = info.substr( 0, info.find("|") );
    		info.erase(0, info.find("|") + 1);
    		
    		mail = info.substr( info.find("(") + 1, info.find(")") - info.find("(") - 1);
    		info.erase(info.find("("), info.find(")") - info.find("(") + 1);
    
    
    		outputLine( area, tele, city, mail );
    	}
    		
    }
    void outputLine( string area, string tele, string city, string mail )
    {
    	cout << area << setw( 3 )<<"|"<< setw( 14 ) << tele << setw( 4 )<<"|"
    		<< setw( 5 ) << city << setw( 4 )<<"|"<< setw( 8 ) << mail << endl;
    }
    

    二刷代码:
    二刷时觉得一刷时写代码太麻烦了,上述过程完全可以用strtok()/strtok_s()来简单解决,关于这两个函数的用法,我先放一个网上找到的博主链接,后面有空我再就这个知识点另写一篇博客。

    #include <iostream>
    #include <fstream>
    #include <cstring>
    using namespace std;
    
    #define MAXSIZE 100
    int main()
    {
    	ifstream inputFile( "teleNumber.txt" );
    	if(!inputFile)
    	{
    		cerr << "File can not opened!" << endl;
    		exit( 1 );
    	}
    	char str[MAXSIZE];
    	char *tokenPtr = NULL;
    	char *buf;
    	while (inputFile >> str)
    	{
    		//cout << "str:" << str;
    		tokenPtr = strtok_s(str,"()|",&buf);
    
    		while (tokenPtr)
    		{
    			if( *buf == '\0' )
    				//buf中的内容为‘\0’时,最后一个字符串已经复制给tokenPtr,只输出字符串就好
    			{
    				cout << tokenPtr;
    				break;
    			}
    			cout << tokenPtr << " | ";
    			tokenPtr = strtok_s( NULL, "()|",&buf);
    			//cout << buf << " ";
    			
    		}
    		cout << endl;
    	}
    }
    

    4、设计一个多项式类 Polynomial :包括构造函数、复制构造函数、析构函数、赋值函数、 实现两个多项式相加


    这里为了简化问题,我们将所有的多项式都统一看成
    p = a0 + a1 x + a2x^2 + a3 x^3 + ………… + anx^n
    然后将所有的系数a0、a1、a2直至an依次存储在一个向量vector中(其实数组也行)。
    通过对vector元素的操作,我们就可以实现对多项式的基本操作。

    一刷代码:

    //Polynomial.h
    #ifndef POLYNOMIAL_H
    #define POLYNOMIAL_H
    
    #include <iomanip>
    #include <vector>
    using namespace std;
    
    class Polynomial
    {
    public:
    	static const int SIZE = 100;
    
    	Polynomial();
    	//Polynomial( Polynomial & );
    	Polynomial( double [], const int );
    	~Polynomial();
    
    	void setCoe( double [], int );
    
    	void setMaxPow( int );
    
    	void print() const;
    	//赋值运算符,未经重载就可以运用于任何类对象,所以可以不写
    	//Polynomial operator=( Polynomial &p )
    	//{
    	//	Polynomial::maxPow = p.maxPow;
    	//	for( int i = 0; i < Polynomial::maxPow; i++ )
    	//	{
    	//		coe[ i ] = p.coe[ i ];
    	//	}
    	//	return *this;
    	//}
    //两种重载运算符+的方法
    	Polynomial operator+( Polynomial &p)
    	{
    		int finalMaxPower = ( p.maxPow < maxPow ) ? p.maxPow : maxPow;
    		//this->maxPow = finalMaxPower;//要把最大幂次赋值给返回对象,否则返回对象保持原有的最大幂次
    		cout << fixed <<setprecision( 1 );
    		//较短的多项式相较于较长多项式,有一部分未被初始化,所以计算结果出现垃圾值
    		//当多项式短长/长短 出现顺序不同时,运行结果就有误,所以要先判断长短
    		Polynomial p3( ( p.maxPow > maxPow ) ? p : *this );
    		if( p.maxPow > maxPow )
    		{//多项式p更长,p3 = p,p3 = p3 + this;
    			for( int i = 0; i < finalMaxPower; i++ )
    				p3.coe[ i ] += coe[ i ];
    			return p3;
    		}
    		else
    		{//多项式this更长,p3 = this,p3 = p3 + p;
    			for( int i = 0; i < finalMaxPower; i++ )
    				p3.coe[ i ] += p.coe[ i ];
    			return p3;
    		}
    	}
    	//当运算符重载为类的成员函数时,函数的参数个数比原来的操作数要少一个(后置单目运算符除外),
    	//这是因为成员函数用this指针隐式地访问了类的一个对象,它充当了运算符函数最左边的操作数。
    	friend Polynomial operator+( Polynomial &p1, const Polynomial &p2)
    	{
    		cout << fixed <<setprecision( 2 );
    		int finalMaxPower = ( p1.maxPow < p2.maxPow ) ? p1.maxPow : p2.maxPow;
    		p1.maxPow = finalMaxPower;
    		//较短的多项式相较于较长多项式,有一部分未被初始化,所以计算结果出现垃圾值
    		Polynomial p3( ( p1.maxPow > p2.maxPow ) ? p1 : p2 );//将较长多项式先赋值给第三个类对象
    		if( p1.maxPow > p2.maxPow )
    		{//多项式p1更长,p3 = p1,p3 = p3 + p2;
    			for( int i = 0; i < finalMaxPower; i++ )
    				p3.coe[ i ] += p2.coe[ i ];
    			return p3;
    		}
    		else
    		{//多项式p2更长,p3 = p2,p3 = p3 + p1;
    			for( int i = 0; i < finalMaxPower; i++ )
    				p3.coe[ i ] += p1.coe[ i ];
    			return p3;
    		}
    	}
    
    private:
    	int maxPow;
    	double coe[ SIZE ];
    };
    
    #endif
    
    Polynomial.cpp
    #include <iostream>
    #include "Polynomial.h"
    using namespace std;
    
    Polynomial::Polynomial()
    {
    	for( int i = 0; i < SIZE; i++ )
    		coe[ i ] = 0.0;
    }
    //Polynomial::Polynomial( Polynomial &p )
    Polynomial::Polynomial( double a[], const int pow )
    {
    	setCoe( a, pow );
    }
    Polynomial::~Polynomial()
    {
    
    }
    
    void Polynomial::setCoe( double pcoe[], int max )
    {
    	setMaxPow( max );
    	for( int i = 0; i < max; i++ )
    		coe[ i ] = pcoe[ i ];
    }
    
    void Polynomial::setMaxPow( int max )
    {
    	maxPow = max;
    }
    
    
    void Polynomial::print() const
    {
    	for( int i = 0; i < maxPow; i++ )
    	{
    		if( coe[i] )
    		{
    			if( i == 1 )
    				cout << showpos <<coe[ i ] << "x";
    			else if( i == 0 )
    				cout << coe[ i ];
    			else
    				cout << showpos << coe[ i ] << "x^" << noshowpos << i;
    		}
    	}
    }
    
    //mian.cpp
    #include <iostream>
    #include <string>
    #include <vector>
    #include"Polynomial.h"
    using namespace std;
    
    int main()
    {
    	double i = 0.0;
    	cout << i << endl;
    	double a[ 5 ] = { -1.5, 23, 0, 43, -2 };
    	double b[ 7 ] = { 2, -8, 4, -10.9, 3, -5.5, 9 };
    	double c[ 5 ] = { -1.5, 23, 0, 43, -2 };
    	double d[ 7 ] = { 2, -8, 4, -10.9, 3, -5.5, 9 };
    	//double c[100];
    	Polynomial p1( a, sizeof( a ) / sizeof( double ) );
    	Polynomial p2( b, sizeof( b ) / sizeof( double ) );
    	Polynomial p4( c, sizeof( c ) / sizeof( double ) );
    	Polynomial p5( d, sizeof( d ) / sizeof( double ) );
    	Polynomial p3;
    
    	p1.print();
    	cout << endl;
    
    	p2.print();
    	cout << endl;
    
    	p3 = p1.operator+( p2 );
    	cout << "\n\np1.operator+( p2 ):" << endl;
    	p3.print();
    	cout << endl;
    
    	p3 = p4 + p5;
    	cout << "p3 = p4 + p5:" << endl;
    	p3.print();
    	cout << endl;
    
    }
    

    在这个博主的题目中还发现了第5题和第6题,好像是我偷懒没写,直接附链接。

    展开全文
  • C++复试题 笔记

    2020-03-04 20:59:20
    string是C++标准程序库中的一个头文件,定义了C++标准中的字符串的基本模板类std::basic_string及相关的模板类实例 CString是MFC中定义的字符串类,MFC中很多类及函数都是以CString为参数的 2017.面向对象程序...
  • c++编程 复试

    2012-01-05 01:35:41
    c++编程 考研复试资料
  • 此资源为东南大学历年的c++复试
  • c++面试、复试 常用问题总结

    千次阅读 2020-05-07 13:50:38
    c++面试、复试 常用问题总结C++重载:三大特性:C++默认是私有的,public,private,protected这些操作符的使用体现了封装特性析构函数赋值操作符重载:Const函数修饰Inline内联函数C++中建议用const/ enum /inline...
  • 写一个职工类,其中私有数据成员包括职工姓名name,职工号id,入职年月rznf,年度评分score(每年每个员工会得到一个分,是4-9之中的整数值,当得到第三个评分后,会判断是否加薪或辞退,然后清零这三个评分),员工...
  • 地方地圭地土著人土土土土土土土土土土土土土寺院
  • 复试——C++

    2020-05-20 15:55:19
    C和C++ 类:类定义了事物的属性和它可以做到的(它的行为)。一个类的方法和属性被称为“成员”。一个类所包含的方法和数据描述一组对象的共同属性和行为。类是在对象之上的抽象,对象则是类的具体化,是类的实例。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,779
精华内容 1,511
关键字:

c++复试

c++ 订阅