【C++】面经整理1

目录

1.static的作用:

2.指针和引用

区别:

&&右值引用:

3.类的默认函数

4.#endif  #defind  #ifndef

预处理:

1.宏定义:

2.文件包含

3.条件编译 

a##b

5.五大内存区

堆区和栈区的区别:

堆栈溢出

 6.常见排序算法

7.不能声明为虚函数的

8.switch()

9.五种循环


1.static的作用:

  • 延长局部变量生命周期(不会多次创建,直到程序结束其生命周期才结束)
  • static修饰的函数只能在本源文件中使用
  • 其他文件无法使用static修饰的全局变量

普通的全局变量使用关键字 extern 可以达到跨文件调用的目的。


2.指针和引用

为什么经常把指针和引用对比:两者都是间接引用某个数据。

区别:

  • 引用是别名,指针是指向地址的变量
  • 引用没有解引用
  • 引用必须赋初始值,指针可以不用(但一般防止其成为野指针还是会赋值为nullptr的)
  • 引用不能更改,指针可以重新指向别的(引用相当于常指针)
  • 有二级指针int**p = q,但是没有二级引用int&& a = b;

&&右值引用

int && a = 10;

右值往往是没有名称的,使用它只能借助引用。和常量左值引用不同的是,右值引用还可以对右值进行修改。例如:

int && a = 10;
a = 100;
cout << a << endl;

程序输出结果为 100。


3.类的默认函数

  • 构造函数
  • 拷贝构造函数
  • 析构函数
  • 重载赋值运算符
  • 重载取地址运算符
  • const
  • 移动构造函数和重载移动赋值操作符函数

4.#endif  #defind  #ifndef

C/C++的宏定义,防止该头文件被重复引用

#ifndef x :if not defined测试x是否被宏定义过

#ifndef x
程序段1//若x没有被宏定义过,定义x,并编译程序段1
#else
程序段2//若x已经定义过了则编译程序段2的语句,忽视程序段1
#endif

预处理:

1.宏定义:

       无参的宏定义:#define N 100

       有参的宏定义:#define S(a,b) (a+b)

2.文件包含

       #include<>//直接在系统目录中查找
       #incldue"   "//先在工程目录中查找,找不到再在系统中查找

3.条件编译 

        #if...#else...#endif
        #ifdef...#define...#endif

a##b

a##b 实际上就是ab,为了和防止别人定义的变量冲突我们可以定义一个宏,使我们自己的变量都带一个my_前缀,宏定义如下:#define MY_DECLARE(type,name)    type  my_##name;

#include
#define MY_DECLARE(type,name) type my_##name;
void main()
{
    MY_DECLARE(int,a) // 实际上宏展开为:int my_a;
    my_a=88;
    printf("%d\n", my_a);
}

5.五大内存区

  1. 栈区(向下增长):编译器自动分配释放,类似数据结构中的栈
  2. 堆区(向上增长):程序员分配释放,程序结束也会释放,分配方式类似链表
  3. 全局变量区:全局变量和静态变量,初始化和未初始化的分开放
  4. 文字常量区:字符串常量,一般为只读数据段
  5. 程序代码区,函数中的二进制代码

全局,static全局,局部变量,static局部变量,extern变量(外部),外部函数(另一个文件里面的函数),static函数

【C++】面经整理1_第1张图片

例:

p本身4字节在栈区,开辟的100个字节在堆区

int main()
{
	char* p = (char*)malloc(100);
}

堆区和栈区的区别:

1.申请方式:
    栈自动分配
    堆程序员申请,并指明大小
2.申请后系统响应
    栈的剩余空间大于申请空间就可以,否则异常:栈溢出
    堆遍历空闲链表结点,寻找第一个大于申请空间的空闲链表结点,分配空间,将该链表从空闲链表中删除,记录结点,最后delete用
3.申请大小的限制
        栈小
        堆大,有虚拟内存空间
4.申请效率

        栈效率高,堆效率低

5.内存

        栈区内存空间有限

        堆区空间很大,几乎没有限制

堆栈溢出

        没有回收垃圾资源,层次太深的递归调用导致。

注意:没有死循环(堆栈溢出)

int main()
{
	int a = 10;
	while (a < a + 10)
		a++;
	cout << "main" << endl;
}

最后会输出main,程序结束。 

内存泄漏:没有释放空间


 6.常见排序算法

排序算法 平均时间复杂度 空间复杂度 稳定性
冒泡排序 O(n^2) O(1) 稳定
选择排序 O(n^2) O(1) 不稳定
插入排序 O(n^2) O(1) 稳定
归并排序 O(nlogn) O(n) 稳定
快速排序 O(nlogn) O(nlogn) 不稳定
堆排序 O(nlogn) O(1) 不稳定
希尔排序 O(nlogn) O(nlogn) 不稳定
计数排序 O(n+k) O(n+k) 稳定
桶排序 O(n+k) O(n+k) 稳定
基数排序 O(n*k) O(n+k) 稳定

7.不能声明为虚函数的

        虚函数要等对象出来后再构造,运行时产生。

        constructor,构造,拷贝构造(设置虚表指针),内联(编译时对象的拷贝,无映射关系),静态成员函数(所有同类对象共有)。


        一般把析构函数设为虚函数,实现多态,程序编译时所有的析构函数名字都变成了destruction,合理的释放子类动态申请的空间;


8.switch()

不能switch()做的参数类型:浮点型(有精度),但是强制转换后可以

case后面的只能是定值;case可以嵌套.

int main()
{
	int a = 4, b = 6;
	switch (a + b)
	{
	case 10:
		cout << a + b << endl;
		break;
	case 5:
		cout << "lalala" << endl;
		break;
	}
}

9.五种循环

5种循环:for、while、do……while、if……goto、递归

for( ;1; )相当于while(1),也可以for(;;)

for (;;)
{
	for (;;)
	{
		for (;;)
		{
    		if (1)goto a;
		}
	}
a:cout << "end" << endl;
}

你可能感兴趣的:(写题做项目,C++,java,开发语言,c++,面试)