Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

PowerFullMac

macrumors 601
Original poster
Oct 16, 2006
4,000
2
I have this C app I am trying to make, basically what it does is takes two numbers then adds, subtracts, divides or multiplies the number depending on what the user enters. However, it doesent work... For example it seems to think 1+1 is 1... What am I doing wrong?

Code:
#include <stdio.h>
main()

{
int a,b,c,d;
printf ("Command-line calculator tool by Josh. \n");
printf ("Enter the first number ");
scanf ("%d" ,&a);
printf ("Enter the second number ");
scanf ("%d" ,&b);
printf ("Do you want to +, -, * or /? ");
scanf ("%d",&c);
d=a,c,b;
printf ("The answer is %d \n" ,d);
}
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Its meant to take a and d and do the operation defined by c.

Well it doesn't. Not even close. It evaluates the first expression. Which is a so this just evaluates to a. Then the second, which is another comma expression so gets broken down the same way so it evaluates c, which is c and finally evaluates b. As this is the end of the compound expression this is the final value of the expression.

To the best of my knowledge there is no direct operator in plain C that does what you are trying to do: you actually have to write code. You need to write some conditional logic to work out which operator was supplied (and complain if something else was supplied) and evaluate the correct expression in each case...
 

PowerFullMac

macrumors 601
Original poster
Oct 16, 2006
4,000
2
Thats annoying, its such a simple operation!

I'll make it do all operations for now then, thats way easier.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Thats annoying, its such a simple operation!

I'll make it do all operations for now then, thats way easier.

You may think it's simple, bit for C it's not. C is not a very dynamic language. On fact it's very static. It expects to know the address of function calls, their definition, everything at complile time. These operators are basically built I'm function calls. You cannot expect the system to dynamically look up the function and use different memory addresses at run time: that's not how a C function call works. Worse than that you are trying to use the name of re function, which is meaningless at runtime!
 

PowerFullMac

macrumors 601
Original poster
Oct 16, 2006
4,000
2
I'm new give me a break! :D

The new approach worked... I will try doing it again when I know a bit more.

This is the first program I wrote without using a tutorial, yay! :)
 

Attachments

  • Picture 2.png
    Picture 2.png
    43.3 KB · Views: 68

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
What you're likely looking for is a switch statement:

Code:
char c;
int a,b,d;
//... (do input, etc.)
switch (c) {
  case '+':
    d= a + b;
    break;
  case '-':
    d= a - b;
    break;
  case '/':
    if(b == 0) {
      fprintf(stderr,"Cannot divide by 0");
      d=0;
    } else {
      d= a / b;
    }
    break;
  case '*':
    d= a * b;
    break;
  default:
    d=0;
    fprintf(stderr,"Invalid operator, %c, entered.",c);
    break;
}
printf("The value of %d %c %d is: %d\n",a,c,b,d);

no, it isn't as simple, but you can't take a character like '+' and "perform" it. it's just a value, namely a byte with the value 43. With your original example, with 4 entered for a, 2 for b, and '+' for c, the statement you had was:
d = 4,43,2;
So d would be assigned 2, for the reasons Cromulent stated above.

-Lee
 

PowerFullMac

macrumors 601
Original poster
Oct 16, 2006
4,000
2
Thanks, Lee.

Makes sense... Seems the hardest thing with C is having to write your own code for things which seem easy at the surface but obviously are not that simple for C!

I'm learning... :)
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Thanks, Lee.

Makes sense... Seems the hardest thing with C is having to write your own code for things which seem easy at the surface but obviously are not that simple for C!

I'm learning... :)

I think that's one of the great things about C. It's about as close to the metal as you can get without dropping the assembly. It forces you to actually think about howthe machine works and what's really going on. In general I find this makes people write better, tighter code on other languages. Keep at it :)
 

PowerFullMac

macrumors 601
Original poster
Oct 16, 2006
4,000
2
I think that's one of the great things about C. It's about as close to the metal as you can get without dropping the assembly. It forces you to actually think about howthe machine works and what's really going on. In general I find this makes people write better, tighter code on other languages. Keep at it :)

Indeed :)

I also intend to learn Assembly, too, after C! I wanna make my own operating system! :)
 

PowerFullMac

macrumors 601
Original poster
Oct 16, 2006
4,000
2
Oh dear. Your one of those sort of beginners. You'll soon get over it :p

LOL I dont really expect to make something amazing, it will just be a project I can work on when I am not doing anything else and its especially good for that because it can never really be finished :)
 

lee1210

macrumors 68040
Jan 10, 2005
3,182
3
Dallas, TX
You also have the early benefit of a nasty run-in with the comma operator. Some people go years without doing so. Just last week I found a bug with it, as follows:

Code:
#define V_DBCMD_NEXT 1 //Made this up, it was actually from an include
V_TAG *time_tags = NULL;
V_SYS *vptr = NULL;
char reqbuf[256], msgbuf[256];
char *res = NULL;
time_tags = VSI_Server_Olog_Get,(vptr,reqbuf,0,V_DBCMD_NEXT,msgbuf);
res = some_other_call(time_tags);

VSI_Server_Olog_Get returns a V_TAG *. The comma after VSI_Server_Olog_Get was committed inadvertently at some point. But the code still compiled, it ran OK, but the results were wrong. What this line:

Code:
time_tags = VSI_Server_Olog_Get,(vptr,reqbuf,0,V_DBCMD_NEXT,msgbuf);

was actually doing was:
Evaluating the address of VSI_Server_Olog_Get, and discarding it.
Evaluating vptr's address, and discarding it
Evaluating 0, and discarding it
Evaluating V_DBCMD_NEXt, and discarding it
Evaluating msgbuf's address, and assigning it to time_tags

So at the end of the line, time_tags is pointing to some chars in memory instead of a V_TAG structure. some_other_call was into something that expected a V_TAG *, so it's behavior was indeterminate (after some other tweaks, this would reliably cause a crash). After pulling out the errant comma, everything worked as expected, and VSI_Server_Olog_Get was actually called, instead of simply having its address evaluated and discarded.

The moral is two-fold:
One, pay attention to compiler warnings. This was the only indication that the comma had mucked things up.
Two, Be weary of the comma. It can bite you in ways you would not imagine possible.

-Lee
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.