0

我很好奇我应该如何将一个相对简单的 C++ 脚本编译为尽可能小的可执行文件大小。

无需过多讨论为什么这个程序会有用,这里是我的代码:

#include <cstdlib>
#include <stdio.h>
#include <string>

using namespace std;

unsigned long long inputAdjust(const string myinput) {
    unsigned long long myadjust;
    if (myinput=="B") {
        myadjust=1;
    } else if (myinput=="K") {
        myadjust=1024;
    } else if (myinput=="M") {
        myadjust=1048576;
    } else if (myinput=="G") {
        myadjust=1073741824;
    } else {
        myadjust=1;
    }
    return myadjust;
}

long long asmAnswer (const string myinput, const unsigned long long fir, const unsigned long long sec) {
    unsigned long long myanswer;
    if (myinput=="A") {
        myanswer = fir + sec;
    } else if (myinput=="S") {
        myanswer = fir - sec;
    } else if (myinput=="M") {
        myanswer = fir * sec;
    } else {
        myanswer = fir + sec;
    }
    return myanswer;
}

double dAnswer (const unsigned long long fir, const unsigned long long sec) {
    double myanswer;
    myanswer = (double)fir/sec;
    return myanswer;
}

void outputAnswer (const string myinput, const long long myanswer) {
    if (myinput=="B") {
        printf("%lld",myanswer);
    } else if (myinput=="K") {
        printf("%.2f",(double)(myanswer/1024));
    } else if (myinput=="M") {
        printf("%.2f",(double)(myanswer/1048576));
    } else if (myinput=="G") {
        printf("%.2f",(double)(myanswer/1073741824));
    } else if (myinput=="O") {
        if (myanswer>0) {
            if (myanswer<1024 && myanswer>-1024) {
                printf("%lld b",myanswer);
            } else if (myanswer<1048576 && myanswer>-1048576) {
                printf("%.2f kb",(double)(myanswer/1024));
            } else if (myanswer<1073741824 && myanswer>-1073741824) {
                printf("%.2f mb",(double)(myanswer/1048576));
            } else {
                printf("%.2f gb",(double)(myanswer/1073741824));
            }
        }
    } else { //assume bytes
        printf("%lld",myanswer);
    }
}

void outputAnswer (const string myinput, const double myanswer) {
    if (myinput=="P") {
        printf("%.3f",(myanswer*100.0));
    } else {
        printf("%.3f",myanswer);
    }
}

int main(int argc, char* argv[]) { 
    if (argc < 5) {
        // If we have less than 5 arguments, output the usage 
        string filename = argv[0];
        printf("\nUsage: bytemath.exe BKMG BKMGO[P] ASMD FirstNum SecondNum\n    First <OPERATOR> Second\n");
        return 0;
    } else {
        string input =  argv[1];
        string output = argv[2];
        string oper =   argv[3];
        unsigned long long first =  atoll(argv[4]);
        unsigned long long second = atoll(argv[5]);
        unsigned long i_adjust;
        unsigned long o_adjust;

        i_adjust = inputAdjust(input);
        first *= i_adjust;
        second*= i_adjust;

        if (oper=="D") { // we want to divide so need to use a double rather than long
            double answer;
            answer = dAnswer(first, second);
            outputAnswer(output, answer);
        } else { // otherwise do +, -, or *
            long long answer;
            answer = asmAnswer(oper, first, second);
            outputAnswer(output, answer);
        }

        return 1;
    }
}

基本上它对大数进行数学运算,因为批处理文件只能处理 32 位无符号整数。我可能只使用 VBS 之类的东西,但这是我目前正在使用的解决方案。

我需要程序是独立的,所以它必须静态链接到库。cout通过将所有命令替换为 ,我能够将大小从 ~570kb 减小到 ~148kb printf,但我想知道我还能做些什么来减小文件大小。

我正在用 MiniGW 4.6 编译它,这是我目前的编译命令:

g++ -Os -s -static bytemath.cpp -o bytemath.exe

在不重写太多代码的情况下,我还能做些什么来减小文件大小?

谢谢。

编辑

两个大节省者正在摆脱<iostream>and <string>,我可以通过用 char* 比较替换我的所有cout命令printf和替换我的字符串比较来做到这一点。对于字符,我需要确保访问数组的第 0 个元素并将其与单引号中的字符进行比较,而不是双引号(即if (myinput[0]=='P') {,而不是if (myinput=="P") {)。

再次感谢大家!570kb 到 18kb,适合我!

4

2 回答 2

2

只是一个猜测,但是:删除字符串并用枚举和/或 char* 替换它们。无论如何,您通常都使用像枚举这样的字符串,并且输入字符上的简单 if 可以为您提供枚举。

于 2013-09-18T16:00:20.033 回答
0

如果您已完成调试,则可以在编译器命令中添加“-s”。'-s' 表示去除所有符号。剥离或修改附加到汇编器和链接编辑器输出的符号表可以节省程序调试后的空间,并且它还将限制动态绑定的符号

此外,尝试通过 ref 传递 std::string 而不是通过值更改 inputAdjust(const string myinput) 来传递给 inputAdjust(const string& myinput) 这可能无助于减少二进制大小,但它会避免在运行时进行堆分配。

于 2013-09-18T16:04:56.750 回答