C++中頭文件的概念與基本編寫方法
1 標(biāo)準(zhǔn)庫(kù)中的頭文件
C++標(biāo)準(zhǔn)庫(kù)中的一切內(nèi)容都被放在名字空間std中(名字空間中的內(nèi)容對(duì)外是不可見(jiàn)的),但是帶來(lái)了一個(gè)新問(wèn)題,無(wú)數(shù)現(xiàn)有的C++代碼都依賴于使用了多年的偽標(biāo)準(zhǔn)庫(kù)中的功能,如聲明在<iostream.h>等頭文件中的功能,使用std包裝標(biāo)準(zhǔn)庫(kù)導(dǎo)致現(xiàn)有代碼的不可用,為了兼容這種情況,標(biāo)準(zhǔn)委員會(huì)為包裝了std的那部分標(biāo)準(zhǔn)庫(kù)創(chuàng)建了新的頭文件,新的頭文件的文件名與舊的一樣,只是沒(méi)有.h這個(gè)后綴,如<iostream.h>就變成了<iostream>。對(duì)于C頭文件,采用同樣的方法,但還在每個(gè)頭文件名前加了字符c,如<string.h>就變成了<cstring>,<stdio.h>變成了<cstdio>。最好使用新的文件頭,使用新的文件頭的C++程序,需要使用using namespace std或者using namespace std::指定的類名,等方法來(lái)使需要的類對(duì)于我們的代碼可視。
2 自定義的頭文件
為了防止頭文件被重復(fù)引用,最好使用預(yù)處理定義,如下所示:
#ifndef MYHEAD_H #define MYHEAD_H ……//頭文件中的內(nèi)容 #endif
(1)#ifndef:
指示符#ifndef用來(lái)檢查頭文件的內(nèi)容是否在前面已經(jīng)被定義過(guò),如果定義過(guò),則#ifndef與#endif之間的語(yǔ)句將不被執(zhí)行.所以習(xí)慣上要把頭文件的定義寫在這兩個(gè)語(yǔ)句之間.
如:對(duì)于MYHEAD.H這個(gè)頭文件
#ifndef MYHEAD_H #define MYHEAD_H #include "myhead.h" ...... #endif
(2) #ifdef
指示符#ifdef常常被用來(lái)判斷一個(gè)預(yù)處理器常量是否已被定義,以便有條件地包含程序代碼。
如:
int main()
{
#ifdef DEBUG
cout<<"Beginning execution of main()\n";
#endif
string word;
vector<string> text;
while(cin>>word)
{
#ifdef DEBUG
cout<<"word read:"<<word<<"\n";
#endif
text.push_back(word);
}
//..... }
在此程序中,如果定義了DEBUG,則其中包含的兩個(gè)語(yǔ)句都將被執(zhí)行,如果沒(méi)有定義,則其中的兩個(gè)輸出語(yǔ)句不被執(zhí)行。
3 預(yù)處理相關(guān)知識(shí)
(1) #ifdef :判斷一個(gè)預(yù)處理常量是否被定義,如#infef DEGUG
(2) #ifndef:判斷一個(gè)預(yù)處理常量是否沒(méi)被定義
(3) #define:定義一個(gè)預(yù)處理常量,如#define DEBUG
(4) #include
(5) #endif
(6) 對(duì)預(yù)處理常量的定義還可以在編譯時(shí)進(jìn)行,如CC –D DEBUG main.c
(7)編譯C++程序時(shí),編譯器自動(dòng)定義了一個(gè)預(yù)處理器名字__cplusplus(注意前面有兩個(gè)下劃線),因此可以根據(jù)這個(gè)來(lái)判斷該程序是否是C++程序,以便有條件地包含一些代碼,如:
#ifndef MYHEAD_H
#define MYHEAD_H
#ifdef __cplusplus
extern "C" {
#endif
int DMpostprocessing();
#ifdef __cplusplus
}
#endif
#endif
(8)在編譯C程序時(shí),編譯器會(huì)自動(dòng)定義預(yù)處理常量__STDC__。當(dāng)然__cplusplus和__STDC__ 不會(huì)同時(shí)被定義;
(9)另外兩個(gè)比較有用的預(yù)定義常量是__LINE__(記錄文件已經(jīng)被編譯的行數(shù))和__FILE__(包含正在被編譯的文件名稱)。使用如下:
if(element_count==0) cerr<<"Error:"<<__FILE__ <<":line"<<__LINE__ <<"element_count must be non-zero.\n";
(10) __DATE__:編譯日期,當(dāng)前被編譯文件的編譯日期
(11) __TIME__:編譯時(shí)間,當(dāng)前被編譯文件的編譯時(shí)間
格式如:hh:mm:ss
08:17:05 Oct 31 2006
(12) C庫(kù)頭文件的C++名字總是以字母C開頭,后面去掉.h,如assert.h在C++中為cassert;
assert()是C語(yǔ)言標(biāo)準(zhǔn)庫(kù)中提供的一個(gè)通用預(yù)處理器宏。常用其來(lái)判斷一個(gè)必需的前提條件,以便程序能夠正確執(zhí)行。與其關(guān)聯(lián)的頭文件是:#include <assert.h>
如:
assert(filename!=0);
表示:如果后面的程序能夠正確執(zhí)行,需要filename不為0,如是條件為假,即其等于0,斷言失敗,則程序?qū)⑤敵鲈\斷消息,然后終止。
其c++名字是:cassert
C庫(kù)頭文件的C++名字總是以字母C開頭
注:在C++中使用C標(biāo)準(zhǔn)庫(kù)中的頭文件時(shí),一定要使用using namespace std;來(lái)使其處在一個(gè)名字空間中,才能正確使用
(13)在C++中頭文件后綴各不相同,因此標(biāo)準(zhǔn)的C++頭文件沒(méi)有指定后綴
4 C++中的文件輸入輸出
頭文件:#include <fstream>
使用文件輸入輸出實(shí)例:
#include <fstream>
//為了打開一個(gè)輸出文件,先聲明一個(gè)ofstream類型的對(duì)象:
ofstream outfile("name-of-file");
//為了測(cè)試是否已經(jīng)成功打開了一個(gè)文件,如下判斷:
//如文件不能打開值為false
if(!outfile)
cerr<<"Sorry! We were unable to open the file!\n";
//為了打開一個(gè)輸入文件,先聲明一個(gè)ifstream類型的對(duì)象:
ifstream infile("name of file");
if(!infile)
cerr<<"Sorry! We were unable to open the file!\n";
一個(gè)簡(jiǎn)單程序:
#include <iostream>
#include <fstream>
#include <string>
int main()
{
ofstream outfile("out_file");
ifstream infile("in_file");
if(!infile){
cerr<<"error:unable to open input file!\n";
return -1;
}
if(!outfile) {
cerr<<"error:unable to open output file!\n";
return -2;
}
string word;
while (infile>>word)
outfile<<word<<' ';
return 0;
}
頭文件里有些什么?
頭文件的使用主要體現(xiàn)在兩個(gè)方面,一個(gè)是重(音chóng)用(即多次使用),另一個(gè)是共用。
那些提供標(biāo)準(zhǔn)庫(kù)函數(shù)的頭文件就是為了重用。很多程序或工程可能會(huì)用到這些標(biāo)準(zhǔn)庫(kù)函數(shù),把它們寫在頭文件里面,每次使用的時(shí)候只需要包含已經(jīng)完成的頭文件就可以了。
頭文件的共用主要體現(xiàn)在C++的多文件結(jié)構(gòu)中。由于目前的程序規(guī)模較小,尚不需要用到多文件結(jié)構(gòu),所以在此對(duì)頭文件的共用不作展開。有興趣的讀者可以查閱相關(guān)書籍。
那么,如果我們要自己編寫一個(gè)可以重用的頭文件,里面應(yīng)該寫些什么呢?
類似于標(biāo)準(zhǔn)庫(kù)函數(shù),我們?cè)陬^文件里面應(yīng)該模塊化地給出一些函數(shù)或功能。另外還應(yīng)該包括獨(dú)立實(shí)現(xiàn)這些函數(shù)或功能的常量、變量和類型的聲明。
下面我們就來(lái)看一個(gè)頭文件應(yīng)用的實(shí)例:
//shape.h
#include "math.h"http://在計(jì)算三角形面積時(shí)要用到正弦函數(shù)
const double pi=3.14159265358;//常量定義
struct circle//類型聲明
{
double r;
};
struct square
{
double a;
};
struct rectangle
{
double a,b;
};
struct triangle
{
double a,b,c,alpha,beta,gamma;
};
double perimeter_of_circle(double r)//函數(shù)定義
{
return 2*pi*r;
}
double area_of_circle(double r)
{
return pi*r*r;
}
double perimeter_of_square(double a)
{
return 4*a;
}
double area_of_square(double a)
{
return a*a;
}
double perimeter_of_rectangle(double a,double b)
{
return 2*(a+b);
}
double area_of_rectangle(double a,double b)
{
return a*b;
}
double perimeter_of_triangle(double a,double b,double c)
{
return a+b+c;
}
double area_of_triangle(double a,double b,double gamma)
{
return sin(gamma/180*pi)*a*b/2;
}
//main.cpp
#include "iostream.h"
#include "shape.h"http://包含我們編寫好的shape.h
int main()
{
circle c={2};
square s={1};
rectangle r={2,3};
triangle t={3,4,5,36.86989,53.13011,90};
cout <<"Perimeter of circle " <<perimeter_of_circle(c.r) <<endl;
cout <<"Area of square " <<area_of_square(s.a) <<endl;
cout <<"Perimeter of rectangle " <<perimeter_of_rectangle(r.a,r.b) <<endl;
cout <<"Area of triangle " <<area_of_triangle(t.b,t.c,t.alpha) <<endl;
return 0;
}
運(yùn)行結(jié)果:
Perimeter of circle 12.5664 Area of square 1 Perimeter of rectangle 10 Area of triangle 6
我們編寫好了shape.h頭文件,以后用到計(jì)算圖形周長(zhǎng)或面積的時(shí)候,就不需要重新編寫函數(shù)了,只需要包含這個(gè)頭文件就行了。
相關(guān)文章
C++17文件系統(tǒng)庫(kù)之std::filesystem 示例詳解
std::filesystem是C++17引入的一個(gè)強(qiáng)大且易用的文件系統(tǒng)操作庫(kù),它提供了跨平臺(tái)的文件系統(tǒng)操作接口,簡(jiǎn)化了文件和目錄操作的代碼實(shí)現(xiàn),本文給大家介紹C++17文件系統(tǒng)庫(kù)之std::filesystem 示例詳解,感興趣的朋友一起看看吧2025-03-03
深入理解約瑟夫環(huán)的數(shù)學(xué)優(yōu)化方法
本篇文章是對(duì)約瑟夫環(huán)的數(shù)學(xué)優(yōu)化方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
解決c++?error:crosses?initialization?of?問(wèn)題
最近在寫代碼的時(shí)候,碰到了?crosses?initialization?of?...?的問(wèn)題,只因我在?switch?的某個(gè)?case?分支下定義了一個(gè)變量,于是乎便將這個(gè)問(wèn)題整理一下,需要的朋友可以參考下2023-03-03
VSCode 搭建 Arm 遠(yuǎn)程調(diào)試環(huán)境的步驟詳解
這篇文章主要介紹了VSCode 搭建 Arm 遠(yuǎn)程調(diào)試環(huán)境的步驟詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Visual Studio調(diào)試C/C++教程指南
VisualStudio是微軟開發(fā)的一款集成開發(fā)環(huán)境軟件,本文主要介紹了Visual Studio調(diào)試C/C++教程指南,熟悉地掌握基于VS的C/C++調(diào)試技術(shù),可以大幅提升調(diào)試性能,感興趣的可以了解一下2024-06-06
C++字符數(shù)組的輸入輸出和字符串結(jié)束標(biāo)志使用講解
這篇文章主要介紹了C++字符數(shù)組的輸入輸出和符串結(jié)束標(biāo)志使用講解,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-09-09
stringstream操縱string的方法總結(jié)
下面小編就為大家?guī)?lái)一篇stringstream操縱string的方法總結(jié)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12

