Register | Login
Views: 19364387
Main | Memberlist | Active users | ACS | Commons | Calendar | Online users
Ranks | FAQ | Color Chart | Photo album | IRC Chat
11-02-05 12:59 PM
0 user currently in Programming. | 3 guests
Acmlm's Board - I2 Archive - Programming - Thinking of getting serious with C. | |
Pages: 1 2 3Add to favorites | "RSS" Feed | Next newer thread | Next older thread
User Post
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 2832/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 01-06-05 12:34 PM Link | Quote
Not sure why, but I suddenly have this urge to do C stuff. The biggest problem I have with C is that all the compilers/IDEs I've tried tend to suck for various reasons. That said, I'm trying to find the following:

-Good compiler with minimal bugs. (I hear MinGW is good?)
-Good IDE, similar to VB6's. Preferrably one that keeps a list of variable/function names and auto-corrects the capitalization like VB's does. (Case-sensitivity is one of the things I like least about it. ) I could just use Notepad but I'd much prefer an IDE if one exists. VC++ is nice, but seems lacking, and isn't entirely stable. (Plus it's confusing as hell trying to figure out where it's putting the files. I find them strewn all over the HD. )
-Some sort of resource builder, the thing I would use to make windows and such, and information on just how I'm supposed to use them.

Also, any references to string-related code that might be useful is greatly appreciated, as I always seem to have trouble with string manipulation. Finally, I should know this, but I just can't seem to get it to stick: How does the whole */& thing work? Like *foo = address of foo, &foo = copy of foo's contents, or something like that, isn't it?
Dish

Spiny
Level: 38

Posts: 224/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 01-06-05 01:31 PM Link | Quote
I use Visual Studio for pretty much everything. But MingW is a good compiler, gcc is good too.

As for IDE... VS is good. There's an addon called Visual Assist which is great. But if you want something more lightweight (and free), TextPad might work.

VS has a resource builder... and a good one at that. I don't know of any alternatives =/ although I'm sure there are some.



Also, any references to string-related code that might be useful is greatly appreciated, as I always seem to have trouble with string manipulation


Strings are nothing but arrays. When you can think of a string as being synonymous with being an array... you can understand strings. Only difference is arrays tend to be fixed length (or have their length specified in a seperate var), wheras the end of a string is signaled with a null terminator.

There are several string functions which aid in string manipulation:

strcpy --- copy the contents of one string to another
strcat --- append one string to the end of another
strcmp --- compare two strings
strcmpi --- ditto (case insensitive)
strlen --- finds the length of a string
sprintf -- string formatting!

There's also search functions too, but I dont know them offhand.


How does the whole */& thing work? Like *foo = address of foo, &foo = copy of foo's contents, or something like that, isn't it?


You have it backwards.

'&' is the Address-of operator... it gives you the address of (pointer to) the following var.
'*' is the Indirection operator... it gives you what the following pointer is pointing to. '*' is also used when declaring pointers:

int* foo; // makes an int pointer
int var; // makes an int
foo = &var; // set foo to point to var
*foo = 5; // sets what foo is pointing to (in this case: var) to 5 (this is like saying "var = 5;")

Another really cool concept with pointers is that an array without its brakets gives you a pointer... and brakets double as an indirection operator. For example:

Saying *foo is exactly the same as saying foo[0]. foo[1] is the same as *(foo + 1). Etc.

Since arrays without brakets are pointers, you don't need to use & when you want to get a pointer to an array:

int* foo;
int ar[5];
foo = ar; // foo will point to ar
foo[3] = 0; //same as saying ar[3] = 0


Kudos on making the switch! There's really no reason at all to use VB ever... as you'll see when you get more comfortable with C. ;D


(edited by Disch on 01-06-05 04:32 AM)
(edited by Disch on 01-06-05 04:38 AM)
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 2840/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 01-06-05 04:42 PM Link | Quote
How do I get into VS's resource builder? I can't seem to find it.
[edit] Woah, there it is. Neat! Now how do I actually use these resources?

So, just to clarify... int* foo just makes foo a pointer, meaning you can't actually store a value in it, just point it to one? (This has always been one of the bigger problems I had with C. If I can get it all memorized, I imagine things will go a lot easier. )


(edited by HyperHacker on 01-06-05 07:44 AM)
Euclid

Cheep-cheep
Level: 23

Posts: 126/193
EXP: 65528
For next: 2195

Since: 03-15-04
From: Australia

Since last post: 24 days
Last activity: 7 days
Posted on 01-06-05 04:52 PM Link | Quote
int* foo;

foo points to NULL

char blah[10]; //array of char
int* foo = &blah; // make foo point to address of blah in memory.

foo will point to blah[0].

foo++;

foo will now point to blah[1];

simple? no?

fyi blah[ i ] is simply telling the compiler to do *(blah+i)

Borland C++ builder has a Resource thingy as well to save time with gui apps.


(edited by Euclid on 01-06-05 07:52 AM)
Dish

Spiny
Level: 38

Posts: 225/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 01-06-05 08:52 PM Link | Quote
Originally posted by HyperHacker
Woah, there it is. Neat! Now how do I actually use these resources?


In VS, you #include the resource header file in any file that needs access to one or more resources... then use the resource ID's as needed. The .rc file also needs to be included in the build of the project.

I'd imagine it's the same/similar for other compilers, but I really couldn't say. I completely lack experience when it comes to anything but VS

Many WINAPI functions take a resource ID in the form of a string.. but resources get IDs which are ints, which can make it kind of weird to use. For this, there's a MAKEINTRESOURCE macro which converts a resource ID to a resource string for these functions.

For example... the DialogBox() function (which pops up a modal dialog) takes the resource string as the 2nd parameter. If your dialog id is, say, IDD_MAINDIALOG, it would look something like this:

DialogBox( hInstance, MAKEINTRESOURCE( IDD_MAINDIALOG ), hParentWnd, MyDialogProcedure );


So, just to clarify... int* foo just makes foo a pointer, meaning you can't actually store a value in it, just point it to one? (This has always been one of the bigger problems I had with C. If I can get it all memorized, I imagine things will go a lot easier. )


Yes. You could technically typecast the pointer to treat it as a normal int or whatever... but I'm just getting technical. Basically, you're right... a pointer does not hold a var, it just points to a var (or the start of an array of vars).

And yeah... pointers are hard to get used to, but once you understand them they're soooooooooo great.


@ Euclid: you're giving the right idea... but you're technically inaccurate, so I'm going to point out corrections (don't want to give HH misleading pointer info)

Originally posted by Euclid

int* foo;

foo points to NULL


foo will NOT point to NULL until you tell it to:

int* foo = NULL; (or) int* foo = 0;

uninitialized pointers are just like uninitialized vars. Their contents are undefined and they'll be filled with garbage RAM... effectively making foo point to random memory when unset.



char blah[10]; //array of char
int* foo = &blah; // make foo point to address of blah in memory.



No, blah is an array, so you don't need the '&' operator in this case. Remeber that an array without its brakets already is a pointer.

char* foo = blah; // will set foo to point to blah.. no '&' needed.
or:
char* foo = &blah[0]; // this would work too... but your example wouldn't

'&blah' will try to get a pointer to the pointer, which will probably make the compiler yell at you.

Also note your different types... int is typically 4-byte... char is 1-byte. When working with pointers you typically want to point to a var of whatever type yout pointer is. When changing types you typically need to / should typecast:

char blah[10];
int* foo = blah;

this may generate compiler errors since blah is char and foo is an int pointer. To remedy this in my above exmples I changed foo to a char pointer. However if you want blah to be a char array and still want foo to be an int array... typecasting would be recommended (or even necessary depending on your compiler):

char blah[10];
int* foo = (int*)blah;

that will work without problems.



foo++;

foo will now point to blah[1];



If foo is a char pointer. Yes. If foo was an int pointer, it would actually point to blah[4] (due to ints being 4 times the size of chars). When you add to a pointer, it adds by the element size... not by bytes.

char blah[10];
int* foo = (int*)blah;
char* bar = blah;

-- at this point, both foo and bar point to blah

foo += 1;
bar += 4;

-- at this point, both foo and bar point to blah[4]. (foo == bar) will come up true
Parasyte

Bullet Bill
Level: 35

Posts: 176/514
EXP: 267348
For next: 12588

Since: 05-25-04

Since last post: 104 days
Last activity: 32 days
Posted on 01-07-05 09:23 AM Link | Quote
Here is something which may help you understand C pointers a bit better. A pointer ( for example: int *foo; ) is actually a container. It is a container in the same way that a variable ( int foo; ) is a container. Both declarations of "foo" contain something. In this case, the former declaration contains a pointer, while the latter contains an integer. The difference is the way in which they are used.
A pointer which "contains" the value of 0 is said to point to 0. (It is also referred as "pointing to null) If you read an indirected pointer containing null, it means you are reading from memory address 0. ( bar = *foo; ) Since you are somewhat into assembly, HyperHacker, this should make quite a lot of sense to you.

Pointers have many practical applications, but the most common uses are for pointing to arrays. The array can contain any data format you like; from integers, to characters to structures. A text string is usually a simple character array. When you want to pass a string to a function (say you want the function to search the string, or modify the string, for example) it is wasteful to pass the ENTIRE string to the function. It is more efficient to simply pass a pointer to the string. (Imagine writing it in assembly: Passing an entire string requires pushing the whole string onto the stack before calling the function. Passing a pointer to the string requires only pushing a pointer to the stack [or even better - placing the pointer in a register] before calling the function. The pointer is usually only 16- or 32-bits wide, depending on the available address space within the machine.)
So that's why you pass string pointers to functions like strcpy(), strcat(), and printf().


I hope this explanation has proved useful. The reason I chose to mention some of the low-level workings of pointers here is because you have some low-level knowledge, already. All you have to do is forget what VB taught you and connect the dots between C and assembly. This is why VB is considered so bad; it tends to teach "improper techniques" which make learning some of the more lower-level languages quite a bit more difficult.


As a final example of how a pointer is just a container, I'd like to talk about a little C feature called CASTING. Casting forces the compiler to treat a variable, pointer, or just about anything as ANY data type you want. You can set a pointer to contain any value you want through casting. You are NOT limited to having pointers only point to declared variables or arrays.

int *foo = (int*)0x10000000;

This sets 'foo' to contain a pointer to memory address 0x10000000 (of data type: int -- reads and writes will be treated as integers). This is very useful for console development, where you may be required to read and write to specific memory addresses, such as I/O registers. (Reading joypads, for example!) If the joypad register were at address 0x10000000, you could use the above code to declare 'foo' as a pointer to the joypad register. From there, reading the joypad may be as easy as:
joypad = *foo;

However, a lot of times, programmers will use preprocessor defines to get rid of keeping the pointer in memory (or on the stack, or in a register, whatever the case may be). Taking the above example a step further by removing the pointer (container) can help illustrate:
joypad = (int*)0x10000000;

Here you have the same result, just without keeping the container in memory. (At runtime, the executable will 'build' the pointer once to run the code, and then the pointer is discarded, since it is not within any container). Now that I am going way off topic, I might as well leave you with a final example using a preprocessor define (as mentioned earlier).
#define JOYPAD_IO (int*)0x10000000
joypad = JOYPAD_IO;


In closing, pointers are simply data. The way which a compiler uses that data is what makes them point to memory. Simple!


(edited by Parasyte on 01-07-05 12:25 AM)
(edited by Parasyte on 01-07-05 12:26 AM)
(edited by Parasyte on 01-07-05 12:27 AM)
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 2851/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 01-07-05 12:54 PM Link | Quote
Cool. I get how pointers themselves work, it's just the syntax I tend to have trouble with (mostly when it gets into a complicated mess of pointers to pointers to arrays of addresses and whatnot). I'm starting to understand better, just one other thing I wanted to ask: What's the difference between these two statements?
int* foo;
int *foo;

The first one should create a pointer called foo, but what would the second do?
Euclid

Cheep-cheep
Level: 23

Posts: 127/193
EXP: 65528
For next: 2195

Since: 03-15-04
From: Australia

Since last post: 24 days
Last activity: 7 days
Posted on 01-07-05 12:58 PM Link | Quote
absolutely nothing is different between the 2 statements.

it's just some people like to write it one way, and other people like to write it the other way.
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 2852/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 01-07-05 01:30 PM Link | Quote
Ah, I thought that might be the case.

Now I'm a bit confused as to how I actually display the dialogs I've created. I included the resoure .h and .rc files, but I can't find anything in them that looks like it could be used to reference the dialog itself.
Parasyte

Bullet Bill
Level: 35

Posts: 177/514
EXP: 267348
For next: 12588

Since: 05-25-04

Since last post: 104 days
Last activity: 32 days
Posted on 01-07-05 01:45 PM Link | Quote
There are a couple of API calls you can use to display dialogs. CreateDialog() and DialogBox()

If you don't have MSDN library installed, now's the time to create a bookmark to this site: http://msdn.microsoft.com/library/.

The main difference between the two functions is how they return; CreateDialog() returns immediately. You should use it to open multiple dialogs which act or react seperate from one another. DialogBox() returns only when the dialog is closed. (This can be used to retieve a return value from the dialog.) You should use this when you want the dialog to take precedence within the program. (The program will relinquish control to the dialog until it is closed)

For some examples, download FCEUXD. The debugger dialog is created with CreateDialog(), so the main window still retains control of the program. When you click the breakpoint Add button, the little breakpoint editor dialog is opened with DialogBox(). The program will completely stop until this dialog is closed. When that dialog is closed, DialogBox() returns a value indicating whether a breakpoint was added or not.

Check the MSDN pages I've linked to for the function declarations, as well as example code. If you need help with the callback or anything, I'm sure someone can explain it well enough to get you on your way.
FreeDOS

Lava Lotus
Wannabe-Mod :<
Level: 59

Posts: 991/1657
EXP: 1648646
For next: 24482

Since: 03-15-04
From: Seattle

Since last post: 6 hours
Last activity: 4 hours
Posted on 01-08-05 01:04 PM Link | Quote
MinGW is a port of several GNU tools, including GCC, to Windows. GCC is the standard compiler on GNU/Linux and mostly standard on other *nixes... What MinGW does is emulate some *nix functions that don't exist in Windows and compile it... DJGPP does the same thing, only that's for DOS.

Dev-C++ is a Windows IDE for GCC-based compilers..
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 2853/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 01-08-05 03:42 PM Link | Quote
Blech, I tried Dev-C++. Bug city.

I've heard MinGW is good, what all is it exactly? Like just a compiler or is there other stuff as well?
Gavin

Fuzzy
Rhinoceruses don't play games. They fucking charge your ass.
Level: 43

Posts: 372/799
EXP: 551711
For next: 13335

Since: 03-15-04
From: IL, USA

Since last post: 13 hours
Last activity: 13 hours
Posted on 01-09-05 01:49 AM Link | Quote
I've been messing with Dev-C++ for a while, I've never had a single bug. *Gavin shrugs*
labmaster

Blue Octorok
Level: 12

Posts: 14/43
EXP: 6135
For next: 1786

Since: 07-17-04
From: New Zealand!

Since last post: 10 days
Last activity: 2 min.
Posted on 01-09-05 02:14 AM Link | Quote
MinGW is basically the whole shebang for Windows.

Personally, I use MSVC (I started out with Dev-C++) - there's only one really annoying bug that causes it to crash when building a project (it's quite rare though) - it's very easy to use once you get used to it.
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 2856/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 01-09-05 07:31 AM Link | Quote
Eh, maybe it's just my computer "self-optimizing" again by removing a few random instructions. (Inside joke. ) I always got errors when starting it up, either that or it would crash when opening the file, plus there was a zillion little bugs in the IDE itself.

[edit] Hmm, both of those functions want a "Handle to the module whose executable file contains the dialog box template". How do I get that?
Nevermind... I got it, and it works! Now if only the window would actually close. (Of course given that I didn't provide any message handler, I'm surprised it works at all. I was just expecting it to compile and crash right away, at least that would mean I did it right.)
Now, the question is how do I make it send messages for controls? Like I have a button on the dialog, but the message handler isn't getting anything from it.


(edited by HyperHacker on 01-09-05 01:17 PM)
(edited by HyperHacker on 01-09-05 01:28 PM)
(edited by HyperHacker on 01-09-05 01:53 PM)
Dish

Spiny
Level: 38

Posts: 227/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 01-10-05 02:47 AM Link | Quote
Originally posted by HyperHacker
Now if only the window would actually close. (Of course given that I didn't provide any message handler, I'm surprised it works at all. I was just expecting it to compile and crash right away, at least that would mean I did it right.)


Yeah you'll need a message handler =P.

Typcially, when the dialog is to be closed, a WM_COMMAND message is send to the message handler, with BN_CLICKED as the high word of the wparam, and IDCANCEL as the low word (this will catch not only the escape button being pushed, but the 'X' in the corner, and also a press of a Cancel button if you have one on your dialog). To actually close the dialog, you need to call EndDialog(), which takes 2 params... 1st being the HWND of the dialog to close, and the second being its exit value (this is what DialogBox() will return with)

so something like:


INT_PTR CALLBACK MyCallbackProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
 switch(msg)
 {
 case WM_COMMAND:
  if( (LOWORD(wparam) == IDCANCEL) && (HIWORD(wparam) == BN_CLICKED) )
  {
   EndDialog( wnd, 0 );
   return 1;
  }
  break;
 }
 return 0;
}



Now, the question is how do I make it send messages for controls? Like I have a button on the dialog, but the message handler isn't getting anything from it.


Most controls signal the main window through the WM_COMMAND message (like my example above). With WM_COMMAND, the high word of the wparam is the action being performed by the control (typically just BN_CLICKED for pushbuttons... but can be other things for other controls -- like for example, list boxes have a wide variety, like LBN_SELCHANGE, LBN_DBLCLK, and others). The low word of the wparam is the ID to the control (whatever ID you gave it in the resource editor... like IDC_BUTTON or whatever)... and if memory serves, the lparam is the HWND to the control.
HyperLamer
<||bass> and this was the soloution i thought of that was guarinteed to piss off the greatest amount of people

Sesshomaru
Tamaranian

Level: 118

Posts: 2881/8210
EXP: 18171887
For next: 211027

Since: 03-15-04
From: Canada, w00t!
LOL FAD

Since last post: 2 hours
Last activity: 2 hours
Posted on 01-10-05 07:02 AM Link | Quote
Cool, though the control method seems complicated. Now of course another problem - I renamed a control, and it refuses to acknowledge the new name! I re-compiled the script resource, checked that the new name was declared in the header (and removed the old one which was still there for some reason) but it just won't accept it (keeps saying it isn't defined). I had to use the actual resource ID instead. What's up with that?

Also how do I change controls' properties? Do I have to send them messages and such?
Dish

Spiny
Level: 38

Posts: 228/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 01-10-05 07:30 AM Link | Quote
Originally posted by HyperHacker
Cool, though the control method seems complicated.


Not really.. it's just weird that it all get channeled through the same function (instead of each message getting its own routine -- which is how I assume VB does it (MFC does something similar)). I guess it takes some getting used to.



Now of course another problem - I renamed a control, and it refuses to acknowledge the new name! I re-compiled the script resource, checked that the new name was declared in the header (and removed the old one which was still there for some reason) but it just won't accept it (keeps saying it isn't defined). I had to use the actual resource ID instead. What's up with that?


Umm... you always have to use the resource ID... that's what it's there for. I must be misunderstand what you're saying




Also how do I change controls' properties? Do I have to send them messages and such?


For some things... yes. Like for stuff specific to the control, you'd have to send the control the appropriate message (like for setting a checkbox's check state, or adding strings to a listbox... stuff like that). But there's also a bunch of functions which will apply to almost any window (and remember that all controls are windows).

So stuff like:

SetWindowText() -- will change the display text (like the caption of a pushbutton, or the contents of an edit box)

EnableWindow() - will enable/disable a control

ShowWindow() - will show/hide a control
sloat

Level: 16

Posts: 30/85
EXP: 18044
For next: 2212

Since: 05-21-04
From: South Central Delaware

Since last post: 19 days
Last activity: 5 hours
Posted on 01-10-05 08:06 AM Link | Quote
Don't forget about SetDlgItemText, SetDlgItemInt, and SendDlgItemMessage. They come in quite handy for dialogs, especially if you're lazy.

As a side note, be careful when using CreateDialog, it does not work exactly like DialogBox. You have to have a message pump for those dialogs to work, and you have to call IsDialogMessage in there. You also do not use EndDialog; you call DestroyWindow instead.

Now that I think about it, just read the tutorial on winprog.org.
Dish

Spiny
Level: 38

Posts: 229/596
EXP: 355646
For next: 14801

Since: 03-15-04
From: Disch

Since last post: 18 days
Last activity: 18 days
Posted on 01-11-05 03:19 AM Link | Quote
Originally posted by sloat
Don't forget about SetDlgItemText, SetDlgItemInt, and SendDlgItemMessage. They come in quite handy for dialogs, especially if you're lazy.


Haha... I actually never knew about those before. They look like they're just macros though... like SetDlgItemText() just calls both GetDlgItem() and SetWindowText()


[speaking of CreateDialog dialogs]You have to have a message pump for those dialogs to work,



No you don't... they operate (more or less) the same way... only CreateDialog returns immedaitly rather than waiting for the dialog to close... and you exit with DestroyWindow (rather than EndDialog... like you mentioned). Other than that, it's driven the same way... you just supply a DLGPROC callback function when you call CreateDialog() and it feeds messages to it for you... no need to actually run your own pump.

That's my experience anyway. I don't even see where you'd need to call IsDialogMessage or where you'd even put your pump.
Pages: 1 2 3Add to favorites | "RSS" Feed | Next newer thread | Next older thread
Acmlm's Board - I2 Archive - Programming - Thinking of getting serious with C. | |


ABII


AcmlmBoard vl.ol (11-01-05)
© 2000-2005 Acmlm, Emuz, et al



Page rendered in 0.014 seconds.