你好,C++(3)2.1 一个C++程序的自白

2023-12-17

第2部分 与C++第一次亲密接触

在浏览了C++“三分天下”的世界版图之后,便对C++有了基本的了解,算是一只脚跨入了C++世界的大门。那么,怎样将我们的另外一只脚也跨入C++世界的大门呢?是该即刻开始编写C++程序?还是……

正在我们犹豫的时候,便看到前面有一个人被一群满头问号的C++初学者围在当中。我们赶紧挤进去一看,噢,原来是一个C++程序正做自我介绍呢。

2.1 一个C++程序的自白

“大家好,欢迎来到奇妙的C++世界。我是C++世界的迎宾——一个最简单最普通的C++程序,我的名字叫
“HelloWorld.exe”。我虽然简单而普通,但却几乎是这个世界上最著名的C++程序。每个来到C++世界的初学者与C++的第一次亲密接触都
是通过我来完成的。大家在听我介绍之前,一定会觉得C++程序非常神秘,比如,C++程序是如何创建的?一个完整的C++程序由哪几部分构成?传说中的源
文件到底是什么文件?C++程序是如何执行的?其实,我们C++程序一点都不神秘,跟大家一样,我们有自己的老爸老妈,有自己的五官四肢,也有自己的生命
过程。什么?大家觉得不可思议?别着急,下面且听我一一道来……”

2.1.1 用Visual Studio创建C++程序

大家进入C++世界最感兴趣的第一件事,就是亲自动手创建一个C++程序。大多数C++程序都是通过一种叫做集成开发环境
(Integrated Development
Environment,IDE)的软件创建的,可以说,它是创建C++程序的工厂。虽然可以用于创建C++程序的集成开发环境有很多,但是我们首选的还
是由微软公司开发的Visual Studio。作为一款经过二十多年不断发展而来的集成开发环境,Visual
Studio拥有多种功能各异的版本:有适用于大规模团队开发的旗舰版,也有适用于个人开发的专业版,还有免费的快速版。如果我们只是想利用Visual
Studio进行C++的学习,我们可以使用其中的Visual C++
Express版本。它不仅功能齐备,而且小巧。更重要的是,它是免费的,我们可以从微软的网站免费下载安装。Visual
Studio是Windows平台上最常用的开发环境,至于其它的开发工具以及Linux平台上的开发工具,请大家参考后文的2.3小节。

现在,请大家在我的引导下,一步一步地使用Visual
Studio创建我们的第一个C++程序。第0步,新建项目。从开始菜单找到已经安装好的Visual
Studio并点击启动。当第一次启动Visual Studio时,它会要求我们选择界面布局设置,这里我们选择适用于Visual
C++的布局设置,然后经过片刻的等待就可以看到Visual Studio华丽丽的起始页了。在Visual
Studio中,我们所有的开发工作都是在某个项目中进行的,所以我们利用Visual
Studio编写程序的第一步就是创建用于管理程序文件的项目:单击起始页左侧的“新建项目”,在弹出的“新建项目”对话框中,选中左侧树状图中的
“Visual
C++”节点,然后在右侧的项目类型列表中选中“空项目”这个项目模板,接着在对话框下方输入项目名称“HelloWorld”并选择项目存放的位置,最
后点击“确定”按钮,就完成了新项目的创建。

图2-1 新建项目

第1步,添加源文件。新项目的创建,只是搭起了一个空的框架,还等着我们向其中添加一些实质的内容。在左侧的“解决方案资源
管理器”中,找到“HelloWorld”项目下的“源文件”分支,然后右键单击“源文件”分支,在弹出的菜单中依次选择“添加->新建项”,就可
以得到“添加新项”对话框。在“添加新项”对话框中,选中左侧树状图中的“Visual
C++”分支,然后在右侧文件类型列表中选中“C++文件”,接着在对话框下方将文件名称修改为“HelloWorld.cpp”,最后点击“确定”按
钮,Visual Studio就会为我们新建一个HelloWorld.cpp源文件并添加到项目中。

图2-2 添加源文件

第2步,编辑代码。有了空白的源文件,就相当于画家支好了画板,作家摆好了稿纸,就等着我们开始编写代码了。在已经被打开的HelloWorld.cpp文件中,我们编辑如下的代码(这里值的特别提醒的是,其中的标点都应该是英文的):

#include <iostream>

using namespace std;

 int main()
{
    // 在屏幕输出“Hello World!”字符串
    cout<<"Hello World!"<<endl;

    return 0;
}

图2-3 编辑代码

第3步,编译执行程序。代码编辑完成之后,我们就可以编译并执行这个程序向C++世界打个招呼了。这一步可以通过菜单命令
“调试->开始执行(不调试)”来完成,但更多时候,我们通过Ctrl+F5快捷键来完成。当我们按下快捷键之后,Visual
Studio会编译项目当中的源文件,如果源文件中没有错误,它就会生成相应的HelloWorld.exe可执行文件,随后会启动执行这个程序,从而在
DOS窗口打印出一个“Hello World!”字符串向C++世界打招呼。

图2-4 Hello World!

最佳实践:等一下,等一下,我还没看清输出结果呢!

当我们在Visual
Studio中执行某个程序时,如果这个程序在执行过程中不需要与用户进行交互,那么它执行时打开的DOS窗口会在其执行完毕后立即关闭。如果这个程序有
结果输出,我们甚至来不及看清程序的输出结果。一个程序执行完了,连输出结果都来不及看清这怎么行呢?

为了解决这个问题,我们可以在程序的主函数返回之前加上一条“system("pause");”语句。例如:

int main()
{

    // …

    // 让程序在结束之前暂停
   system("pause");

    return 0;
}

加上这条语句后,程序会在执行完毕之前暂停,这样,我们就有足够的时间看清程序的输出结果了。自然,这条语句也还可以用在程序执行过程中那些需要暂停的地方,以此来提高程序的可交互性。

另外一种查看程序输出结果的方法,就是先启动DOS窗口,然后DOS窗口中手动地执行我们的应用程序。在这种方式下,DOS窗口并不会在程序执行完毕后关闭,所以我们也有时间查看程序的输出结果。

经过这样四个简单的步骤,我们就轻松编写了我们的第一个C++程序,完成了与C++的第一次亲密接触。除了借助Visual
Studio创建C++程序之外,我们甚至还可以采取纯粹手工的方式创建C++程序。但无论何种方式,它们的基本流程都是一样的。如果使用Visual

Studio方式,因为有开发工具的帮助,上手容易开发效率也会比较高。而如果是使用手工方方式,则可以对整个开发过程进行灵活定制,从而满足我们一些个
性化的需求。对于初学者而言,手工方式稍显复杂。最佳的学习路线应该是,先以Visual
Studio方式入门,等到有了一定的基础,需要对程序的编写过程有更精细控制的时候,再改用手工方式。这样才不至于在入门阶段就被复杂的手工方式困住了
脚步,而在进阶后又受到开发工具的限制。

2.1.2 C++程序=预编译指令+程序代码+注释

麻雀虽小,五脏俱全。大家别看我个头小,只有短短的几行代码,实现的功能也很简单,但是我同样拥有C++程序的“五官和四
肢”:预编译指令、程序代码和注释,如图2-5所示。大多数情况下,这三个基本组成部分都被放在一个扩展名为“cpp”的文本文件中,这个文件被称为
C++
源文件。源文件记录了我的“五官和四肢”,规划了我的人生。源文件的编写者就是我的设计师了。通过修改源文件,可以改变我的面貌、我的人生轨迹,让我完成
各种任务,实现各种功能。

图2-5 C++程序=预编译指令+程序代码+注释

下面,大家一起来看看我的源文件,从中认识我的“五官和四肢”。

1. 预编译指令

在源文件中,以“#”开始的内容就是预编译指令。它的作用是告诉编译器,让它在真正进行编译之前对源文件进行一些插入文件、替换字符串等预处理,以得到最终参与编译的源文件。例如,在我的源文件HelloWorld.cpp中,第一行就是一个插入文件的预编译指令:

#include <iostream>

其中,“#include”指令用于将指定的文件插入该指令所在的位置,作为整个源文件的一部分。因为这样的文件总是在一个源文件的头部被插入,所
以我们通常将这样的文件称为头文件(header
file)。在这里,我们插入了“iostream”这个头文件,这是因为我们在程序中需要用到其中定义的cout和endl来完成输出(关于C++的输
入输出,可以参考后文2.2小节的介绍)。需要注意的是,“#include”指令后的文件名有两种表示方式:如果使用双引号""来包围一个文件名,则预
处理器在处理这个指令的时候,将首先在当前目录(也就是这个源文件所在的目录)下搜索这个文件,如果不存在,则继续在项目的包含目录(包括项目的默认头文
件目录,也就是Visual
Studio安装目录下的“\VC\include”文件夹,以及在项目属性中设置的项目附加头文件目录)下搜索这个文件;而如果使用尖括
号<>来包围一个文件名,预处理器则会直接在项目的包含目录下搜索这个文件。所以,通常我们使用""来插入当前项目目录下的头文件(比如我们
自己创建的头文件),而使用<>来插入各种项目包含目录下的库头文件(比如这里的iostream)。这里值得再次提醒的是,代码中使用的所
有标点符号(这里使用的尖括号,也包括后面代码中用到的双引号、逗号、分号等)必须是英文的。某些中英文符号非常相似,很容易被初学者搞混淆而引起编译错
误,这一点尤其值得初学者注意。

2. 程序代码

程序代码主体由若干C++语句(通常以分号结束的一行代码就是一条语句)构成,可以说语句是构成程序的基本单位。在我的源文件中,第一条C++语句是:

using namespace std;

这条语句表示我所使用的名字空间是std。所谓名字空间,就是程序中各种标识符(比如这里的cout和endl,我们通过这些符号来访问程序中的各
种元素,实际上也可以说是这些元素的名字,所以这些符号也被称为标识符)所在的范围,更具体的可以参考7.3.2小节关于名字空间的介绍。在C++中,任
何标识符都被定义在某个名字空间中,而同一个标识符也可以在多个名字空间中同时定义。这就像张家村有一个人叫陈良乔,而李家村也有一个人叫陈良乔一样,大
家在称呼“陈良乔”这个人的时候,为了表达清楚,我们必须在名字前加上一个前缀,称之为“张家村的陈良乔”或是“李家村的陈良乔”。C++中的名字空间就
相当于这里的“张家村”、“李家村”。在这里,我们在后面代码中使用的cout、endl都是来自std这个村的,所以我们用这条语句告诉编译器,如果遇
到没有加前缀的标识符(比如,这里的cout),可以到std村去找找看,如果能找到,那就是它了(结果,在std村里找到了std::cout)。
C++的大多数内容都定义在std这个名字空间中,所以,很多时候我们都需要在代码中使用这条语句引入std名字空间。当然,如果不使用这条语句,我们也
可以在标识符的前面直接加上名字空间的前缀,明确地表示这是来自于某个名字空间的标识符(在代码中,使用 std::cout代替
cout,用std::endl代替endl)。

接下来的一条语句是:

int main()

这条语句连同它后面大括号内的内容,共同构成了main()函数,也称为主函数。所谓函数,是C++程序中最基本的一个组织单元,它把若干条语句组
织到一起共同实现某个功能。如果说一条语句相当于人体的一个细胞的话,那么函数就相当于由若干细胞构成的拥有一定功能的器官。而这里的主函数就是一个程序
中最重要的“器官”。一个C++程序必须有一个主函数,且只能有一个主函数。当C++程序开始执行的时候,将首先进入主函数,然后逐条地执行其中的语句,
直到其中的语句执行完毕退出主函数,程序执行也就宣告结束。可以说,主函数定义了一个C++程序的一生。

知道更多:为什么一个C++程序必须有且只能有一个main函数?

当我们双击执行程序后,执行程序的进程会首先创建主线程,主线程然后调用约定启动运行时库,由启动运行时库调用约定好的main函数,自此开始执行用户的代码。main函数是主线程的执行入口,所以一个C++程序必须有一个main函数。

同时,一个线程不可能拥有多个执行入口。而且在C++中,全局符号(变量、函数) 只能有一个定义。main函数作为一个全局函数,自然也就只能有一个。

接下来的就是主函数中的一条语句:

cout<<"Hello World!"<<endl;

cout是定义在头文件“iostream”中的一个输出流对象,它是C++标准库预定义的对象,通常用于将文字或数字输出到屏幕。前面使用
“#include”预编译指令包含“iostream”头文件就是为了在代码中使用这个对象。关于输入/输出流,会在以后的章节中做更详细的介绍,这里
只要知道这条语句可以将“Hello World!”这串文字输出到屏幕上即可。值得再次提醒的是,这里的双引号也必须是英文的。

我的最后一条语句是:

return 0;

它表示程序成功执行完毕并返回(return)。通常,我们返回一个0值表示程序成功执行(如果在程序的执行过程中出现错误,也可以返回表示错误信
息的其他数值。程序的执行者可以接受这个返回值以判断程序是否成功执行)。到这里,主函数中的语句执行完毕,而我的一生也到此终结。

3. 注释

注释是源代码的编写者为了帮助代码的阅读者(代码后期维护人员,也包括编写者自己)更好地理解代码,而在代码中写下的关于某
一行或某一段代码的一些解释性文字。虽然源代码中的注释并不会参与最终的编译,不会对程序的功能产生影响,但它会提高代码的可读性,为后期的维护带来极大
的便利。例如这里的:

// 在屏幕输出“Hello World!”字符串

就是一条注释,它解释了接下来的一条语句的作用,从而可以让我们对代码有更好的理解。

在形式上,C++中的注释可以分为单行注释和块注释两种。“//”是单行注释符,“//”之后直到换行的所有内容都属于注释。因为内容只有一行,所以它常常用来对代码作简短的解释。例如上面的注释就是一个典型的单行注释。

C++中的块注释我们用一对“/*”和“*/”表示,凡是出现在这对符号之间的所有内容都属于注释。因为它可以包含多行内容,当我们需要对代码做详细解释的时候,可以使用块注释。例如:

/*
    这是一段注释
*/

在功能上,注释一般分为序言性注释和解释性注释。序言性注释多位于程序源文件的开始,用来说明程序的文件名、用途、编写时间、维护历史等。在上面的例子中,我们可以在源文件的第一行加上一个序言性注释来解释这个源文件的功能:

// HelloWorld.cpp:在屏幕输出“Hello World!”字符串

序言性注释被广泛用于大型的项目中。通常,每个项目都有自己定义的序言性注释格式,用来向代码的阅读者说明一些必要的信息。
下面是从一个实际的项目中摘录的一段序言性注释,它说明了源文件的名字、作用、文件的修改历史等信息,帮助阅读者更好地理解代码。大家可以以此为模板,编
写适合于自己的序言性注释。

///
// AppDataView.cpp : implementation file
//
//CAppDataView
//  This view is designed to display the App Data
//
// Version: 2.1
// Date: September 2001
// Author: Chen Liangqiao
// Email: chenlq@live.com
// Copyright (c) 2002. All Rights Reserved.
//
//   History:
/*
27.09.2001       Chen Liangqiao   
                     Added OnCreate(), OnUpdate():
                        Added usage of mesh tracer layers
                        Added bugfix for Graphics zoom error
30.10.2001       Chen Liangqiao   
                     Changed order of MPR View only in _TORCHTONAV
08.11.2001       Zeng Me   
                        Added EUpdateReason, used for UpdateAllView(),
                        Added voxel trafo
                        Changed the control panel due to new CTestCtrl
*/

///

与序言性注释多位于源文件开始部分不同,解释性注释多分散于源代码的各个部分,用来向代码阅读者解释代码的含义,说明一些必要的问题等。例如,上面例子中的注释:

//在屏幕上输出“Hello World!”字符串
cout<<"Hello World!"<<endl;

这句解释性注释就是用来向代码阅读者说明其下代码的功能是输出字符串“Hello World!”。

最佳实践:什么是好的注释

虽然程序的注释并不影响程序功能的实现,编译器也不会去阅读我们的注释,但是好的注释却可以增加程序代码的可读性,使程序更易于维护。谁都不愿意维护一份没有注释的代码,那无异于阅读天书。那么,什么样的注释才算是好注释呢?

首先,该注释的地方一定要注释。

注释是对代码的“提示和说明”,是为了帮助代码的阅读者更好地理解代码而存在的。当我们认为代码不能被“一眼看穿”而需要加以解释,或者是代码需要特别说明的时候,就应该添加注释,加以额外的解释和说明,帮助阅读者理解代码。例如:

// 判断某个浮点数是否近似整数
bool is_int(double d)
{
    // 用浮点数d减去其整数部分(int)d,获得其小数部分
    double s = d - (int)d;

   // 判断小数部分是否在误差范围内
    if(s > 0.000001)
        return false;
    else
        return true;
}

这里的注释,恰当地对比较难以理解的代码进行了解释(如果没有注释,很难一下子就理解“double s = d - (int)d;”这行代码的含义到底是什么),提高了代码的可读性。

其次,不该注释的地方最好不要注释。

注释仅仅是对代码的“提示和说明”而已,如果代码本身已经能够很好地做到“望文生义”,也就没有必要“画蛇添足”地加以注
释了。另外需要注意的是,注释只是简短的说明性文字,不是详尽的文档。程序的注释不可喧宾夺主,注释过多会让人眼花缭乱,反而降低了代码的可读性。例如,
下面代码中的注释就不太合适:

// 判断某个浮点数是否近似整数

// 其参数是表示输入的浮点数d

// 其返回值是一个表示是否近似的bool值

bool is_int(double d)
{
    // 用浮点数减去其整数部分,获得其小数部分
    // 其中,d表示浮点数,(int)d表示浮点数的整数部分
    double s = d - (int)d;

    // 判断小数部分是否在误差范围内
    if(s > 0.000001)
         return false; // 小数部分大于误差范围,则表示浮点数不近似整数,返回false
    else
         return true; // 小数部分小于误差范围,则表示浮点数近似整数,返回true
}

这段代码中的注释,对一些含义非常浅显易懂的代码也进行了详尽的解释,注释的内容远超过了代码的内容,这样不但没有增加代码的可读性,反倒是让代码淹没在了复杂的注释中,反而降低了代码的可读性。这样的注释实属“画蛇添足”多此一举。

另外,应该养成良好的代码注释习惯。编写代码时添加必要的注释,修改代码时修改相应的注释,删除无用的注释,保证注释与代码的一致性。

注释应当准确、易懂,避免二义性。错误的注释不但无益反而有害。

注释的位置应与被描述的代码相邻,可以放在代码的上方或右方,不可放在下方。例如:

// 在屏幕输出“Hello World!”字符串
// 对下方的代码进行注释
cout<<"Hello World!"<<endl;


int n = 1024; // 循环次数,对左侧代码进行注释

如果代码比较长,特别是有多重嵌套时,应当在某些段落的结束处加以注释,以便于查看嵌套结构的起始和结束位置。例如,一个多重循环的代码及其注释如下:

for ( int i = 0; i < 100; ++i )
{
    for ( int j = 0; j < 100; ++j )
    {
        // 算法处理...
    } // j循环结束
} // i循环结束

程序代码不仅仅是写给编译器看的,它更是写给程序员自己或者他人看的。对于编译器来说,代码中有没有注释无所谓,然而对于阅读代码的程序员来说,合
适的注释可以很大程度上提高代码的可读性,让代码更易于维护。因而,注释是C++程序代码中必不可少的一部分,而程序代码中是否包含合适的注释,也成为衡
量一个程序员是否优秀的标准。

预编译指令、程序代码与注释共同构成了我的“五官与四肢”,但这时候我还只是一个后缀为cpp的文本文件,而要得到最后的可执行的exe文件,还得靠我的父亲母亲:编译器和链接器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

你好,C++(3)2.1 一个C++程序的自白 的相关文章

  • 使用 ## 和 __LINE__ 创建 C 宏(与定位宏的标记串联)

    我想创建一个 C 宏来创建一个基于名称的函数 在行号上 我想我可以做类似的事情 真正的函数在大括号内有语句 define UNIQUE static void Unique LINE void 我希望能扩展到类似的内容 static voi
  • 低级挂钩/SetWindowsHookEx lParam 自动重复?

    在这里阅读 Windows PC 上如何实现键盘自动重复 https stackoverflow com questions 876852 how is keyboard auto repeat implemented on a windo
  • 函数“sum”的隐式声明在 C99 中无效

    我一直在寻找解决方案 但没有找到任何有帮助的东西 我收到以下错误 Implicit declaration of function sum is invalid in C99 Implicit declaration of function
  • 检查数据库中是否存在记录

    我正在使用这些代码行来检查记录是否存在 SqlCommand check User Name new SqlCommand SELECT FROM Table WHERE user txtBox UserName Text conn int
  • 从 unsigned char* 到 char* 的转换无效

    这是一个代码 1 int main int argc char argv 2 3 signed char S psc 4 unsigned char U pusc 5 char C pc 6 7 C S 8 C U 9 10 pc psc
  • 为什么迭代器类型推导失败? [复制]

    这个问题在这里已经有答案了 为什么这在 C 中不起作用 为什么我不能限制foo的参数为std vector
  • 如何进行Visual Studio格式字典初始化?

    所有 Visual Studio 也包括 2012 不格式化以下内容 messageProcessor new Dictionary
  • 为什么下面的重叠比较总是评估为 true

    我不明白为什么以下代码有警告 指出重叠比较始终评估为真 接下来的语句永远不会被执行 QVariant MainModel data const QModelIndex index int role const if index isVali
  • 如何在 C# 中创建 PKCS12 .p12 文件?

    这可能是一个n00b问题 但我在这方面确实没有任何经验 我需要创建一个包含 X509 证书和私钥的 p12 捆绑包 我当前有两个对象 X509Certificate2 和包含关键信息的 RSAParameters 对象 如何将它们合并到 p
  • 如何从命名空间内重载运算符<<

    这是我能想到的最小的包含示例 首先是类的标题 每当使用 pragma once ifndef EURO H define EURO H include
  • 如何检查给定调用站点的重载决策集

    如何检查重载解析集 我在多个调用站点中使用了 4 个相互竞争的函数 在一个调用站点中 我期望调用一个函数 但编译器会选择另一个函数 我不知道为什么 这不是微不足道的 为了了解发生了什么 我正在使用enable if disable if打开
  • 是否可以在对Where 的调用中调用命名方法?

    我试图从 RedGate 的这本免费电子书中了解 Linq 的一些性能影响ftp support red gate com ebooks under the hood of net memory management part1 pdf f
  • 指向 VLA 的指针

    你可能知道 VLA 的优点和缺点 https stackoverflow com a 3082302 1606345在 C11 中它们是可选的 我认为使 VLA 成为可选的主要原因是 堆栈可能会爆炸 int arr n where n 10
  • C# SignalR 异常 - 连接在收到调用结果之前开始重新连接

    我正在开发 2 个应用程序 第一个是 C 控制台应用程序 另一个是 Asp net Web 应用程序 我正在使用 SignalR 连接两者 这是我的 C 控制台应用程序 客户端 public class RoboHub public sta
  • 如何使用 MongoDB 实现 ASP.NET Core 3.1 Identity?

    是一个 API 用于简化后端和逻辑代码来管理用户 密码 个人资料数据 角色 声明 令牌 电子邮件确认等 对于 Visual Studio 来说 支撑脚手架 https learn microsoft com en us aspnet cor
  • 智能感知不显示评论

    如果我在 Visual Studio 2010 中输入类似的内容数据集1 我得到所有可用方法和属性的列表 智能感知 这很好用 但是 如果我在此列表中选择一个方法或属性 我不会得到 if 的描述 例如 如果我有类似的东西 public cla
  • 如何编写完全可移植的 4 字节字符常量的编译时初始化

    遗留 代码大致如下所示 define MAKEID a b c d UInt32 a lt lt 24 UInt32 b lt lt 16 UInt32 c lt lt 8 UInt32 d define ID FORM MAKEID F
  • 查找文本文件中每行的行大小

    如何计算每行中的字符或数字数量 是否有类似 EOF 的东西更像是行尾 您可以遍历行中的每个字符并不断增加计数器直到行尾 n 遇到 确保以文本模式打开文件 r 而不是二进制模式 rb 否则流不会自动将不同平台的行结束序列转换为 n 人物 这是
  • 如何在c#中获取斐波那契数

    伙计们 我有一个关于斐波那契的问题 如何获得斐波那契数列 该数字也将以用户输入结束 例如 如果我输入 21 则输出必须为 0 1 1 2 3 5 8 13 21 这是我的代码 static void Main string args int
  • 使用 List.Contains 方法为 LINQ 构建表达式树

    Problem 我正在重构一些LINQ查询我们的 Web 应用程序中的多个报告 并且我尝试将一些重复的查询谓词移至它们自己的中IQueryable扩展方法 以便我们可以将它们重新用于这些报告以及将来的报告 正如您可能推断的那样 我已经重构了

随机推荐

  • 服务器安全的威胁和防范

    由于服务器发挥着至关重要的作用 因此存储在服务器上的机密数据和信息非常具有价值 做好服务器安全至关重要 常见的服务器 安全隐患 包括 1 恶意的攻击 遭受CC攻击和DDoS攻击 导致游戏或是网站打不开 严重影响业务开展 2 网站挂马 网站被
  • 代码随想录算法训练营Day3 | 203.移除链表元素、707.设计链表、59.螺旋矩阵II

    LeetCode 203 移除链表元素 本题思路 就是常规的移除链表中的元素的操作 需要注意的点 头节点 head val val 的情况的处理 如果 head val val 就要继续往后 head head next 因此我们要遍历到第
  • 最强姿态模型 mmpose 使用实例

    mmpose 介绍 https blog csdn net jacke121 article details 135040186 图片姿态实例 本机地址 B project pose mmpose dev 1 x Copyright c O
  • Arrays.asList()方法:陷阱与解决之道

    在Java编程中 Arrays类提供了一系列用于操作数组的实用方法 其中 Arrays asList 方法是一个常用的方法 用于快速将数组转换为List集合 然而 这个方法存在一些潜在的陷阱 可能导致出现意外的行为 本文将介绍 Arrays
  • DSP捕获输入简单笔记

    程序 cap c Created on 2023年12月16日 Author My PC include cap h void cap init EALLOW SysCtrlRegs PCLKCR3 bit GPIOINENCLK 1 gp
  • 蓝禾2024届秋招/校招内推信息/内推码

    公司名称 蓝禾 内推码 SQDPVPM 内推来源 内推鸭小程序 官方招聘网站 https lanhevip jobs feishu cn index m position external referral code SQDPVPM
  • 007 Windows组策略

    组策略的应用 1 基本概念 组策略是一组策略的集合 组策略 英语 Group Policy 是 微软 Windows NT 家族操作系统的一个特性 它可以控制 用户帐户 和计算机帐户的工作环境 组策略提供了操作系统 应用程序 和 活动目录
  • 剑指 Offer(第2版)面试题 35:复杂链表的复制

    剑指 Offer 第2版 面试题 35 复杂链表的复制 剑指 Offer 第2版 面试题 35 复杂链表的复制 解法1 模拟 剑指 Offer 第2版 面试题 35 复杂链表的复制 题目来源 48 复杂链表的复刻 解法1 模拟 算法 复制原
  • mmpose 使用笔记

    目录 自己整理的可以跑通的代码 图片demo 检测加关键点 自己整理的可以跑通的代码 最强姿态模型 mmpose 使用实例 CSDN博客 图片demo python demo image demo py tests data coco 00
  • 2023“楚怡杯”湖南省赛“信息安全管理与评估“--数字取证调查(高职组)

    2023 楚怡杯 湖南省 信息安全管理与评估 高职组 任务书 2023 楚怡杯 湖南省 信息安全管理与评估 高职组 任务书 第一阶段竞赛项目试题 第二阶段竞赛项目试题 第二部分 数字取证调查 需
  • python快速实现简单的图片透明化

    整张图片透明化的完整代码如下 import os import glob from PIL import Image def convert to transparent image path output folder image Ima
  • Llama 架构分析

    从代码角度进行Llama 架构分析 Llama 架构分析 前言 Llama 架构分析 分词 网络主干 DecoderLayer
  • 牛客小白月赛83 解题报告

    题目链接 https ac nowcoder com acm contest 72041 question A题 解题思路 签到 代码 include
  • OSG中几何体的绘制(二)

    5 几何体操作 在本章的前言中就讲到 场景都是由基本的绘图基元构成的 基本的绘图基元构成简单的几何体 简单的几何体构成复杂的几何体 复杂的几何体最终构造成复杂的场景 当多个几何体组合时 可能存在多种降低场景渲染效率的原因 在很多3D引擎中
  • 中文星期几&十二时辰

    输入年月日输出中文星期败 输入时间字符串 输出十二时辰 笔记模板由python脚本于2023年12月16日 23 39 04创建 本篇笔记适合 熟悉python字符串类型str 并可以熟练应用 的coder翻阅 学习的细节是欢悦的历程 Py
  • 时序预测 | Python实现GRU电力需求预测

    时序预测 Python实现GRU电力需求预测 目录 时序预测 Python实现GRU电力需求预测 预测效果 基本描述 程序设计 参考资料
  • 软件工程期末复习+数据仓库ETL

    一 软件工程 请用基本路径测试方法为下列程序设计测试用例 并写明中间过程 第1步 画出流程图 1 菱形用于条件判断 用在有分支的地方 2 矩形表示一个基本操作 3 圆形是连接点 第2步 计算程序环路复杂性 流图G的环路复杂度V G 定义为
  • 十七、如何将MapReduce程序提交到YARN运行

    1 启动某个节点的某一个用户 hadoop node1 jps 13025 Jps hadoop node1 yarn daemon start resourcemanager hadoop node1 jps 13170 Resource
  • ES6 面试题 | 14.精选 ES6 面试题

    前端开发工程师 主业 技术博主 副业 已过CET6 阿珊和她的猫 CSDN个人主页 牛客高级专题作者 在牛客打造高质量专栏 前端面试必备 蓝桥云课签约作者 已在蓝桥云课上架的前后端实战课程 Vue js 和 Egg js 开发企业级健康管理
  • 你好,C++(3)2.1 一个C++程序的自白

    第2部分 与C 第一次亲密接触 在浏览了C 三分天下 的世界版图之后 便对C 有了基本的了解 算是一只脚跨入了C 世界的大门 那么 怎样将我们的另外一只脚也跨入C 世界的大门呢 是该即刻开始编写C 程序 还是 正在我们犹豫的时候 便看到前面