• 腾讯使用C++为主要开发语言?java少?为什么


    在C++里,我们使用cout进行控制台文本输出。这在学习编程的阶段很常用,但在真实的工作场合却极少使用,毕竟大部分的应用程序都是基于图形界面,而不是终端的。甚至,在C/C++的某些应用场合,比如单片机编程里,嵌入式设备甚至连屏幕都没有。

    考虑到部分OJ系统中的在线编程题可能对输出格式作出精细要求,这里我们对cout控制输出进行“详细”讨论:包括cout的基本工作原理,以及通过cout进行精细格式输出的方法。

    1. cout基本工作原理

    下述代码可以帮助我们理解通过cout的插入操作符(insertion operator<<)进行控制台文本输出的基本原理。

    1. //Project - COUT
    2. #include
    3. using namespace std;
    4. int main() {
    5. cout << "pi = " << 3.14159 << endl;
    6. operator<<(cout,"pi = ").operator<<(3.14159).operator<<(endl);
    7. return 0;
    8. }

    上述代码的执行结果为:

    pi = 3.14159
    pi = 3.14159

     在iostream头文件中,很容易找到cout的定义。cout是一个类型为ostream的对象,其被连接到了标准输出流,即控制台。

    extern ostream cout;    /// Linked to standard output

    上述程序的第6行与第7行完全等价。相关代码的执行过程如下:

    • cout << “pi = “的实质是执行了一个名为operator<<( )的函数,其中,第1个参数是cout对象,第2个参数是”pi = “。这个函数把第2个参数的字符串输出到第1个参数所代表的控制台中。同时,该函数返回了cout的引用作为函数执行的结果。
    • … << 3.141519则以前述函数调用所返回的cout引用作为基础,执行其成员函数operator<<( )。该成员函数存在多个函数名重载的版本,其中一个版本接受一个double作为参数,并将double的值输出到cout。同样地,本次函数调用也返回了cout的引用作为结果。
    • 类似地,… << endl同样对应cout.operator<<( )函数的一次执行,该成员函数的一个重载版本接受endl作为参数,并向cout所代表的控制台输出一个换行符。

    <<操作符在C语言里用作左移位操作,C++的标准模板库通过定义与该操作符“同名”的函数,扩展了该操作符的功能:向cout输出对象内容。

    总结:iostream定义了多个重载的operator<<()操作符函数,这些不同版本的函数接受不同类型的参数,包括int, char, float, double, const char*, string等,并将这些参数对象转换成字符串,并输出到控制台屏幕上。

    2. 改变进制

    1. //Project - HexOct
    2. #include
    3. #include
    4. using namespace std;
    5. int main(){
    6. int b = 0x17; //十六进制 hexadecimal
    7. int c = 017; //八进制 octal
    8. int d = 0b01111110; //二进制 binary
    9. cout << "0x17 = " << b << ", 017 = " << c << ", 0b01111110 = " << d << endl;
    10. printf("17: %x, %d, %o\n", 17, 17, 17);
    11. cout << "17: " << hex << 17 << ", " << dec << 17 << ", " << oct << 17 << endl;
    12. hex(cout);
    13. cout << "17: " << 17 << ", ";
    14. dec(cout);
    15. cout << 17 << ", ";
    16. oct(cout);
    17. cout << 17 << endl;
    18. return 0;
    19. }

    上述代码的执行结果为:

    0x17 = 23, 017 = 15, 0b01111110 = 126

    17: 11, 17, 21

    17: 11, 17, 21

    17: 11, 17, 21

    上述代码可以看出,通过执行cout << hex,可以改变cout的内部状态,使用在后续输出数值时使用16进制。cout << dec (十进制),cout << oct (八进制)同理。

    事实上,这里的hex, dec, oct是一种被称之为操作算子(manipulator)的特殊函数。下述3行代码事实上等价:

    1. cout << hex;
    2. cout.operator<<(hex);
    3. hex(cout);

     在ios_base.h中我们可以找到hex()函数的定义:

    1. inline ios_base&
    2. hex(ios_base& __base)
    3. {
    4. __base.setf(ios_base::hex, ios_base::basefield);
    5. return __base;
    6. }

    在形式上,cout << hex被解释成多轮函数调用,首先是:

    cout.operator<<(hex);

    这个被重载的operator<<()函数将hex函数名当成一个函数指针,然后通过这个函数指针调用hex()函数:

    hex(cout);

    而hex()函数又通过cout的setf()函数发挥作用。读者或许会疑惑说,这么多层的函数调用是否会降低代码的执行效率,事实上,由于相关函数多是内联(inline)的,编译器的优化会消除这些“形式”上的不必要的函数调用。

    3. 输出宽度控制

    1. #include
    2. #include
    3. using namespace std;
    4. int main(){
    5. cout << "12345678901234567890" << endl;
    6. cout << "--------------------" << endl;
    7. cout.width(5);
    8. cout << "N";
    9. cout.width(15);
    10. cout << "2**N" << endl;
    11. cout << "--------------------" << endl;
    12. for (auto n=0;n<=10;n++){
    13. cout.width(5);
    14. cout << n;
    15. cout.width(15);
    16. cout << pow(2,n) << endl;
    17. }
    18. return 0;
    19. }上述代码的执行结果为:12345678901234567890
    20. --------------------
    21. N 2**N
    22. --------------------
    23. 0 1
    24. 1 2
    25. 2 4
    26. 3 8
    27. 4 16
    28. 5 32
    29. 6 64
    30. 7 128
    31. 8 256
    32. 9 512
    33. 10 1024

    cout的成员函数width( )可以设定下一个输出项的宽度,但其作用范围仅限后一个输出项。当输出项的实际宽度小于设定宽度时,其左侧以空格填充。可以看到,上述程序借助于width( )函数,输出了一个严格右对齐的表格,第一列的宽度为5,第2列的宽度为15。

    通过fill( )成员函数,可以修改填充字符。请参见下述程序及其执行结果。

    1. #include
    2. using namespace std;
    3. int main(){
    4. cout.fill('*'); //修改填充字符为*
    5. cout.width(5);
    6. cout << "idx";
    7. cout.width(15);
    8. cout << "content";
    9. return 0;
    10. }

    上述程序的执行结果为:

    **idx********content

    4. 浮点数的输出格式

    通过cout的precision( )函数可以设置其输出浮点数时的精度。见下述代码。

    1. #include
    2. using namespace std;
    3. int main(){
    4. float v1 = 17.90f;
    5. float v2 = 3.1415926535798932f;
    6. cout << "before .precision(2)" << endl;
    7. cout << "v1 = " << v1 << endl;
    8. cout << "v2 = " << v2 << endl;
    9. cout.precision(2);
    10. cout << "after .precision(2)" << endl;
    11. cout << "v1 = " << v1 << endl;
    12. cout << "v2 = " << v2 << endl;
    13. return 0;
    14. }

    执行结果为:

    before .precision(2)
    v1 = 17.9
    v2 = 3.14159
    after .precision(2)
    v1 = 18
    v2 = 3.1

    上述执行结果与我们的期望有很大不同。

    在默认情况下,cout输出浮点数的精度为6,且这个精度并不是指小数点后的位数,而是所有的位数。cout会借助于四舍五入的方法输出指定“精度”的字符串,同时会舍弃末尾多余的0。

    执行结果的第2行显示,17.90被舍弃掉末尾的0,输出为17.9。

    执行结果的第3行显示,3.1415926535798932被四舍五入为3.14159,正好6位数字。

    接下来,cout.precision(2)设定浮点数输出精度为2,此时,17.90被四舍五入输出为18,3.1415926535798932被四舍五入输出为3.1,都是两位数字。

    如果期望cout输出的浮点数的位数确定,当位数不足时用0补齐,可以执行cout.setf(ios_base::showpoint)。

    1. #include
    2. using namespace std;
    3. int main(){
    4. float v1 = 17.90f;
    5. float v2 = 3.1415926535798932f;
    6. cout.setf(ios_base::showpoint);
    7. cout.precision(4);
    8. cout << "v1 = " << v1 << endl;
    9. cout << "v2 = " << v2 << endl;
    10. return 0;
    11. }

    执行结果为:

    v1 = 1.7900e+001
    v2 = 3.1416e+000

     然后今天就讲到这里啦,大家记得点赞收藏,分享转发,关注小哥哥哦! 最后,如果你想学或者正在学C/C++编程,可以加入小编的编程学习C/C++企鹅圈https://jq.qq.com/?_wv=1027&k=vLNylJeG

  • 相关阅读:
    数据结构(c语言版本) 字符串操作
    Map集合
    自定义注解
    实现一个Windows环境一键启停Oracle的bat脚本
    使用kettle进行数据的多表关联
    python scanpy spatial空转全流程
    G-Ghost-RegNet实战:使用G-Ghost-RegNet实现图像分类任务(一)
    javeEE高校专业实训评价系统ssm
    解除OU屏蔽(EBS检查无法直接查询解决)
    一文讲通物联网&嵌入式
  • 原文地址:https://blog.csdn.net/m0_64407685/article/details/126525861