标题:扑克牌24点
只看楼主
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 9楼 xzlxzlxzl
我试过用静态链接库,可以成功编译文件,但如果一个不小心没有打开工作空间直接编译附加在工作空间里面的文件,那个工作空间就废了,多少有点无语~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-05-07 23:47
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
最近我也看了一下关于静态链接库操作的相关内容,这个比动态链接库相对来说要简单一些~

静态链接库其实已经把需要编译的函数内容写进lib文件里面了,所以只要有个lib那么就算主体实现函数的C文件不见了也没关系,只要有个lib(或者加上.h头文件)就可以了~
这样做的好处就是对于一些不怎么更新的代码块来说使用方便,编译速度相对于动态链接库来说会快一些~

但用静态链接库因为包含整个函数内容,所以所占的空间比较大,而且一个库如果只是需要其中一个,那要么全部要,要么全部不要
所以如果修改了某个lib实现文件的代码块,那么要重新对所有引用该代码块的lib都要进行编译,这样多少会影响编译效率~
当然,查过资料说早期的tcc甚至看过vc那些库函数都是用静态链接库实现的(因此vc找不到库函数实现的C文件,这个问题当时不怎么理解现在可以了),所以对于实现文件不常更新或者说不再更新这种情况用静态链接库还是比较好用的~

动态链接库就是链接库只包含该函数的地址信息而不包含主体内容,所以说对外依赖相对来说较强~
但它所占用的空间比较少,通常是用到某个函数就链接哪个具体函数,修改函数实现主体(删除该函数除外)不需要重新编译dll(就是动态链接库)
如果对于一些只实现部分功能要长期跟进,或者要长期测试维护的代码,而且被外部引用比较多的那用动态链接库比较方便管理
但如果删除了那个实现函数那dll文件,因为dll加载的地址入口还在,那样编译的时候难免会出问题,所以dll还是需要同步更新的~

其实链接库涉及到内容还有很多,就是自己组织一次顺便加深理解而简单说说而已~





[此贴子已经被作者于2018-5-8 01:39编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-05-08 01:36
xzlxzlxzl
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:湖北
等 级:贵宾
威 望:125
帖 子:1091
专家分:5825
注 册:2014-5-3
得分:0 
动态库和静态库的共同点是用函数调用方式使用第三方代码,不同点在于代码编译成可执行的exe文件之后,静态库的内容会原样拷贝到exe文件里和自己写的函数融为一体,因此复制这个exe文件可以拿到其他机器上单独执行,而使用了动态库则只在exe文件头部有一个加载动态库文件接口,exe文件每次执行时都会动态加载动态库文件到内存才能正常运行,如果要拷贝到其他电脑上,则必须也要附带拷贝动态库文件,exe不能单独执行。
动态库比较灵活,有共享特性(多个exe同时使用一个时只需加载一次),加载执行速度较慢;静态库独立性强,相对好使用管理(你只要拷贝一个exe就可以拿到其它机器上了),加载执行速度快。
一楼代码geteval函数需要做写调整,那个使用运算符优先级相同就免除括号算法的有部分错误,当存在除法是“a/b*c*d”和“a/(b*c)*d”显然不一样,因此优先级相同的不能一概而论,修改后的代码如下,可显著减少算式冗余:
int geteval(int *a,int k,int o)
{
    char op[]="+-*/",kz[5]={0},kf[5]={0},ev[100];
    int i,b[3]={0};
    for(i=0;i<3;i++,o/=4)b[i]=o%4;  //分解运算符组合(分解为3个4进制数组合)
   
    //实际上括号只和乘除配对,可以在精简算式,太啰嗦就不再考虑怎么组织逻辑了
    if(k)
    {//处理括号组合,0:无括号,6:两对括号,1-5:通过运算一对括号包含2个或3个操作数
        if((b[0]<2&&b[1]<2&&b[2]<2)||(b[0]==2&&b[1]==2))return 0;  //运算只有加减或连续两个乘法的不需要括号
        if(k<6)
        {//一对括号
            kz[(k-1)/2]='(';
            kf[(k+2)/2]=')';
        }
        else
        {//两对括号
            kz[0]=kz[2]='(';
            kf[1]=kf[3]=')';
        }
    }
    //用sprintf组合算式
    sprintf(ev,"%s%d%c%s%d%s%c%s%d%s%c%d%s",kz,a[0],op[b[0]],kz+1,a[1],kf+1,op[b[1]],kz+2,a[2],kf+2,op[b[2]],a[3],kf+3);
    if(eval(ev)==24)
    {
        printf("%s=24\n",ev);
        return 1;
    }
    return 0;
}
感谢版主提供的几个全排列代码,看来都差不多,看来是不是要考虑一个非递归的全排列了。
我更需要一个能顺序返回全排列结果的函数,就是第一次调用返回1234,第二次调用返回1243……一直到返回0就是全排列完成。
2018-05-08 07:34
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
得分:0 
回复 13楼 xzlxzlxzl
其实这个不关运算符优先级问题,而是和数据整除直接相关,因为楼主那个代码是整除而不是小数的所以才会这样,至于全排列非递归可以的,可以用栈保存递归信息返回就可以了(相信以楼主的能力可以弄出来的)~
我还想到另一个处理方法就是用指针函数(这个在二叉树遍历输出经常看到)先上课,有什么再来补充~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2018-05-08 08:18



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-486711-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.405595 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved