#include stdio.h
让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名与空间、网页空间、营销软件、网站建设、洞口网站维护、网站推广。
#include stdlib.h
double my_add(double a, double b) { return a + b; }
double my_sub(double a, double b) { return a - b; }
double my_mul(double a, double b) { return a * b; }
double my_div(double a, double b) { return a / b; }
typedef double (*cal_fp)(double a, double b);
double my_cal(double a, double b, cal_fp fp)
{
return fp(a, b);
}
int main()
{
double a, b, r;
char sign;
scanf("%lf %c %lf", a, sign, b);
switch(sign)
{
case '+': r = my_cal(a, b, my_add); break;
case '-': r = my_cal(a, b, my_sub); break;
case '*': r = my_cal(a, b, my_mul); break;
case '/': r = my_cal(a, b, my_div); break;
}
printf("%lf %c %lf = %lf\n", a, sign, b, r);
return 0;
}
下面是个完整的程序,我测试通过符合你的要求,你在看看,我写的模块化实现,给你贴的有些乱,
函数声明如果在一个.c 文件把所有的子函数都在前面在声明一下,不是很复杂,
#include stdio.h
#include math.h
(#include "head.h" ) //自己定义的一定要用双引号括起来
//如果用尖括号就会出错
//这里包含的.h 文件时各个子函数的声明可以去掉
//函数功能:实现了减加乘除运算
void main()
{
void (*p)(float ,float); //定义指向函数的指针变量
float a,b; //上面的语句有些难度,相当于一个函数
char logo;
puts("输入两个数和想要的操作:\n");
scanf("%f%c%f",a,logo,b);
while(1)
{switch(logo)
{
if((logo=='+')(logo=='-')(logo=='/')(logo=='*'))
{case '+': p = sum; (*p)(a,b);break; //这里就把指针给加
case '-': p = subtraction; (*p)(a,b);break; //同上
case '/': p = division; (*p)(a,b);break; //同上 给除
case '*': p = multiplication; (*p)(a,b);break;
default:break;
}
else
printf("输入错误重新输入")
}
}
}
#include stdio.h
#include math.h
void division(float a,float b)
{
float div;
div=a/b;
printf("%.3f\n",div);
}
#include stdio.h
#include math.h
void multiplication(float a,float b)
{
float mul;
mul=a*b;
printf("%.3f\n",mul);
}
#include stdio.h
#include math.h
void subtraction(float a,float b)
{
float ch;
ch=a-b;
printf("%.3f\n",ch);
}
#include stdio.h
#include math.h
void sum(float a,float b)
{
float he;
he=a+b;
printf("%.3f\n",he);
}
#include stdio.h
#include math.h
int AddNumber(double *res, double left, double right)
{
*res = left+right;
return 1;
}
int SubNumber(double *res, double left, double right)
{
*res = left-right;
return 1;
}
int MulNumber(double *res, double left, double right)
{
*res = left*right;
return 1;
}
int DivNumber(double *res, double left, double right)
{
if (fabs(right) 1e-10)
{
printf("DIV 0!\n");
return 0;
}
*res = left/right;
return 1;
}
int (*(EvaluateTable[4]))(double *, double, double) = {
AddNumber, SubNumber, MulNumber, DivNumber
};
int main()
{
double left, right, res;
int i;
while (scanf("%lf%lf", left, right) != EOF)
{
for (i=0; i4; i++)
{
if ((EvaluateTable[i])(res, left, right))
printf("%lf\n", res);
}
}
return 0;
}
不知道怎么左对齐,//后面是英文注释///后面是中文注释 给采纳!!
// EX6_08.CPP
// A program to implement a calculator
#include stdio.h // For input/output
#include stdlib.h // For the exit() function
#include ctype.h // For the isdigit() function
#include string.h // For the strcpy() function
void eatspaces(char * str); // Function to eliminate blanks
double expr(char * str); // Function evaluating an expression
double term(char * str, int * pindex); // Function analyzing a term
double number(char * str, int * pindex); // Function to recognize a number
char * extract(char * str, int * index); // Function to extract a substring
const int MAX = 80; // Maximum expression length including '\0'
int main(void)
{
char buffer[MAX]; // Input area for expression to be evaluated
char c;
int j,i;
printf("Welcome to your friendly calculator.\n");
printf("Enter an expression, or an empty line to quit.\n");
for(;;)///无开始无终止只有过程,就是不停的循环,保证可以连续输入好几个式子,如先求1+2回车直接3+2再回车,可以多次求
{///式子是一步一步来的,就是说不进行完这个语句是不会进行下一个的
i=0;
scanf("%c",c); ///捕捉第一个数是c// Read an input line
while(c!='\n')
{
buffer[i++]=c;///,i++是先运算后自加,++i是先自加后运算,所以第一个数放在buffer[0]处
scanf("%c",c);
}///把式子放在这个数列中,while控制回车时式子结束,此时i是
buffer[i]='\0';///式子最后是一个\o作为标志"\0代表字符数串的结束标志,最后一个在i-1的位置
eatspaces(buffer);///对式子去空格处理 // Remove blanks from input
if(!buffer[0]) // Empty line ends calculator
return 0;///已经去过空格了,buffer[0]应该是有值的,但是没有的话就直接结束,返还0
printf( "\t= %f\n\n",expr(buffer)); ///结果是expr分函数return的结果 // Output value of expression
}
}
// Function to eliminate blanks from a string
void eatspaces(char * str)///预处理,把指向数组的指针设为*str,其中数组中数的地址都是相连的,char数组每个地址差1,int数组每个差2依次类推,其中char型的指针加1就是加一,int型的加一是加二
{
int i=0; // 'Copy to' index to string
int j=0; // 'Copy from' index to string
while((*(str+i) = *(str+j++)) != '\0')///这里是对*(str+i)的一个赋值,没有空格时每次i都加1式子有空格时(str+i)和(str+j++)是相等的,
/// 当有空格时i不加一,就让空格这个地址等于下一个地址,即把式子向前推了一个字符,直到\0 // Loop while character copied is not \0
if(*(str+i) != ' ') // Increment i as long as
i++; // character is not a blank
return;
}
// Function to evaluate an arithmetic expression
double expr(char * str)///真正处理,对加减的分函数
{
double value = 0; ///value是结果,也就是真实值 // Store result here
int index = 0; // Keeps track of current character position
value = term(str, index);///先解决第一步,因为数字还是char型根本没法算,先把第一个数变成数顺便有()*/都做完了直到看见-+ // Get first term
for(;;) ///保证了多加的情况,后同 // Infinite loop, all exits inside
{
switch(*(str+index++)) ///通过加数组对应的地址时数组一个一个往后推,碰到\0 + -做判断 其他符号输出错误 // Choose action based on current character
{
case '\0': ///一直到最后的标记,输出 // We're at the end of the string
return value; // so return what we have got
case '+': ///先把第一个数变成数然后有()就先()有/*就先/* 最后不都没有了就到-+了然后-+后面的也要先乘除啊,就value += term(str, index);这样也能让后面的也能变成数,也能让后面的先*/依次类推 // + found so add in the
value += term(str, index); // next term
break;
case '-': // - found so subtract
value -= term(str, index); // the next term
break;
default: // If we reach here the string
printf("Arrrgh!*#!! There's an error.\n");///其他符号输出错误因为先进行的*、和()运算,所以再不是-+就一定错了
exit(1);
}
}
}
// Function to get the value of a term
double term(char * str, int * pindex)///对乘除的分函数
{
double value = 0; // Somewhere to accumulate the result
value = number(str, pindex); // Get the first number in the term
// Loop as long as we have a good operator
while((*(str+(*pindex))=='*')||(*(str+(*pindex))=='/'))///进来的是/或者*才继续,不然直接输出了
{
if(*(str+(*pindex))=='*') // If it's multiply,
{
++(*pindex);///是乘先加,就是乘的是后面的
value *= number(str, pindex); ///通过这样,先括号后乘除解决第一步以后的 // multiply by next number
}
if(*(str+(*pindex))=='/') // If it's divide,
{
++(*pindex);
value /= number(str, pindex); // divide by next number
}
}
return value; // We've finished, so return what we've got
}
// Function to recognize a number in a string
double number(char * str, int * pindex)///对(的分函数
{
double value = 0.0; // Store the resulting value
char * psubstr; // Pointer for substring
if(*(str + (*pindex)) == '(') // Start of parentheses
{
++(*pindex);
psubstr = extract(str, pindex);///先看后括号 // Extract substring in brackets
value = expr(psubstr); ///打回来以后再直接用大的顺序进行计算 // Get the value of the substring
return value; // Return substring value
}
///以下是将我们在数组中定义为char的数变为int形式
while(isdigit(*(str+(*pindex)))) ///isdidit是调用的ctype.h 这个库函数的一种函数,判断字符是否为阿拉伯数字 // Loop accumulating leading digits
value=10*value + (*(str+(*pindex)++) - 48);///因为ASC码48就是'0',也就是说'0'的值是48,而后依次是'1'到'9'。这样正好是char型的减去48就是它对应的int值
///这样层层推进,直到value是这个数为止(如125就会定义为三个char变量,先判断1是阿拉伯数字,让它乘10加2就成12,再看5是阿拉伯数字,12乘10加5就成了125,变成阿拉伯数字了)
// Not a digit when we get to here
if(*(str+(*pindex))!='.') ///如果没有小数点可以回去了,这里小数点显然无法通过上面的isdigit,就是会有123.45这原来是六个字符(1/2/3/。/4/5)通过上面变成了(123/。/4/5)其中4/5还是char型 // so check for decimal point
return value; // and if not, return value
double factor = 1.0; // Factor for decimal places
while(isdigit(*(str+(++(*pindex)))))///当检测到小数点后面是数的时候就会进行 // Loop as long as we have digits
{
factor *= 0.1; // Decrease factor by factor of 10
value=value + (*(str+(*pindex))-48)*factor;///这里直接第一轮123加0.1*4,第二轮再加0.01*5 // Add decimal place
}
return value; // On loop exit we are done
if(*(str+(*pindex))!='.') // so check for decimal point
return value; ///在此看后面有无小数点,没有就回去,有的话就双小数点,没有返回值发生错误 // and if not, return value
}
// Function to extract a substring between parentheses
// (requires string.h)
char * extract(char * str, int * pindex)///对)的分函数
{
char buffer[MAX]; // Temporary space for substring
char * pstr = NULL; ///代表一个空指针 // Pointer to new string for return
int numL = 0; // Count of left parentheses found
int bufindex = *pindex;///这个定义是 bufindex直接指向当前所指了 // Save starting value for index
do///多次循环
{
buffer[(*pindex) - bufindex] = *(str + (*pindex));///这相当于重新引进了一套目的是不会混乱
switch(buffer[(*pindex) - bufindex])
{
case ')':///当遇到)时
if(numL == 0)///第一次就代表只有()没有套((()))这种情况,((()))会一层一层的算
{
buffer[(*pindex) - bufindex] = '\0'; ///就直接算()里面的把)当成结束去算 // Replace ')' with '\0'
++(*pindex);
pstr = (char *) malloc((*pindex) - bufindex + 1);///malloc是申请使用((*pindex) - bufindex + 1)大小的空间然后指向这个空间的指针设为pstr
if (!pstr)///指针无效就会运行下面这个
{
printf("Memory allocation failed, program terminated.") ;
exit(1);
}
strcpy(pstr, buffer); /// strcpy也是一个函数复制字符串买就是吧buffer的复制到 pstr中去// Copy substring to new memory
return pstr; ///把()里面的东西直接打回去。 // Return substring in new memory
}
else
numL--; // Reduce count of '(' to be matched
break;
case '(':
numL++; ///说明有((()))这样的结构,用numl记录有几个(,有一个)减一个1 // Increase count of '(' to be // matched
break;
}
} while(*(str + (*pindex)++) != '\0'); ///没有)直接结束会输出这句话 // Loop - don't overrun end of string
printf("Ran off the end of the expression, must be bad input.\n");
exit(1);
}
#includestdio.h
#includectype.h
#includestdlib.h
char token[61]; /*存放表达式字符串的数组*/
int n=0;
void error(void) /*报告错误函数*/
{
printf("ERROR!\n");
exit(1);
}
void match(char expected) /*检查字符匹配的函数*/
{
if(token[n]==expected)
token[++n]=getchar();
else error();
}
double term(void); /*计算乘除的函数*/
double factor(void); /*处理括号和数字的函数*/
double exp(void) /*计算加减的函数*/
{
double temp=term();
while((token[n]=='+')||(token[n]=='-'))
switch(token[n])
{
case'+':match('+');
temp+=term();
break;
case'-':match('-');
temp-=term();
break;
}
return temp;
}
double term(void)
{
double div;
double temp=factor();
while((token[n]=='*')||(token[n]=='/'))
switch(token[n])
{
case'*':match('*');
temp*=factor();
break;
case'/':match('/');
div=factor();
if(div==0) /*处理除数为零的情况*/
{
printf("The divisor is zero!\n");
exit(1);
}
temp/=div;
break;
}
return temp;
}
double factor(void)
{
double temp;
char number[61];
int i=0;
if(token[n]=='(')
{
match('(');
temp=exp();
match(')');
}
else if(isdigit(token[n])||token[n]=='.')
{
while(isdigit(token[n])||token[n]=='.') /*将字符串转换为浮点数*/
{
number[i++]=token[n++];
token[n]=getchar();
}
number[i]='\0';
temp=atof(number);
}
else error();
return temp;
}
main()
{
double result;
FILE *data=fopen("61590_4.dat","at");
if(data==NULL)
data=fopen("61590_4.dat","wt");
if(data==NULL)
return 0;
token[n]=getchar();
result=exp();
if(token[n]=='\n')
{
token[n]='\0';
printf("%s=%g\n",token,result);
fprintf(data,"%s=%g\n",token,result);
}
else error();
fclose(data);
return 0;
getch();
}
我觉得这个就可以.我试了!
请先给出明确答复:因为程序规定的是先输入操作符,再输入两个操作数
解释原因:请看下面部分的代码
第一个scanf("%c",oper);这一句要求输入一个(注意是一个)字符格式的值,给oper;
如果你输入一个数字、英文等等,假如你第一个输入的是10,那oper就是1,而不是10,因为%c一次只能读取一个字符;
接下来,输入第二第三个,程序再往下就会拿oper判断,如果oper等于-号,就会执行减法,如果等于+号就会执行加法;
所以你输入的操作数是不会匹配任何运算符,就不能进行运算。
有无解决办法:
调换语句顺序:复制第一个printf那一行与第一个scanf那一行,注意这两行printf在scanf的上面,把这两句放到第二个scanf之后,第三个print之前。就能输入 1 空格 + 空格 2 回车,这种的