C++学习 之 初识头文件
声明:
本人自学C++, 没有计算机基础,在学习的过程难免会出现理解错误,出现风马牛不相及的现象,甚至有可能会贻笑大方。 如果有幸C++大牛能够扫到本人的博客,诚心希望大牛能给予批评与指正!不胜感激!
学习的过程分为初识、入门、进阶三个阶段。
因为对C++没有什么了解,这样的学习设定可能也有失准确性。望兄弟们多指点。谢谢!
目录:
科普---- 引用头文件
1. 引用头文件的作用
2. 头文件的结构及作用
3. 常用C++头文件及描述
4. 编写头文件
回顾
科普:
- 头文件的引用方式
今天我们要开始学习头文件了。还记得我们第一天学习时写的“Hello world!” 么?还记得头文件是怎么被引入的么?就是那个"hello world!"第一行代码啊!
啥你忘记了 ?回家跪方便面去,不许碎!哈哈,就是#inlude 这一行了。iostream 就是头文件,#include 是告诉程序,我现在需要引用这个文件的内容。
昨天我也问自己,<> 是干嘛的,现在我可以告诉自己,一个大于号一个小于号,两个符号标明了符号间的内容代表的是C++标准头文件。啥?你问我难道还有不标准的么?我X,你太聪明了,你就是天才啊。日后必成大器啊。
还有另外一种标识为头文件的符号是: “”, 对的,就是双引号。但是这种引用头文件的方式,并不能说不标准 ,那两人者的区别在哪里呢?一会儿我们会说到。
也就是说引用头文件有两种写法:
#include
#include "iostream"
那这两种写法有什么区别呢?区别可大了!
前者告诉程序,你要C++安装路径中库头文件默认存储路径下去找头文件,比如 我环境里就是/usr/inlude/C++/4.8 这个路径里查找。而后者,则告诉程序去源代码的相对路径去找。
,你可别问我啥叫相对路径啊~不理你,你逗我玩儿。
我们一起来了解头文件吧。
1. 引用头文件的作用
在了解头文件前,我们先了解下调用头文件有什么作用吧。
为了了解调用头文件的作用,先来看下istream 头文件的内容,为啥不直接看iostream呢?为啥啊~这怎么说呢,你难住我了。。。因为iostream只不过是把istream和ostream封装了下,这么说可以么?其实不完全正确的。大牛们勿喷,我觉得在初学C++的时候,这样理解是最容易理解的。
关于iostream标准库介绍比较详细的可以看http://www.cppblog.com/yuqilin1228/archive/2010/03/26/110620.html
我还没有能力理解那么深入。。嘿嘿,慢慢来。
但是这不影响所了解引用头文件的作用:调用了头文件,就等于赋予了调用某些函数的权限。不好理解么?那这样吧,你把头文件想象成一个厨柜,里面有各种厨具。一个厨师学徒就是我们的源代码,大厨就是编译器。这时 厨师学徒(源代码)想要学炒菜(编译源代码),去找大厨指点(找G++编译器),大厨跟他说,第一步,你看到那个?柜(调用了头文件)没?学徒说看到了,大厨说你去那个厨柜里拿厨具(给了学徒使用厨柜里厨具的权限)。
我个去,我要把自己绕晕了。。。。。你明白没?当然G++编译源代码的过程可能跟我描述的过程不一样啊,这里的主要的目的也不是为了说明编译过程,而是想说明调用头文件的作用。
那么引用头文件作用也就是:
1. 指导编译器查寻头文件的路径
2. 给源代码使用库文件内容的权限
2. 头文件的结构及作用
我们知道调用头文件,便有了使用头文件中的函数的权限。那么头文件本身是用来干嘛的呢?通过查看头文件的内容,我们会发现头文件本身只进行声明或者定义函数、类结构、数据接口等。
那我们先来看看头文件吧。
想要查看头文件,我们首先应该知道C++的头文件存储在哪里吧?嘿嘿,你不知道了吧?来来来,见证神奇的时刻到了:C++的标准头文件一般情况下存放在/usr/include/c++/$releaseOfC++
比如我现在刚开始学C++,相对于我这个时代来说已经是稳定版里最高版本了,是4.8的,那我可以到/usr/include/c++/4.8 这个路径下去查看C++的标准头文件。
这里为了节省篇副,我选了一个比较小的头文件:typeinfo
// RTTI support for -*- C++ -*-
// Copyright (C) 1994-2013 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>. /** @file typeinfo
* This is a Standard C++ Library header.
*/ #ifndef _TYPEINFO
#define _TYPEINFO #pragma GCC system_header #include <exception>
#if __cplusplus >= 201103L
#include <bits/hash_bytes.h>
#endif #pragma GCC visibility push(default) extern \"C++\" { namespace __cxxabiv1
{
class __class_type_info;
} // namespace __cxxabiv1 // Determine whether typeinfo names for the same type are merged (in which
// case comparison can just compare pointers) or not (in which case strings
// must be compared), and whether comparison is to be implemented inline or
// not. We used to do inline pointer comparison by default if weak symbols
// are available, but even with weak symbols sometimes names are not merged
// when objects are loaded with RTLD_LOCAL, so now we always use strcmp by
// default. For ABI compatibility, we do the strcmp inline if weak symbols
// are available, and out-of-line if not. Out-of-line pointer comparison
// is used where the object files are to be portable to multiple systems,
// some of which may not be able to use pointer comparison, but the
// particular system for which libstdc++ is being built can use pointer
// comparison; in particular for most ARM EABI systems, where the ABI
// specifies out-of-line comparison. The compiler\'s target configuration
// can override the defaults by defining __GXX_TYPEINFO_EQUALITY_INLINE to
// 1 or 0 to indicate whether or not comparison is inline, and
// __GXX_MERGED_TYPEINFO_NAMES to 1 or 0 to indicate whether or not pointer
// comparison can be used. #ifndef __GXX_MERGED_TYPEINFO_NAMES //预处理块
// By default, typeinfo names are not merged.
#define __GXX_MERGED_TYPEINFO_NAMES 0
#endif // By default follow the old inline rules to avoid ABI changes.
#ifndef __GXX_TYPEINFO_EQUALITY_INLINE
#if !__GXX_WEAK__
#define __GXX_TYPEINFO_EQUALITY_INLINE 0
#else
#define __GXX_TYPEINFO_EQUALITY_INLINE 1
#endif
#endif //预处理结束 namespace std // 声明了命名空间STD
{
/**
* @brief Part of RTTI.
*
* The @c type_info class describes type information generated by
* an implementation.
*/
class type_info
{
public:
/** Destructor first. Being the first non-inline virtual function, this
* controls in which translation unit the vtable is emitted. The
* compiler makes use of that information to know where to emit
* the runtime-mandated type_info structures in the new-abi. */
virtual ~type_info(); /** Returns an @e implementation-defined byte string; this is not
* portable between */
const char* name() const _GLIBCXX_NOEXCEPT
{ return __name[] == \'*\' ? __name + 1 : __name; } #if !__GXX_TYPEINFO_EQUALITY_INLINE
// In old abi, or when weak symbols are not supported, there can
// be multiple instances of a type_info object for one
// type. Uniqueness must use the _name value, not object address.
bool before(const type_info& __arg) const _GLIBCXX_NOEXCEPT;
bool operator==(const type_info& __arg) const _GLIBCXX_NOEXCEPT;
#else
#if !__GXX_MERGED_TYPEINFO_NAMES
/** Returns true if @c *this precedes @c __arg in the implementation\'s
* collation order. */
// Even with the new abi, on systems that support dlopen
// we can run into cases where type_info names aren\'t merged,
// so we still need to do string comparison.
bool before(const type_info& __arg) const _GLIBCXX_NOEXCEPT
{ return (__name[] == \'*\' && __arg.__name[0] == \'*\')
? __name < __arg.__name
: __builtin_strcmp (__name, __arg.__name) < ; } bool operator==(const type_info& __arg) const _GLIBCXX_NOEXCEPT
{
return ((__name == __arg.__name)
|| (__name[] != \'*\' &&
__builtin_strcmp (__name, __arg.__name) == ));
}
#else
// On some targets we can rely on type_info\'s NTBS being unique,
// and therefore address comparisons are sufficient.
bool before(const type_info& __arg) const _GLIBCXX_NOEXCEPT
{ return __name < __arg.__name; } bool operator==(const type_info& __arg) const _GLIBCXX_NOEXCEPT
{ return __name == __arg.__name; }
#endif
#endif
bool operator!=(const type_info& __arg) const _GLIBCXX_NOEXCEPT
{ return !operator==(__arg); } #if __cplusplus >= 201103L
size_t hash_code() const noexcept
{
# if !__GXX_MERGED_TYPEINFO_NAMES
return _Hash_bytes(name(), __builtin_strlen(name()),
static_cast<size_t>(0xc70f6907UL));
# else
return reinterpret_cast<size_t>(__name);
# endif
}
#endif // C++11 // Return true if this is a pointer type of some kind
virtual bool __is_pointer_p() const; // Return true if this is a function type
virtual bool __is_function_p() const; // Try and catch a thrown type. Store an adjusted pointer to the
// caught type in THR_OBJ. If THR_TYPE is not a pointer type, then
// THR_OBJ points to the thrown object. If THR_TYPE is a pointer
// type, then THR_OBJ is the pointer itself. OUTER indicates the
// number of outer pointers, and whether they were const
// qualified.
virtual bool __do_catch(const type_info *__thr_type, void **__thr_obj,
unsigned __outer) const; // Internally used during catch matching
virtual bool __do_upcast(const __cxxabiv1::__class_type_info *__target,
void **__obj_ptr) const; protected:
const char *__name; explicit type_info(const char *__n): __name(__n) { } private:
/// Assigning type_info is not supported.
type_info& operator=(const type_info&);
type_info(const type_info&);
}; /**
* @brief Thrown during incorrect typecasting.
* @ingroup exceptions
*
* If you attempt an invalid @c dynamic_cast expression, an instance of
* this class (or something derived from this class) is thrown. */
class bad_cast : public exception
{
public:
bad_cast() _GLIBCXX_USE_NOEXCEPT { } // This declaration is not useless:
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual ~bad_cast() _GLIBCXX_USE_NOEXCEPT; // See comment in eh_exception.cc.
virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
}; /**
* @brief Thrown when a NULL pointer in a @c typeid expression is used.
* @ingroup exceptions
*/
class bad_typeid : public exception
{
public:
bad_typeid () _GLIBCXX_USE_NOEXCEPT { } // This declaration is not useless:
// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
virtual ~bad_typeid() _GLIBCXX_USE_NOEXCEPT; // See comment in eh_exception.cc.
virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
};
} // namespace std } // extern \"C++\" #pragma GCC visibility pop #endif
通过这个文件,我们发现,C++的标准头文件,主要包含三个部分:
1、头文件开始处的版权和版本声明
2、预处理块
3、函数和类结构声明部分等。
啥你问我,我是怎么知道有函数和类结构的?
这个么。。。嘿嘿,俺还学过shell的。对比下就猜到了。
函数的结构一般是这样的:
function_name()
{
………………
}
至于类嘛 ?class 英文翻译过来不就是类么?嘿嘿
你现在看这个头文件会不会跟我一样一头露水呢?我就纳闷了,这都啥东西啊?class是啥东西啊?namespace 又是啥东东啊?const 这又是个啥东西啊?
以前很多次,我在学东西的时候,一遇到这种情况,我就会想,XX,好难啊,这都什么东西啊,怎么一开始就让我看这么复杂、晦涩难懂的东西呢。。什么逻辑嘛!
如果你是跟我一样的,不要急,我们这里,只是想来说明头文件包含了哪些东西,弄清楚头文件本身是干嘛的,这就足够了,至于要看懂头文件的内容,我们后面一起学习,相信不久看懂它,还不如探囊取物一般?嘿嘿
都知道了头文件的组成了,还不知道头文件的作用么?就是声明函数和类结构啊~
现在,我们知道了头文件的作用(声明函数、类结构等),调用头文件的作用(使我们拥有直接调用头文件中的函数、类的权限)。眼珠子一转,我瞬间明白了,发明头文件的人,真的是熊才大略啊。
居然能想到这么牛的方式来简化我们的工作。为啥这么说呢?你想啊,函数、类结构等在头文件中声明过了,我们在编写源文件过程中,当需要使用某个函数时,如果已经在头文件中声明过,那我们直接调用就可以了啊,不用重新编写了呢!这不就简化了我们的工作么!
头文件的最大贡献,作为初学者看来,就是实现了代码的重用(在同一个源文件中可以多次使用)和共用(在不同源文件甚至不同工程中都可以共用同一个头文件)。
3. C++ 常用头文件及描述
C++都有哪些常用的头文件呢?每个头文件的具体作用又是什么呢?
4. 编写头文件
555555…… 现在怎么可能实现呢?
通过第二步的分析我们知道头文件的主体部分包含两层内容,一层是引用另外一些头文件,这个没问题啊,不就是#inlude <头文件>么,但是另一部分是声明函数、类结构等信息啊。。。
别灰心,别丧气,等我们学习了函数、类以后,再写头文件还不手到摛来?嗯嗯,就是这样,必须的,要循序渐进!
等学会编写头文件了,再把连接搞过来,嗯,就这么定了!
回顾:
通过这一节的学习,我们学习了哪些东西呢?来复习一下:
1. 如何调用头文件
2. 调用头文件的作用是什么
3. 头文件本身的作用是什么
4. 使用头文件的好处是什么
5. 头文件的组成结构是怎样的
6. 关于编写头文件。。。。这个还没学会,放后面再说吧。嘿嘿
C++学习 之 初识头文件的更多相关文章
- C++学习——输入输出及头文件
C++学习 ——输入输出及头文件 一.输入输出 (1)cin与cout C++中也可以用printf与scanf,但是相对于这个,cin与cout更加方便一点.让我们先来看一段代码. 运行结果: 这里 ...
- Python学习笔记7 头文件的添加规则(转载)
转载自:https://www.cnblogs.com/taurusfy/p/7605787.html ************************************************ ...
- [转]Linux学习笔记——例说makefile 头文件查找路径
0.前言 从学习C语言开始就慢慢开始接触makefile,查阅了很多的makefile的资料但总感觉没有真正掌握makefile,如果自己动手写一个makefile总觉得非常吃力.所以特意借助 ...
- 内存管理pbuf.h头文件源码解析——LwIP学习
声明:个人所写所有博客均为自己在学习中的记录与感想,或为在学习中总结他人学习成果,但因本人才疏学浅,如果大家在阅读过程中发现错误,欢迎大家指正. LwIP的内核(core文件夹)文件中pbuf.c是包 ...
- Linux学习笔记——例说makefile 头文件查找路径
0.前言 从学习C语言開始就慢慢開始接触makefile,查阅了非常多的makefile的资料但总感觉没有真正掌握makefile,假设自己动手写一个makefile总认为非常吃力.所以特意借 ...
- linux学习,c语言头文件分类总结
1.includee 称为文件包含命令,其意义是把尖括号""或引号<>内指定的文件包含到本程序来,成为本程序的一部分.被包含的文件通常是由系统提供的,其扩展名为.h.因 ...
- C++学习笔记(一):头文件和源文件
说明: 当一个源文件(a.cpp)要调用另一个源文件(b.cpp)定义的方法时,需要在a.cpp中写上这个方法的声明(只需要该方法的名称.返回值和参数,类似Java的接口): 如果每次调用其他文件的方 ...
- 51单片机C语言学习笔记6:51单片机C语言头文件及其使用
很多初学单片机者往往对C51的头文件感到很神秘,而为什么要那样写,甚至有的初学者喜欢问,P1口的P为什么要大写,不大写行不行呢?其实这个是在头文件中用sfr定义的,现在定义好了的是这样的 sfr P1 ...
- Android(java)学习笔记260:JNI之native方法头文件的生成
1. JDK1.6 ,进入到工程的bin目录下classes目录下: 使用命令: javah packageName.ClassName 会在当前目录下生成头文件,从头文件找到jni协议方法 下面举 ...
随机推荐
- 6.Shell 计划任务服务程序
计划任务服务程序 经验丰富的系统运维工程师可以使得Linux在无需人为介入的情况下,在指定的时间段自动启用或停止某些服务或命令,从而实现运维的自动化. 如何设置服务器的计划任务服务,把周期性.规律性的 ...
- BZOJ 1001 平面图转对偶图
原图的面转成点,原图的边依旧边,只是连接的是两个面. 对偶图的点数=原图的面数 对偶图的边数=原图的边数(如果原边只属于一个面,则它为环边) #include<bits/stdc++.h> ...
- 一次完整的HTTP请求所经历的7个步骤【转】
HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤: 1. 建立TCP连接 在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该 ...
- Mysql 5.6主从同步配置
主从同步,本质是利用数据库日志,将主库数据复制一份到从库,本质上是使用了数据复制技术. 本文概要 主库的基本配置 从库的基本配置 完全同步的步骤 注意事项 工作原理 1. 主库的基本配置 做两件事:启 ...
- c++关于字符串的读入和截取
#include<iostream>#include<string>#include<vector>using namespace std;vector<st ...
- MySQL数据库MyISAM存储引擎转为Innodb
MySQL数据库MyISAM存储引擎转为Innodb 之前公司的数据库存储引擎全部为MyISAM,数据量和访问量都不是很大,所以一直都没什么问题.但是最近出现了MySQL数据表经常被锁的情况,直接导 ...
- linux编译esp8266
编译工具是xtensa-lx106-elf-gcc,一般会在~/.bashrc文件下添加 export PATH="$HOME/esp-open-sdk/xtensa-lx106-elf/b ...
- Hadoop-No.5之压缩
Hadoop存储数据时需要着重考虑的一个因素就是压缩.这里不仅要满足节省存储空间的需求,也要提升数据处理性能.在处理大量数据时,消耗最大的是磁盘和网络的I/O,所以减少需要读取或者写入磁盘的数据量就能 ...
- 【Winform-自定义控件】ImageButton 支持鼠标正常、悬停、按下更改图片,支持文本
原文地址:https://www.codeproject.com/Articles/29010/WinForm-ImageButton 自定义winfrom图片按钮:支持鼠标正常.悬停.按下更改图片, ...
- docker安装redis并允许外网访问
拉取redis镜像 docker pull redis:3.2 本地新建redis配置文件 redis.conf ,写入以下内容 #允许外网访问bind 0.0.0.0 daemonize NO pr ...