C/C++零碎知识点

总是看到很多零碎的知识点,想记下来又不知道该放在哪里,不记的话又不知道在哪里去找,尴尬。
PS:不要盲目相信答案哦。
知识太杂,以后有空再分类吧

1.当派生类中不含对象成员时
· 在创建派生类对象时,构造函数的执行顺序是:基类的构造函数→派生类的构造函数;
· 在撤消派生类对象时,析构函数的执行顺序是:派生类的构造函数→基类的构造函数。
当派生类中含有对象成员时
· 在定义派生类对象时,构造函数的执行顺序:基类的构造函数→对象成员的构造函数→派生类的构造函数;
· 在撤消派生类对象时,析构函数的执行顺序:派生类的构造函数→对象成员的构造函数→基类的构造函数。
例子:

#include<iostream>
using namespace std;

class Test {
public:
    Test() {
        cout << "Test constructing!" << endl;
    }
    ~Test() {
        cout << "Test destructing!" << endl;
    }
};
class Base {
public:
    Base() {
        cout << "Base constructing!" << endl;
    }
    ~Base() {
        cout << "Base destructing!" << endl;
    }
};

class Derived : public Base {
public:
    Derived() {
        cout << "Derived constructing!" << endl;
    }
    ~Derived() {
        cout << "Derived destructing!" << endl;
    }
    Test test;
};

int main()
{
    Derived* derived = new Derived;
    delete derived;

    system("pause");
}
运行结果为:
Base constructing!
Test constructing!
Derived constructing!
Derived destructing!
Test destructing!
Base destructing!

2.内联函数与其他普通函数的区别是,内联函数在生成可执行文件时,其代码块是直接嵌入到调用处的,以此减少函数调用的开销提高程序性能,它与宏很类似。但是,C++ primer 上明明白白的写过这么一句话:内联说明(inline specification)对于编译器来说只是一个建议编译器可以选择忽略这个建议。也就是说,是否以嵌入式方式存在,是由编译器决定的,并不是一定。

3.面向过程是C的特性,基本单位函数

4.“++”的优先级比“*”高

5.char a[]={0,1,2,3,4,5}这样赋值没毛病,因为编译器会把数字当成ascll来赋值进去。

6,.下列C程序执行后c输出结果为( )(32位)
void main()
{
  int a = -3;
  unsigned int b = 2;
  long c = a + b;
  printf(“%ld\n”,c);
}
无符号和有符号整数进行运算时,有符号整数会被提升为无符号整数。
-3对应的二进制表示是0xfffffffd,和2相加表示0xffffffff。
输出结果取决于long是32位,还是64位。这个取决于编译器和机器。
long是有符号的整型。
如果是32位,0xfffffff在补码表示法(最高位是负数位)下是等于-1.
如果是64位,0xfffffff是属于long的正整数范围(负数位在第64位),等于4294967295。

7.对于函数指针比如:char (* f) (char*) = func;它的表示方式可以是
(*f1)(s),与f1(s)

8.“%”取余只能针对int型,对于浮点数要用库函数fmod。

9.C语言允许函数值类型缺省定义,此时该函数值隐含的类型是整形。

10.在C++中,为了让某个类只能通过new来创建(即如果直接创建对象,编译器将报错),应该将析构函数设为私有。编 译器在为类对象分配栈空间时,会先检查类的析构函数的访问性,其实不光是析构函数,只要是非静态的函数,编译器都会进行检查。如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存。 因此, 将析构函数设为私有,类对象就无法建立在栈(静态)上了,只能在堆上(动态new)分配类对象 。

11.函数中的局部变量,如果不专门声明为static存储类别,都是动态的分配存储空间的,数据储存在动态存储区中。这类变量叫做自动变量,自动变量可以用关键字auto作为存储类别的声明,实际上关键字auto是可以省略的(一般都是不写的),不写则自动隐含为“自动存储类别”。

12.在内联函数中不允许使用循环语句(for,while)和switch结果,带有异常接口声明的函数也不能声明为内联函数。另外,递归函数(自己调用自己的函数)是不能被用来做内联函数的。

13.对于带参数列表的函数,必须从右向左添加默认值。也就是说,要为某个参数设置默认值,则必须为它右边的所有参数提供默认值。

14.
a.成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
b.覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。
c.“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual 关键字。此时,基类的函数被隐藏.

15.对于#include后面的头文件来说
双引号:搜索用户所在目录;如果找不到,搜系统指定的目录
尖括号:仅仅搜索系统指定目录

16.

`int fun(unsigned int x)
{
     int n=0;
     while((x+1))     //统计x在二进制下0的个数
     //while(x)     //统计x在二进制下1的个数
     {
         n++;
         x=x|(x+1);
         //x=x&(x-1);

     }
     return n;
}`

17.

#include <stdio.h>
#include <string.h>
int main(){
    char *s="ABCDEF";
    char a[]="ABCDEF";
    char b[]={'A','B','C','D','E','F'}; 
    //char b[]={'A','B','C','D','E','F','\0'}; 
    printf("sizeof: s is %d,a is %d,b is %d\n",sizeof(s),sizeof(a),sizeof(b));//输出结果4,7,6
    printf("strlen: s is %d,a is %d,b is %d\n",strlen(s),strlen(a),strlen(b));//输出结果6,6,12
}

主要说最后的输出为啥是12,因为strlen是要遇到‘\0’才会结束计算的,这里没有,所以它计算到了内存中的’\0’,因此也不一定是12,正确输出的话,需要在字符数组最后加上’\0’。

18.C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。
关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。
基本类型的对象没有析构函数,所以回收基本类型组成的数组空间用 delete 和 delete[] 都是应该可以的;但是对于类对象数组,只能用 delete[]。
所以一个简单的使用原则就是:new 和 delete、new[] 和 delete[] 对应使用。

19.构造函数初始化时必须采用初始化列表一共有三种情况,
1.需要初始化的数据成员是对象(继承时调用基类构造函数)
2.需要初始化const修饰的类成员
3.需要初始化引用成员数据

20.C++中不能重载的运算符:“?:”、“.”、“::”、“sizeof”和”.*”
只能使用成员函数重载的运算符有:=、()、[]、->、new、delete。

21.const static数据成员可以在类内初始化 也可以在类外,不能在构造函数中初始化,也不能在构造函数的初始化列表中初始化
static数据成员只能在类外,即类的实现文件中初始化,也不能在构造函数中初始化,不能在构造函数的初始化列表中初始化;
const数据成员只能在构造函数的初始化列表中初始化;
普通数据成员不能在类内初始化,可以在构造函数中初始化,也可以在构造函数的初始化列表中初始化;

22.抽象类不能初始化,不能当做返回值,不能当做参数,可以作为指针变量,因为此时还没有初始化

23.floor : 意为地板,指向下取整,返回不大于它的最大整数 ceil : 意为天花板,指向上取整,返回不小于它的最小整数 round : 意为大约,表示“四舍五入”,而四舍五入是往大数方向入。Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11而不是-12。

24.抽象类 不能实例化,抽象类不能参数类型 和 函数返回类型

25.面向对象的五大基本原则:
单一职责原则(SRP)
开放封闭原则(OCP)
里氏替换原则(LSP)
依赖倒置原则(DIP)
接口隔离原则(ISP)

26.(1) 双目运算符重载为类的成员函数时,函数只显式说明一个参数,该形参是运算符的右操作数。
(2) 前置单目运算符重载为类的成员函数时,不需要显式说明参数,即函数没有形参。
(3) 后置单目运算符重载为类的成员函数时,函数要带有一个整型形参。

27.对于只做输入的参数:
a) 始终用const限制所有指向只输入参数的指针和引用。
b) 优先通过值来取得原始类型和复制开销比较低的值的对象。
c) 优先按const的引用取得其他用户定义类型的输入。
d) 如果函数需要其参数的副本,则可以考虑通过值传递代替通过引用传递。这在概念上等同于通过const引用传递加上一次复制,能够帮助编译器更好的优化掉临时变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值