目录
一、头文件命名
C++中头文件是不带扩展名的,如#include <iostream>,与C中带扩展名区分开,如#include <stdio.h>,部分属于C的头文件被转换成C++中的头文件,文件名会加上c前缀,如math.h转换成cmath,这种转换不只是名称转换,也会增加属于C++的特性,如名称空间。
二、名称空间
1、名称空间使用
名称空间相当于包名,允许不同名称空间下有相同的类名或者函数名,使用using编译指令表示当前使用的类或者函数来自于哪个名称空间下,名称空间有如下多种写法,以标准库的名称空间std为例。
//声明在函数外面则对该文件的所有函数都有效
using namespace std;
int main()
{
//using属于编译指令,名称空间相当于包名,允许不同名称空间下存在相同的类名或者函数,using指定使用的名称空间
//可直接使用std下的所有类或者函数
//声明在函数内则只在当前函数内有效
using namespace std;
cout << "Hello World!";
cout << endl;
//直接使用std下的cout
std::cout <<"Hello World!";
std::cout << endl;
//声明只使用std空间下的cout
using std::cout;
cout << "Hello World!";
cout << endl;
return 0;
}
2、名称空间定义
注意名称空间是开放的或者是不连续的,可以把名称加入到一个已经存在的名称空间中,在匿名名称空间内定义的变量或者函数相当于加了static关键字,即只有在定义的文件内才能访问。
头文件namesp.h
// namesp.h
#include <string>
#ifndef NAMESP
#define NAMESP 1
namespace pers
{
struct Person
{
std::string fname;
std::string lname;
};
void getPerson(Person &);
}
//名称空间是开放的,可以把新的名称加入到已有的名称空间
namespace pers{
void showPerson(const Person &);
}
namespace debts
{
//定义内部名称空间,合并编译报错debts::inter::name 的多重定义,应该是GCC未完全支持这种写法
// namespace inter{
// using std::string;
// string name="test";
// }
//将pers名称空间中定义的名称导入到debs,可以通过debs直接访问debs中的名称
using namespace pers;
struct Debt
{
Person name;
double amount;
};
void getDebt(Debt &);
void showDebt(const Debt &);
double sumDebts(const Debt ar[], int n);
}
//定义名称空间别名
//namespace mypers=debts::inter;
namespace mypers=debts;
//不支持这种形式,报错pers找不到,但是可以通过debts防范pers中的名称
//namespace mypers=debts::pers;
//匿名的名称空间,相当于static int count=1
namespace{
int count=1;
}
#endif
函数实现 namesp.cpp
#include <iostream>
#include "namesp.h"
namespace pers
{
using std::cout;
using std::cin;
void getPerson(Person & rp)
{
cout << "Enter first name: ";
cin >> rp.fname;
cout << "Enter last name: ";
cin >> rp.lname;
}
void showPerson(const Person & rp)
{
std::cout << rp.lname << ", " << rp.fname;
}
}
namespace debts
{
void getDebt(Debt & rd)
{
getPerson(rd.name);
std::cout << "Enter debt: ";
std::cin >> rd.amount;
}
void showDebt(const Debt & rd)
{
showPerson(rd.name);
std::cout <<": $" << rd.amount << std::endl;
}
double sumDebts(const Debt ar[], int n)
{
double total = 0;
for (int i = 0; i < n; i++)
total += ar[i].amount;
return total;
}
}
调用函数 main.cpp
#include <iostream>
#include "namesp.h"
int main(){
using namespace mypers;
Person a={"te","tb"};
Debt debt={a,1.2};
getPerson(a);
showPerson(a);
showDebt(debt);
std::cout << count;
return 0;
}
参考:C++/C++11中命名空间(namespace)的使用
3、iostream头文件定义解析
//ifndef和define配合使用防止头文件重复引入
#ifndef _GLIBCXX_IOSTREAM
#define _GLIBCXX_IOSTREAM 1
//GCC编译器使用,在源代码中加入版本信息等
#pragma GCC system_header
#include <bits/c++config.h>
#include <ostream>
#include <istream>
//标准用法中std后面是没有_GLIBCXX_VISIBILITY(default)
//这个是宏函数,最终转换成__attribute__ ((__visibility__ (default)))
//__attribute__是GCC特有的扩展用法,该关键字用于高速编译器特定的信息,这里是可见性相关的
namespace std _GLIBCXX_VISIBILITY(default)
{
//跟下面的_GLIBCXX_END_NAMESPACE_VERSION配合使用,通常情形下无意义
_GLIBCXX_BEGIN_NAMESPACE_VERSION
//此处extern关键字表示使用其他文件中已经定义的cin
extern istream cin; /// Linked to standard input
extern ostream cout; /// Linked to