user-0 提问: C语言求幂运算非得那么反人类么？

回复:
user: user-1
content: 考虑算符优先级的话,参考下面: /*--------------------------------------- 函数型计算器(VC++6.0,Win32 Console)程序由 yu_hua 于2007-07-27设计完成 功能： 目前提供了10多个常用数学函数:     ⑴正弦sin     ⑵余弦cos     ⑶正切tan     ⑷开平方sqrt     ⑸反正弦arcsin     ⑹反余弦arccos     ⑺反正切arctan     ⑻常用对数lg     ⑼自然对数ln     ⑽ｅ指数exp     ⑾乘幂函数∧ 用法： 如果要求2的32次幂，可以打入2^32<回车> 如果要求30度角的正切可键入tan(Pi/6)<回车> 注意不能打入：tan(30)<Enter> 如果要求1.23弧度的正弦，有几种方法都有效： sin(1.23)<Enter> sin 1.23 <Enter> sin1.23  <Enter> 如果验证正余弦的平方和公式,可打入sin(1.23)^2+cos(1.23)^2 <Enter>或sin1.23^2+cos1.23^2 <Enter> 此外两函数表达式连在一起,自动理解为相乘如：sin1.23cos0.77+cos1.23sin0.77就等价于sin(1.23)*cos(0.77)+cos(1.23)*sin(0.77) 当然你还可以依据三角变换，再用sin(1.23+0.77)也即sin2验证一下。 本计算器充分考虑了运算符的优先级因此诸如：2+3*4^2 实际上相当于：2+(3*(4*4)) 另外函数名前面如果是数字,那么自动认为二者相乘. 同理，如果某数的右侧是左括号，则自动认为该数与括弧项之间隐含一乘号。 如：3sin1.2^2+5cos2.1^2 相当于3*sin2(1.2)+5*cos2(2.1) 又如：4(3-2(sqrt5-1)+ln2)+lg5 相当于4*(3-2*(√5 -1)+loge(2))+log10(5) 此外，本计算器提供了圆周率 Pi键入字母时不区分大小写,以方便使用。 ----------------------------------------*/ #include <iostream> #include <iomanip> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <stdio.h> #include <string.h> #include <windows.h> using namespace std; const char Tab=0x9; const int  DIGIT=1; const int MAXLEN=16384; char s[MAXLEN],*endss; int pcs=15; double fun(double x,char op[],int *iop) {     while (op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>         switch (op[*iop-1]) {         case  7: x=sin(x);  (*iop)--;break;         case  8: x=cos(x);  (*iop)--;break;         case  9: x=tan(x);  (*iop)--;break;         case 10: x=sqrt(x); (*iop)--;break;         case 11: x=asin(x); (*iop)--;break;         case 12: x=acos(x); (*iop)--;break;         case 13: x=atan(x); (*iop)--;break;         case 14: x=log10(x);(*iop)--;break;         case 15: x=log(x);  (*iop)--;break;         case 16: x=exp(x);  (*iop)--;break;         }     return x; } double calc(char *expr,char **addr) {     static int deep; //递归深度     static char *fname[]={ "sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp",NULL};     double ST[10]={0.0}; //数字栈     char op[10]={'+'}; //运算符栈     char c,*rexp,*pp,*pf;     int ist=1,iop=1,last,i;      if (!deep) {         pp=pf=expr;         do {             c = *pp++;             if (c!=' '&& c!=Tab)                 *pf++ = c;         } while (c!='\0');     }     pp=expr;     if ((c=*pp)=='-'||c=='+') {         op[0] = c;         pp++;     }     last = !DIGIT;     while ((c=*pp)!='\0') {         if (c=='(') {//左圆括弧             deep++;             ST[ist++]=calc(++pp,addr);             deep--;             ST[ist-1]=fun(ST[ist-1],op,&iop);             pp = *addr;             last = DIGIT;             if (*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是：当右圆括弧的右恻为左圆括弧或函数名字时，默认其为乘法                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }         else if (c==')') {//右圆括弧             pp++;             break;         } else if (isalpha(c)) {             if (!strnicmp(pp,"Pi",2)) {                 if (last==DIGIT) {                     cout<< "π左侧遇）" <<endl;exit(1);                 }                 ST[ist++]=3.14159265358979323846264338328;                 ST[ist-1]=fun(ST[ist-1],op,&iop);                 pp += 2;                 last = DIGIT;                 if (!strnicmp(pp,"Pi",2)) {                     cout<< "两个π相连" <<endl;exit(2);                 }                 if (*pp=='(') {                     cout<< "π右侧遇（" <<endl;exit(3);                 }             } else {                 for (i=0; (pf=fname[i])!=NULL; i++)                     if (!strnicmp(pp,pf,strlen(pf))) break;                 if (pf!=NULL) {                     op[iop++] = 07+i;                     pp += strlen(pf);                 } else {                     cout<< "陌生函数名" <<endl;exit(4);                 }             }         } else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='^') {             char cc;             if (last != DIGIT) {                 cout<< "运算符粘连" <<endl;exit(5);             }             pp++;             if (c=='+'||c=='-') {                 do {                     cc = op[--iop];                     --ist;                     switch (cc) {                     case '+':  ST[ist-1] += ST[ist];break;                     case '-':  ST[ist-1] -= ST[ist];break;                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 } while (iop);                 op[iop++] = c;             } else if (c=='*'||c=='/') { operate:        cc = op[iop-1];                 if (cc=='+'||cc=='-') {                     op[iop++] = c;                 } else {                     --ist;                     op[iop-1] = c;                     switch (cc) {                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 }             } else {                 cc = op[iop-1];                 if (cc=='^') {                     cout<< "乘幂符连用" <<endl;exit(6);                 }                 op[iop++] = c;             }             last = !DIGIT;         } else {             if (last == DIGIT) {                 cout<< "两数字粘连" <<endl;exit(7);             }             ST[ist++]=strtod(pp,&rexp);             ST[ist-1]=fun(ST[ist-1],op,&iop);             if (pp == rexp) {                 cout<< "非法字符" <<endl;exit(8);             }             pp = rexp;             last = DIGIT;             if (*pp == '('||isalpha(*pp)) {                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }     }     *addr=pp;     if (iop>=ist) {         cout<< "表达式有误" <<endl;exit(9);     }     while (iop) {         --ist;         switch (op[--iop]) {         case '+':  ST[ist-1] += ST[ist];break;         case '-':  ST[ist-1] -= ST[ist];break;         case '*':  ST[ist-1] *= ST[ist];break;         case '/':  ST[ist-1] /= ST[ist];break;         case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;         }     }     return ST[0]; } int main(int argc,char **argv) {     int a;      if (argc<2) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算函数表达式的值。"<<endl<<"支持(),+,-,*,/,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;         while (1) {             cout << "请输入表达式：";             gets(s);             if (s[0]==0) break;//             cout << s <<"=";             cout << setprecision(15) << calc(s,&endss) << endl;         }     } else if (argc==2 && 0==strcmp(argv[1],"/?")) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算由≥1个命令行参数给出的函数表达式的值。最后一个参数是.0～.15表示将计算结果保留小数0～15位"<<endl<<"支持(),+,-,*,/,^^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp"<<endl;     } else {         strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0;         if (argc>2) {             for (a=2;a<argc-1;a++) strncat(s,argv[a],MAXLEN-1);//将空格间隔的各参数连接到s             if (1==sscanf(argv[a],".%d",&pcs) && 0<=pcs && pcs<=15) {//最后一个参数是.0～.15表示将计算结果保留小数0～15位                 printf("%.*lf\n",pcs,calc(s,&endss));             } else {                 strncat(s,argv[a],MAXLEN-1);                 printf("%.15lg\n",calc(s,&endss));             }         } else {             printf("%.15lg\n",calc(s,&endss));         }     }     return 0; }

user: user-0
content: 引用 65 楼 zhao4zhong1 的回复:算符优先级那是词法分析和表达式树所能解决的问题。 //将A^B        替换为pow(A,B) //将A^(bbb)    替换为pow(A,bbb) //将(aaa)^B    替换为pow(aaa,B) //将(aaa)^(bbb)替换为pow(aaa,bbb) //将(A^B)^(a^b)替换为pow(pow(A,B),pow(a,b)) //将(a^(A^B))^b替换为pow(pow(a,pow(A,B)),b) //将a^((A^B)^b)替换为pow(a,pow(pow(A,B),b)) //依此类推  哈，终于有人回复了。  问题是转化后要能用，就必须要考虑算符优先级和语法树这些。  perl版本： [code=perl]#!/usr/bin/perl my $levelN = qr/ (?> [^()]+ | \( [^\(|\)]* (??{ $levelN }) [^\(|\)]* \) )* /x; while (<STDIN>) {   (/\^/) while     s/(\w*\.*\w+|[pow]*\($levelN\))\s*\^\s*([pow]*\($levelN\)|\w+\.*\w*)/pow($1,$2)/;   print "$_"; }

user: user-1
content: 引用 63 楼 felonwan 的回复:zhao大神的程序能比较好的处理“^”嵌套。只有些小毛病，比如这个： (10.000+(200.0*c)^(10.0+c))^B ==> pow(pow(10.000+200.0*c,10.0+c),B)  我的perl脚本相比之下差多了：没考虑嵌套的问题，虽然也能做一点嵌套，仅限于四种不同类型之间的嵌套，同种类型的嵌套会出错。 算符优先级那是词法分析和表达式树所能解决的问题。 //将A^B        替换为pow(A,B) //将A^(bbb)    替换为pow(A,bbb) //将(aaa)^B    替换为pow(aaa,B) //将(aaa)^(bbb)替换为pow(aaa,bbb) //将(A^B)^(a^b)替换为pow(pow(A,B),pow(a,b)) //将(a^(A^B))^b替换为pow(pow(a,pow(A,B)),b) //将a^((A^B)^b)替换为pow(a,pow(pow(A,B),b)) //依此类推 #pragma warning(disable:4018) #include <stdio.h> #include <string.h> char s[100]; char t[100]; int topow(char *p,int n) {//对p开始，长度n的内容进行替换     int i,j,k,m;     //形如"xxxxx"且xxxxx中不含^且不以(开头,原样返回     if (p[0]!='(') {         for (i=0;i<n;i++) if (p[i]=='^') break;         if (i>=n) {             strcpy(t,s);             if (p==s && n==strlen(s)) return 1;             else return 0;         }     } else if (p[n-1]==')') {//形如"(xxxxx)"且xxxxx中不含^,替换为"xxxxx",返回         for (i=1;i<n-1;i++) if (p[i]=='^') break;         if (i>=n-1) {             sprintf(t,"%.*s%.*s%s",p-s,s,n-2,p+1,p+n);             if (p==s && n==strlen(s)) return 1;             else return 0;         } else {//形如"(xxx^yyy)"且xxx和yyy中都不含^和(，替换为"pow[xxx,yyy]",返回             k=0;             for (i=1;i<n-1;i++) {                 if (p[i]=='^') {                     k++;                     if (k==1) j=i;                 }             }             if (k==1) {                 for (i=1;i<j;i++) if (p[i]=='(') break;                 if (i>=j) {                     for (i=j+1;i<n-1;i++) if (p[i]=='(') break;                     if (i>=n-1) {                         sprintf(t,"%.*spow[%.*s,%.*s]%s",p-s,s,j-1,p+1,n-j-2,p+j+1,p+n);                         if (p==s && n==strlen(s)) return 1;                         else return 0;                     }                 }             }         }     }     //形如"xxx^yyy"且xxx和yyy中都不含^和(，替换为"pow[xxx,yyy]",返回     k=0;     for (i=0;i<n;i++) {         if (p[i]=='^') {             k++;             if (k==1) j=i;         }     }     if (k==1) {         for (i=0;i<j;i++) if (p[i]=='(') break;         if (i>=j) {             for (i=j+1;i<n;i++) if (p[i]=='(') break;             if (i>=n) {                 sprintf(t,"%.*spow[%.*s,%.*s]%s",p-s,s,j,p,n-j-1,p+j+1,p+n);                 if (p==s && n==strlen(s)) return 1;                 else return 0;             }         }     }     //形如"wwwww"且wwwww中含≥2个^,按()层次从内到外逐层递归调用topow直到topow返回1     while (1) {         m=0;         k=0;         for (i=0;i<n;i++) {             if (p[i]=='(') {                 k++;                 if (k>m) m=k;             }             if (p[i]==')') {                 k--;             }         }         if (m==0) break;// //没有(),返回         k=0;         for (i=0;i<n;i++) {             if (p[i]=='(') {                 k++;                 if (k==m) j=i;             }             if (p[i]==')') {                 if (k==m) {                     k=i;                     break;//                 }                 k--;             }         }         topow(p+j,k-j+1);         strcpy(s,t);         if (1==topow(s,strlen(s))) break;//     }     return 1; } void chg() {//将[替换为(,]替换为)     int i,L;     char c;      L=strlen(t);     for (i=0;i<L;i++) {         c=t[i];         if (c=='[') c='(';         if (c==']') c=')';         s[i]=c;     } } int main() {     strcpy(s,"A^B");        printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"A^(bbb)");    printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(aaa)^B");    printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(aaa)^(bbb)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(A^B)^(a^b)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(a^(A^B))^b");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"a^((A^B)^b)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(10.000+(200.0*c)^(10.0+c))^B");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(10.000+((200.0*c)^(10.0+c)))^B");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     return 0; } //A^B ==> pow(A,B) //A^(bbb) ==> pow(A,bbb) //(aaa)^B ==> pow(aaa,B) //(aaa)^(bbb) ==> pow(aaa,bbb) //(A^B)^(a^b) ==> pow(pow(A,B),pow(a,b)) //(a^(A^B))^b ==> pow(pow(a,pow(A,B)),b) //a^((A^B)^b) ==> pow(a,pow(pow(A,B),b)) //(10.000+(200.0*c)^(10.0+c))^B ==> pow(pow(10.000+200.0*c,10.0+c),B) //(10.000+((200.0*c)^(10.0+c)))^B ==> pow(10.000+pow(200.0*c,10.0+c),B) //

user: user-0
content: 好了，下面这个基本完美，期待大家的检验。 小缺点：括号不能去掉；代码里面4种不同类型的代码顺序不能变（不熟悉正则表达式，凑合用，高手可能能简化吧）。   #!/usr/bin/perl  # dynamic regexp my $levelN; $levelN = qr/ (?> [^()]+ | \( (??{ $levelN }) \) )* /x;  while(<STDIN>){ my $line=$_; my $line1=$line; while(1){ 	$line1=~ s/(\($levelN\))\s*\^\s*(\($levelN\))/pow($1,$2)/g; #(a+b)^(c+d) 	if("$line1" eq "$line"){last;} 	$line=$line1; } while(1){ 	$line1=~ s/(\w*\.*\w*)\s*\^\s*(\($levelN\))/pow($1,$2)/g; #a^(b+c) 	if("$line1" eq "$line"){last;} 	$line=$line1; } while(1){ 	$line1=~ s/(\($levelN\))\s*\^\s*(\w*\.*\w*)/pow($1,$2)/g; #(a+b)^c 	if("$line1" eq "$line"){last;} 	$line=$line1; } while(1){ 	$line1=~ s/(\w*\.*\w*)\s*\^\s*(\w*\.*\w)/pow($1,$2)/g; #a^b 	if("$line1" eq "$line"){last;} 	$line=$line1; } print "$line1" }

user: user-0
content: zhao大神的程序能比较好的处理“^”嵌套。只有些小毛病，比如这个： (10.000+(200.0*c)^(10.0+c))^B ==> pow(pow(10.000+200.0*c,10.0+c),B)  我的perl脚本相比之下差多了：没考虑嵌套的问题，虽然也能做一点嵌套，仅限于四种不同类型之间的嵌套，同种类型的嵌套会出错。

user: user-0
content: 感谢上面的大神。 我自己写了个perl版本，第一次写perl，哈哈：  #!/usr/bin/perl  # copy file use File::Copy; use strict; my $file_new="@ARGV[0]c"; copy("@ARGV[0]",$file_new);  # dynamic regexp my $levelN; $levelN = qr/ (?> [^()]+ | \( (??{ $levelN }) \) )* /x;  # replacement open FH,$file_new; while(<FH>){ 	for my $line ($_) { 		$line=~ s/(\($levelN\))\s*\^\s*(\($levelN\))/pow($1,$2)/g; #(a+b)^(c+d) 		$line=~ s/(\w*\.*\w*)\s*\^\s*(\($levelN\))/pow($1,$2)/g; #a^(b+c) 		$line=~ s/(\($levelN\))\s*\^\s*(\w*\.*\w*)/pow($1,$2)/g; #(a+b)^c 		$line=~ s/(\w*\.*\w*)\s*\^\s*([^\(]\w*\.*\w)/pow($1,$2)/g; #a^b 		print $line; 	} } close FH;

user: user-2
content: 这么空闲啊，过来给我做义工吧，可以做很多好玩的东西。  引用 58 楼 felonwan 的回复:[quote=引用 55 楼 xiyuyan 的回复:] 同时需要说明，C是低层语言，这么设计也是合理的。 C语言本身支持的基本都是比较简单的原始操作。 而幂属于复杂数学运算。  请教下： 按位异或“^”如果设计之初就用“$”，应该不会造成什么其它问题吧？[/quote]  引用 59 楼 zhao4zhong1 的回复:技痒难忍，挠挠！//将A^B        替换为pow(A,B) //将A^(bbb)    替换为pow(A,bbb) //将(aaa)^B    替换为pow(aaa,B) //将(aaa)^(bbb)替换为pow(aaa,bbb) //将(A^B)^(a^b)替换为pow(pow(A,B),pow(a,b)) //将(a^(A^B))^b替换为pow(pow(a,pow(A,B)),b) //将a^((A^B)^b)替换为pow(a,pow(pow(A,B),b)) //依此类推 #pragma warning(disable:4018) #include <stdio.h> #include <string.h> char s[100]; char t[100]; int topow(char *p,int n) {//对p开始，长度n的内容进行替换     int i,j,k,m;     //形如"xxxxx"且xxxxx中不含^且不以(开头,原样返回     if (p[0]!='(') {         for (i=0;i<n;i++) if (p[i]=='^') break;         if (i>=n) {             strcpy(t,s);             if (p==s && n==strlen(s)) return 1;             else return 0;         }     } else if (p[n-1]==')') {//形如"(xxxxx)"且xxxxx中不含^,替换为"xxxxx",返回         for (i=1;i<n-1;i++) if (p[i]=='^') break;         if (i>=n-1) {             sprintf(t,"%.*s%.*s%s",p-s,s,n-2,p+1,p+n);             if (p==s && n==strlen(s)) return 1;             else return 0;         } else {//形如"(xxx^yyy)"且xxx和yyy中都不含^和(，替换为"pow[xxx,yyy]",返回             k=0;             for (i=1;i<n-1;i++) {                 if (p[i]=='^') {                     k++;                     if (k==1) j=i;                 }             }             if (k==1) {                 for (i=1;i<j;i++) if (p[i]=='(') break;                 if (i>=j) {                     for (i=j+1;i<n-1;i++) if (p[i]=='(') break;                     if (i>=n-1) {                         sprintf(t,"%.*spow[%.*s,%.*s]%s",p-s,s,j-1,p+1,n-j-2,p+j+1,p+n);                         if (p==s && n==strlen(s)) return 1;                         else return 0;                     }                 }             }         }     }     //形如"xxx^yyy"且xxx和yyy中都不含^和(，替换为"pow[xxx,yyy]",返回     k=0;     for (i=0;i<n;i++) {         if (p[i]=='^') {             k++;             if (k==1) j=i;         }     }     if (k==1) {         for (i=0;i<j;i++) if (p[i]=='(') break;         if (i>=j) {             for (i=j+1;i<n;i++) if (p[i]=='(') break;             if (i>=n) {                 sprintf(t,"%.*spow[%.*s,%.*s]%s",p-s,s,j,p,n-j-1,p+j+1,p+n);                 if (p==s && n==strlen(s)) return 1;                 else return 0;             }         }     }     //形如"wwwww"且wwwww中含≥2个^,按()层次从内到外逐层递归调用topow直到topow返回1     while (1) {         m=0;         k=0;         for (i=0;i<n;i++) {             if (p[i]=='(') {                 k++;                 if (k>m) m=k;             }             if (p[i]==')') {                 k--;             }         }         if (m==0) break;// //没有(),返回         k=0;         for (i=0;i<n;i++) {             if (p[i]=='(') {                 k++;                 if (k==m) j=i;             }             if (p[i]==')') {                 if (k==m) {                     k=i;                     break;//                 }                 k--;             }         }         topow(p+j,k-j+1);         strcpy(s,t);         if (1==topow(s,strlen(s))) break;//     }     return 1; } void chg() {//将[替换为(,]替换为)     int i,L;     char c;      L=strlen(t);     for (i=0;i<L;i++) {         c=t[i];         if (c=='[') c='(';         if (c==']') c=')';         s[i]=c;     } } int main() {     strcpy(s,"A^B");        printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"A^(bbb)");    printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(aaa)^B");    printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(aaa)^(bbb)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(A^B)^(a^b)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(a^(A^B))^b");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"a^((A^B)^b)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     return 0; } //A^B ==> pow(A,B) //A^(bbb) ==> pow(A,bbb) //(aaa)^B ==> pow(aaa,B) //(aaa)^(bbb) ==> pow(aaa,bbb) //(A^B)^(a^b) ==> pow(pow(A,B),pow(a,b)) //(a^(A^B))^b ==> pow(pow(a,pow(A,B)),b) //a^((A^B)^b) ==> pow(a,pow(pow(A,B),b)) //

user: user-2
content: 引用 57 楼 felonwan 的回复:[quote=引用 55 楼 xiyuyan 的回复:] 唉，这用争论吗？ 改不小菜一碟。 出100元辛苦费我给你改个。  同时需要说明，C是低层语言，这么设计也是合理的。 C语言本身支持的基本都是比较简单的原始操作。 而幂属于复杂数学运算。  但是，但是，世上无难事，就怕你能力不够又囊中羞涩！  最后，推荐尝试下： 习语言， 最完美的 C语言， 可以随意改变。  哈哈，您是说预处理上面改是吧，自己也能改，只是觉得光为改这个玩意花那么多时间和精力得不偿失，谢谢了。  比如说，自己简单写了几个sed： echo "d+ ((a*c)+b)^(a-b)*e" | sed 's/\([\* + - \/]\)\((.*)\)\^\((.*)\)\([ \* + - \/]\)/\1pow(\2,\3)\4/g' echo "10.011^20" | sed 's/\([a-z A-Z 0-9]\{1,\}\)\.\([a-z A-Z 0-9]\{1,\}\)\^\([a-z A-Z 0-9]\{1,\}\)/pow(\1.\2,\3)/g'[/quote]  看你的代码真心累，不清楚有几个人喜欢读你这个代码，反正我是不会看的。 我说好改是因为我有自己的编译器：习语言。 可以随意修改语法和实现。 修改语法定义及实现很容易。  当然在现有处理器，前置一个预处理动作，也是可以的。 总体不推荐，不能兼容的改变不如不改变，  中文符号库大的很，很多漂亮符号，干嘛非要吊死在几个英文符号上呢？

user: user-1
content: 技痒难忍，挠挠！//将A^B        替换为pow(A,B) //将A^(bbb)    替换为pow(A,bbb) //将(aaa)^B    替换为pow(aaa,B) //将(aaa)^(bbb)替换为pow(aaa,bbb) //将(A^B)^(a^b)替换为pow(pow(A,B),pow(a,b)) //将(a^(A^B))^b替换为pow(pow(a,pow(A,B)),b) //将a^((A^B)^b)替换为pow(a,pow(pow(A,B),b)) //依此类推 #pragma warning(disable:4018) #include <stdio.h> #include <string.h> char s[100]; char t[100]; int topow(char *p,int n) {//对p开始，长度n的内容进行替换     int i,j,k,m;     //形如"xxxxx"且xxxxx中不含^且不以(开头,原样返回     if (p[0]!='(') {         for (i=0;i<n;i++) if (p[i]=='^') break;         if (i>=n) {             strcpy(t,s);             if (p==s && n==strlen(s)) return 1;             else return 0;         }     } else if (p[n-1]==')') {//形如"(xxxxx)"且xxxxx中不含^,替换为"xxxxx",返回         for (i=1;i<n-1;i++) if (p[i]=='^') break;         if (i>=n-1) {             sprintf(t,"%.*s%.*s%s",p-s,s,n-2,p+1,p+n);             if (p==s && n==strlen(s)) return 1;             else return 0;         } else {//形如"(xxx^yyy)"且xxx和yyy中都不含^和(，替换为"pow[xxx,yyy]",返回             k=0;             for (i=1;i<n-1;i++) {                 if (p[i]=='^') {                     k++;                     if (k==1) j=i;                 }             }             if (k==1) {                 for (i=1;i<j;i++) if (p[i]=='(') break;                 if (i>=j) {                     for (i=j+1;i<n-1;i++) if (p[i]=='(') break;                     if (i>=n-1) {                         sprintf(t,"%.*spow[%.*s,%.*s]%s",p-s,s,j-1,p+1,n-j-2,p+j+1,p+n);                         if (p==s && n==strlen(s)) return 1;                         else return 0;                     }                 }             }         }     }     //形如"xxx^yyy"且xxx和yyy中都不含^和(，替换为"pow[xxx,yyy]",返回     k=0;     for (i=0;i<n;i++) {         if (p[i]=='^') {             k++;             if (k==1) j=i;         }     }     if (k==1) {         for (i=0;i<j;i++) if (p[i]=='(') break;         if (i>=j) {             for (i=j+1;i<n;i++) if (p[i]=='(') break;             if (i>=n) {                 sprintf(t,"%.*spow[%.*s,%.*s]%s",p-s,s,j,p,n-j-1,p+j+1,p+n);                 if (p==s && n==strlen(s)) return 1;                 else return 0;             }         }     }     //形如"wwwww"且wwwww中含≥2个^,按()层次从内到外逐层递归调用topow直到topow返回1     while (1) {         m=0;         k=0;         for (i=0;i<n;i++) {             if (p[i]=='(') {                 k++;                 if (k>m) m=k;             }             if (p[i]==')') {                 k--;             }         }         if (m==0) break;// //没有(),返回         k=0;         for (i=0;i<n;i++) {             if (p[i]=='(') {                 k++;                 if (k==m) j=i;             }             if (p[i]==')') {                 if (k==m) {                     k=i;                     break;//                 }                 k--;             }         }         topow(p+j,k-j+1);         strcpy(s,t);         if (1==topow(s,strlen(s))) break;//     }     return 1; } void chg() {//将[替换为(,]替换为)     int i,L;     char c;      L=strlen(t);     for (i=0;i<L;i++) {         c=t[i];         if (c=='[') c='(';         if (c==']') c=')';         s[i]=c;     } } int main() {     strcpy(s,"A^B");        printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"A^(bbb)");    printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(aaa)^B");    printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(aaa)^(bbb)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(A^B)^(a^b)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"(a^(A^B))^b");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     strcpy(s,"a^((A^B)^b)");printf("%s ==> ",s);topow(s,strlen(s));chg();printf("%s\n",s);     return 0; } //A^B ==> pow(A,B) //A^(bbb) ==> pow(A,bbb) //(aaa)^B ==> pow(aaa,B) //(aaa)^(bbb) ==> pow(aaa,bbb) //(A^B)^(a^b) ==> pow(pow(A,B),pow(a,b)) //(a^(A^B))^b ==> pow(pow(a,pow(A,B)),b) //a^((A^B)^b) ==> pow(a,pow(pow(A,B),b)) //

user: user-1
content: 引用 44 楼 felonwan 的回复:[quote=引用 43 楼 zhao4zhong1 的回复:] 完全可以自己写一小段C语言程序，将命令行指定的C/C++源代码文件中的 A^B自动替换为pow(A,B) A^(…)自动替换为pow(A,…) (...)^B自动替换为pow(...,B) (...)^(…)自动替换为pow(...,…)   其实linux下直接用sed处理一下也可以吧。[/quote] 你原来不笨啊！

user: user-0
content: 引用 55 楼 xiyuyan 的回复:同时需要说明，C是低层语言，这么设计也是合理的。 C语言本身支持的基本都是比较简单的原始操作。 而幂属于复杂数学运算。  请教下： 按位异或“^”如果设计之初就用“$”，应该不会造成什么其它问题吧？

user: user-0
content: 引用 55 楼 xiyuyan 的回复:唉，这用争论吗？ 改不小菜一碟。 出100元辛苦费我给你改个。  同时需要说明，C是低层语言，这么设计也是合理的。 C语言本身支持的基本都是比较简单的原始操作。 而幂属于复杂数学运算。  但是，但是，世上无难事，就怕你能力不够又囊中羞涩！  最后，推荐尝试下： 习语言， 最完美的 C语言， 可以随意改变。  哈哈，您是说预处理上面改是吧，自己也能改，只是觉得光为改这个玩意花那么多时间和精力得不偿失，谢谢了。  比如说，自己简单写了几个sed： echo "d+ ((a*c)+b)^(a-b)*e" | sed 's/\([\* + - \/]\)\((.*)\)\^\((.*)\)\([ \* + - \/]\)/\1pow(\2,\3)\4/g' echo "10.011^20" | sed 's/\([a-z A-Z 0-9]\{1,\}\)\.\([a-z A-Z 0-9]\{1,\}\)\^\([a-z A-Z 0-9]\{1,\}\)/pow(\1.\2,\3)/g'

user: user-3
content: 引用 53 楼 zhao4zhong1 的回复:不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。   赵老师，你邮箱发邮件了，但是没回复。我qq：9301462    c++ 源码修改

user: user-2
content: 唉，这用争论吗？ 改不小菜一碟。 出100元辛苦费我给你改个。  同时需要说明，C是低层语言，这么设计也是合理的。 C语言本身支持的基本都是比较简单的原始操作。 而幂属于复杂数学运算。  但是，但是，世上无难事，就怕你能力不够又囊中羞涩！  最后，推荐尝试下： 习语言， 最完美的 C语言， 可以随意改变。

user: user-0
content: 引用 53 楼 zhao4zhong1 的回复:不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。  确实。 搞过C中用matlab库画图，麻烦。 还是直接输出数据再用matlab画省事。

user: user-1
content: 不要做A语言代码修改为B语言代码的无用功。 也不要做用A语言代码直接调用B语言代码库这样复杂、这样容易出错的傻事。 只需让A、B语言代码的输入输出重定向到文本文件，或修改A、B语言代码让其通过文本文件输入输出。 即可很方便地让A、B两种语言之间协调工作。

user: user-0
content: 引用 51 楼 zhao4zhong1 的回复:[quote=引用 50 楼 felonwan 的回复:] [quote=引用 49 楼 zhao4zhong1 的回复:] 调侃容易写代码难。 Talk is cheap,show me the codes.——Linus Torvalds  用户调侃一下，提点建议还是可以的吧，改不改还是赵大师这样的大神说了算嘛。[/quote] gcc和g++源代码摆在那里，没人能够阻止你将它们分支为mygcc和myg++，将^重新定义为指数操作。[/quote]  之前还真有这样的想法，搞个为数值计算优化的C编译器，pow函数是一个小方面，我所知道的Fortran的动态数组和矩阵操作也可以引进来嘛。不过转念一想，这样的话，用C还有什么好处么？直接用Fortran不就完了。

user: user-1
content: 引用 50 楼 felonwan 的回复:[quote=引用 49 楼 zhao4zhong1 的回复:] 调侃容易写代码难。 Talk is cheap,show me the codes.——Linus Torvalds  用户调侃一下，提点建议还是可以的吧，改不改还是赵大师这样的大神说了算嘛。[/quote] gcc和g++源代码摆在那里，没人能够阻止你将它们分支为mygcc和myg++，将^重新定义为指数操作。

user: user-0
content: 引用 49 楼 zhao4zhong1 的回复:调侃容易写代码难。 Talk is cheap,show me the codes.——Linus Torvalds  用户调侃一下，提点建议还是可以的吧，改不改还是赵大师这样的大神说了算嘛。

user: user-1
content: 引用 48 楼 felonwan 的回复:[quote=引用 47 楼 zhao4zhong1 的回复:] 写个完成将命令行指定的C/C++源代码文件中的 A^B自动替换为pow(A,B) A^(…)自动替换为pow(A,…) (...)^B自动替换为pow(...,B) (...)^(…)自动替换为pow(...,…)  功能的sed命令，贴到此帖，留给后人，估计会让你名垂青史！  这样伟大的功绩还是留给zhao大师吧，偶等小辈无此实力，只能“调侃”一下pow(x,n)函数反人类。 [/quote] 调侃容易写代码难。 Talk is cheap,show me the codes.——Linus Torvalds