Tekforums

Chat => Entertainment & Technology => Topic started by: SteveF on August 02, 2007, 22:11:31 PM

Title: C Question
Post by: SteveF on August 02, 2007, 22:11:31 PM
ok, I know this should be simple but Im having a problem getting my head around a piece of C code.  I was hoping someone could explain it to me.

The code is:

int a=10,b;
b=a++ + ++a;
printf("%d,%d,%d,%d",b,a++,a,++a);

The output of that code is:
22,13,13,13

which is the correct answer when you compile it.  But I cant work out how.


I understand the first number, i.e. b=22.  I believe it is because a++ reads the value first and then increments the number after its used, while ++a increments the number before it is used.

Therefore, 10++ + ++10
is the same as writing 10 + 12 = 22.


What I dont understand is how the next part works.  How can the next three values all be 13?  Surely ++a has to be a bigger number.

Is it because the print statement is evaluated totally before any number updates can occur?  i.e. only the ++a comes into effect before the print statement is completed? and then the a++ kicks in?
Title: Re:C Question
Post by: SteveF on August 02, 2007, 22:17:30 PM
ok, nvm I think I worked out the answer while typing the question lol.

When I output a after the script runs it gives me the answer 14 - therefore it is just down to when things update.
Title: Re:C Question
Post by: SteveF on August 03, 2007, 00:50:42 AM
Got another one...  (Im crash coursing C again and its amazing how many semantics you forget when youve not used it in a while).

Whats wrong with declaring and initiating a pointer in one line?

Say I want to create a pointer and making it point at address 0x400...  I can do it by saying:

int *x;
*x = 0x400;

Great!  But why is it throwing errors when I combine the two lines into one? i.e.

int *x = 0x400;
The compiler error is saying "initialization makes pointer from integer without a cast".  I dont understand the reasoning behind the error.  Anyone able to help?
Title: Re:C Question
Post by: Shakey on August 03, 2007, 04:37:39 AM
For a start, pointing pointers at a random block of memory is baaaad.

Your code isnt doing what you think it is
The first line, "int *x;" Allocates memory for a pointer called x. Because you didnt initialise it (generally sticking an =NULL on the end), the random crap that was already at that address in memory was interpreted as a memory address. Then when it reads the second line, "*x = 0x400" it set the value stored in the memory POINTED TO by x to equal 0x400. so some random point in memory now has the value 0x400, but we have no clue where (very bad indeed);

To change the memory address that x points to you would use "x = 0x400", WITHOUT a star. The problem with this is that when assigning a pointer, it wants to know not only the address to point to, but also the type of variable thats at that address, so it can get the length of the variable in memory correct etc. By giving it just an address, youll probably get the same error as when you tried to do it in one line.

One (very hacky) solution is to use a cast, so the one line version would be:

int *x = (int&)(0x400);

Dont blame me if that doesnt work though....
Title: Re:C Question
Post by: SteveF on August 03, 2007, 05:30:51 AM
hmmm, perhaps I should explain.  This is a contrived example as part of an assessment.  Im working back through my answers to see how I did.  Just done over 100 of these trick questions and its 5am so my heads starting to spin lol.  The full test question was:

QuoteWhich one of the following declares a pointer to an integer at address 0x400 in memory?
a) int *x;  *x = 0x400;
b) int *x = &0x400;
c) int *x = *0x400;
d) int *x = 0x400;
e) int *x( &0x400 );
I wanted to say the answer is d (in fact I did in the test).  I reasoned I was  just making a pointer and forcing it to be 0x400.  Thats how Id do it in assembly.  But the ANSI C compiler didnt/doesnt like it, so Im kind of stumped.  The only one of the options that actually compiled without a warning about bad casting was a.

However, a doesnt seem to answer the question. i.e. it appears to declare a pointer x and then put 0x400 in the location pointed to by x rather than change the address of x.

The question is from a major corporate assessment system, so its fairly unlikely that its the question thats wrong.  Its got to come down to this casting thing.  I dont really understand why the compiler is having issues with me writing the answer d.  In the test I had 180 seconds per question so didnt have time to do much more than type them in quickly and then compile them all.  Looking at it now, they all seem wrong but Im sure theyre not.
 
int *x = 0x400;
That seems like perfectly sensible code to me, but theres something wrong with it or it would compile without errors.


Cheers for the help btw :D


PS: regarding pointers addressing random memory locations thats somewhat unavoidable in hardware drivers.  Normally Id just hard code this address accessing in assembly and not use this approach whatsoever but the test was to do it all in ANSI compliant C.
Title: Re:C Question
Post by: Shakey on August 03, 2007, 15:43:12 PM
Think from those options Id go for b, with a sight possibility if b is wrong of going for c.
Title: Re:C Question
Post by: SteveF on August 03, 2007, 17:28:00 PM
cool - as long as its not just me being dumb...

I chose d in the test.  Still no idea which is correct.