Nowcoder专项练习:C++(七)

1,格式控制符问题

对于问题:

float k=0.8567;
printf("%06.1f%%",k*100);

最后的输出是什么?

从上面的输出控制符我们可以得知,从左往右我们有:

  • 0:表示第一个非零数字前用零填充
  • 6:表示用6个位置
  • .1:表示小数点后保留一位小数,四舍五入
  • %%:表示输出%

因此,最后的输出为:
0085.7%


2,fopen函数的用法
  • 函数:fopen
  • 函数原型FILE * fopen(const char * path,const char * mode);
  • 返回值:文件顺利打开后,指向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno中。

一般而言,打开文件后会做一些文件读取或写入的动作,若打开文件失败,接下来的读写动作也无法顺利进行,所以一般在fopen()后作错误判断及处理。

参数说明:
参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态。
mode有下列几种形态字符串:

  • “r” 以只读方式打开文件,该文件必须存在。
  • “r+” 以可读写方式打开文件,该文件必须存在。
  • ”rb+“ 读写打开一个二进制文件,允许读写数据(可以任意修改),文件必须存在。
  • “w” 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。
  • “w+” 打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。
  • “a” 以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)
  • ”a+“ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)
  • “wb” 只写打开或新建一个二进制文件;只允许写数据(若文件存在则文件长度清为零,即该文件内容会消失)。
  • “wb+” 读写打开或建立一个二进制文件,允许读和写(若文件存在则文件长度清为零,即该文件内容会消失)
  • “wx” 创建文本文件,只允许写入数据.[C11]
  • “wbx” 创建一个二进制文件,只允许写入数据.[C11]
  • ”w+x“ 创建一个文本文件,允许读写.[C11]
  • “wb+x” 创建一个二进制文件,允许读写.[C11]
  • “w+bx” 和"wb+x"相同[C11]
  • “rt” 只读打开一个文本文件,只允许读数据
  • “wt” 只写打开或建立一个文本文件,只允许写数据
  • “at” 追加打开一个文本文件,并在文件末尾写数据
  • “rb” 只读打开一个二进制文件,只允许读数据
  • “wb” 只写打开或建立一个二进制文件,只允许写数据
  • “ab” 追加打开一个二进制文件,并在文件末尾写数据
  • “rt+” 读写打开一个文本文件,允许读和写
  • “wt+” 读写打开或建立一个文本文件,允许读写
  • “at+” 读写打开一个文本文件,允许读,或在文件末追加数据
  • “rb+” 读写打开一个二进制文件,允许读和写
  • “ab+” 读写打开一个二进制文件,允许读,或在文件末追加数据

其中,对于r+w+
相同点:

  1. 二者都是可读写
  2. 二者都从文件头开始写
  3. 二者都是当文件不存在时创建文件

不同点:
4. r+直接在原文上覆盖,未覆盖的字符保留
5. w+先将原文清零,再写入


3,运算符的重载

C++语言允许在重载运算符时改变运算符原来的功能。例如将“++符号重载时,可以定义为--的功能。但是,不提倡这样做,重载运算符最好仍保持原有的功能。

而,C++语言不允许重载运算符时改变:

  • 运算符的操作个数
  • 运算符的优先级
  • 运算符的结合性

4,虚函数与指针问题

如果调用的函数是实函数,则看指针的定义;如果调用的函数是虚函数,则看指针的指向(赋值)。

对于问题:

#include<iostream>
using namespace std;
 
class Base
{
    int x;
public:
    Base(int b): x(b) {}
    virtual void display()
    {
        cout << x;
    };
};
class Derived: public Base
{
    int y;
public:
    Derived(int d): Base(d), y(d) {} void display()
    {
        cout << y;
    }
};
 
int main()
{
    Base b(1);
    Derived d(2);
    Base *p = & d;
    b.display();
    d.display();
    p->display();
    return 0;
 
}

最后的输出为?

  • b为Base类的对象,调用显示x,为1;
  • d为派生类对象,b.display()自然调用派生类的函数,显示y,为2;
  • p->display()为基类指针指向派生类对象,(此为多态的实现核心,详情可参考虚表部分内容),此时调用的函数由对象决定,对象是派生类对象,故调用派生类的函数,故输出y,为2

因此,最后的输出为122。

根据上面的原则,指针p调用的是虚函数,而指针p的指向(赋值)为派生类,所以是派生类的函数部分。


5,数组作为函数实参的问题
  • 在主调函数中,不一定非要指定数组的大小。比如,如果是char[] 数组,我们可以通过最后的’\0’来识别数组结束,不一定必须要显式说明数组大小。
  • 在被调函数中,不需要考虑形参数组的大小。因为传数组都是只传一个地址过来。

6,static与const
  • 对于static,用其修饰的变量不可以被其他的文件使用
  • 数据段可以分成data段——初始化不为0的static和global数据、以及bss段——未初始化或者已初始化为0的static和global数据
  • static静态变量存储在静态域中。
  • const表面含义是个常量,但实际上还是占据一个内存位置的变量,但是它的值一般实在编译时期就决定了。

7,静态成员
  • 非静态成员函数也可以操作静态数据成员。
  • 静态成员是属于类的,不是属于对象的,而this是当前对象的指针,所以静态成员没有this指针
  • 在C++中,类的静态成员(static member)必须在类内声明在类外初始化,像下面这样:
class A 
{ 
private: 
static int count ; // 类内声明 
};
int A::count = 0 ; // 类外初始化,不必再加static关键字

为什么?因为静态成员属于整个类,而不属于某个对象,如果在类内初始化,会导致每个对象都包含该静态成员,这是矛盾的。

而在类内可以初始化的成员只有一种,就是静态常量成员,其余类型的数据成员均不可以在类内初始化。

  1. 错误一:
class A 
{ 
private: 
static int count = 0; // 静态成员不能在类内初始化 
};
  1. 错误二:
class A 
{ 
private: 
const int count = 0; // 常量成员也不能在类内初始化 
};
  1. 错误三:
class A 
{ 
private: 
static const float count = 3.14; // 非静态整型成员常量不能在类中初始化
};
  1. 正确写法
class A 
{ 
private: 
static const int count = 0; // 静态整型常量成员可以在类内初始化
};

8,纯虚函数

纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。

不过值得注意的是,我们也可以为纯虚函数提供定义,不过函数体必须定义在类的外部。


9,构造函数的执行顺序

当派生类中不含对象成员时:

  • 在创建派生类对象时,构造函数的执行顺序是:基类的构造函数 → 派生类的构造函数;
  • 在撤消派生类对象时,析构函数的执行顺序是:派生类的析构函数 → 基类的析构函数。

当派生类中含有对象成员时:

  • 在定义派生类对象时,构造函数的执行顺序:基类的构造函数 → 对象成员的构造函数 → 派生类的构造函数;
  • 在撤消派生类对象时,析构函数的执行顺序:派生类的析构函数 → 对象成员的析构函数 → 基类的析构函数。

10,引用类型

对于引用类型,在使用时必须要设定初值、进行初始化;指针倒是不用。


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值