导航:首页 > 源码编译 > 使用前置声明能节省编译时间吗

使用前置声明能节省编译时间吗

发布时间:2022-03-09 14:20:40

‘壹’ C++ 类的前置声明为什么有时不起作用,VC6.0编译

你应该列出你认为不起作用的对应代码

前置声明只说明有这么个类,类的具体定义是未知的。如果你使用类的任何信息,都是错误的。你只能用它的指针或者引用

‘贰’ Qt:在头文件中既包含QDialog的头文件,也采用了对QCheckBox类的前置声明,可以都采用头文件或前置声明吗

包含头文件可以,前置声明也行,采用前置声明是为了提高编译速度,因为编译器只需知道该类已经被定义了,而无需了解定义的细节

‘叁’ C++:如何通过编码技巧加快大项目重新编译的速度

如果你觉得重新编译文件的时间很短或者时间长一点无所谓,反正需要重新编译,那么你也可以选择略过此文,不过也建议浏览。 如果你想学习或者关心这块内容,那么此文必定会给你带来收获。 首先我不给出依存关系的定义,我给出一个例子。 1 class Peopel{ 2 public: 3 People(const std::string & name,const Date& brithday,Image Img) 4 std::string name( ) const; 5 Date birthDate( ) const; 6 Image img( ) const; 7 … 8 private: 9 std::string theName; //名字 10 Date theBirthDate; //生日 11 Image img; //图片 12 }; 如果编译器没有知道类string,Date和Image的定义,class People是无法通过编译的。一般该定义式是由#include包含的头文件所提供的,所以一般People上面有这些预处理命令 1 #include <string> 2 #include "date.h" 3 #inblude "image.h" 4 class Peopel{ 5 public: 6 People(const std::string & name,const Date& brithday,Image Img) 7 std::string name( ) const; 8 Date birthDate( ) const; 9 Image img( ) const; 10 … 11 private: 12 std::string theName; //名字 13 Date theBirthDate; //生日 14 Image img; //图片 15 }; 那么这样People定义文件与该三个文件之间就形成了一种编译依存关系。如果这些头文件任何一个文件被改变,或这些头文件所依赖其他头文件任何改变,那么每一个包含People类的文件就需要重新编译,使用People类文件也需要重新编译。想想如果一个项目包含一个上千的文件,每个文件包含其他几个文件,依次这样下来,改动一个文件内容,那么就需要几乎重新编译整个项目了,这可以说很槽糕了。 我们可以进行如下改动 1 namespace std { 2 class string; 3 } 4 class Date; 5 class Image; 6 7 class Peopel{ 8 public: 9 People(const std::string & name,const Date& brithday,Image& Img) 10 std::string name( ) const; 11 Date birthDate( ) const; 12 Image img( ) const; 13 … 14 private: 15 std::string theName; //名字 16 Date theBirthDate; //生日 17 Image img; //图片 18 }; 这样只有People该接口被改变时才会重新编译,但是这样有连个问题,第一点string不是class,它是个typedef basic_string<char> string.因此上述前置声明不正确(附其在stl完全代码);,正确的前置声明比较复杂。其实对于标准库部分,我们仅仅通过#include预处理命令包括进来就可以了。 1 #ifndef __STRING__ 2 #define __STRING__ 3 4 #include <std/bastring.h> 5 6 extern "C++" { 7 typedef basic_string <char> string; 8 // typedef basic_string <wchar_t> wstring; 9 } // extern "C++" 10 11 #endif 前置声明还有一个问题,就是编译器必须在编译期间知道对象的大小,以便分配空间。 例如: 1 int main(int argv,char * argc[ ]) 2 { 3 int x; 4 People p( 参数 ); 5 … 6 } 当编译器看到x的定义式,它知道必须分配多少内存,但是看到p定义式就无法知道了。但是如果设置为指针的话,就清楚了,因为指针本身大小编译器是知道的。 #include <string> #include <memory> class PeopleImpl; class Date; class Image; class People{ public: People(const std::string & name, const Date& brithday, const Image &Img); std::string name( ) const; Date birthDate( ) const; Imge img( ) const; … private: PeopleImpl * pImpl; } PeopleImpl包含下面这三个数据,而People的成员变量指针指向这个PeopleImpl,那么现在编译器通过People定义就知道了其分配空间的大小了,一个指针的大小。 1 public PeopleImpl 2 { 3 public: 4 PeopleImple(…) 5 … 6 private: 7 std::string theName; //名字 8 Date theBirthDate; //生日 9 Image img; //图片 10 } 这样,People就完全与Date、Imge以及People的实现分离了上面那些类任何修改都不需要重新编译People文件了。另外这样写加强了封装。这样也就降低了文件的依存关系。 这里总结下降低依存性方法: 1、如果可以类声明就不要使用类定义了。 2、将数据通过一个指向该数据的指针表示。 3、为声明式和定义式提供不同的头文件。 这两个文件必须保持一致性,如果有个声明式被改变了,两个文件都得改变。因此一般会有一个#include一个声明文件而不是前置声明若干函数。 像People这样定 1 #include "People.h" 2 #include "PeopleImpl.h" 3 4 People::People(const std::string& name, const Date& brithday, const Image& Img) 5 :pImpl(new PersonImpl(name,brithday,addr)) 6 { } 7 std::string People::name( ) const 8 { 9 return pImpl->name( ); 10 } 而另外一种Handle类写法是令People成为一种特殊的abstract base class称为Interface类。看到interface这个关键字或许熟悉C#、java的同学可能已经恍然大悟了。这种接口它不带成员变量,也没有构造函数,只有一个virtual析构函数,以及一组纯虚函数,用来表示整个接口。针对People而写的interface class看起来是这样的。 1 class People{ 2 public: 3 virtual ~People( ); 4 virtual std::string name( ) const = 0; 5 virtual Date brithDate( ) const =0; 6 virtual Image address( ) const =0; 7 … 8 }; 怎么创建对象呢?它们通常调用一个特殊函数。这样的函数通常称为工厂函数或者虚构造函数。它们返回指针指向动态分配所得对象,而该对象支持interface类的接口。 1 class People { 2 public: 3 … 4 static People* create(const std::string& name,const Date& brithday, const Image& Img); 5 }; 支持interface类接口的那个类必须定义出来,而且真正的构造函数必须被调用 1 class RealPeople:public People{ 2 public: 3 RealPeople(const std::string& name,const Date& birthday,const Image& Img) 4 :theName(name),theBrithDate(brithday),theImg(Img) 5 {} 6 virtual ~RealPeople() { } 7 std::string name( ) const; 8 Date birthDate( ) const; 9 Image img( ) const; 10 private: 11 std::string theName; 12 Date theBirthDate; 13 Image theImg; 14 } 有了RealPeople类,我们People::create可以这样写 1 People* People::create(const std::string& name, const Date& birthday, const Image& Img) 2 { 3 return static_cast<People *>(new RealPerson(name,birthday,Img)); 4 } Handle类与interface类解除了接口和实现之间的耦合关系,从而降低了文件间的编译依存性。但同时也损耗了一些性能与空间。

‘肆’ 为什么我们前置声明时,只能使用类型的指针和引用

你好:
对于前置的声明,编译器只检查参数个数与类型,不检查参数名,没有分配内存。所以,只需要类型与个数即可。

祝你顺利。

‘伍’ 如何加快C++代码的编译速度

一、代码角度
1、在头文件中使用前置声明,而不是直接包含头文件。
不要以为你只是多加了一个头文件,由于头文件的"被包含"特性,这种效果可能会被无限放大。所以,要尽一切可能使头文件精简。很多时候前置申明某个namespace中的类会比较痛苦,而直接include会方便很多,千万要抵制住这种诱惑;类的成员,函数参数等也尽量用引用,指针,为前置声明创造条件。
2、使用Pimpl模式
Pimpl全称为Private Implementation。传统的C++的类的接口与实现是混淆在一起的,而Pimpl这种做法使得类的接口与实现得以完全分离。如此,只要类的公共接口保持不变,对类实现的修改始终只需编译该cpp;同时,该类提供给外界的头文件也会精简许多。
3、高度模块化
模块化就是低耦合,就是尽可能的减少相互依赖。这里其实有两个层面的意思。一是文件与文件之间,一个头文件的变化,尽量不要引起其他文件的重新编译;二是工程与工程之间,对一个工程的修改,尽量不要引起太多其他工程的编译。这就要求头文件,或者工程的内容一定要单一,不要什么东西都往里面塞,从而引起不必要的依赖。这也可以说是内聚性吧。
以头文件为例,不要把两个不相关的类,或者没什么联系的宏定义放到一个头文件里。内容要尽量单一,从而不会使包含他们的文件包含了不需要的内容。记得我们曾经做过这么一个事,把代码中最"hot"的那些头文件找出来,然后分成多个独立的小文件,效果相当可观。
其实我们去年做过的refactoring,把众多DLL分离成UI与Core两个部分,也是有着相同的效果的 - 提高开发效率。
4、删除冗余的头文件
一些代码经过上十年的开发与维护,经手的人无数,很有可能出现包含了没用的头文件,或重复包含的现象,去掉这些冗余的include是相当必要的。当然,这主要是针对cpp的,因为对于一个头文件,其中的某个include是否冗余很难界定,得看是否在最终的编译单元中用到了,而这样又可能出现在一个编译单元用到了,而在另外一个编译单元中没用到的情况。
之前曾写过一个Perl脚本用来自动去除这些冗余的头文件,在某个工程中竟然去掉多达了5000多个的include。
5、特别注意inline和template
这是C++中两种比较"先进"的机制,但是它们却又强制我们在头文件中包含实现,这对增加头文件的内容,从而减慢编译速度有着很大的贡献。使用之前,权衡一下。
二、综合技巧
1、预编译头文件(PCH)
把一些常用但不常改动的头文件放在预编译头文件中。这样,至少在单个工程中你不需要在每个编译单元里一遍又一遍的load与解析同一个头文件了。
2、Unity Build
Unity Build做法很简单,把所有的cpp包含到一个cpp中(all.cpp) ,然后只编译all.cpp。这样我们就只有一个编译单元,这意味着不需要重复load与解析同一个头文件了,同时因为只产生一个obj文件,在链接的时候也不需要那么密集的磁盘操作了,估计能有10x的提高,看看这个视频感受一下其做法与速度吧。
3、ccache
compiler cache, 通过cache上一次编译的结果,使rebuild在保持结果相同的情况下,极大的提高速度。我们知道如果是build,系统会对比源代码与目标代码的时间来决定是否要重新编译某个文件,这个方法其实并不完全可靠(比如从svn上拿了上个版本的代码),而ccache判断的原则则是文件的内容,相对来讲要可靠的多。
很可惜的是,Visual Studio现在还不支持这个功能 - 其实完全可以加一个新的命令,比如cache build,介于build与rebuild之间,这样,rebuild就可以基本不用了。
4、不要有太多的Additional Include Directories
编译器定位你include的头文件,是根据你提供的include directories进行搜索的。可以想象,如果你提供了100个包含目录,而某个头文件是在第100个目录下,定位它的过程是非常痛苦的。组织好你的包含目录,并尽量保持简洁。
三、编译资源
要提高速度,要么减少任务,要么加派人手,前面两个方面讲得都是减少任务,而事实上,在提高编译速度这块,加派人手还是有着非常重要的作用的。
1、并行编译
买个4核的,或者8核的cpu,每次一build,就是8个文件并行着编,那速度,看着都爽。 要是你们老板不同意,让他读读这篇文章:Hardware is Cheap, Programmers are Expensive
2、更好的磁盘
我们知道,编译速度慢很大一部分原因是磁盘操作,那么除了尽可能的减少磁盘操作,我们还可以做的就是加快磁盘速度。比如上面8个核一块工作的时候,磁盘极有可能成为最大的瓶颈。买个15000转的磁盘,或者SSD,或者RAID0的,总之,越快越好。
3、分布式编译
一台机子的性能始终是有限的,利用网络中空闲的cpu资源,以及专门用来编译的build server来帮助你编译才能从根本上解决我们编译速度的问题,想想原来要build 1个多小时工程的在2分钟内就能搞定,你就知道你一定不能没有它 - Incredibuild。
4、并行,其实还可以这么做。
这是一个比较极端的情况,如果你用了Incredibuild,对最终的编译速度还是不满意,怎么办?其实只要跳出思维的框架,编译速度还是可以有质的飞跃的 - 前提是你有足够多的机器:
假设你有solution A和solution B,B依赖于A,所以必须在A之后Build B。其中A,B Build各需要1个小时,那么总共要2个小时。可是B一定要在A之后build吗?跳出这个思维框架,你就有了下述方案:
◦同时开始build A和B 。
◦A的build成功,这里虽然B的build失败了,但都只是失败在最后的link上。
◦重新link B中的project。
这样,通过让A的build与B的编译并行,最后link一下B中的project,整个编译速度应该能够控制在1个小时15分钟之内。

‘陆’ 将对静态数据成员初始化语句删除或者移到主函数体内,编译程序会出现什么现象

可以通过以下几个例子更形象的说明这个问题:
//test.cpp
#include <stdio.h>
class A {
public:
static int a; //声明但未定义
};
int main() {
printf("%d", A::a);
return 0;
}
编译以上代码会出现“对‘A::a’未定义的引用”错误。这是因为静态成员变量a未定义,也就是还没有分配内存,显然是不可以访问的。
再看如下例子:
//test.cpp
#include <stdio.h>
class A {
public:
static int a; //声明但未定义
};
int A::a = 3; //定义了静态成员变量,同时初始化。也可以写"int A:a;",即不给初值,同样可以通过编译
int main() {
printf("%d", A::a);
return 0;
}
这样就对了,因为给a分配了内存,所以可以访问静态成员变量a了。
因为类中的静态成员变量仅仅是声明,暂时不需分配内存,所以我们甚至可以这样写代码:
//a.cpp
class B; //这里我们使用前置声明,完全不知道B是什么样子
class A {
public:
static B bb;//声明了一个类型为B的静态成员,在这里编译器并未给bb分配内存。
//因为仅仅是声明bb,所以编译器并不需要知道B是什么样子以及要给其对应的对象分配多大的空间。
//所以使用前置声明"class B"就可以保证编译通过。
};
使用命令"g++ -c -o a.o a.cpp"通过编译。
对于类来说,new一个类对象不仅会分配内存,同时会调用构造函数进行初始化,所以类对象的定义和初始化总是关联在一起。

‘柒’ 有关C++的问题~~请教

1、就是在dlg2.h的文件中为何非得加上class CDlg1;??
当然需要,在dlg2中也要加上对dlg1的引用,用class CDlg1是为避免循环重复引用。
2、道理同上。

看下面的详细解释:
一、类嵌套的疑问

C++头文件重复包含实在是一个令人头痛的问题,前一段时间在做一个简单的数据结构演示程序的时候,不只一次的遇到这种问题。假设我们有两个类A和B,分别定义在各自的有文件A.h和B.h中,但是在A中要用到B,B中也要用到A,但是这样的写法当然是错误的:
class B;

class A
{
public:
B b;
};

class B
{
public:
A a;
};
因为在A对象中要开辟一块属于B的空间,而B中又有A的空间,是一个逻辑错误,无法实现的。在这里我们只需要把其中的一个A类中的B类型成员改成指针形式就可以避免这个无限延伸的怪圈了。为什么要更改A而不是B?因为就算你在B中做了类似的动作,也仍然会编译错误,表面上这仅仅上一个先后顺序的问题。
为什么会这样呢?因为C++编译器自上而下编译源文件的时候,对每一个数据的定义,总是需要知道定义的数据的类型的大小。在预先声明语句class B;之后,编译器已经知道B是一个类,但是其中的数据却是未知的,因此B类型的大小也不知道。这样就造成了编译失败,VC++6.0下会得到如下编译错误:
error C2079: ‘b’ uses undefined class ‘B’
将A中的b更改为B指针类型之后,由于在特定的平台上,指针所占的空间是一定的(在Win32平台上是4字节),这样可以通过编译。

二、不同头文件中的类的嵌套

在实际编程中,不同的类一般是放在不同的相互独立的头文件中的,这样两个类在相互引用时又会有不一样的问题。重复编译是问题出现的根本原因。为了保证头文件仅被编译一次,在C++中常用的办法是使用条件编译命令。在头文件中我们常常会看到以下语句段(以VC++6.0自动生成的头文件为例):

#if !defined(AFX_STACK_H__1F725F28_AF9E_4BEB_8560_67813900AE6B__INCLUDED_)
#define AFX_STACK_H__1F725F28_AF9E_4BEB_8560_67813900AE6B__INCLUDED_
//很多语句……
#endif

其中首句#if !defined也经常做#ifndef,作用相同。意思是如果没有定义过这个宏,那么就定义它,然后执行直到#endif的所有语句。如果下次在与要这段代码,由于已经定义了那个宏,因此重复的代码不会被再次执行。这实在是一个巧妙而高效的办法。在高版本的VC++上,还可以使用这个命令来代替以上的所有:
#pragma once
它的意思是,本文件内的代码只被使用一次。

但是不要以为使用了这种机制就全部搞定了,比如在以下的代码中:

//文件A.h中的代码
#pragma once

#include “B.h”

class A
{
public:
B* b;
};

//文件B.h中的代码
#pragma once

#include “A.h”

class B
{
public:
A* a;
};

这里两者都使用了指针成员,因此嵌套本身不会有什么问题,在主函数前面使用#include “A.h”之后,主要编译错误如下:
error C2501: ‘A’ : missing storage-class or type specifiers
仍然是类型不能找到的错误。其实这里仍然需要前置声明。分别添加前置声明之后,可以成功编译了。代码形式如下:

//文件A.h中的代码
#pragma once

#include “B.h”

class B;

class A
{
public:
B* b;
};

//文件B.h中的代码
#pragma once

#include “A.h”

class B;

class B
{
public:
A* a;
};

这样至少可以说明,头文件包含代替不了前置声明。有的时候只能依靠前置声明来解决问题。我们还要思考一下,有了前置声明的时候头文件包含还是必要的吗?我们尝试去掉A.h和B.h中的#include行,发现没有出现新的错误。那么究竟什么时候需要前置声明,什么时候需要头文件包含呢?

三、两点原则

头文件包含其实是一想很烦琐的工作,不但我们看着累,编译器编译的时候也很累,再加上头文件中常常出现的宏定义。感觉各种宏定义的展开是非常耗时间的,远不如自定义函数来得速度。我仅就不同头文件、源文件间的句则结构问题提出两点原则,仅供参考:

第一个原则应该是,如果可以不包含头文件,那就不要包含了。这时候前置声明可以解决问题。如果使用的仅仅是一个类的指针,没有使用这个类的具体对象(非指针),也没有访问到类的具体成员,那么前置声明就可以了。因为指针这一数据类型的大小是特定的,编译器可以获知。

第二个原则应该是,尽量在CPP文件中包含头文件,而非在头文件中。假设类A的一个成员是是一个指向类B的指针,在类A的头文件中使用了类B的前置声明并便宜成功,那么在A的实现中我们需要访问B的具体成员,因此需要包含头文件,那么我们应该在类A的实现部分(CPP文件)包含类B的头文件而非声明部分(H文件)。

‘捌’ C++类的前置声明问题

因为编码器在读到X obj;时还不知道X的大小,无法为class Y分配内存空间。
如果把声明顺序反一下就可以通过了。
class Y;
class X{
private: Y* ptr; //这里虽然Y还没有声明,但编码器知道这是一个指针,至于指向什么数据可以先不关心。
};
class Y{
X obj;
};
int main()
{
Y y;
return 0;
}

‘玖’ 还是 关于一个C++的小问题

我也是网上搜集的,对你的问题逐个进行解答
一。
1、什么是const?
常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。
为什么引入const?
const 推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。
3、cons有什么主要的作用?
(1)可以定义const常量,具有不可变性。 例如:
const int Max=100; int Array[Max];
(2)便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患。例如: void f(const int i) { .........} 编译器就会知道i是一个常量,不允许修改; (3)可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。 同宏定义一样,可以做到不变则已,一变都变!如(1)中,如果想修改Max的内容,只需要:const int Max=you want;即可!
(4)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。 还是上面的例子,如果在函数体内修改了i,编译器就会报错; 例如:
void f(const int i) { i=10;//error! }
(5) 为函数重载提供了一个参考。
class A { ......
void f(int i) {......} //一个函数
void f(int i) const {......} //上一个函数的重载 ......
};
(6) 可以节省空间,避免不必要的内存分配。 例如:
#define PI 3.14159 //常量宏
const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 ......
double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存!
const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是象#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干个拷贝。
(7) 提高了效率。 编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。

4、如何使用const?
(1)修饰一般常量 一般常量是指简单类型的常量。这种常量在定义时,修饰符const可以用在类型说明符前,也可以用在类型说明符后。 例如:
int const x=2; 或 const int x=2;
(2)修饰常数组 定义或说明一个常数组可采用如下格式:
int const a[5]={1, 2, 3, 4, 5};
const int a[5]={1, 2, 3, 4, 5};
(3)修饰常对象 常对象是指对象常量,定义格式如下:
class A; const A a;
A const a; 定义常对象时,同样要进行初始化,并且该对象不能再被更新,修饰符const可以放在类名后面,也可以放在类名前面。
(4)修饰常指针
const int *A; //const修饰指向的对象,A可变,A指向的对象不可变
int const *A; //const修饰指向的对象,A可变,A指向的对象不可变
int *const A; //const修饰指针A, A不可变,A指向的对象可变
const int *const A;//指针A和A指向的对象都不可变
(5)修饰常引用 使用const修饰符也可以说明引用,被说明的引用为常引用,该引用所引用的对象不能被更新。其定义格式如下:
const double & v;
(6)修饰函数的常参数 const修饰符也可以修饰函数的传递参数,格式如下:
void Fun(const int Var); 告诉编译器Var在函数体中的无法改变,从而防止了使用者的一些无意的或错误的修改。
(7)修饰函数的返回值: const修饰符也可以修饰函数的返回值,是返回值不可被改变,格式如下:
const int Fun1(); const MyClass Fun2();
(8)修饰类的成员函数: const修饰符也可以修饰类的成员函数,格式如下:
class ClassName {
public:
int Fun() const; .....
}; 这样,在调用函数Fun时就不能修改类里面的数据
(9)在另一连接文件中引用const常量
extern const int i;//正确的引用
extern const int j=10;//错误!常量不可以被再次赋值 另外,还要注意,常量必须初始化! 例如: const int i=5;
具体请参看http://..com/question/91670015.html?si=1

二。区别是第一个3是实参,他在作为函数调用的时候传递给形参,第二个是函数的定义,括号内的区别就是形参和实参的区别,其中t可以省略,如果传递的实参是3,那么将3转化为浮点形式的3.00000

三,这个问题看不开懂,你是问强制转化的方向吗?那么是浮点型>整型>字符型
就是低精度的向高精度的转化

四,sizeof用与测试变量类型长度(即所占字节数),格式sizeof( 变量类型 )
例如:测试整形int所占字节数 ,sizeof( int ),显示结果:4

五,传统 C/C++

#include <assert.h> //设定插入点
#include <ctype.h> //字符处理
#include <errno.h> //定义错误码
#include <float.h> //浮点数处理
#include <fstream.h> //文件输入/输出
#include <iomanip.h> //参数化输入/输出
#include <iostream.h> //数据流输入/输出
#include <limits.h> //定义各种数据类型最值常量
#include <locale.h> //定义本地化函数
#include <math.h> //定义数学函数
#include <stdio.h> //定义输入/输出函数
#include <stdlib.h> //定义杂项函数及内存分配函数
#include <string.h> //字符串处理
#include <strstrea.h> //基于数组的输入/输出
#include <time.h> //定义关于时间的函数
#include <wchar.h> //宽字符处理及输入/输出
#include <wctype.h> //宽字符分类

//////////////////////////////////////////////////////////////////////////

标准 C++ (同上的不再注释)

#include <algorithm> //STL 通用算法
#include <bitset> //STL 位集容器
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex> //复数类
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque> //STL 双端队列容器
#include <exception> //异常处理类
#include <fstream>
#include <functional> //STL 定义运算函数(代替运算符)
#include <limits>
#include <list> //STL 线性列表容器
#include <map> //STL 映射容器
#include <iomanip>
#include <ios> //基本输入/输出支持
#include <iosfwd> //输入/输出系统使用的前置声明
#include <iostream>
#include <istream> //基本输入流
#include <ostream> //基本输出流
#include <queue> //STL 队列容器
#include <set> //STL 集合容器
#include <sstream> //基于字符串的流
#include <stack> //STL 堆栈容器
#include <stdexcept> //标准异常类
#include <streambuf> //底层输入/输出支持
#include <string> //字符串类
#include <utility> //STL 通用模板类
#include <vector> //STL 动态数组容器
#include <cwchar>
#include <cwctype>

using namespace std;

//////////////////////////////////////////////////////////////////////////

C99 增加

#include <complex.h> //复数处理
#include <fenv.h> //浮点环境
#include <inttypes.h> //整数格式转换
#include <stdbool.h> //布尔环境
#include <stdint.h> //整型环境
#include <tgmath.h> //通用类型数学宏

六,strlen 是个函数,是求字符串的长度,不包括结尾的'\0'
格式 strlen(字符串指针); 比如r=strlen("student"),那么r的值为7
strlen()+1就是自加1而已

好了,如果觉得可以就给分吧

阅读全文

与使用前置声明能节省编译时间吗相关的资料

热点内容
如何在app上架自己的游戏 浏览:459
安卓系统车载导航支持什么格式u盘 浏览:624
天翼云服务器怎么打开端口 浏览:909
如何启用对服务器远程的访问 浏览:774
程序员环境分析 浏览:814
tsp算法是数据挖掘算法吗 浏览:672
编译原理好处 浏览:820
怎么买服务器主机 浏览:176
什么app可以存档游戏 浏览:430
那里有螺杆压缩机修理 浏览:31
什么电脑软件检测安卓机 浏览:728
c语言编译没问题组件有错误 浏览:513
迅捷pdf编辑器破解版下载 浏览:14
电火花线切割怎么编程 浏览:778
linux查看驱动命令 浏览:998
苏州车辆解压代办大概多少钱 浏览:593
租房app什么比较靠谱 浏览:678
运动app如何测量运动心率 浏览:784
苹果手机文件夹图标背景图透明度 浏览:736
辽宁省解压旅游 浏览:273