Simple C code help

Discussion in 'Mac Programming' started by PowerFullMac, Nov 4, 2008.

  1. macrumors 601

    PowerFullMac

    Joined:
    Oct 16, 2006
    #1
    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);
    }
     
  2. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    1st tip: use the CODE UBB tags :)

    Now, can you explain, exactly, what you think the like I have quoted is doing?

    Now that you've done that, have a read of what the comma operator really does...
     
  3. thread starter macrumors 601

    PowerFullMac

    Joined:
    Oct 16, 2006
    #3
    Just did :D

    Its meant to take a and d and do the operation defined by c.
     
  4. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #4
    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...
     
  5. thread starter macrumors 601

    PowerFullMac

    Joined:
    Oct 16, 2006
    #5
    Thats annoying, its such a simple operation!

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

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #6
    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!
     
  7. thread starter macrumors 601

    PowerFullMac

    Joined:
    Oct 16, 2006
    #7
    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! :)
     

    Attached Files:

  8. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #8
    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
     
  9. thread starter macrumors 601

    PowerFullMac

    Joined:
    Oct 16, 2006
    #9
    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... :)
     
  10. Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #10
    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 :)
     
  11. thread starter macrumors 601

    PowerFullMac

    Joined:
    Oct 16, 2006
    #11
    Indeed :)

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

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #12
    Oh dear. Your one of those sort of beginners. You'll soon get over it :p
     
  13. thread starter macrumors 601

    PowerFullMac

    Joined:
    Oct 16, 2006
    #13
    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 :)
     
  14. macrumors 6502a

    yeroen

    Joined:
    Mar 8, 2007
    Location:
    Cambridge, MA
    #14
    Well, you can check hubris and delusions of grandeur off your list of necessary stops on the road to becoming a successful coder.
     
  15. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #15
    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
     

Share This Page