Sponsored By

Sign in to follow this  
Matt

My First Program

Recommended Posts

Ok yall, this is the first program I have written by myself. It calculates the area of a circle when the user enters a radius. I know I'm lame,:P but what do yall think? Anything within it I can improve on? Also open for comments... Here's the source code:

//
//  This is a test program designed to find the
//  area of a circle when the user enters the radius.          
//
// the following include files define the majority of
// functions that any given program will need
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;

int main(int nNumberofArgs, char* pszArgs[])
{
double darea;
 cout << "This program calculates the area of"
      << "a circle when the user enters the radius\n";
 cout << "Terminate the program by entering a zero \n";
 
   //loop forever
   for (;;)
   {  
double r;
 cout << "Enter the radius of the circle: ";
 cin >> r;
// Enter a O to terminate
 if (r == 0)
 {
 break;
 }
 
// otherwise, find the area
darea = (3.1415927 * r) * r;
cout << "\n The area of the circle is "
    << darea
    << "\n";
    }

   // wait until user is ready before terminating program
   // to allow the user to see the program results
   system("PAUSE");
   return 0;
}

If you want to download it, the .zip file is below. By the way, can anyone tell me why such a small program is so big? 1.2MB??? hmmm....

Also, how come (this is more of a general C++ question) if I were to inter a char instead of an int or double , such as "F" the programm continusly reprints "Enter the are of radius of the circle" and "The area is 0"? Is that because it cannot handle a char?

[email protected]

Share this post


Link to post
Share on other sites

the char is a wierd number, that makes the system loop continuosly forever, as it doesnt make sence F*48 = ??

you could add checks, which you should do but for something like this its okay

its soo big because the compiler i believe is adding all the debug crap to the .exe, i think you can change the settings of the compiler and the file will be smaller but im not sure

Share this post


Link to post
Share on other sites
the char is a wierd number, that makes the system loop continuosly forever, as it doesnt make sence F*48 = ??

you could add checks, which you should do but for something like this its okay

its soo big because the compiler i believe is adding all the debug crap to the .exe, i think you can change the settings of the compiler and the file will be smaller but im not sure

thanks pierce, yes, I did set it to debug.

[email protected]

Share this post


Link to post
Share on other sites

as noted, some checking on the user input is always a good idea unless the program is being done as an exercise or as a 'quick-and-dirty'. you should try

to NEVER assume that the user of your program will enter the data you expect.

somewhere, sometime, some user is guaranteed to find a way to confuse your code.

most compilers provide some means of controlling what is emitted by the compiler,

such as debug info. some even provide a means of using run-time calls to libraries,

rather than rolling in library code into a stand-alone executable, resulting in a smaller exe file - but then the program would only run on the machine used for development.

but don't worry too much about compiler settings or switches while learning the programming language...

Share this post


Link to post
Share on other sites
some even provide a means of using run-time calls to libraries,

rather than rolling in library code into a stand-alone executable, resulting in a smaller exe file

Dynamically linked executables are the norm on most modern (non-embedded) systems. Static linkage is often reserved for programs that really need to be able to function in the absense of libraries, and occasionally for performance-critical programs.

Share this post


Link to post
Share on other sites
Anything within it I can improve on?

Adding to what others have said, you should also check for errors on cin. I entered EOF (end-of-file) to terminate the program (the normal Unix approach) and it collapsed into a infinite loop. The same loop, in fact, that you noticed when you enter a non-number.

You could also replace

system("PAUSE");

with

char c;
cin >> c;

which should have the same effect but is more portable and faster.

If you want to download it, the .zip file is below. By the way, can anyone tell me why such a small program is so big? 1.2MB???  hmmm....

It appears that it is indeed a combination of debug code and static linkage. Looks like it's roughly 1MiB of symbols (mostly debugging symbols, I assume) and 200KiB of library code. The executable is 5172 bytes when I build it dynamically linked, without debug symbols, and stripped, with GCC under Linux.

Edited by jcl

Share this post


Link to post
Share on other sites

hey all, thanks for the comments. Unfortunately, I have no idea what most of you said :huh: This was the first program I have ever written, and I'm learning from 'C++ for Dummies' (only on chapter 6) what are checks? I think I'll keep the debug in for now, since the book told me too, lol. And jcl, how would

char c;
cin >> c;

be the same thing? Like I said, I am prolly this biggest programming n00b here, and I have only touched functions and loops in my learning.

[email protected]

Share this post


Link to post
Share on other sites
Unfortunately,  I have no idea what most of you said  :huh:

Heh. You'll learn soon enough :)

what are checks?

Just bits of code checking for various conditions. For example, you could check for EOF on cin with

cin.eof()

or for errors with

cin.fail()

which I think covers conversion errors and so should address the problem non-numbers in the input (i.e., put a fail() check in after you read in the number to make sure it was in fact a number).

I think I'll keep the debug in for now, since the book told me too, lol.

May as well, you'll need it sooner or later.

And jcl, how would

char c;
cin >> c;

  be the same thing?

The effect of the code from the perspective of the user is similar. The system() function invokes the operating system's command interpreter (cmd.exe, I assume) and passes the argument string (in your case, "PAUSE") to it as a command to be executed. PAUSE just pauses, prints the lovely "Press any key to continue..." prompt, and waits for the user to press a key.

The code I posted does roughly the same thing. This does almost exactly the same thing:

cout << "Press enter to continue...";
cin.get();

the only difference being that the user can't get away with pressing any key. (Needless to say, this is what I should have posted last night, but I'm not a C++ programmer and I was too lazy to check the istream documentation to see if get() existed. Sorry :))

It really doesn't matter, I only mentioned it because (surprise) I'm running Linux, so...

 $ ./a.out 
This program calculates the area ofa circle when the user enters the radius
Terminate the program by entering a zero
Enter the radius of the circle: 0
sh: line 1: PAUSE: command not found

Edited by jcl

Share this post


Link to post
Share on other sites

Thanks for the suggestions jcl.

Also thanks for the info. I'm gunna keep learning, and perhaps I'll be able to further understand these commands. For now, I'll try to only incoorporate what I've read, so as not to get confused within everything. (lol I ahven't even gotten to using strings or chars yet)

Thanks again everyone.

[email protected]

Share this post


Link to post
Share on other sites

I downloaded it but it only works on windows and such...

I tried to compile it but it found 32 errors. Its only one thing that it doesnt understand that comes in the code frequently

errors...

/usr/bin/jam -d1 JAMBASE=/Developer/Makefiles/pbx_jamfiles/ProjectBuilderJambase JAMFILE=- build ACTION=build _DEFAULT_GCC_VERSION=3.1 BUILD_STYLE=Development CPP_HEADERMAP_FILE=/Users/seas/matt/build/matt.build/matt.build/matt.hmap SRCROOT=/Users/seas/matt OBJROOT=/Users/seas/matt/build SYMROOT=/Users/seas/matt/build DSTROOT=/tmp/matt.dst

...updating 13 target(s)...

Mkdir /Users/seas/matt/build/matt.build/matt.build/Objects-normal/ppc

CompileCplusplus /Users/seas/matt/build/matt.build/matt.build/Objects-normal/ppc/main.o

main.cpp: In function `int main(int, char**)':

main.cpp:15: stray '\312' in program

main.cpp:16: stray '\312' in program

main.cpp:16: stray '\312' in program

main.cpp:16: stray '\312' in program

main.cpp:17: stray '\312' in program

main.cpp:18: stray '\312' in program

main.cpp:19: stray '\312' in program

main.cpp:19: stray '\312' in program

main.cpp:20: stray '\312' in program

main.cpp:20: stray '\312' in program

main.cpp:21: stray '\312' in program

main.cpp:21: stray '\312' in program

main.cpp:21: stray '\312' in program

main.cpp:23: stray '\312' in program

main.cpp:24: stray '\312' in program

main.cpp:26: stray '\312' in program

main.cpp:27: stray '\312' in program

main.cpp:28: stray '\312' in program

main.cpp:29: stray '\312' in program

main.cpp:30: stray '\312' in program

main.cpp:34: stray '\312' in program

main.cpp:34: stray '\312' in program

main.cpp:35: stray '\312' in program

main.cpp:35: stray '\312' in program

main.cpp:36: stray '\312' in program

main.cpp:36: stray '\312' in program

main.cpp:38: stray '\312' in program

main.cpp:38: stray '\312' in program

main.cpp:39: stray '\312' in program

main.cpp:39: stray '\312' in program

main.cpp:40: stray '\312' in program

main.cpp:40: stray '\312' in program

main.cpp:41: stray '\312' in program

main.cpp:41: stray '\312' in program

/usr/bin/g++3 -c -F/Users/seas/matt/build -I/Users/seas/matt/build/include "-arch" "ppc" "-fno-common" "-fpascal-strings" "-O0" "-Wmost" "-Wno-four-char-constants" "-Wno-unknown-pragmas" "-pipe" "-fmessage-length=0" "-mdynamic-no-pic" "-g" "-precomp-trustfile" "/Users/seas/matt/build/matt.build/matt.build/TrustedPrecomps.txt" "-Wp,-header-mapfile,/Users/seas/matt/build/matt.build/matt.build/matt.hmap" main.cpp -o /Users/seas/matt/build/matt.build/matt.build/Objects-normal/ppc/main.o

...failed CompileCplusplus /Users/seas/matt/build/matt.build/matt.build/Objects-normal/ppc/main.o ...

Compiling with Mac Os X Project Builder (I picked C++ Tool)

It probably compiled on windows but not on my mac....

So does anyone know how to fix it?

Itd be a nice thing for everyone to learn how to make programs workable on ALL OSs

:D

Share this post


Link to post
Share on other sites

Hi Oni, as far as I know, it will only work in windows or windows emulators because some of the declarations are meant for the Windows DOS... Other errors that you ome accross could be because of your compilier... Someone with more experience could probly clarify this better...

[email protected]

Share this post


Link to post
Share on other sites
It probably compiled on windows but not on my mac....

So does anyone know how to fix it?

Itd be a nice thing for everyone to learn how to make programs workable on ALL OSs

That's a bug in your environment. When you copied the source some non-printing garbage characters were copied along with it. Seems to happen occasionally when copy-pasting code to OS X or Cygwin. Filtering out the garbage should fix it.

As for his source, as far as I can tell it's almost completely portable ISO C++. The system() call is the only issue. It builds clean with only two warnings (unused variables) with GCC 3.3.4 -W -Wall -std=c++98 -pedantic under Linux, and, except for the system() call, runs as intended.

Appendix

Okay, one more complaint about the program :) Or rather, about the book. Whatever you do, do not get accustomed to naming variables like this:

int main(int nNumberofArgs, char* pszArgs[])

Those are an examples of what is called Hungarian Notation. The idea is to help you remember the types of the objects by encoding the type information as prefixes: 'n' for integer, 'p' for pointer, 'sz' for for zero-terminated string, and so on. It is Evil. It's redundant, unreadable, brittle, and the need for it is often an indication that something is very wrong.

It also happens to be wrong in this case. psz is a pointer to a single string. It should be something like rgszArgs. An argument could also be made for renaming nNumberofArgs to iNumberofArgs since it serves as an index for rgszArgs, or to cNumberofArgs or cszNumberofArgs since it's a count of the number of elements in rgszArgs. Hungarian Notation is fun!

Edited by jcl

Share this post


Link to post
Share on other sites

Hi jcl

int main(int nNumberofArgs, char* pszArgs[])

is not explained at all yet... The book just has it as the "template" and advises me to just use their tepmplate when writeind a program. The template also includes the

#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;

which I have no idea what it does. hmmm... well, thanks for the input. Could you tell me what those above code snippets mean? Thx

[email protected]

Share this post


Link to post
Share on other sites
Hi jcl

int main(int nNumberofArgs, char* pszArgs[])

is not explained at all yet...

Sorry, I knew you were just following the book. What I meant to say was that there's no reason to bother with Hungarian Notation in your own code; odds are you'll either never use it again or it you'll use a different form. As long as you're using code from the book (or Win32, which also uses it) you should, of course, follow its example (consistency trumps clarity).

IOW it's another one of those things I mentioned for no reason that you shouldn't worry about :)

Could you tell me what those above code snippets mean?  Thx

Sure.

First thing you need to know is that C++ uses a preprocessor, often called CPP, that it inherited from C. CPP is essentially a very stupid macro compiler that is usually invoked automatically when you compile C++ source code. It provides a small number of directives that can be used in C++ source to define and use simple textual macros. When CPP is run on a file it 'compiles' the macros it sees by transforming them into source code that is inserted into the file just before it's passed to the compiler.

The simplest of these is the #define directive, which you didn't ask about but which may make it easier to understand #include. #define defines a macro name and the source code to replace it. For example,

#define FOO 0

defines a macro named 'FOO' that is transformed in '0' when CPP is run. That is to say,

#define FOO 0
int main()
{
   return FOO;
}

is exactly the same as

int main()
{
   return 0;
}

CPP sees the #define directive and then searches the file for 'FOO', replacing every occurance with '0'.

#include is another CPP directive. The text that follows '#include' is (more or less) a file name surrounded by either brokets (<>) or double-quotes (""). When CPP encounters an #include, it searches for the named file (where it searches depends on whether brokets or quotes are used) and copies the contents of that file into the source code. In other words, it literally includes one file in another. So this code

#include <cstdio>
#include <cstdlib>
#include <iostream>

will (conceptually) result in the contents of the files named 'cstdio', 'cstdlib', and 'iostream' being merged into your source code. Those files contain the declarations of a variety of classes, functions, variables, and whatnot. For example, 'iostream' contains the declarations of 'cin' and 'cout' and 'cstdlib' contains the declaration of system(). By #including those files you also include those declarations and thereby gain access to those features. (This will make more sense once you're familiar with C++'s rules for declaring and defining.)

You can think of #include as an incantation that gives you access things that appear in other source files. The actual operation of it doesn't matter until it bites you in the arse.

As for this

int main(int nNumberofArgs, char* pszArgs[])

that defines a function named main() with two parameters, an int and, uh, a collection of strings, and an int return value. (The second parameter is actually a pointer to a NULL terminated array of pointers to strings, but I'm going to a wild guess and say that that doesn't mean much to you right now. Just play along until you get to that chapter ;))

main() is the entry point of (almost) every C++ program, the first thing that is executed when a program is run. If the program is run with any arguments -- command-line arguments, for example -- those are made available through the main()'s parameters. The first (the int) is the number of arguments, and the second (the array of strings) is the arguments themselves. The name of the program is usually treated as the first argument. The return value is an int that indicates how the program exited. A value of 0 indicates normal termination, anything else usually indicates an error.

It's probably easier to understand if you just play with an example:

#include <iostream>

using namespace std;

int main(int argc, char * argv[])
{
   for (int i = 0; i < argc; i++) {
       cout << argv[i] << endl;
   }
   return 0;
}

(Note that I'm using the conventional names for main()'s parameters. It doesn't matter what you use, of course, but my brain locks up when I try to use something else.)

This program will print each argument out, one per line.

 $ ./a.out 
./a.out
$ ./a.out foo
./a.out
foo
$ ./a.out foo bar baz
./a.out
foo
bar
baz

Notice that the first argument is the command used to invoke the program.

Edited by jcl

Share this post


Link to post
Share on other sites
Hi jcl, thanks for all the info  :)  Got another question, you said the #include finds a file, and puts it in the source code.  where did that file come from?  on my hard drove somewhere?

Yes, almost certainly. Usually the compiler has a list of directories that are searched for #include'd files. The headers you used (header is the common term for files intended for #inclusion) probably came with your compiler and are stored with it, possibly in a directory named "include" (a old convention). Your compiler will have an option to add additional directories and maybe an option to display the search list.

Since we're talking about it, the difference between

#include <file>

and

#include "file"

is that most compilers respond to the latter by first searching the directory containing the file being compiled. Otherwise they're the same.

Oh, and strictly speaking the compiler can interpret #include any way it wants as long as the effect is the same. In particular, the standard headers (the headers defined by the ISO standard) are magical and don't have to exist at all. For example, it's entirely possible that

#include <cstdlib>

will actually use the C header named "stdlib.h" from whatever C compiler is handy. If you go looking for the headers don't be surprised if you don't find them right away.

Edited by jcl

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this