C/C++刷题总结(2)

  1. 关于拷贝构造函数,重载赋值运算符
    A b = a;
    此情况属于:一个对象(b)需要通过另外一个对象(a)进行初始化
    这种情况需要利用拷贝构造函数,除此之外,还有两种情况需要调用拷贝构造函数
    (1) 一个对象以值传递的方式传入函数体
    (2)一个对象以值传递的方式从函数返回
    A b;b=a;
    此情况属于:定义了一个对象(b),然后调用后面重载的赋值函数
    A *b = new A;
    此时调用了构造函数,但是注意,这里的赋值运算符不是类中的赋值运算符,而是普通的赋值运算符;

如果定义一个指针或者引用,不会调用构造函数

拷贝构造函数没有返回值,拷贝构造函数的参数可以使一个或多个,但左起第一个必须是类的引用对象

  1. 关于scanf里的%xd
    scanf(“%3d%f”,&x,&y);则会将输入的前3位数赋给x,输入中后面的部分将赋给y,
    如输入12345□678↙,则x=123,y=45.000000。

  2. double类型可以与int,float进行匹配
    如果同时出现两种函数,会出现多个匹配

  3. 内联函数
    一般可以用于加快程序执行速度,但是可能增加也可能减少可执行文件大小
    构造函数可以是内联函数

  4. sizeof和strlen
    sizeof返回所占内存空间,strlen返回字符串长度
    char *str1 = “Hello”,str2[] = “Hello”;
    sizeof(str1)= 4
    sizeof(str2)= 6

但是得注意八进制转义字符和十六进制转义字符
八进制字符的一般形式是’\ddd’,d是0-9的数字。十六进制字符的一般形式是’\xhh’,h是0-9或A-F内的一个
如strlen以下字符串,结果为
" 0123\0789 " 7 (0 ,1,2,3,\07,8,9)
" 0123\0123 " 6(0 ,1,2,3,\012,3)
" 0123\0889 " 4(0 ,1,2,3,\0)

  1. 计算结构体空间
    注意#pragma pack(4)与8
    每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行
    注意点
    1 先找有没有virtual 有的话就要建立虚函数表,+4
    有virtual修饰的成员函数编译器会构建虚函数表,在该类的对象中会存放一个指向虚函数表的指针,
    2 static作为静态变量是对类而言的,为所有对象共有 +0
    3 神马成员都没有的类,或者只有成员函数 +1
    4 对齐法则

  2. 函数指针的用法
    C++指向函数的指针定义方式为:
    返回类型 (*指针名) (函数参数列表) ,例如 void (*p)(int)是指向一个返回值为void 参数为int类型的函数

函数指针作为参数传递

int test(int a)
{
    return a-1;
}
int test2(int (*fun)(int),int b)
{
    
    int c = fun(10)+b;
    return c;
}
int main(int argc, const char * argv[])
{
    
    typedef int (*fp)(int a);
    fp f = test;
    cout<<test2(f, 1)<<endl; // 调用 test2 的时候,把test函数的地址作为参数传递给了 test2
    return 0;
}

指向成员函数的指针有所不同
1非静态成员函数
定义方式:返回类型 (类名::*指针名)(函数参数列表)例如void (A::*p)(int)是一个指向A类中成员函数的函数指针。
赋值方式:p=&A::函数名,而一般的函数指针的赋值是p=函数名即可,注意区别。(成员函数必须是public类型的)
调用方式:成员函数指针的调用必须通过类对象进行调用,a.*p(int)即可调用成员函数(该成员函数是public类型的)

2静态成员函数
对于静态成员函数的定义和使用方法都与普通函数指针的相同,只是在赋值的时候和非静态成员们函数指针的赋值方法相同。

因为静态成员函数的指针类型是与普通函数指针类型相同的。

声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,参数是int*
结果是int (*(*p)[10])(int *)
*p指向一个大小为10的数组,即(*p)[10]
2.*( *p)[10]表示*p指向一个大小为10的数组,且每个数组的元素为一个指针

  1. 堆与栈对比
    栈是向低地址扩展的数据结构,是一块连续的内存的区域。在WINDOWS下,栈的大小是2M,能从栈获得的空间较小

堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储 的空闲内存地址的,堆获得的空间比较灵活,也比较大

函数中定义的局部变量是存在在栈区,动态生成的变量存在在堆区,由指针进行读写。
堆的效率不如栈。大量的new/delete会造成内存空间不连续

  1. new delete malloc free

https://blog.csdn.net/Hackbuteer1/article/details/6789164

  1. clase与struct区别
    C++里:a.成员访问权限->class的成员访问权限为private,而struct的成员访问权限为public b.默认的继承方式->class的默认继承方式为private,而struct的默认继承方式为public

struct在C和C++之间的区别
a.c中,struct是用户自定义数据类型,而c++中,struct是抽象数据类型,支持成员定义函数
b.c中的struct是没有权限设置的,但是在c++中,给strcut添加了权限设置,增加了访问权限;
c.c中的struct只是变量的聚合体,可以封装数据,但是不可以隐藏,不可以定义函数成员;但是C++中的struct可以定义函数成员

  1. 不能被重载的运算符
    . (成员访问运算符)
    *星号 (成员指针访问运算符)
    :: (域运算符)
    sizeof (长度运算符)
    ?: (条件运算符)

  2. 全局变量可不可以定义在可被多个.c文件包含的头文件中
    如果不使用static,会报错
    但是使用了static,可以定义,此时变为内部链接,此时所谓的全局变量相当于每个c文件的局部变量。即不会相互影响。

  3. 构造函数与析构函数
    构造函数在创建对象的时候调用,先调用父类,再子类,析构相反
    1)当父类的指针new一个子类的对象时,
    父类析构不是虚析构,则delete的时候不调用子类的,只是调用父类的析构函数,如果是virtual的析构函数,则先子类之后父类
    2)当子类的指针new一个子类的对象时,构造析构都会调用父类


A *a = new C();是调用父类的指针new一个子类的对象
即:A B C deA
若A中的析构函数是virtual,则A B C deC deB deA


B *b = new C(); 即:A B C deB
若B中的析构函数是virtual,则A B C deC deB deA


C *c = new C();子类的指针new一个子类的对象,先构造(父->子)后析构(子->父)
结果A B C deC deB deA

  1. 继承
    基类public成员, 在子类中仍然是public成员,在子类中可以使用, 在子类的对象中也可以调用
    基类的protected成员,在子类中仍然是protected成员,在子类中可以使用,在子类的对象中不能直接调用
    private成员,只能在基类中使用,在基类对象,子类,子类对象中都不能使用

其他:
1.char a =’\82’;
因为有一个8,显然已经不是八进制,实际上就’\82’中包含3个字符,分别是‘\’,‘8’,‘2’,会将最后一个字符赋值给表达式的值,赋值时是将字符’2’给了a
2.递归
时间复杂度:递归次数
空 间复杂度:递归深度(调用栈帧)
3.头文件作用
Stdio输入输出,stdlib数值转换,内存分配,srdarg可变参数

4.C++不属于类型安全,因为可以进行强制类型转换

5.setbase将数字转换为 n 进制,既可用于输入,也可用于输出
以下均是输出
setw(n)用法: 通俗地讲就是预设宽度
setfill(char c) 在预设宽度中如果已存在没用完的宽度大小,则用设置的字符c填充
setprecision(n)可控制输出流显示浮点数的数字个数

6.(int &)a
float a=1;
(int &)a 是告诉编译器将a看成int对待(不做任何转换),所以(int &)a值为1065353216.
(int&)a 相当于*(int*)&a ,*(int*)(&a),*((int*)&a)

7.c语言默认返回类型int

发布了21 篇原创文章 · 获赞 0 · 访问量 383

猜你喜欢

转载自blog.csdn.net/weixin_41605876/article/details/104814794