研究生院 网站 建设,番禺制作网站技术,百度统计app,长春做网站建设的公司1 单独编译
C允许将组件函数放在独立的文件即头文件中#xff0c;头文件中可以包含以下内容#xff1a;
函数原型#xff1b;使用#define或const定义的符号常量#xff1b;结构声明#xff1b;类声明#xff1b;模板声明#xff1b;内联函数。 注意#xff0c;在包含…1 单独编译
C允许将组件函数放在独立的文件即头文件中头文件中可以包含以下内容
函数原型使用#define或const定义的符号常量结构声明类声明模板声明内联函数。 注意在包含自定义的头文件时应使用 #include “test.h”这样编译器才会优先从当前工作目录或其他目录查找如果是#include test.h形式则编译器将在存储标准头文件的主机系统的文件系统中查找。 在同一个文件中只能将同一个文件包含一次。但是在实际开发时很可能会使用包含了另一个头文件的头文件从而造成头文件被重复包含的问题因此一般都需要在头文件的头尾加上预处理器编译指令#ifndef意味着仅当之前未使用预处理器编译指令#define定义名称CODE_TEST_H时才处理#ifndef和#endif之间的语句。
#ifndef CODE_TEST_H
#define CODE_TEST_H
// ...
// 头文件具体内容
// ...
#endif2 存储持续性
根据数据在内存中保留时间的不同可以将存储数据方案分为
自动存储持续性在函数定义中声明的变量包括函数参数的存储持续性为自动的。它们在程序开始执行其所属的函数或代码块时被创建在执行完成后它们使用的内存被释放。静态存储持续性在函数定义外定义的变量和使用关键字static定义的变量的存储持续性为静态的。它们在程序的整个运行过程中都存在。动态存储持续性用new操作符分配的内存将一直存在直到使用delete操作符将其释放或程序结束为止。
2.1 自动变量
可以使用关键字auto来显式地指出存储类别由于局部变量默认状态下就是自动的因此程序员几乎不使用它。
auto int num;2.2 寄存器变量
可以使用关键字register来声明局部变量表示该变量使用频率很高寄存器变量会提醒编译器用户希望它通过使用CPU寄存器来处理特定变量从而提供对变量的快速访问理念是CPU访问寄存器中的值的速度比访问堆栈中内存快。 注意编译器不一定会用寄存器来存储register变量因为寄存器可能已经全被占用或者寄存器无法存储所请求的类型。 如果变量被存储在寄存器中则没有内存地址因此不能将地址操作符用于寄存器变量。
int num1;
register int num2;
cout num1 endl; // ok
cout num2 endl; // not allowed2.3 静态持续变量
C为静态存储持性变量提供了3种链接性外部链接性、内部链接性和无链接性。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IWhEwhSN-1677946789635)(C:\Users\LYJ\AppData\Roaming\Typora\typora-user-images\image-20230304220011282.png)]
所有的静态持续变量都有下面的两个初始化特征
未被初始化的静态变量的所有位都被设置为0。只能使用常量表达式来初始化静态变量。
#include iostreamusing namespace std;int global 1; // 外部链接性可在其他文件使用static int one_file 2; // 内部链接性被限定在当前文件内使用void test()
{static int count 0; // 无链接性仅在函数定义内使用
}int main()
{return 0;
}C支持使用关键字 extern 来重新声明以前定义过的外部变量以及使用作用域解析操作符::来访问被隐藏的外部变量。
#include iostreamusing namespace std;int global 1; // 外部全局变量void test1()
{extern int global; // 引用声明重新声明在外部已定义的变量cout global endl; // 输出1
}void test2()
{int global 2; // 定义声明定义与全局变量同名的局部变量后局部变量将隐藏全局变量cout global endl; // 输出2cout ::global endl; // 输出1 // 表示使用变量的全局版本
}int main()
{test1();test2();return 0;
}2.4 说明符和限定符
存储说明符包括auto、register、static、extern、mutablecv-限定符包括const、volatile。
2.4.1 volatile
volatile 关键字表明即使程序代码没有对内存单元进行修改其值也可能发生变化。例如在两个程序共享数据场景下当A程序在第一次访问结束后B程序可能会在这之后修改数据值后面A程序再一次访问时就是新数据值了。 该关键字的作用是为了改善编译器的优化能力因为编译器在发现程序在几条语句中两次使用了某个变量的值时编译器为了能让查找效率更高可能会将该变量值缓存到寄存器中而不是让程序查找这个值两次这种优化假设变量的值在这两次使用之间不会变化。将变量声明为volatile相当于告诉编译器不要进行这种优化。 2.4.2 mutable
mutable 是用来修饰一个 const 结构或类实例的部分可变的数据成员的。
#include iostreamusing namespace std;struct ST {char name[20];mutable int num;
};int main()
{const ST st { Tom, 1 };st.num; // okst.name Job; // not allowedreturn 0;
}2.4.3 const
在C中在默认情况下全局变量的链接性为外部的但const全局变量的链接性为内部的。
const int num 1; // same as static const int num 1;C修改了常量类型的规则是为了能让程序员更便于使用。例如假设将一组常量放在头文件中并在同一个程序的多个文件中使用该头文件那么所有的源文件都将包含该定义。
如果const声明的链接性像常规变量那样是外部的这将出错因为不能在多个文件中定义同一个全局变量。也就是说其他引用文件必须都要使用extern关键字来提供引用声明。如果const声明是内部的那每个源文件都有自己的一组常量而不是所有文件共享一组常量。
如果出于某种原因程序员希望某个常量的链接性为外部的则可以使用关键字extern来覆盖默认的内部链接性。
extern const int num 1;2.5 语言链接性
在C中由于同一个名称可能会对应多个函数因此C编译器执行名称矫正或名称修饰为重载函数生成不同的符号。例如可能将spiff(int)转换为_spiff_i而将spiff(double)转换为_spiff_d这种方法被称为C语言链接。
如果要在C程序中使用C库中预编译的函数由于spiff(int)在C库文件中符号为spiff_而C查找约定是查找符号名称_spiff_i此时需要使用函数原型来指出要使用的约定
extern C void spiff(int); // C
extern void spiff(int); // C
extern C void spiff(int); // C3 布局new操作符
布局new操作符能够在使用new申请内存时指定要使用的内存位置。
与常规new操作符的区别在于布局new操作符使用传递给它的地址它不跟踪哪些内存单元已被使用也不查找未使用的内存块因此这要求程序员自己去管理内存。
#include iostream
#include newusing namespace std;const int N 3;
char buffer[512];int main()
{double *pd1, *pd2;pd1 new double[N];pd2 new (buffer) double[N];for (int i 0; i N; i) {pd1[i] pd2[i] i * 0.2 1000;}cout Memory address: \n heap: pd1 , buffer: (void*)buffer endl;for (int i 0; i N; i) {cout pid1[ i ] in address pd1[i] , ;cout pid2[ i ] in address pd2[i] endl;}return 0;
}输出
Memory address:
heap: 0x7a1760, buffer: 0x407040
pid1[0] in address 0x7a1760, pid2[0] in address 0x407040
pid1[1] in address 0x7a1768, pid2[1] in address 0x407048
pid1[2] in address 0x7a1770, pid2[2] in address 0x4070504 名称空间
C中可以通过关键字namespace定义一种新的声明区域来创建命名的名称空间。
任何名称空间中的名称都不会与其他名称空间中的名称发生冲突。可以通过作用域解析操作符::使用名称空间来限定该名称。
4.1 using声明和using编译指令
using声明使指定的标识符可用using编译命令使整个名称空间可用。
namespace Test1 {int num 1;
}namespace Test2 {int num 2;
}using Test1::num; // using声明
using namespace Test2; // using编译命令另外可以给名称空间创建别名以简化对嵌套名称空间的使用。
namespace Out {namespace Inner {int num 1;}
}namespace OI Out::Inner;4.2 未命名的名称空间
可以通过省略名称空间的名称来创建未命名的名称空间。
由于这种名称空间没有名称因此不能在匿名空间所属文件外的其他文件中使用该名称空间中的名称因此这种方法可以替代链接性为内部的静态变量。
static int count; // 内部静态变量namespace {int count; // 应替代为匿名空间形式
}