|
Post by doyleman on Nov 16, 2006 22:17:56 GMT -5
Some of you may know I've tooken up C++, but if you haven't, well I am...
Anyway, i dont have a journal of sorts, or a blog, and i find that it'd be better to keep things rounded to near one site, and this is it (as I frequent here more than anywhere else).
Here, I'll be posting concerns, issues, or general topics about how i'm handling on this. If you know programming, you can reply or whatnot in this topic. This is kinda more so a blog so i can look back at issues at one point, hoping that i figure out where i'm going wrong somewhere.
anyway, i'll post something later, right now, i'm tired.
|
|
|
Post by Doan the Nado on Nov 18, 2006 3:28:28 GMT -5
This is a good idea, and is something that I may be able to facilitate a bit better in the future. If I ever get around to writing the site myself, one idea I had was to provide personal webspace to members, tightly integrated with the message board. I haven't thought it all the way through, yet, so I'm not sure exactly how it would be, but I have an idea. Anyways, I will be graduating soon with a degree in Computer Science, and I am somewhat familiar with C++, so if you need any help, I will be glad to offer it. One thing you might want to check out is the Standard Template Library (STL). A good reference site is cppreference.com. Finally, remember that if you have any question at all about C++, there is a ton of information out there, and Google can be very helpful. That's pretty much how I learned it.
|
|
|
Post by doyleman on Nov 18, 2006 18:24:24 GMT -5
Sounds like a cool idea. STL, composing most basic elements into a templated format... sounds bizarre, but ok. (I have no knowledge of templates in C++ yet, I've only just learned about references awhile ago, and am hitting the topic of advanced functions). That reference site, however, looks like it'll be a tremendous help. Thank you very much for pointing this out to me
|
|
|
Post by doyleman on Nov 20, 2006 20:05:52 GMT -5
Ok, I've run into a problem of passing in values into function's parameters.
Example: (main.cpp)
I'd think that passing in string array s, that the name I typed would pass into the member data of class Person, defined here, in class.h:
however, when run, the name is fetched as the inf. sign, but the string itself (string array 's'), shows what I typed.
I'm sure it's a matter of misplacement of pointer, or something dealing with them.
|
|
|
Post by Doan the Nado on Nov 20, 2006 20:35:14 GMT -5
Um... avoid character arrays if you're using C++. You're already using namespace std, so you can simply use "string" instead of having to use character arrays. There are numerous errors that even veteran programmers run into when using character arrays, so it's best to stay away from them unless you have a specific reason for using them.
Also, on a different note, it might be a bad idea to use Character as your own defined class. I believe that there is already a Character class defined (but I might be wrong), which is an object-oriented view of the char type. You might want to change it to something like Member or Person or whatever else you can come up with.
Okay, but the problem with what you have right now is the way you are using character arrays. You have:
char *s[10]; cin >> s[10]; Character Nate (80, 30, 10, 11, 9, 7, 5, *s);
This should be:
char s[10]; cin >> s; Character Nate (80, 30, 10, 11, 9, 7, 5, s);
Even better, however, is to just use:
string s; cin >> s; Character Nate (80, 30, 10, 11, 9, 7, 5, s);
And then of course change your constructor to accept the type "string".
What you were creating was a pointer to your character array. This may be a bit over your head, but when you're using character arrays, you either want to use char* or char[], not a mixture (unless that is what you are trying to do).
Good luck, I hope that helps.
|
|
|
Post by doyleman on Nov 20, 2006 20:41:41 GMT -5
i'm now under the assumption that I should include <string.h>, after reading that. Anyway, I am somewhat still a beginner, (off of 'teach yourself c++ in 21 days, i'm on day 11), so forgive me if I'm using awkward methods of achieving a goal , but there are just to many options to get one thing done! Example: int a; a = a +1; a +=; a++; all do the same thing (i'm not sure if I listed #2 correctly). Anyway, when using a string, i'm guessing it automatically generates the appropriate room to set aside based off of characters? (thanks for the reply to my problem, and the suggestion
|
|
|
Post by Doan the Nado on Nov 21, 2006 9:41:06 GMT -5
Yes, when you use the string class, it automatically generates some predefined amount of room (although you can control this in the constructor, I believe, if you have a good idea what the length will be). The problem with character arrays is best exemplified by your use of them, actually. Do you know what will happen in the following code if a string of more than 10 characters is entered?
char s[10]; cin >> s;
It will not appear to cause any errors. The problem is that immediately following the string s is some other data, and it will be silently overwritten by characters beyond s[9]. So when you were passing s[10] as an argument, you were actually passing the byte of memory just beyond your character array, which is numbered from 0 to 9.
Strings, however, if you declare them initially as size 10, will automatically manage their size. If some operation requires a string longer than what is being used, a new longer string will be created and all of the data will be copied over.
As far as int, you are nearly right with what you said. You were correct that #2 is wrong. It should be
a += 1;
That is, "a +=" is shorthand for "a = a +", so whatever you put after the += is what will be added to a. There are two increment operations, actually, and they have a subtle difference. You could write either:
++a; or a++;
In that form, both will do the same thing. The thing is, the ++ operation is actually a function, and it returns a value. So if you say:
int a = 0, b = 0, c, d;
c = ++a; d = b++;
// c now contains value 1 // d now contains value 0
The position of the ++ indicates when the operation occurs. ++a will increment a and then return the new value. a++ will return the original value of a and then increment it. You may wonder why you would do something like this, but C was created to be "close to" assembly language; it is a pretty low-level language. Most machines have an increment operation in their hardware, so by using increment operations in various ways, you can save a few instruction executions. This is not as critical now that there are better optimizing compilers that will do all that stuff for you.
So the lesson is to do whatever is clearest and easiest for you. If you are trying to create a game with this, I think a higher level language like Python might actually be easier. If your goal is to learn C++, then this is a great way to do it. If you find yourself getting stuck, you may want to look for an O'Reilly book (they are a publishing firm with a lot of good technology-related books) on beginner C++ (or Python, or whatever language you decide to use). Continued good luck to you!
|
|
|
Post by doyleman on Nov 21, 2006 18:36:50 GMT -5
I've gotten into C++ about 2 years ago, I believe. And yes, I'm learning it mostly because of it's vast in use in the game design industry (along with it's predecessor, C). This 'game' I'm doing now is just a little project to help me develop on the skills I know now. The postfix and prefix operator, I am aware of. ++a incriments first, then the left hand side operand is applied, while a++ (postfix) is incrimented AFTER the left hand side operand is applied. I knew the troubles of overshooting an array, but as I was going to be the only one to actually use this program, i didn't find it a problem. An array is merely a pointer to a list of characters/integers/whatever. Though, this is the first time I was introduced to the string class defined in namespace std, and how users knew how to properly use that class (istream.h is a pretty big file...). anyway, I have pursuited this language for awhile now, and I find that downgrading to another language might not help me (though, it may, idk...). many sources, however, say (and this is a controversial issue) to start with C++. Personally, I just got into the OOP part of C++, and so far, I'm having a blast with it's capabilities. thank you for your support, help, and luck, doan
|
|
|
Post by Doan the Nado on Nov 22, 2006 2:41:27 GMT -5
Yeah, there are a couple different approaches to how programming should be learned. The thing is, in my opinion (and many others') it is much more enjoyable to program in higher level languages like Python, Lisp, Perl, or even gasp Java (I say "gasp" because I personally do not like Java all that much). This, I believe, is because they are close to the way that we think, rather than being closer to the way that a computer thinks. To program in Python is not "downgrading", it is actually quite the opposite. You can say things in a few lines of Python, Lisp, or Perl code that would take you much more time to write out in C++. For one example (using Perl), let's say that you wanted to rename a bunch of pages with a .htm extension to a .html extension. This means that you would also have to update the links on all the pages, something that would be most easily done by a program. Let's assume that all of the pages have been loaded into an array of strings called pages, where each string is the entire page's text. The Perl code would be:
foreach $page (@pages) { $page =~ s/href="(.*?)\.htm(?!l)"/href="$1.html"/g; }
That's it! The foreach operation causes $page to point to each element of @pages in turn. Then, the "=~" means "perform the following regular expression on the preceding variable". s/pattern/replacement/ is the replace operation, so anything that matches the first part will be replaced by the second part, and the "g" at the end says to do it for every occurrence (not just once). So it will match a string that looks like href="some_string.htm(no 'l' here)" and replace it with href="some_string.html".
In C++, it would be something like:
// assume pages[] has size num_pages for (int n=0; i<num_pages; i++) { int j = pages[n].size(); while (j > 0) { j = pages[n].rfind(".htm", j); if (j >= 0) { if (pages[n][j+4] != 'l'){ pages[n].insert(j+4, 'l') } } } }
That's the easiest way I can think of to do it, and it's actually nowhere near as thorough as what I was doing in Perl (that is, it's not even making sure that the address found is with an a href="..." tag). This is a somewhat trivial example, but the point is that a bunch of little stuff like this adds up to the fact that if you're programming in a language like C++ or C, you are telling the computer exactly what to do, and you are likely to implement things yourself which are already built into languages like Python, Perl, Lisp, or Java.
So when is it good to use C/C++? When efficiency is the most important thing. The "magical" things that higher-level languages do come at a price, and that cost is runtime efficiency. The thing is, even if it's important for a program to be efficient, it can still be hard to know which parts are actually consuming the most time until you run the program. Paul Graham (see his site at paulgraham.com) has contended a few times (mostly in regards to Lisp) that the most effective way to use your time is to program in a more abstract language first, then test your code to see what part is slow. This slow part can then be recoded in a lower-level language so that it runs a little bit faster.
Don't let that discourage you from learning C++, though. It is indeed a great language to learn, because so many applications, companies, and people in general use it, and because you will probably need it at some point in a programming career, anyways. I'm just trying to ensure that if you start to get weary of programming, because it seems too repetitive or unenjoyable, chances are good that you might enjoy programming in a different language a little bit better.
On an aside, the reason that I don't like Java all that much is a two-part answer. First of all, it sacrifices the efficiency of C/C++ while being a little bit more high level, but it is still less abstract that the three that I keep repeating (Perl, Python, and Lisp, which I will now call "the Big 3"). That is, I feel as though it treads the middle ground too much; for someone who has only ever programmed in C++, Java will seem amazingly easy, but for someone who is accustomed to using one of the Big 3, Java doesn't seem all that much different from C++.
The second reason is actually something that many people love about Java: its ability to run on any architecture. This tends to discourage using open source software, which I am a huge proponent of (if you have ever used Gimp, Firefox, OpenOffice, Gaim, or any other free, open source program, you will know why). In Java, you can compile your source code into "Java bytecode" which can run on nearly any machine. This means that you can distribute that program without the source code, and anyone can run it, freeing you to keep the source hidden to yourself. With C/C++, the source code is compiled directly into machine-specific code, so in order for any machine to run it, the source code must be freely available. If you're using one of the Big 3, the source code is the program. That is, an interpreter reads the source code directly and runs from that.
Well, that's enough ranting for one night. Sorry if I sounded like I was lecturing or carrying on about something that you don't care about. I'm just tired of seeing 4th-year computer science majors (and others, of course), who think that programming is a drag because they've never actually seen a true high-level language. Once you start to use them, it's truly liberating. If you really want to have some fun, check out Lisp, but I highly suggest looking for Ansi Common Lisp by Paul Graham. It is a great read and really takes you through the language very effectively.
Happy coding!
|
|
|
Post by doyleman on Nov 22, 2006 20:38:41 GMT -5
I, by all means, don't think C++ is boring. I got heavily excited from the idea of calling functions, and again when learning about classes; though, i see your point on excessive typing to get from A to B.
I'm to tired to post a big speech or whatnot, but I'll try out lisp (while still learning C++, it's something that's become of habit to read something about it...)
anyway, lisp, how do i set it up? (right now, the only thing i have is newlisp, and it doesn't seem that awesome...)
|
|
|
Post by Doan the Nado on Nov 22, 2006 21:23:21 GMT -5
I'm not sure how to set up Lisp in Windows. I've only ever programmed in Lisp in a Unix environment (Sun Solaris and Linux). It's a pretty complex language and may be a bit difficult to learn without some kind of resource, which is why I suggest Ansi Common Lisp, by Paul Graham (Prentice Hall). I also found the following website in a Google search. It seems to have a lot of good resources. www.apl.jhu.edu/~hall/lisp.htmlOne good Lisp environment is Slime, and they have a version for Windows, it appears. I'm not sure what all you will need to install, but you should be able to Google a how-to on setting up Lisp with Slime in Windows. The Slime website is: common-lisp.net/project/slimeThis might be a good place to start in order to get Emacs for Windows: www.gnu.org/software/emacs/windows/ntemacs.htmlFinally, you will need some version of Common Lisp. The most popular are CLisp, CMUCL, and GCL (Gnu Common Lisp), not necessarily in that order. Again, I suggest searching online to see where you can get one of these for Windows. Good luck!
|
|
|
Post by doyleman on Nov 29, 2006 15:35:48 GMT -5
Hm, the whole parenthysis thing going on is completely confusing, and I can't seem to understand the 'list' structure it uses I've only seen screens and read documentations, as I haven't a clue how to set it up (they all have some directory with .tar.gz extensions, and I can't open them...), so I'm not 100% sure how it works. Perhaps I'll try another language, like perl... However, I have still maintained my learning of C++, and I think I've learned quite a bit. One thing that has me confused, is why does main take an argument of an int. and character pointer? Bah, I'll find out sometime. My latest gain in knowledge would be to follow the flow of execution, rather than in top to bottom order (starting from the main function, jumping to called functions, etc). Also, I've learned a little more about strings (comparing them, to some degree, re arranging the letters backwards, and setting all letters to upper/lower case). anyway, that's all...
|
|
|
Post by Doan the Nado on Nov 30, 2006 2:11:43 GMT -5
Perl, too, is a great language, especially if you ever get into a Unix environment like Linux, FreeBSD, or even MacOSX or Cygwin on Windows. If you are serious about programming but stuck with Windows, Cygwin provides a great Unix envrionment, with access to many of the free tools that we have come to know and love. Getting back to Perl, I have used it to automate some tasks that I wouldn't have dreamed of doing before learning Perl. I wrote up a file in about a minute or so that allowed me to run 100 different test files on 5 different versions of a program (I'm grading for a class). The program ran all of the test cases in less than a minute, so in a couple minutes, I was able to do what could have easily taken hours to run one-by-one. As far as the main operation in C++, there are very good reasons for the way it is set up: int main (int argc, char** argv) First to note is the "int" at the beginning of the line. This means that when your program finishes, it returns an integer to whatever program called it (after all, every program is started up by some other program). Typically, a return value of 0 indicates a successfully completed program, and various errors are encoded by using different return values. Much later, you may even find yourself invoking other programs through fork() and exec(), and then you will specifically see the value of the int return statement in determining whether these "child processes" completed as they were supposed to. And yet I still haven't touched your question. The parameters of the main function serve very important roles in any program, but again, if you've only ever used Windows, it's hard to see the use of them. When you write a program and then compile it, that creates an executable file that can be run. Let's say that you had a file called game.cpp. Now when you compile it (using "g++ game.cpp -o game") you will have an executable called "game". In Windows, it would probably "game.exe", but that is a whole other issue. Now, in a Desktop-oriented environment, you would probably simply double-click on the icon in order to run it. That is convenient in many cases, but it is also quite limited in its capabilities. Let's say that you wanted to start up a previous save of the game. You would double click on it, wait for it to load and open to the title screen, perhaps watch a brief intro, then navigate various menus in order to find your save and load it. Now from the command line, you would normally invoke the game by simply typing "game" in the same directory that the executable is in. Now, supposing that you wanted to load a previously-saved game, it would be possible to type "game save.savefile" at the command line, which would be a signal to the game to skip the title screen and intro stuff and go straight to loading the game. Hopefully you can see why being able to give "options" to programs can be useful, as that is the whole point behind the two parameters to main(). When you run a command from a command line, that command line is itself a program which is invoking the program you wish to execute. Even from a Desktop standpoint, the Desktop environment is a program that can start up other programs as well. Now, the way that these programs are started is by using one of various versions of an exec() call. Any command line qrguments need to somehow be passed to the program, and that is where the parameters come in. The first parameter, "int argc" is a variable indicating how many command line arguments there are ("ARGument Count"). Every C/C++ program has at least one command line argument which is the name of the program that was used to invoke the program. The second parameter provides the arguments themselves. Look closely: there are two *'s. This means that it is not a pointer to a char, but rather a pointer to a string. That is, char** is loosely equivalent to Java's usage of "String[] args". The notation you see actually comes from the early days of C, before there were string classes and array classes. Everything was basically viewed as blocks of memory. In the same way that char* is a pointer to a block of characters, char** is a pointer to a block of pointers. Operations that use char* are written to continue looking for characters until a NULL '\0' is encountered. There is no actual "length" field for the char* or anything of that nature. This is one problem that has led to many software vulnerabilities: if a string is written to a char* that is longer than the space it was intended to take up, it could have bad side effects. So anyways, a char* might look like this: char* text = "abcdefg"; text | V abcdefg\0 In this case, if you looked at the actual contents of the variable text, it is a number which is the address of 'a' in memory. Since chars are a fixed size of one byte, it makes it easy for the computer to allow you to reference other characters in the string. text[0] is equivalent to a, as is *text. Now if you want to reference the second character in the string, you simply say text[1], which tells the computer to look one storage unit (in this case one byte) beyond the address of the pointer. In this way, you can easily address subsequent blocks in memory and view them as a string of characters that make up a word. The important thing to remember is that the only way to know where the end of the char* is is to note the position of the \0 character, or to keep track of the amount of memory allocated to it yourself. Now, similarly, a char** is a pointer to a char*, just as a char* is a pointer to a char. Physically, a char** looks no different from a char*: they are both memory addresses. The only difference is what they point to. A char** would look something like: char** words; /* Let's assume that it is already declared to be big enough. */ words | V word1 --> "abc\0" word2 -\ word3 | \-> "defg\0" wor... V ........"hijkl\0" I'm trying to show that the char** words is pointing to a bunch of continuous pointers which could in turn be pointing anywhere. There is no "\0" NULL terminator for pointers of this type as there are for character arrays, to the only way to know the size is to declare it a certain size yourself and keep track of it, or to have someone tell you. This is where the int argc parameter comes in: it tells you how many command line arguments you can expect to see, since there is no other way to know. The char** argv, I hope you can see now, is a pointer to the first of a series of strings which are placed in memory on behalf of the parent program that initializes it. At the outset of execution, this is a program's communication with the outside world. Some examples: gunzip filename.tar.gz This program's parameters would be argc = 2, argv[0] points to the 'g' in "gunzip", and argv[1] points to the 'f' in "filename.tar.gz". Then, after unzipping your file, you would likely run tar xvf filename.tar In this case, argc = 3, argv[0] points to the 't' in "tar", argv[1] points to the 'x' in "xvf", and argv[2] points to the 'f' in "filename.tar". In this way you could have a program that did something like: modify-files file1 file2 file3 ... and it could easily be written as int main (int argc, char** argv) { for (int i=0; i < argc; i++) { // modify argv } }
I hope that helps you understand a little bit more of what is going on
|
|
|
Post by doyleman on Dec 2, 2006 11:13:11 GMT -5
Actually, that helped a whopping lot!
I understood the concept of Return Types for functions (and that in the case of an Class object being a return type, it'd make a duplicate-which could take up memory fast!), and parameters, but it never really crossed my mind that Main could take them to 'alter' the start of the program (of course, being as they're parameters, they could be used anywhere in the scope of main-which is the whole life of the application...).
Anyway, I'm guessing running it through command line would be equivilant as dragging and dropping a file into the main application? (ie: i drop a HTML file into internet explorer/firefox, and it opens it that way?)
Hm, I still have a lot to learn. I haven't a clue what Unix is, really, except that it's a platform. I'll study some stuff and get back to this topic.
|
|
|
Post by doyleman on Dec 2, 2006 12:07:45 GMT -5
Eh, I may as well post my latest creation:
That's a TicTacToe game. It's quite long, but I've managed to cut it down to:
The change is a loop check is used for displaying the grid. Now to cut down on the Win/Lose check...
|
|
|
Post by Doan the Nado on Dec 3, 2006 1:20:21 GMT -5
That's good that you're starting with somewhat simple programs, but programs that actually do something that is somewhat interesting. So often, text books start you off with writing extremely simple code snippets that do nothing that appears to be of much use, so your approach is very good.
You will find that the more you program, the more you look for loops and other optimizations to decrease the amount of code that you have to write. Pretty soon, you will start to understand why I preach some of the scripting practices that I do in my RPGM2 advice (using script calls for common functions, using loops, etc). Another very powerful tool that doesn't work correctly in RPGM2 is recursion. It can be a little hard to wrap your head around, but once you do, it's pretty cool. One example to get you thinking is to reverse a text string. You could write this in Java as:
I used Java because it allows the "+" operator for string concatenation, which made it easier to write. Anyways, I hope you can see what's going on: if the string has any characters, then to reverse it, it returns the last character of the string + the reverse of the rest of the string. So the call sequence for Reverse_String("abcd") would look like:
ReverseString("abcd") ->"d" + ReverseString("abc") -->"c" + ReverseString("ab") ---> "b" + ReverseString("a") ----> "a" + ReverseString("") -----> ""
Which means that from a different viewpoint, we have:
ReverseString("abcd") = "d" + ReverseString("abc") = "d" + "c" + ReverseString("ab") = "d" + "c" + "b" + ReverseString("a") = "d" + "c" + "b" + "a" + ReverseString("") = "d" + "c" + "b" + "a" + "" = "dcba"
which is exactly what we want, and pretty simple to write. In fact, there are some things that are extremely difficult to write without the use of recursion. One that comes to mind is when using Binary_Tree data structures, which are useful in many situations. But anyways, that's a discussion for another day.
It certainly looks like you're making good progress so far.
Edit: I thought the "code" tag would maintain the formatting of my post (it should), but all it served to do was to make it really small. I changed it to "quote" so that it would actually be readable.
|
|
|
Post by doyleman on Dec 3, 2006 20:50:24 GMT -5
Yeah, I kinda was wondering if recursion would be allowed in RPGM2... (cant see why not, but then again, doesn't RPGM2 only go 10 scripts in, then it stops?) For laughs, I had a recursion that counted to see how far it could go till the program would crash (as it builds up on the stack, i believe...), and got pretty far, past the 10,000s, i think (i'll have to re-do it again, and check). And yeah, I know very little about binary trees, or any linked data of that sort... but thanks for the support (and yeah, i was wondering if there were 'code' or some odd tags, but i instantly just thought quote ones would do good...*shrug*)
|
|
|
Post by Doan the Nado on Dec 3, 2006 21:17:17 GMT -5
Yeah, recursion works in RPGM2, but it doesn't go deep enough to be very useful. I think 6 or 7 is the max.
|
|
|
Post by doyleman on Dec 7, 2006 14:17:49 GMT -5
8 is, I just checked it. Either way, is there really a use of recursion in RPGM2? It may save a repeat command, but that's only a TINY bit of memory.
|
|
|
Post by Doan the Nado on Dec 8, 2006 5:50:06 GMT -5
I came across a situation where I considered it, but I can't remember what it was now.
|
|
|
Post by doyleman on Dec 9, 2006 21:55:51 GMT -5
the 'newer' version of TTT. much shorter.
edit: Lines: ' if (board[2] == board[4] && board[4] == board[6]) { if (board[2] == 0) cout << "Player 2 wins" << endl << endl; if (board[2] == 1) cout << "Player 1 wins" << endl << endl; if (board[2] != 9 && turns > 3) initialize(); }' the 'if (board[2] != 9... was originally 'if board[0]...'. thanks to ves for finding that.
|
|
|
Post by Doan the Nado on Dec 11, 2006 4:38:45 GMT -5
If I don't reply to this in a couple days, please bump it to remind me .
|
|
|
Post by vespuleth on Dec 11, 2006 14:48:09 GMT -5
nevermind... you already edited the post to reflect...
|
|
|
Post by doyleman on Jan 6, 2007 11:43:46 GMT -5
bump...
|
|
|
Post by doyleman on Jan 23, 2007 19:00:24 GMT -5
I got a book for christmas. I went over it twice, going for a 3rd time. I now know like 5 times the amount then I had. This is cool.
One thing I still cant grasp my mind around: the 'this' pointer. If it invokes the method of the current instance only, why even bother using it period? is there a way to switch to a different instance within another's method?
Anyway, I have no code to put up. Yet...
|
|