0%

C++ 问题集

'\n\'std::endl 的区别

  • '\n’表示内容为一个回车符的字符。
  • std::endl 是流操纵符(manipulator),输出的作用和输出’\n’类似,其效果是结束当前行,并将与设备关联的缓冲区(buffer)中的内容冲刷(flush)到设备中。缓冲刷新操作可以保证到目前为止程序所产生的所有输出都真正写入输出流中,而不是仅停留在内存中等待写入流。
1
std::cout << std::endl;

等价于

1
std::cout << '\n' << std::flush;

对于有输出缓冲的流(例如cout、clog),如果不手动进行缓冲区刷新操作,将在缓冲区满后自动刷新输出。不过对于cout来说(相对于文件输出流等),缓冲一般体现得并不明显。但是必要情况下使用endl代替’\n’一般是个好习惯。
对于无缓冲的流(例如标准错误输出流cerr),刷新是不必要的,可以直接使用 ‘\n’,过多的endl会影响程序的执行效率。

说明指针和引用的区别

  • 引用是另一个对象的别名,而指针本身就是一个对象。
  • 引用必须初始化,并且一旦定义了引用就无法再绑定到其他对象。而指针无须在定义时赋初值,也可以重新赋值让其指向其他对象。

常量指针和常量引用有什么不同?

常量指针(const pointer)是常量化的指针是正规翻译,常量引用(reference to const)是对常量的引用是坊间俗称。

说明decltype和auto的区别

auto: 类型说明符,用它能让编译器代替我们去分析表达式所属的类型。auto定义的变量必须有初始值,auto在一条语句中声明多个变量必须保证同样的基本数据类型。

decltype: 类型指示符,为了从表达式的类型推断出要定义的变量的类型,但是不想用该表达式的值初始化变量。

  1. decltype处理顶层const和引用的方式与auto不同,auto 会忽略顶层const和直接推演引用所指的类型,decltype会将顶层const和引用保留起来。
1
2
3
4
5
6
const int ci = 0, &cj = ci;
decltype(ci) x1 = 0; // x1的类型是const int
auto x2 = ci; // x2的类型是int
decltype(cj) y1 = x; // y1的类型是const int &
auto y2 = cj; // y2的类型是int
auto y3 = &cj; // y3的类型是const int*,取值算底层const会保留
  1. decltype处理(对指针)解引用操作得到引用类型,而auto得到指针所指对象的类型
1
2
3
int i = 1, *p = &i;		
decltype(*p) pr = i; // pr的类型是int &
auto pa = *p; // pa的类型是int
  1. decltype结果类型与表达式形式密切相关

如果decltype使用的是一个不加括号的变量,则得到的结果就是该变量的类型;如果给变量加上了一层或多层括号,编译器就会将把它当成一个表达式。变量是一种可以作为赋值语句左值的特殊表达式,所以这样的decltype就会的得到引用类型:

1
2
3
4
int a = 1, b = 0;
decltype((a)) d=a; // d的类型为int &
decltype(a) d2; // d2的类型为未初始化的int
decltype(a=b) d3=b; // d3的类型为int &