include是一个计算机专业术语,一指C/C++中包含头文件命令,用于将指定头文件嵌入源文件中。二指include 指令,在JSP中包含一个静态的文件,同时解析这个文件中的JSP语句。三指PHP语句。/n
命令
引言
做c/c++编程的对#include指令都不会陌生,绝大多数人也都知道如何使用,但我相信仍有人对此是一知半解的,
C:
#include
C++:
#include
表示包含C/C++标准输入输出头文件。包含指令不仅仅限于.h头文件,可以包含任何编译器能识别的C/C++代码文件,包括.c、.hpp、.cpp、.hxx、.cxx等,甚至.txt、.abc等等都可以。
预处理器发现 #include 指令后,就会寻找指令后面<>中的文件名,并把这个文件的内容包含到当前文件中。被包含文件中的文本将替换源代码文件中的#include 指令, 就像你把被包含文件中的全部内容键入到源文件中的这个位置一样。
名词解释
preprocess
预处理:为方便编译器处理而设置的一种机制,包括一些常用预处理指令和语句,我们统称为预处理系统。
如#include #define #if…#else…#endif #pragma等
这些指令的实现是由编译器来决定的(implementation specified)
提到预处理指令,顺便说一下头文件防止重复包含的2种方法
a.保护宏(暂且称为Macro guard 宏卫兵?):
#ifndef _ABCDE_H
#define _ABCDE_H
/*
代码部分
*/
#endif
在被包含过一次之后,宏_ABCDE_H已经有了,下次再碰到就会略过从#define _ABCDE_H开始到#endif之间的代码
还有一种特定编译器支持的指令:
b.#pragma once
能保证该文件(物理上的)只被编译一次,也能起到防止重复包含的作用
但这2种方式是有区别的:
a.Macro guard可移植性好,绝大多数编译器都支持,而且万一不小心拷贝了几分相同的代码也不会出问题,但你得确保这个宏名不会与其他的宏冲突,否则等编译器报出一大堆错误的时候你可能会觉得莫名其妙;
b.#pragma once指令简单,它能保证该文件(物理上的)只被编译一次,不用去费劲的想不同的宏名,但如果有几份该文件的拷贝,显然起不到作用。
declaration
声明:指将一个名称引入当前编译单元,或者重新声明一个前面已经声明过的名称,声明指定了如何解释一个名称和该名称具有的属性;
例如:
int main(void)
{
int a; // 声明了变量a,类型为int
int *pa; // 声明了变量pa,类型为指向int型的指针类型
}
definition
定义:除了以下情况,声明就是定义
a.声明函数但不包括函数体;
b.声明包含extern链接限定符,例如:extern int a;
c.声明既没有初始化语法,也没有函数体;
d.类声明中声明静态数据成员;
e.类名字声明;
f.typedef声明;
g.using声明或者using指令;
以上情况适用于C具有的特征,C++则完全适用,一般来说定义要为其对象分配或预留存储空间,而声明则不用。
translation unit
编译单元:一个源文件,.c .cpp等和它所包含的文件一起,在经过预处理之后形成一个源码文件,标准称之为translation unit(编译单元)包括一系列的声明和定义;一个program(程序)由一个或多个编译单元组成。编译器将各个编译单元编译为目标代码(.obj),通过连接器(linker)将这些编译后的编译单元(即目标代码)连接成完整的指令序列(可执行文件、静态库、动态库等)。
one definition rule
一次定义规则:是指定义在所有进入连接的编译单元中只能有一次。
观点、例子
A:头文件只放声明
example_a.h
void function();
example_a.cpp:
#include "example_a.h"
void function()
{}
B.被包含的文件可以使用任意扩展名:
只要是用符合标准的代码编写的文本文件,就可以使用#include来进行包含,包括.cpp .c等常见的源文件扩展名;
example_b_1.b
void function();
example_b_1.cpp:
#include "example_b_1.b"
void function()
{}
example_b_2.b
void function1();
void function2();
example_b_21.cpp:
void function1()
{}
example_b_22.cpp:
#include "example_b_1.b"
#include "example_b_21.cpp"
void function2()
{}
上面的例子中,example_b_21.cpp仅被包含在example_b_22.cpp中,不再被其他的文件包含,而且不加入工程中;
C.标准头文件的使用
最新的C++标准库中的一切内容都被放在名字空间std中(名字空间中的内容对外是不可见的),但是带来了一个新问题,无数现有的C++代码都依赖于使用了多年的伪标准库中的功能,如声明在;等头文件中的功能,使用std包装标准库导致现有代码的不可用,为了兼容这种情况,标准委员会为包装了std的那部分标准库创建了新的头文件,新的头文件的文件名与旧的一样,只是没有.h这个后缀,如;就变成了;。对于C头文件,采用同样的方法,但还在每个头文件名前加了字符c,如;就变成了;,;变成了;。最好使用新的文件头,使用新的文件头的C++程序,需要使用using namespace std或者using namespace std::指定的类名,等方法来使需要的类对于我们的代码可视。
用法
#include后面有两种方式,<>;和""前者先在标准库中查找,查找不到在path中查找。后者为文件路径,若直接是文件名则在项目根目录下查找
总结
既然是经常使用的东西,我们就应该明白它的原理,减少编程时的困惑,提高编程的效率。
举例说明
例子
include.jsp:
An Include Test
The current date and time are
<%@ include file="date.jsp" %>
date.jsp:
<%@ page import="java.util.*" %>
<%= (new java.util.Date() ).toLocaleString() %>
Displays in the page:
The current date and time are
Aug 30, 1999 2:38:40
描述
<%@include %>指命将会在JSP编译时插入一个包含文本或代码的文件,当你使用<%@ include %>指命时,这个包含的过程就当是静态的。静态的包含就是指这个被包含的文件将会被插入到JSP文件中去,这个包含的文件可以是JSP文件,HTML文件,文本文件。如果包含的是JSP文件,这个包含的JSP的文件中代码将会被执行。
如果你仅仅只是用include 来包含一个静态文件。那么这个包含的文件所执行的结果将会插入到JSP文件中放<% @ include %>的地方。一旦包含文件被执行,那么主JSP文件的过程将会被恢复,继续执行下一行.
这个被包含文件可以是html文件,jsp文件,文本文件,或者只是一段Java代码,但是你得注意在这个包含文件中不能使用,,,标记,因为这将会影响在原JSP文件中同样的标记 ,这样做有时会导致错误.
有一些<%@ include %>指命的行为是以特殊的JSP编译条件为基础,比如:
这个被包含的文件必须对所有客户都有开放且必须f有效,或者它有安全限制
如果这个包含文件被改变,包含此文件的JSP文件将被重新编译
属性:
file="relativeURL"
这个包含文件的路径名一般来说是指相对路径,不需要什么端口,协议,和域名,如下:
"error.jsp""/templates/onlinestore.html""/beans/calendar.jsp"
如果这个路径以"/"开头,那么这个路径主要是参照JSP应用的上下关系路径,如果路径是以文件名或目录名开头,那么这个路径就是正在使用的JSP文件的当前路径.
在的JSP 1.2,有page、include与taglib三种Directive Elements(指令元素 — 使用<%@ 与 %>包括).现在主要介绍page的用法.
page元素常用属性:
info属性:用于设定目前JSP页面的基本信息,这个信息最后会转换为Servlet程序中使用getServletInf()所取得的信息.
contentType属性:用于设定MIME型态及网页编码方式,这个部份的设定是给浏览器判断该以什么样的方式显示网页文件,在Servlet中,这个部份是对应于HttpServletResponse对象的setContentType()方法.
import属性:则相当于Java语法中的import.
page元素还包括其他属性:
autoFlush:用于设定至客户端的输出串流是否要自动出清,预设是true,如果设定为false,而缓冲区满了,将会产生例外。
buffer属性:用于设定至客户端的输出串流缓冲区大小,预设是8KB。
errorPage:用于设定当JSP执行错误而产生例外时,该由哪一个页面处理这个例外。
extends属性:可以用来指定JSP网页转译为Servlet程序之后,该继承哪一个类别.
isErrorPage:用以设定JSP页面是否为处理例外的页面,这个属性要与errorPage配合使用.
session属性:可设定是否使用session对象,预设是true。
pageEncoding属性:用于指定JSP网页转为Servlet编译时采取的编码方式,如此在编译时才能正确的转换程序代码中设定的字符,预设是操作系统的语系设定。
isELIgnored:用以设定JSP网页中是否忽略Expression Language,预设是false,如果设定为true,则Expression Language被会被转译,Expression Language在JSP 2.0成为标准规格之一。
例子:
<%@page info="JSP指令元素示范"%>
<%@page contentType="text/html;charset=Big5"%>
<%@page import="javax.servlet.jsp.HttpJspPage,java.util.Date"%>
<%= ((HttpJspPage)page).getServletInfo() %>
现在时间: <%= (new Date()).toString() %>
php中
include()语句包含并运行指定文件。
以下文档也适用于require()。这两种结构除了在如何处理失败之外完全一样。include(产生一个警告而require()则导致一个致命错误。换句话说,如果想在遇到丢失文件时停止处理页面就用require()。include()就不是这样,脚本会继续运行。同时也要确认设置了合适的include_path。注意在php4.3.5之前,包含文件中的语法错误不会导致程序停止,但从此版本之后会。
寻找包含文件的顺序先是在当前工作目录的相对的include_path下寻找,然后是当前运行脚本所在目录相对的include_path下寻找。例如include_path是.,当前工作目录是/www/,脚本中要include一个include/a.php并且在该文件中有一句include"b.php",则寻找b.php的顺序先是/www/,然后是/www/include/。如果文件名以../开始,则只在当前工作目录相对的include_path下寻找。
当一个文件被包含时,其中所包含的代码继承了include所在行的变量范围。从该处开始,调用文件在该行处可用的任何变量在被调用的文件中也都可用。不过所有在包含文件中定义的函数和类都具有全局作用域。
例子16-5.基本的include()例子
vars.php
$color='green';
$fruit='apple';
?>
test.php
echo"A$color$fruit";//A
include'vars.php';
echo"A$color$fruit";//Agreenapple
?>如果include出现于调用文件中的一个函数里,则被调用的文件中所包含的所有代码将表现得如同它们是在该函数内部定义的一样。所以它将遵循该函数的变量范围。
例子16-6.函数中的包含
functionfoo()
{
global$color;
include'vars.php';
echo"A$color$fruit";
}
/*vars.phpisinthescopeoffoo()so*
*$fruitisNOTavailableoutsideofthis*
*scope.$colorisbecausewedeclaredit*
*asglobal.*/
foo();//Agreenapple
echo"A$color$fruit";//Agreen
?>例子16-7.通过HTTP进行的include()
/*Thisexampleassumesthatwww.example.comisconfiguredtoparse.php*
*filesandnot.txtfiles.Also,'Works'heremeansthatthevariables*
*$fooand$barareavailablewithintheincludedfile.*/
//Won'twork;file.txtwasn'thandledbywww.example.comasphp
include'http://www.example.com/file.txt?foo=1&bar=2';
//Won'twork;looksforafilenamed'file.php?foo=1&bar=2'onthe
//localfilesystem.
include'file.php?foo=1&bar=2';
//Works.
include'http://www.example.com/file.php?foo=1&bar=2';
$foo=1;
$bar=2;
include'file.txt';//Works.
include'file.php';//Works.
?>相关信息参见使用远程文件,fopen()和file()。
因为include()和require()是特殊的语言结构,在条件语句中使用必须将其放在语句组中(花括号中)。
例子16-8.include()与条件语句组
//ThisisWRONGandwillnotworkasdesired.
if($condition)
include$file;
else
include$other;
//ThisisCORRECT.
if($condition){
include$file;
}else{
include$other;
}
?>处理返回值:可以在被包括的文件中使用return()语句来终止该文件中程序的执行并返回调用它的脚本。同样也可以从被包含的文件中返回值。可以像普通函数一样获得include调用的返回值。不过这在包含远程文件时却不行,除非远程文件的输出具有合法的php开始和结束标记(如同任何本地文件一样)。可以在标记内定义所需的变量,该变量在文件被包含的位置之后就可用了。
因为include()是一个特殊的语言结构,其参数不需要括号。在比较其返回值时要注意。
例子16-9.比较include的返回值
//won'twork,evaluatedasinclude(('vars.php')=='OK'),i.e.include('')
if(include('vars.php')=='OK'){
echo'OK';
}
//works
if((include'vars.php')=='OK'){
echo'OK';
}
?>注:在php3中,除非是在函数中调用否则被包含的文件中不能出现return。在此情况下return()作用于该函数而不是整个文件。
例子16-10.include()和return()语句
return.php
$var='php';
return$var;
?>
noreturn.php
$var='php';
?>
testreturns.php
$foo=include'return.php';
echo$foo;//prints'php'
$bar=include'noreturn.php';
echo$bar;//prints1
?>$bar的值为1是因为include成功运行了。注意以上例子中的区别。第一个在被包含的文件中用了return()而另一个没有。如果文件不能被包含,则返回FALSE并发出一个E_WARNING警告。
如果在包含文件中定义有函数,这些函数可以独立于是否在return()之前还是之后在主文件中使用。如果文件被包含两次,php5发出致命错误因为函数已经被定义,但是php在return()之后不会抱怨函数已定义。推荐使用include_once()而不是检查文件是否已包含并在包含文件中有条件返回。
另一个将php文件“包含”到一个变量中的方法是用输出控制函数结合include()来捕获其输出,例如:
例子16-11.使用输出缓冲来将php文件包含入一个字符串
$string=get_include_contents('somefile.php');
functionget_include_contents($filename){
if(is_file($filename)){
ob_start();
include$filename;
$contents=ob_get_contents();
ob_end_clean();
return$contents;
}
returnfalse;
}
?>要在脚本中自动包含文件,参见php.ini中的auto_prepend_file和auto_append_file配置选项。
注:由于这是一个语言结构而非函数,因此它无法被变量函数调用。
参见require(),require_once(),include_once(),readfile(),virtual()和include_path。
相关拓展
C语言中#include指令的作用域华中理工大学毕世红当源程序很长时,可将其分成几个文本文件。有两种分法:一是工程制作(project-make);二是文件包含(#include)。两者所不同的是,前者可以分别编译,但当源文件较多时。在工程菜单中定义… /n
该文章由作者:【拆字】发布,本站仅提供存储、如有版权、错误、违法等相关信息请联系,本站会在1个工作日内进行整改,谢谢!