|
Starting C |
|
Chris (07:35 2/5/2006) David Buck (07:45 2/5/2006) Chris (08:23 2/5/2006) monkeyson2 (10:08 2/5/2006) monkeyson2 (10:10 2/5/2006) Chris (11:40 2/5/2006) monkeyson2 (13:05 2/5/2006) Chris (14:05 2/5/2006) Phlamethrower (16:31 2/5/2006) Chris (06:51 3/5/2006) monkeyson2 (09:58 3/5/2006)
|
|
Chris |
Message #75125, posted by Chris at 07:35, 2/5/2006 |
Member
Posts: 283
|
Well, I've finally started to try and learn C after months of putting it off. Some success so far: I've got a simple app together with DeskLib which seems to mostly work. Getting things done seems a real pain after Basic - I'm hoping the advantages of C will become apparent soon...
Anyway, I've run into a problem. The app is a simple Icon Flags calculator: 32 option icons, numbered 0-31, which when clicked update a variable giving the flags value. The code is something like (from memory):
unsigned int bitfield;
(when icon clicked) for (i=0; i<32; i++) { bitfield = bitfield | (1 << i ); }
All seems to work OK unless I try and set bit 31, when bitfield becomes a minus number. I'm guessing this is because the number is too large for an int, but I thought these were 32 bits wide? Making bitfield a non-int varible seems to screw the bitwise operation.
Any suggestions as to what I'm doing wrong? |
|
[ Log in to reply ] |
|
David Buck |
Message #75126, posted by David Buck at 07:45, 2/5/2006, in reply to message #75125 |
Member
Posts: 7
|
How do you know bitfield is becoming negative ?
How are you then using bitfield, or printing it.
This could be a cast problem if you are assigning it to a signed int afterwards. |
|
[ Log in to reply ] |
|
Chris |
Message #75127, posted by Chris at 08:23, 2/5/2006, in reply to message #75126 |
Member
Posts: 283
|
How do you know bitfield is becoming negative ?
How are you then using bitfield, or printing it.
This could be a cast problem if you are assigning it to a signed int afterwards. I'm sending it to an icon using Icon_SetInteger(mainwin, 1, bitfield); Could that function be the culprit? |
|
[ Log in to reply ] |
|
Phil Mellor |
Message #75128, posted by monkeyson2 at 10:08, 2/5/2006, in reply to message #75127 |
Please don't let them make me be a monkey butler
Posts: 12380
|
The prototype for Icon_SetInteger is void Icon_SetInteger(window_handle w, icon_handle i, int value);
This means your bitfield is being converted to a signed int.
It doesn't look like there's an equivalent function taking an unsigned int, but you could convert your bitfield to a string and use that instead:
char bitstext[16]; // temp buffer to store string sprintf(bitstext, "%u", bitfield); // write the uint to the string Icon_SetText(mainwin, 1, bitstext); // set the text
[Edited by monkeyson2 at 11:12, 2/5/2006] |
|
[ Log in to reply ] |
|
Phil Mellor |
Message #75129, posted by monkeyson2 at 10:10, 2/5/2006, in reply to message #75128 |
Please don't let them make me be a monkey butler
Posts: 12380
|
Or, even better, use Icon_printf:
Icon_printf(mainwin, 1, "%u", bitfield); |
|
[ Log in to reply ] |
|
Chris |
Message #75130, posted by Chris at 11:40, 2/5/2006, in reply to message #75129 |
Member
Posts: 283
|
Thanks both.
My first impressions of C are rather mixed: compiling and linking are slightly easier than I expected (using Norcroft at any rate, and on very small projects). Getting used to the more restricted scope of variables and functions will take a while, I think, as well as seemingly convoluted string handling. And despite reading about pointers in a number of places I'm not sure I really understand quite what they are or how to use them... |
|
[ Log in to reply ] |
|
Phil Mellor |
Message #75131, posted by monkeyson2 at 13:05, 2/5/2006, in reply to message #75130 |
Please don't let them make me be a monkey butler
Posts: 12380
|
Strings are just arrays of characters, and arrays are just blocks of memory. If you've used DIM, ?, ! and $ in BASIC, you're already there.
These two chunks of code should do the same thing, except that the C version will release the 16 byte buffer when the function exits (as it's stored on the stack, not in the heap).
You could change the char mystring[16] to: char* mystring = calloc(sizeof(char), 16); to work like the DIM statement - claim the memory dynamically and not release it.
DEF PROCexample DIM mystring% 16 $mystring% = "Hello world!" + CHR$0 PRINT "Second character is "; CHR$(mystring% ? 1) mystring%?1 = ASC("i" PRINT "Before wibble: "; $mystring% PROCwibble(mystring%) PRINT "After wibble: "; $mystring% ENDPROC
DEF PROCwibble(text%) $text% = "Changed text" + CHR$0; ENDPROC
void example() { char mystring[16]; strcpy(mystring, "Hello world!" printf("Second character was %c \n", mystring[1]); mystring[1] = 'i'; printf("Before wibble: %s \n", mystring); wibble(mystring); printf("After wibble: %s \n", mystring); return; }
void wibble(char* text) { strcpy(text, "Changed text" return; }
[Edited by monkeyson2 at 14:06, 2/5/2006]
[Edited by monkeyson2 at 14:16, 2/5/2006] |
|
[ Log in to reply ] |
|
Chris |
Message #75132, posted by Chris at 14:05, 2/5/2006, in reply to message #75131 |
Member
Posts: 283
|
OK - I think I get that - helpful.
I suppose the difference is that in Basic you wouldn't have to do things that way: you could just create a string variable and use the built-in functions like LEFT$, etc. to alter it, and you also could define a variable in one PROC and (as long as it wasn't declared as LOCAL) use it happily in another, obviating the need for pointers. |
|
[ Log in to reply ] |
|
Jeffrey Lee |
Message #75133, posted by Phlamethrower at 16:31, 2/5/2006, in reply to message #75132 |
Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff
Posts: 15100
|
I suppose the difference is that in Basic you wouldn't have to do things that way: you could just create a string variable and use the built-in functions like LEFT$, etc. to alter it, That's what C++ is for
and you also could define a variable in one PROC and (as long as it wasn't declared as LOCAL) use it happily in another, obviating the need for pointers. That's what global variables are for |
|
[ Log in to reply ] |
|
Chris |
Message #75143, posted by Chris at 06:51, 3/5/2006, in reply to message #75133 |
Member
Posts: 283
|
That's what global variables are for But there are some differences, aren't there? Variables are always passed to functions by value only, which seems to be one of the main reasons why pointers are used so much.
Anyway, I'm sure it makes perfect sense once you've got the hang of it, but it's all a little different at the moment...
BTW, my flags calculator is going great guns now. When it's finished, it will only be the 87th version written for RISC OS. |
|
[ Log in to reply ] |
|
Phil Mellor |
Message #75146, posted by monkeyson2 at 09:58, 3/5/2006, in reply to message #75143 |
Please don't let them make me be a monkey butler
Posts: 12380
|
Variables are always passed to functions by value only, which seems to be one of the main reasons why pointers are used so much. That's what C++ references parameters are for.
void foo(int& bar) { bar = bar * 2; }
int x = 3; printf("x = %d\n", x); foo(x); printf("x = %d\n", x);
will print: x = 3 x = 6
I suppose it's equivalent to DEF PROCfoo(RETURN bar).
Do any versions of C have this? C99, maybe?
BTW, my flags calculator is going great guns now. When it's finished, it will only be the 87th version written for RISC OS. Yay!
I wrote mine in BASIC. |
|
[ Log in to reply ] |
|
|