I think you mean pop() function, but anyway Sparrowhawk appears to have found and fixed the bugOriginally Posted by stevesmithx
I think you mean pop() function, but anyway Sparrowhawk appears to have found and fixed the bugOriginally Posted by stevesmithx
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Well since we got my pops and pushs in here already... can you guys let me know if this is gonna work before I try to run it and get a major head ache?
Yes, it's a
switch nested in an if nested in a for nested in a switch nested in a for:
Code:for (i=0; i<indexSize; ++i) { int k; switch(expression[i]) { case '1': push(stack, stackSize, 1.0); break; case '2': push(stack, stackSize, 2.0); break; case '3': push(stack, stackSize, 3.0); break; case '4': push(stack, stackSize, 4.0); break; case '5': push(stack, stackSize, 5.0); break; case '6': push(stack, stackSize, 6.0); break; case '7': push(stack, stackSize, 7.0); break; case '8': push(stack, stackSize, 8.0); break; case '9': push(stack, stackSize, 9.0); break; default: for (k=0; k<opSize; ++k) { if(expression[i]==op[k].symbol) { switch(op[k].operands) { case 0: push (stack, stackSize, op[k].f0()); case 1: push (stack, stackSize, op[k].f1(pop(stack, stackSize))); case 2: push (stack, stackSize, op[k].f2(pop(stack, stackSize), pop(stack, stackSize))); } } } } } }
Logically,You are not checking for overflow and underflow which would cause it to crash anytime.
Also don't forget the return 0 in main.
Not everything that can be counted counts, and not everything that counts can be counted
- Albert Einstein.
No programming language is perfect. There is not even a single best language; there are only languages well suited or perhaps poorly suited for particular purposes.
- Herbert Mayer
It is best to just try and see.Originally Posted by Sparrowhawk
I can say, however, that you can simplify by changing the switch into a simple if-else structure:
I note that you seem to be handling the case for '0' in the default case, and in your inner switch you lack breaks... is that intentional?Code:if (expression[i] >= '1' && expression[i] <= '9') { push(stack, stackSize, expression[i] - '0'); } else { int k; for (k=0; k<opSize; ++k) { if (expression[i]==op[k].symbol) { switch (op[k].operands) { case 0: push (stack, stackSize, op[k].f0()); case 1: push (stack, stackSize, op[k].f1(pop(stack, stackSize))); case 2: push (stack, stackSize, op[k].f2(pop(stack, stackSize), pop(stack, stackSize))); } } } }
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
I'm not sure if I know what this does... The problem I'm having is my stack for my program has to be of type double, while my input string from the user is of type char... The user inputted string contains 123456789 and various operators like ^\* etc, as well as some letters that are for certain functions...
Since I can't add chars I use the switch to determine if a char is say '1' then it pushes a 1.0, or if it's a '2' then it pushes a 2.0... if it's not 1 through 9 then it must be an operator... So it finds out which struct it belongs to and goes from there. Also, I needed to add those last few breaks thanks.... And if you're up to here's the program in its entirety, after looking over it you may know why I'm a bit scared of trying to debug a little chunk of code in this whole thing... Usually I would take it out to try and debug it separately but it needs all the structs, and functions to work properly...
First compile...:Code:#include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> double evaluate (const Operator *op, int opSize, const char * expression); double pop (double stack[], int *stackSize); void push (double stack[], int *stackSize, double x); double multiply1 (double x, double y); double add1 (double x, double y); double neg1 (double x); double divide1 (double x, double y); double square1 (double x); double squareRoot1 (double x); double min1 (double x, double y); double max1 (double x, double y); double expo1 (double x, double y); double pi (void); double L (double x); double E (double x); typedef struct Operator { char symbol; int operands; union { void *f; double (*f0)(void); double (*f1) (double x); double (*f2) (double x, double y); } }Operator; Operator mult={'*',2,multiply1}; Operator add={'+',2,add1}; Operator neg={'-',1,neg1}; Operator divide={'/',2,divide1}; Operator square={'S',1,square1}; Operator sqrt={'s',1,squareRoot1}; Operator min={'m',2,min1}; Operator max={'M',2,max1}; Operator expo={'^',2,expo1}; Operator pi={'pi',0,pi}; Operator loga={'log',1,L}; Operator expon={'e^',1,E}; double main (void) { char input[81]={'\0'}; Operator op[13]={mult, add, neg, divide, square, sqrt, min, max, expo, pi, loga, expon}; char *operators operators=&op printf("Enter your calculations (blank to quit): \n"); fgets(input, sizeof(input), stdin); printf("Answer: ", evaluate(op, 13, input)); } double evaluate (const Operator *op, int opSize, const char * expression) { int i; int indexSize; int *stackSize; int stackSz=0; indexSize=strlen(expression); double stack=malloc(indexSize*sizeof(double)); stack for (i=0; i<indexSize; ++i) { int k; switch(expression[i]) { case '1': push(stack, stackSize, 1.0); break; case '2': push(stack, stackSize, 2.0); break; case '3': push(stack, stackSize, 3.0); break; case '4': push(stack, stackSize, 4.0); break; case '5': push(stack, stackSize, 5.0); break; case '6': push(stack, stackSize, 6.0); break; case '7': push(stack, stackSize, 7.0); break; case '8': push(stack, stackSize, 8.0); break; case '9': push(stack, stackSize, 9.0); break; default: for (k=0; k<opSize; ++k) { if(expression[i]==op[k].symbol) { switch(op[k].operands) { case 0: push (stack, stackSize, op[k].f0()); case 1: push (stack, stackSize, op[k].f1(pop(stack, stackSize))); case 2: push (stack, stackSize, op[k].f2(pop(stack, stackSize), pop(stack, stackSize))); } } } } } } double multiply1 (double x, double y) { return x*y; } double add1 (double x, double y) { return x+y; } double neg1 (double x) { return -x; } double divide1 (double x, double y) { return x/y; } double square1 (double x) { return pow(x,2); } double squareRoot1 (double x) { return sqrt(x); } double min1 (double x, double y) { return x>y?x:y; } double max1 (double x, double y) { return x>y?y:x; } double expo1 (double x, double y) { return pow(x,y); } double pi (void) { return 3.1415926535; } double L (double x) { return log(x); } double E (double x) { return exp(x); } double pop (double stack[], int *stackSize) { double value=0; value=stack[*stackSize]; --*stackSize; return value; } void push (double stack[], int *stackSize, double x) { ++*stackSize; stack[*stackSize]=x; }
Oh, and according to my assignment the prototype and declaration for the function evaluate should read as follows:1>------ Build started: Project: cStuff, Configuration: Debug Win32 ------
1>Compiling...
1>cPolishCalculator.c
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(6) : error C2143: syntax error : missing ')' before '*'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(6) : error C2143: syntax error : missing '{' before '*'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(6) : error C2059: syntax error : 'type'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(6) : error C2059: syntax error : ')'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(33 ) : error C2143: syntax error : missing ':' before '}'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(33 ) : error C2059: syntax error : '}'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(35 ) : error C2061: syntax error : identifier 'mult'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(35 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(35 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(36 ) : error C2061: syntax error : identifier 'add'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(36 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(36 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(37 ) : error C2061: syntax error : identifier 'neg'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(37 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(37 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(38 ) : error C2061: syntax error : identifier 'divide'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(38 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(38 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(39 ) : error C2061: syntax error : identifier 'square'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(39 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(39 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(40 ) : error C2061: syntax error : identifier 'sqrt'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(40 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(40 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(41 ) : error C2061: syntax error : identifier 'min'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(41 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(41 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(42 ) : error C2061: syntax error : identifier 'max'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(42 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(42 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(43 ) : error C2061: syntax error : identifier 'expo'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(43 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(43 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(44 ) : error C2061: syntax error : identifier 'pi'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(44 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(44 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(45 ) : error C2061: syntax error : identifier 'loga'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(45 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(45 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(46 ) : error C2061: syntax error : identifier 'expon'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(46 ) : error C2059: syntax error : ';'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(46 ) : error C2513: '/*global*/ ' : no variable declared before '='
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(51 ) : error C2065: 'Operator' : undeclared identifier
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(51 ) : error C2146: syntax error : missing ';' before identifier 'op'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(51 ) : error C2059: syntax error : '{'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2143: syntax error : missing ';' before 'type'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(56 ) : warning C4013: 'evaluate' undefined; assuming extern returning int
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(59 ) : error C2143: syntax error : missing ')' before '*'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(59 ) : error C2143: syntax error : missing '{' before '*'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(59 ) : error C2059: syntax error : 'type'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(59 ) : error C2059: syntax error : ')'
1>Build log was saved at "file://c:\Documents and Settings\Edward\My Documents\Visual Studio 2008\Projects\cStuff\cStuff\Debug\BuildLog.htm"
1>cStuff - 50 error(s), 1 warning(s)
But I get the "can't use an empty block" blah blah blah...Code:double evaluate (const Operator op[], int opSize, const char * expression);
Last edited by Sparrowhawk; 12-15-2008 at 02:04 AM.
So, all the input is to be interpreted one character at a time, and '0' is not a valid input?Originally Posted by Sparrowhawk
My example takes advantage of the fact that the characters '0' to '9' are guaranteed to be in consecutive order. As such, '1'-'0' returns 1, which is converted to 1.0, etc.Originally Posted by Sparrowhawk
Comment out the dependent parts if you need to. By right, you should have written some code, compiled and tested, written more code, compiled and tested, etc. You would certainly have detected several simple typographical errors this way and easily fixed them.Originally Posted by Sparrowhawk
By the way, in your zeal to have functions would double return type you accidentally changed the return type of main to double when it should be int. Also, note that order of evaluation of function arguments is undefined. This means that this line might not behave as you expect:
It would be better to pop separately into temporary variables.Code:push (stack, stackSize, op[k].f2(pop(stack, stackSize), pop(stack, stackSize)));
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
You might want to declare that function after declaring the Operator type.Originally Posted by Sparrowhawk
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Got it, ok I did as you suggested... Commented out the evaluate function, its prototype, and the call to it in main and such for now... I'm mainly getting errors from the struct now... 43 of those 50 or so are still around after removing the evaluate function completely
I get a feeling that there was something I was supposed to declare at the end of that union, but this is my first time using a Union...
[removed the code from this post because it's no longer relevant]
Last edited by Sparrowhawk; 12-15-2008 at 02:31 AM.
Also,since you have include math.h
you can't use variables like sqrt,pi,etc.. methinks
Not everything that can be counted counts, and not everything that counts can be counted
- Albert Einstein.
No programming language is perfect. There is not even a single best language; there are only languages well suited or perhaps poorly suited for particular purposes.
- Herbert Mayer
All are fine except the sqrt one, fixed it
[edit] - Ok fixed the union, needed a bracket at the close of the union... Now I'm down to a meager 12 errors/4 warnings...
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(45 ) : warning C4305: 'initializing' : truncation from 'int' to 'char'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(46 ) : warning C4305: 'initializing' : truncation from 'int' to 'char'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(47 ) : warning C4305: 'initializing' : truncation from 'int' to 'char'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2440: 'initializing' : cannot convert from 'Operator' to 'char'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2440: 'initializing' : cannot convert from 'Operator' to 'int'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2440: 'initializing' : cannot convert from 'Operator' to 'void *'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2440: 'initializing' : cannot convert from 'Operator' to 'char'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2440: 'initializing' : cannot convert from 'Operator' to 'int'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2440: 'initializing' : cannot convert from 'Operator' to 'void *'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2440: 'initializing' : cannot convert from 'Operator' to 'char'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2440: 'initializing' : cannot convert from 'Operator' to 'int'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2440: 'initializing' : cannot convert from 'Operator' to 'void *'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : warning C4047: 'initializing' : 'char' differs in levels of indirection from 'double (__cdecl *)(void)'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2440: 'initializing' : cannot convert from 'Operator' to 'int'
1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2440: 'initializing' : cannot convert from 'Operator' to 'void *'
Last edited by Sparrowhawk; 12-15-2008 at 02:31 AM.
yeah but you are using pi as a function name and as variable which is wrong.
Not everything that can be counted counts, and not everything that counts can be counted
- Albert Einstein.
No programming language is perfect. There is not even a single best language; there are only languages well suited or perhaps poorly suited for particular purposes.
- Herbert Mayer
Got it... I went ahead and changed them all just incase, as well as in the Operator array now...
A good chunk of those errors the "convert from" ones all have to do with the op array in main...
[edit] - Ok nailed the convert from errors... Seems like my compiler likes it better if I type struct op[13] than Operator op[13] for one reason or another... Which makes me nervous about the evaluate function declaration/prototype.
Last edited by Sparrowhawk; 12-15-2008 at 02:39 AM.
and shouldn't this invocation
beCode:op[k].f1(pop(stack, stackSize))
Code:(*op[k].f1)(pop(stack, stackSize)) /* as f0 f1 f2 are all pointers to functions */