城市建设与管理局网站360网站建设公司哪家好

当前位置: 首页 > news >正文

城市建设与管理局网站,360网站建设公司哪家好,上海网站建设推,刷神马网站优化排名目录

  1. 变量声明和定义的关系
  2. 默认状态下#xff0c;const对象仅在文件内有效
  3. 链接指示#xff1a;extern C 3.1 声明一个非C的函数 3.2 链接指示与头文件 3.3 指向extern C函数的指针 3.4 链接指示对整个声明都有效 3.5 导出C函数到…目录
  4. 变量声明和定义的关系
  5. 默认状态下const对象仅在文件内有效
  6. 链接指示extern C 3.1 声明一个非C的函数 3.2 链接指示与头文件 3.3 指向extern C函数的指针 3.4 链接指示对整个声明都有效 3.5 导出C函数到其他语言 3.6 重载函数与链接指示 1. 变量声明和定义的关系 为了允许把程序拆分成多个逻辑部分来编写C语言支持分离式编译separate compilation机制该机制允许将程序分割为若干个文件每个文件可被独立编译。 如果将程序分为多个文件则需要有在文件间共享代码的方法。例如一个文件的代码可能需要使用另一个文件中定义的变量。一个实际的例子是std::cout和std::cin它们定义于标准库却能被我们写的程序使用。 为了支持分离式编译C语言将声明和定义区分开来。声明declaration使得名字为程序所知一个文件如果想使用别处定义的名字则必须包含对那个名字的声明。而定义definition负责创建与名字关联的实体。 变量声明规定了变量的类型和名字在这一点上定义与之相同。但是除此之外定义还申请存储空间也可能会为变量赋一个初始值。 如果想声明一个变量而非定义它就在变量名前添加关键字extern而且不要显式地初始化变量 extern int i; // 声明i而非定义i int j; // 声明并定义j 任何包含了显式初始化的声明即成为定义。我们能给由extern关键字标记的变量赋一个初始值但是这么做也就抵消了extern的作用。extern语句如果包含初始值就不再是声明而变成定义了 extern double pi 3.1416; // 定义 在函数体内部如果试图初始化一个由extern关键字标记的变量将引发错误。 变量能且只能被定义一次但是可以被多次声明。 声明和定义的区别看起来也许微不足道但实际上却非常重要。如果要在多个文件中使用同一个变量就必须将声明和定义分离。此时变量的定义必须出现在且只能出现在一个文件中而其他用到该变量的文件必须对其进行声明却绝对不能重复定义。 // 源文件a.cpp中定义了全局变量a int a 10; // 源文件b.c声明a extern int a; 2. 默认状态下const对象仅在文件内有效 当以编译时初始化的方式定义一个const对象时就如对bufSize的定义一样 const int bufSize 512; // 输入缓冲区大小 编译器将在编译过程中把用到该变量的地方都替换成对应的值。也就是说编译器会找到代码中所有用到bufsize的地方然后用512替换。 为了执行上述替换编译器必须知道变量的初始值。如果程序包含多个文件则每个用了const对象的文件都必须得能访问到它的初始值才行。要做到这一点就必须在每一个用到变量的文件中都有对它的定义。为了支持这一用法同时避免对同一变量的重复定义默认情况下const对象被设定为仅在文件内有效。当多个文件中出现了同名的const变量时其实等同于在不同文件中分别定义了独立的变量。 某些时候有这样一种const变量它的初始值不是一个常量表达式但又确实有必要在文件间共享。这种情况下我们不希望编译器为每个文件分别生成独立的变量。相反我们想让这类const对象像其他非常量对象一样工作也就是说只在一个文件中定义const而在其他多个文件中声明并使用它。 解决的办法是对于const变量不管是声明还是定义都添加extern关键字这样只需定义一次就可以了 // file_1.cc定义并初始化了一个常量该常量能被其他文件访问 extern const int bufSize fcn(); // file_1.h头文件 extern const int bufsize; // 与file_1.cc中定义的bufSize是同一个 如上述程序所示file_1.cc定义并初始化了bufsize。因为这条语句包含了初始值所以它显然是一次定义。然而因为bufsize是一个常量必须用extern加以限定使其被其他文件使用。 file_1.h头文件中的声明也由extern做了限定其作用是指明bufsize并非本文件所独有它的定义将在别处出现。 如果想在多个文件之间共享const对象必须在变量的定义之前添加extern关键字。
  7. 链接指示extern C C程序有时需要调用其他语言编写的函数最常见的是调用C语言编写的函数。像所有其他名字一样其他语言中的函数名字也必须在C中进行声明并且该声明必须指定返回类型和形参列表。对于其他语言编写的函数来说编译器检查其调用的方式与处理普通C函数的方式相同但是生成的代码有所区别。C使用链接指示linkage directive指出任意非C函数所用的语言。 要想把C代码和其他语言包括C语言编写的代码放在一起使用要求我们必须有权访问该语言的编译器并且这个编译器与当前的C编译器是兼容的。 3.1 声明一个非C的函数 链接指示可以有两种形式单个的或复合的。链接指示不能出现在类定义或函数定义的内部。同样的链接指示必须在函数的每个声明中都出现。 举个例子接下来的声明显示了cstring头文件的某些C函数是如何声明的 // 可能出现在C头文件cstring中的链接指示 // 单语句链接指示 extern C sizet strlen(const char); // 复合语句链接指示 extern C {int strcmp(const char, const char);char strcat(char, const char); } 链接指示的第一种形式包含一个关键字extern后面是一个字符串字面值常量以及一个“普通的”函数声明。 其中的字符串字面值常量指出了编写函数所用的语言。编译器应该支持对C语言的链接指示。此外编译器也可能会支持其他语言的链接指示如extern Ada、extern FORTRAN等。 3.2 链接指示与头文件 我们可以令链接指示后面跟上花括号括起来的若干函数的声明从而一次性建立多个链接。花括号的作用是将适用于该链接指示的多个声明聚合在一起否则花括号就会被忽略花括号中声明的函数名字就是可见的就好像在花括号之外声明的一样。 多重声明的形式可以应用于整个头文件。例如C的cstring头文件可能形如 // 复合语句链接指示 extern C { #include string.h // 操作C风格字符串的C函数 } 当一个#include指示被放置在复合链接指示的花括号中时头文件中的所有普通函数声明都被认为是由链接指示的语言编写的。链接指示可以嵌套因此如果头文件包含带自带链接指示的函数则该函数的链接不受影响。 C从C语言继承的标准库函数可以定义成C函数但并非必须决定使用C还是C实现C标准库是每个C实现的事情。 3.3 指向extern C函数的指针 编写函数所用的语言是函数类型的一部分。因此对于使用链接指示定义的函数来说它的每个声明都必须使用相同的链接指示。而且指向其他语言编写的函数的指针必须与函数本身使用相同的链接指示 // pf指向一个C函数该函数接受一个int返回void extern C void (*pf) (int); 当我们使用pf调用函数时编译器认定当前调用的是一个C函数。 指向C函数的指针与指向C函数的指针是不一样的类型。一个指向C函数的指针不能用在执行初始化或赋值操作后指向C函数反之亦然。就像其他类型不匹配的问题一样如果我们试图在两个链接指示不同的指针之间进行赋值操作则程序将发生错误 void (*pf1) (int); // 指向一个C函数 extern C void (pf2) (int); // 指向一个C函数 pf1 pf2; // 错误pf1和pf2的类型不同 有的C编译器会接受之前的这种赋值操作并将其作为对语言的扩展尽管从严格意义上来看它是非法的。 3.4 链接指示对整个声明都有效 当我们使用链接指示时它不仅对函数有效而且对作为返回类型或形参类型的函数指针也有效 // f1是一个C函数它的形参是一个指向C函数的指针 extern C void f1(void () (int)); 这条声明语句指出f1是一个不返回任何值的C函数。它有一个类型是函数指针的形参其中的函数接受一个int形参返回为空。这个链接指示不仅对f1有效对函数指针同样有效。当我们调用f1时必须传给它一个C函数的名字或者指向C函数的指针。 因为链接指示同时作用于声明语句中的所有函数所以如果我们希望给C函数传入一个指向C函数的指针则必须使用类型别名 // FC是一个指向C函数的指针 extern C typedef void FC(int); // f2是一个C函数该函数的形参是指向C函数的指针 void f2(FC); 3.5 导出C函数到其他语言 通过使用链接指示对函数进行定义我们可以令一个C函数在其他语言编写的程序中可用 // calc函数可以被C程序调用 extern C double calc(double dparm) { / …*/ } 编译器将为该函数生成适合于指定语言的代码。 值得注意的是可被多种语言共享的函数的返回类型或形参类型受到很多限制。例如我们不太可能把一个C类的对象传给C程序因为C程序根本无法理解构造函数、析构函数以及其他类特有的操作。 对链接到C的预处理器的支持 有时需要在C和C中编译同一个源文件为了实现这一目的在编译C版本的程序时预处理器定义 _cplusplus两个下画线。利用这个变量我们可以在编译C程序的时候有条件地包含进来一些代码 #ifdef__cplusplus // 正确我们正在编译C程序 extern C #endif int strcmp(const char, const char); 3.6 重载函数与链接指示 链接指示与重载函数的相互作用依赖于目标语言。如果目标语言支持重载函数则为该语言实现链接指示的编译器很可能也支持重载这些C的函数。 C语言不支持函数重载因此也就不难理解为什么一个C链接指示只能用于说明一组重载函数中的某一个了 // 错误两个extern C函数的名字相同 extern C void print(const char); extern C void print(int); 如果在一组重载函数中有一个是C函数则其余的必定都是C函数 class SmallInt { // }; class BigNum { / …*/ }; // C函数可以在C或C程序中调用 // C函数重载了该函数可以在C程序中调用 extern C double calc(double); extern sma1lInt calc(const smallInt); extern BigNum calc(const BigNum); C版本的calc函数可以在C或C程序中调用而使用了类类型形参的C函数只能在C程序中调用。上述性质与声明的顺序无关。