Register | Login | |||||
Main
| Memberlist
| Active users
| ACS
| Commons
| Calendar
| Online users Ranks | FAQ | Color Chart | Photo album | IRC Chat |
| |
0 user currently in Programming. | 3 guests |
Acmlm's Board - I2 Archive - Programming - Thinking of getting serious with C. | | | |
Pages: 1 2 3 | Add 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 |
| ||
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 |
| ||
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.
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.
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 |
| ||
[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 |
| ||
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 |
| ||
Originally posted by HyperHacker 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 );
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 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.
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.
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 |
| ||
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 |
| ||
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 |
| ||
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 |
| ||
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 |
| ||
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 |
| ||
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 |
| ||
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 |
| ||
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. |
| ||
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 |
| ||
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] 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 |
| ||
Originally posted by HyperHacker 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:
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 |
| ||
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 |
| ||
Originally posted by HyperHacker 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.
Umm... you always have to use the resource ID... that's what it's there for. I must be misunderstand what you're saying
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 |
| ||
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 |
| ||
Originally posted by sloat Haha... I actually never knew about those before. They look like they're just macros though... like SetDlgItemText() just calls both GetDlgItem() and SetWindowText()
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 3 | Add to favorites | "RSS" Feed | Next newer thread | Next older thread |
Acmlm's Board - I2 Archive - Programming - Thinking of getting serious with C. | | | |