命令行编译

一.cmd的运行方式

  1. win+R 打开运行框,输入cmd回车,出现命令行窗口
  2. win 后在搜索中输入cmd回车,出现命令行窗口
  3. 在文件夹窗口的地址栏中输入cmd回车,出现命令行窗口。

在命令行中,常用到的命令如下表

内部命令 含义 参数 示例
md make directory 新建立的文件夹名称 md 123
rd remove directory 要删除的文件夹名称 rd 123
cd change directory 要进入的文件夹名称 cd 123
dir 列出当前目录下的所有文件与文件夹
rename 更改文件名 原文件名 新文件名 rename 123.cpp 456.cpp
del 删除文件

另外:

  • 使用E: 来改变盘
  • 可以使用 echo somethings > 456.cpp 来直接生成一个456.cpp,内容是 somethings
  • start 456.cpp 使用cpp关联的程序打开456.cpp
  • notepad 1.in 使用记事本打开1.in

二.设置path

在命令行中运行命令时,系统查找此命令的方式可以理解为先在当前目录中查找,如果没有找到,再在环境变量path设置的路径中查找;如果显示找不到此命令时,可能是环境变量path中没有此命令的路径,可以在我的电脑上右键属性中找高级属性设置,找到系统环境变量中path,修改path,注意,新加的目录与之前的要用英文状态下的分号(;)进行分隔。修改完成后cmd窗口需要重新打开。

三.命令行编译

将g++的路径加入path后,重启命令行窗口后可以使用g++ -v来测试成功与否。

成功后,可以使用命令 g++ 你要编译的源代码文件名 -o 要生成的可执行文件名 来编译,如:

g++ 123.cpp -o 123
g++ 123.cpp -o 123 -O2 (2级优化,俗称吸氧)
g++ 123.cpp -o 123 -std=c++11 (使用c++11标准编译)

四、命令行重定向

  • 命令 > 文件:将命令的输出重定向至文件中,会覆盖原来所有内容
  • 命令 < 文件 :将文件内容做为命令的输入

五、文件内容比较

fc 文件1 文件2

如果有不同,会输出有那些不同,没有不同,fc命令返回0

六、一个完整的命令行示例

g++ 1.cpp -o 1 && 1 < 1.in > 1.out && fc 1.ans 1.out /w

对拍

对拍是一种进行检验或调试的方法,通过对比两个程序的输出来检验程序的正确性。可以将自己程序的输出与其他程序的输出进行对比,从而判断自己的程序是否正确。

对拍过程要多次进行,因此需要通过批处理的方法来实现对拍的自动化。

具体而言,对拍需要一个数据生成器两个要进行输出结果比对的程序

每运行一次数据生成器都将生成的数据写入输入文件,通过重定向的方法使两个程序读入数据,并将输出写入指定文件,最后利用 Windows 下的 fc 命令比对文件(Linux 下为 diff 命令)来检验程序的正确性。如果发现程序出错,可以直接利用刚刚生成的数据进行调试。

对拍的步骤

  1. 建立编写brust程序
  2. 建立编写opt程序
  3. 编写数据生成器程序
  4. 编写对拍程序并运行此程序进行对拍

brust程序(正确的程序或别人正确的程序)

644差分(模板)题目示例

/* created by chjshen, date: 2023-04-18 11:02 */
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1E5 + 5;
int n, m, a, b, s[N];
int l, r, t;
void handle()
{
    for (int i = l; i <= r; i++)
    {
        if (t == 0)
            s[i] -= b;
        else
            s[i] += a;
    }
}
void initInput(void)
{
    cin >> n >> m >> a >> b;
    for (int i = 1; i <= n; i++) cin >> s[i];
    for (int i = 1; i <= m; i++)
    {
        cin >> l >> r >> t;
        handle();
    }
    for (int i = 1; i <= n; i++) cout << s[i] << " ";
    cout << endl;
}
int main(void)
{
    initInput();
    return 0;
}

opt程序(优化后的程序或自己其他的程序)

644差分(模板)题目示例

/* created by chjshen, date: 2023-04-18 16:19 */
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1E5 + 5;
#define debug cout << "DEBUG" << endl
int n, m, a, b, s[N], d[N];
void handle(int l, int r, int c)
{
    if (c == 0)
        d[l] -= b, d[r + 1] += b;
    else
        d[l] += a, d[r + 1] -= a;
}
void show()
{
    for (int i = 1; i <= n; i++)
    {
        d[i] = d[i - 1] + d[i];
        cout << d[i] << " ";
    }
    cout << endl;
}
void initInput(void)
{
    cin >> n >> m >> a >> b;
    for (int i = 1; i <= n; i++)
    {
        cin >> s[i];
        d[i] = s[i] - s[i - 1];
    }
    for (int i = 1; i <= m; i++)
    {
        int l, r, c;
        cin >> l >> r >> c;
        handle(l, r, c);
    }
}
int main(void)
{
    initInput();
    show();
    return 0;
}

数据生成器

  • 最好是保证数据随机,可以生成大样例,但是在对拍时我们应该生成小样例数据,方便调试和查错。
  • 如何生成随机数据:seed rand RAND_MAX ect.. 示例程序:
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<ctime>
#include<algorithm>
using namespace std;
int n, m;
int main(int argc, char * argv[])
{
     int t = 10;
     if(argc > 1)
     {
         t = atoi(argv[1]);
     }
     srand(time(0) + t);
     n = rand() % 10 + 1; // 0 - RANDMAX
     m = rand() % 5 + 1;
     while(n <= m)
     {
         n = rand()% 10 +1;
     }
     cout << n << " " << m << endl;
     int a[11];
     for(int i = 1; i <= m; i++)
         a[i] = i;

     for(int i = m + 1; i <= n; i++)
     {
         a[i] = rand() % m + 1;
     }

     random_shuffle(a + 1, a + n + 1);
     for(int i = 1; i <= n; i++)
         cout << a[i] << " ";
     
     cout << endl;
     return 0;
}

对拍程序

  • 程序化(脚本化)实现 数据生成器生成的随机 样例数据用a程序和b程序运行得结果a.out 和 b.out,自动对比是否相同。 示例程序:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;

int main()
{
    // 1. 先编译3个文件 force.cpp, opt.cpp, data.cpp
    system("g++ force.cpp -o force");   
    system("g++ opt.cpp -o opt");   
    system("g++ data.cpp -o data");
    for(int i = 1; i <= 10000; i++)
    {
    	  // 2. 生成输入文件 pai.in
    	  char f[200];
    	  sprintf(f, "data %d > pai.in", i);
    		system(f);

        // 1. 用force生成答案 pai.ans 
        system("force < pai.in > pai.ans");
        // 2. 生成pai.out
        system("opt < pai.in > pai.out");
        // 3. 比较两个生成的文件
        if(system("fc pai.ans pai.out >null"))
        {
            cout << i <<  ": WA!" << endl;
            break;
        }
        else
            cout << i << ": AC" << endl;
    }
    return 0;
}