Thread: Testing some code, lots of errors...

  1. #31
    Registered User
    Join Date
    Oct 2008
    Posts
    98
    Quote Originally Posted by itCbitC View Post
    and shouldn't this invocation
    Code:
    op[k].f1(pop(stack, stackSize))
    be
    Code:
    (*op[k].f1)(pop(stack, stackSize)) /* as f0 f1 f2 are all pointers to functions */
    Ah, let me post the updated code so people aren't confused... I fixed that when laserlight told me about the evaluation problems...

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
    
    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;
    
    //double evaluate (const Operator op[], int opSize, const char * expression);
    
    Operator mult2={'*',2,multiply1};
    Operator add2={'+',2,add1};
    Operator neg2={'-',1,neg1};
    Operator divide2={'/',2,divide1};
    Operator square2={'S',1,square1};
    Operator sqrt2={'s',1,squareRoot1};
    Operator min2={'m',2,min1};
    Operator max2={'M',2,max1};
    Operator expo2={'^',2,expo1};
    Operator pi2={'pi',0,pi};
    Operator loga2={'log',1,L};
    Operator expon2={'e^',1,E};
    
    int main (void)
    {
    	char input[81]={'\0'};
    	struct op[13]={mult2, add2, neg2, divide2, square2, sqrt2, min2, max2, expo2, pi2, loga2, expon2};
    	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;
    	double temp=0;
    	double temp2=0;
    	indexSize=strlen(expression);
    	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());
    								break;
    							case 1:
    								temp=pop(stack, stackSize);
    								push (stack, stackSize, op[k].f1(temp));
    								break;
    							case 2:
    								temp=pop(stack, stackSize);
    								temp2=pop(stack, stackSize);
    								push (stack, stackSize, op[k].f2(temp, temp2));
    								break;
    						}
    				
    					}
    				}
    		}
    	}
    }*/
    
    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;
    }
    As you can see the evaluate bits are commented out but I've been working on them as well... Using temp variables now for the pops... Seems like an all around good idea.


    [edit] - Sorry I must be sleepy just reread what you posted and realized you're probably right about that...
    [edit2] - Edit well maybe not... Compiler doesn't seem to care... I guess your way is better programming practice however... My way might not work in every compiler.

  2. #32
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Pointers to functions can be used with the same syntax as functions.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #33
    and the hat of copycat stevesmithx's Avatar
    Join Date
    Sep 2007
    Posts
    587
    Code:
    Operator pi2={'pi',0,pi};
    Operator loga2={'log',1,L};
    Operator expon2={'e^',1,E};
    I don't know whether it is a good idea to use multi-character constants.
    I have never used them before.
    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

  4. #34
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    Pointers to functions can be used with the same syntax as functions.
    right but you still need to dereference the pointer in order to get at the function as in
    Code:
    (*op[k].f1)(temp)

  5. #35
    Registered User
    Join Date
    Oct 2008
    Posts
    98
    Quote Originally Posted by stevesmithx View Post
    I don't know whether it is a good idea to use multi-character constants.
    I have never used them before.
    Right-o, good call...

    Down to 1 error:

    1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2143: syntax error : missing ';' before '['
    it has something to do with these 3 lines of code:
    Code:
    	char input[81]={'\0'};
    	struct op[13]={mult2, add2, neg2, divide2, square2, sqrt2, min2, max2, expo2, pi2, loga2, expon2};
    	printf("Enter your calculations (blank to quit): \n");

  6. #36
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    right but you still need to dereference the pointer in order to get at the function as in
    The pointer named op is already dereferenced with op[k]. The function pointer does not need to be explicitly dereferenced.

    However, you have highlighted something that I am otherwise unfamiliar with: unions. To get that part of the code to compile, I had to resort to this:
    Code:
    typedef struct Operator
    {
    	char symbol;
    	int operands;
    	union
    	{
    		void *f;
    		double (*f0)(void);
    		double (*f1) (double x);
    		double (*f2) (double x, double y);
    	} fun;
    } Operator;
    Sparrowhawk, notice the introduction of the name fun. You need to give the union a name, and I have chosen fun as the name. You would then invoke the function as: op[k].fun.f1(temp);

    Incidentally, you probably should just remove the void* named f from the union.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #37
    Registered User
    Join Date
    Oct 2008
    Posts
    98
    Quote Originally Posted by laserlight View Post
    The pointer named op is already dereferenced with op[k]. The function pointer does not need to be explicitly dereferenced.

    However, you have highlighted something that I am otherwise unfamiliar with: unions. To get that part of the code to compile, I had to resort to this:
    Code:
    typedef struct Operator
    {
    	char symbol;
    	int operands;
    	union
    	{
    		void *f;
    		double (*f0)(void);
    		double (*f1) (double x);
    		double (*f2) (double x, double y);
    	} fun;
    } Operator;
    Sparrowhawk, notice the introduction of the name fun. You need to give the union a name, and I have chosen fun as the name. You would then invoke the function as: op[k].fun.f1(temp);

    Incidentally, you probably should just remove the void* named f from the union.
    For unions nested in structures they can be left unnamed but you need to have a bracket there... I'm not sure what happens if you name them really , more to type perhaps.

    Also, have any ideas about the error I posted right before this post?

  8. #38
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    The pointer named op is already dereferenced with op[k]. The function pointer does not need to be explicitly dereferenced.
    isn't op[k] the k-th element of the array of structs.
    Quote Originally Posted by laserlight View Post
    However, you have highlighted something that I am otherwise unfamiliar with: unions. To get that part of the code to compile, I had to resort to this:
    Code:
    typedef struct Operator
    {
    	char symbol;
    	int operands;
    	union
    	{
    		void *f;
    		double (*f0)(void);
    		double (*f1) (double x);
    		double (*f2) (double x, double y);
    	} fun;
    } Operator;
    Sparrowhawk, notice the introduction of the name fun. You need to give the union a name, and I have chosen fun as the name. You would then invoke the function as: op[k].fun.f1(temp);
    good point about naming the union, guess it got overlooked in all this debugging effort and it's sleepy time here.
    so imo it shoud be (*op[k].fun.f1)(temp)
    Quote Originally Posted by laserlight View Post
    Incidentally, you probably should just remove the void* named f from the union.
    excellent point; no need for objects you aren't using.

  9. #39
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Sparrowhawk
    For unions nested in structures they can be left unnamed but you need to have a bracket there
    Where does it state as such in the C Standard? The MinGW port of gcc disagrees with you in both C90 and C99 mode.

    Quote Originally Posted by itCbitC
    isn't op[k] the k-th element of the array of structs.
    Yes. However, at this point there is no array, only a pointer to the first element of the array.

    Quote Originally Posted by itCbitC
    so imo it shoud be (*op[k].fun.f1)(temp)
    Let me ask you a simple question: is op[k].fun.f1 a function pointer?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #40
    Registered User
    Join Date
    Oct 2008
    Posts
    98
    Quote Originally Posted by laserlight View Post
    Where does it state as such in the C Standard? The MinGW port of gcc disagrees with you in both C90 and C99 mode.


    Yes. However, at this point there is no array, only a pointer to the first element of the array.


    Let me ask you a simple question: is op[k].fun.f1 a function pointer?
    Ah my mistake, it's specific to Microsoft... I'm using Visual C++

    Source:
    http://msdn.microsoft.com/en-us/libr...0d(VS.80).aspx

    Didn't see that bolded "Microsoft Specific" text heh...

    I've still got the:

    1>c:\documents and settings\edward\my documents\visual studio 2008\projects\cstuff\cstuff\cpolishcalculator.c(52 ) : error C2143: syntax error : missing ';' before '['
    With
    Code:
    	char input[81]={'\0'};
    	struct op[13]={mult2, add2, neg2, divide2, square2, sqrt2, min2, max2, expo2, pi2, loga2, expon2};

  11. #41
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    Yes. However, at this point there is no array, only a pointer to the first element of the array.
    not sure how you get at that but guess I don't share your point of view and of course I could be totally wrong.
    Quote Originally Posted by laserlight View Post
    Let me ask you a simple question: is op[k].fun.f1 a function pointer?
    yes it's a pointer to a function.

  12. #42
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Instead of "struct op[13]" you probably want to write "Operator op[13]". When you do that, however, the initialiser that follows is not correct since it only an aggregate of function pointers. I am not sure of the correct syntax where unions are involved, so all I can suggest is to manually assign the function pointers to the corresponding Operator objects.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #43
    Registered User
    Join Date
    Oct 2008
    Posts
    98
    Quote Originally Posted by laserlight View Post
    Instead of "struct op[13]" you probably want to write "Operator op[13]". When you do that, however, the initialiser that follows is not correct since it only an aggregate of function pointers. I am not sure of the correct syntax where unions are involved, so all I can suggest is to manually assign the function pointers to the corresponding Operator objects.
    Yup that worked.

  14. #44
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    not sure how you get at that but guess I don't share your point of view and of course I could be totally wrong.
    Look at the context: the code is in a function whose declaration is:
    Code:
    double evaluate (const Operator *op, int opSize, const char * expression)
    Quote Originally Posted by itCbitC
    yes it's a pointer to a function.
    In that case op[k].fun.f1(temp) is valid syntax. If you disagree, then find a standard compliant C compiler that considers this sample program invalid:
    Code:
    void foo(){}
    
    int main()
    {
        void (*f)(void) = foo;
        f();
        return 0;
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #45
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    Look at the context: the code is in a function whose declaration is:
    Code:
    double evaluate (const Operator *op, int opSize, const char * expression)
    cool beans for the longest time i was thinking that its all contained in main(); makes sense now that op is passed as an argument to evaluate(); must be that time i suppose

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. set testing code
    By zxcv in forum C++ Programming
    Replies: 8
    Last Post: 12-22-2008, 02:58 AM
  2. Problem : Threads WILL NOT DIE!!
    By hanhao in forum C++ Programming
    Replies: 2
    Last Post: 04-16-2004, 01:37 PM
  3. Seems like correct code, but results are not right...
    By OmniMirror in forum C Programming
    Replies: 4
    Last Post: 02-13-2003, 01:33 PM
  4. linked list source code errors
    By C++_Learner in forum C++ Programming
    Replies: 1
    Last Post: 04-18-2002, 11:04 PM
  5. Reqd. C source code for Testing purposes
    By DP in forum C Programming
    Replies: 5
    Last Post: 01-14-2002, 12:45 PM