• (6)第2章的尾巴~


    2.6.3编写自己的头文件P67中提到:“库类型string在名为string的头文件中定义。又如,我们应该把Sales_data类定义在名为Sales_data.h的头文件中”,后面又提到:“例如,我们的Sales_data类包含有一个string成员,所以Sales_data.h必须包含string.h头文件。”

    在这我有几个疑问:

    1.string头文件和string.h头文件是两种类?区别?

    参考:https://www.zhihu.com/question/66475735到处挖坑蒋玉成暮无井见铃等回答,顺便发现一个好东西,C++的中文参考手册:

    照例自己总结一下:

    1.查答案的Sales_data和Sales_item头文件,看看里面的代码就发现其实只引用了<string>,所以书里写错了,所有的string.h就是string才对。


    2.这玩意又是历史遗留问题,和HTML5标签的"/"问题差不多.由此看来很多东西不懂的时候可以考虑考虑会不会又是历史原因。

    C++ 倾向标准库头文件无后缀,而第三方库头文件使用 .h/.hpp 后缀。来自 C 的头文件都换了 cxxxx 的马甲,可能是因为写成 xxxx.h 就显得像非标准库。

    (操作系统提供的库,比如<unistd.h>或者<windows.h>还是留着.h的)


    3.发现了一个好网站,C和C++的参考手册,之前都不知道有这东西:
    中文:http://zh.cppreference.com/w/首页
    我是对照着看了,谁让我英语差呢.....(底部有切换语言的地方。)


    4.几个回答的评论里有好东西,比如:

    标准保证的是 xxxx.h ( C++ 版本)有和 cxxxx 同样的名称,只不过前者的在全局,后者的在 std 。但也允许前者把名字放入 std ,后者把名字放入全局。

    一般实现都是 xxxx.h 兼容 C 和 C++ ,不考虑 std (但要考虑 extern "C" ),而 cxxxx 包含 xxxx.h 后再把标准规定的名称导入 std 。

    2.系统定义的类是不是都不加.h,自己定义的类才加.h,以此来区分系统类和自定义类?

    1. 见第一个问题里的2;

    2.自定义头文件不写后缀名会被gcc编译器认为是未知文件所以你仍然需要写.h……

    预处理器概述

    在上一篇文章中,使用Sales_data的程序就先后两次包含了string头文件:一次直接包含的,为了能使用string类;另一次是隐式包含进来的,即Sales_data类定义时用到的那个string头文件。由于我写的时候Sales_data类是定义在主函数外面的,所以实际上只包含了一次string头文件——只有你把Sales_data类定义在另一个文件(头文件)中,才会出现开头提到的情况,那个时候你不仅要#include <string>还要include<Sales_data.h>(头文件一旦改变,相关的源文件必须重新编译才能获取更新的声明,注意是重新编译!重新编译一遍!)

    基于上述描述,你会发现有必要在书写头文件时做适当处理,不然多次包含的情况很可能就不能正常和安全地工作了。

    于是引入了预处理器来解决这个问题。(常用的技术,可能还有别的)

    这个技术是从C语言继承过来的,她可以部分地改变我们所写的程序,之前的#inclued就是一项预处理功能(预处理器看到这个标记会用指定的头文件内容代替#include)

    这里新引入的预处理器功能是头文件保护符(head guard):

    //检查变量指定的预处理变量是否已经定义——当且仅当变量已定义时为真
    //ifndef=if not define
    #ifndef SALES_DATA_H
    //预处理变量有两种状态,这里把一个名字设定为预处理变量
    #define SALES_DATA_H
    #include <string>
    struct Sales_data
    {
    	std::string bookNo;
    	unsigned units_sold = 0;
    	double revenue = 0.0;
    };
    //结束
    #endif
    /*
    *除了ifndef还有个ifdef,用法很像if else,只不过是用来预处理而已。先这样理解:
    *第一次包含Sales_data时,ifndef为真,继续执行define定义预处理量即头文件名,然后就会把在endif前的内容拷贝到程序
    *第二次遇到时,ifndef为假,就结束了。
    */
    //预处理变量无视C++中关于作用域的规则
    

    这一节的课后习题就不贴了,很简单,上面的代码写在头文件里,放在程序文件夹,引用即可。

    微软自己也弄了一种机制,但是不能跨平台,所以最好还是用上面说的那种,详细可以参考文章(其中还说了头文件保护符的缺点,没看懂):

    http://blog.csdn.net/zlhy_/article/details/8192580

    什么是预处理变量?P68

    其实到了这里,我发现在有规定的用法上,与其百度文章看或是知乎,不如直接看参考手册!那才是最正确的!很多文章都是根据自己使用的“经验”去说的,这就难免与手册所言有差别!所以,以后这种问题,只要看作者分析优缺点就够了,用法上不必太理会!

    wuduojia
  • 相关阅读:
    Leetcode_02【两数相加】——【难度:中】
    Leetcode_39【组合总和】
    Leetcode_38【报数】
    Leetcode_36【有效的数独】
    Leetcode_35【搜索插入位置】
    51nod1347 旋转字符串
    WebH
    ExcelHelper
    文件二进制与String相互转换
    汇编语言里 eax, ebx, ecx, edx, esi, edi, ebp, esp
  • 原文地址:https://www.cnblogs.com/wuduojia/p/7648886.html
Copyright © 2020-2023  润新知