牛客 C++刷题day14&15&16&17&18&19&20 假期之后的复习

前几天去大伯家休养了一个星期,打打球,钓钓鱼相当惬意,刷题强度下降了很多。现在恢复正常作息

1:fscanf和fprintf

fscanf() 和 fprintf() 函数与前面使用的 scanf() 和 printf() 功能相似,都是格式化读写函数,两者的区别在于 fscanf() 和 fprintf() 的读写对象不是键盘和显示器,而是磁盘文件。

这两个函数的原型为:

int fscanf ( FILE *fp, char * format, ... );
int fprintf ( FILE *fp, char * format, ... );

fp 为文件指针,format 为格式控制字符串,... 表示参数列表。与 scanf() 和 printf() 相比,它们仅仅多了一个 fp 参数。例如:

  1. FILE *fp;
  2. int i, j;
  3. char *str, ch;
  4. fscanf(fp, "%d %s", &i, str);
  5. fprintf(fp,"%d %c", j, ch);

fprintf() 返回成功写入的字符的个数,失败则返回负数。fscanf() 返回参数列表中被成功赋值的参数个数。

2:面向对象的五大基本原则

单一职责原则(SRP)

 

1.1,SRP(Single Responsibilities Principle)的定义:就一个类而言,应该仅有一个引起它变化的原因。简而言之,就是功能要单一。
  1.2,如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其它职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。(敏捷软件开发)
  1.3,软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。(敏捷软件开发)

 

小结:

 

单一职责原则可以看做是低耦合、高内聚在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。职责过多,可能引起它变化的原因就越多,这样导致职责依赖,相互之间就会产生原因,大大损伤其内聚性和耦合度。

 

开放封闭原则(OCP)

 

 2.1,OCP(Open-Close Principle)的定义:就是说软件实体(类,方法等等)应该可以扩展,但是不能修改。它是软件设计中也是最重要的一种设计原则。
  2.2,OCP的两个特征:
    2.2.1> 对于扩展是开放的。
    2.2.2> 对于修改是封闭的。

 

 

 

  2.3,什么时候应用OCP原则呢?
    在我们最初编写代码时,假设变化不会发生,当变化发生时,我们就创建抽象(比如抽象类,接口等等)来隔离以后发生的同类变化。
  2.4,开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护,可扩展,可复用,灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象,然而,对于应用程序中的每个部分都刻意地进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。
  2.5,OCP的UML图:

 

 

小结:

 

开放封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处:可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现频繁变化的那些部分做出抽象,然而,对于应用程序中的每个部分都刻意地进行抽象同样也不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。“需求总是变化”没有不变的软件,所以需要用开放封闭原则来封闭变化满足需求,同时还能保持软件内部的封装体系稳定,不被需求的变化影响。

依赖倒置原则(DIP)

 

3.1,DIP(Dependence Inversion Principle)的定义:抽象不应该依赖细节,细节应该依赖于抽象。简单说就是,我们要针对接口编程,而不要针对实现编程。

 

           3.1. 1 高层模块不应该依赖低层模块。两个都应该依赖抽象。

 

           3.1.2 抽象不应该依赖具体(细节)。具体(细节)应该依赖抽象。

 


  3.2、反面例子UML图:

 

      
  缺点:高层模块太依赖低层模块,耦合太紧密。低层模块发生变化会影响到高层模块。
  解决方法:利用依赖倒置原则使高层模块和低层模块都依赖于抽象(接口或抽象类)。
  3.3、修改后的UML图如下:
  
  优点:这样的话修改低层模块不会影响到高层模块,减小了它们之间的耦合度,增强系统的稳定性。
  

 

小结:

 

依赖倒置原则其实可以说是面向对象设计的标志,用哪种语言来编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象的设计,反之那就是过程化的设计了。

 

接口隔离原则(ISP)

 

使用多个专门的接口比使用单一的总接口要好。

 

一个类对另外一个类的依赖性应当是建立在最小的接口上的。

 

一个接口代表一个角色,不应当将不同的角色都交给一个接口。没有关系的接口合并在一起,形成一个臃肿的大接口,这是对角色和接口的污染。

 

“不应该强迫客户依赖于它们不用的方法。接口属于客户,不属于它所在的类层次结构。”这个说得很明白了,再通俗点说,不要强迫客户使用它们不用的方法,如果强迫用户使用它们不使用的方法,那么这些客户就会面临由于这些不使用的方法的改变所带来的改变。

 

 小结:

 

接口隔离的方法有两种(分享客户就是分离接口):
1、使用委托(此委托非.net委托[delegate])分离接口
使用委托即,创建一个委托类,用此类去实现分离后的其它接口中的方法。
2、使用多重继承分离接口、
此方法,即将现有“胖”接口分成供不同客户程序调用的两个或多个接口,而需要实现多个接口的客户程序,则使用多重继承来实现。

 

里氏替换原则(LSP)

5.1,LSP(Liskov Substitution Principle)的定义:子类型必须能够替换掉它们的父类型。简单地说,这是因为子类型继承了父类,所以子类可以以父类的身份出现。

  实例UML图:

     

 

小结:

任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

 

补充:

迪米特法则(LoD):

     自从我们接触编程开始,就知道了软件编程的总的原则:低耦合,高内聚。无论是面向过程编程还是面向对象编程,只有使各个模块之间的耦合尽量的低,才能提高代码的复用率。低耦合的优点不言而喻,但是怎么样编程才能做到低耦合呢?那正是迪米特法则要去完成的。

迪米特法则又叫最少知道原则,最早是在1987年由美国Northeastern University的Ian Holland提出。通俗的来讲,就是一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息。迪米特法则还有一个更简单的定义:只与直接的朋友通信。首先来解释一下什么是直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。其中,我们称出现成员变量、方法参数、方法返回值中的类为直接的朋友,而出现在局部变量中的类则不是直接的朋友。也就是说,陌生的类最好不要作为局部变量的形式出现在类的内部。

   1,LoD(Law of Demeter)的定义:如果两个类不必彼此直接通信,那么这两个类就不应当直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

   2,在类的结构设计上,每一个类都应当尽量降低成员的访问权限,也就是说,一个类包装好自己的private状态,不需要让别的类知道的字段或行为(方法)就尽量不要公开。

 

定义:一个对象应该对其他对象保持最少的了解。

问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。

解决方案:尽量降低类与类之间的耦合。

小结:

迪米特法则的初衷是降低类之间的耦合,由于每个类都减少了不必要的依赖,因此的确可以降低耦合关系。但是凡事都有度,虽然可以避免与非直接的类通信,但是要通信,必然会通过一个“中介”来发生联系,例如本例中,总公司就是通过分公司这个“中介”来与分公司的员工发生联系的。过分的使用迪米特原则,会产生大量这样的中介和传递类,导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。

3:关于整数强转为指针变量

int是可以强制转换的,而float,double均不可。且我们知道整数的位长不能超过寻址范围。

4:一个类中的构造函数可以是私有的比如单例模式。

5:二维数组作为形参时,一维可以省略但是二维不可省略,声明二维数组一维不可省略,二维可以。

6:常成员只能在初始列表初始化,常静态变量只能通过类外定以。要注意定以时加上const type 不需要static

7:静态联编是通过对象名调用虚函数,这个是在编译阶段就确定了的。

但是动态联编在编译阶段无法通过语句本身确定调用哪一个类的虚函数,只有在运行时指向一个对象后才能确定调用哪个类的虚函数。

8:

小端存储:低位存低位,高位存高位

大端存储:低位存高位,高位存低位

还有结构体中先声明的是低地址,后声明的是高地址

9:静态变量,全局变量其实不在栈区而是在另外一个单独的区,这里不要搞混淆了

 10:逗号运算符得到的结果都是括号最后一个表达式的值....16位机器下不考虑字节对齐,划重点,要考的(shit!!!)

转载于:https://www.cnblogs.com/Tonarinototoro/p/11565853.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值