C and C++ (I will post all my questions here while I learn.)
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
C and C++ (I will post all my questions here while I learn.)
As I said in another post I am a complete newbie with C and C++, I just started teaching myself yesterday. Before I actually get into the coding part I am trying to understand the relations files have with each other.
For example, .h .c and .o
I hope I can explain this question correctly.
Now with the .c file. Is there one main one that points to the rest or would it be the first one, then it moves on to another .c, etc. For example programs.c which points at the headers, etc. Then when it completes it points to programs222.c which in turn does the same thing. Did I explain that right?
Now with .h I am slowly learning what headers are and what they do.
.o I am still a little lost on that one.
Also if the program needs other libraries, I am not sure how that works yet.
I do have a huge amount of links and pdf I got from this forum. Right now I am trying to sort through it all and learn this and understand it my way, which is why I am asking the questions like this. I hope the questions don't sound too idiotic, as I said I am a complete newbie. I have a feeling in a month I will reread this and laugh at my lack of knowledge at this point, lol.
(For the record. I am one of those people that does horrible in a class environment. I am much better learning these things on my own, my way.)
Before you jump off the bridge, it might be a good idea to get (and actually read) an introduction to C programming -- do not get one that emphasizes Microsoft (which is not going to do you a lot of good), rather get a Unix- or Linux-specific book.
Header files, .h files, contain definitions and declarations; e.g., definitions might be something like
Code:
/* values for conversion of dd-mm-ss to decimal degrees */
#define MINDEG (1.0/60.0) /* minutes in a decimal degree */
#define SECDEG (1.0/3600.0) /* seconds in a decimal degree */
Declarations declare, for example, a function protype or a structure definition; e.g., a structure definition might look like
Code:
/* US Concise Listing Files */
struct concise {
char fips [11];
char name [128];
char type [16];
char county [48];
char state [32];
char lat_deg [8];
char lat_min [8];
char lat_sec [8];
char lat_lat [8];
char lon_deg [8];
char lon_min [8];
char lon_sec [8];
char lon_lon [8];
char elevat [16];
};
and a set of function prototype declarations might look like this
(these functions are void; i.e., they do not return a value, and are expecting one argument, a character string).
You already know that the source code file for a C program is a .c file. The compiler, most likely GCC if you're using Linux, translates the source code in the .c file to a object code file, a .o file, which is then linked with other functions you have written or with libraries containing one or more object files to create an executable program. For example, if you use the printf() function in your source code file, the C library will be linked with your object file because that's where the object code for the printf() function is stored (this is automatically done by the compile-in-one-go process that you execute with)
Code:
cc -o prog prog.c
See the manual page or the introductory text.
Now, a C program must contain one main() function and can contain zero or more other functions. You can link multiple files together by
Code:
cc -o proj prog.c a.c b.c c.c d.c ... z.c
where you've written a.c ... z.c. If you're using any library functions, you need to add the ones that aren't automatic; e.g., if you use mathematical functions (in the math library), you would
Code:
cc -o prog prog.c -lm
Again, you really need to crawl before you walk, walk before you run; get a good introductory text, read it and do all the exercises provided in that text.
It does help. Thanks. I have a weird way of learning things, but it somehow works for me.
I just did the HelloWorld one here at LinuxQuestions. In the process I learned what the warning, "no newline at end of file" means and why it is important.
Now I am in the process of trying to find out if I can get it to automatically open up the terminal and run in Xubuntu 8.04.1. I want to see if I can do it with in the binary file itself rather then just associate it and have it open in a terminal. In other words I want the code to automatically do it for me if that is possible.
The Hello World one was very simple.
g++ to compile
path to the .cpp file
-o to tell it what the output binary file will be
and keeping in mind that there needs to be an empty line at the end to avoid the warnings.
and
\n means new line
And I am in the process of understand the rest of this. I need to know exactly what it all does. The exact whys will come later.
There aren't really any files "pointing" to any others.
To understand what's going on with source files (.c), header files (.h), and object files (.o), we should understand more about the compilation process.
There are three stages of C compiling (that we care about, anyway: )
1) The preprocessor
2) The compiler
3) The linker
1) The preprocessor takes all the lines in your source code starting with #, like
#include <iostream>
or
#define NDEBUG
and turns them into normal source code. You can use it to repeat a certain bit of code many times, or to make some code only get used sometimes. The important thing is that when it's done, only real C (or C++) code is left, so the compiler only sees valid code, and none of this funky #whatever stuff.
#include "file.h" does just what it says -- it includes the contents of file.h at the point where it appears. So header files are copied into whatever source files use them.
Header files are useful when many programs, or many source files in the same program, want to use the same functions or variables. For instance, you might have a function int randomNum() which returns a random number, and you want to use it in lots of places. Say you wrote that function in "random.c".
Code:
int randomNum() { return 347; }
If you just call it in "foo.c", the compiler will complain because it's never heard of this function.
Code:
#include <stdio.h>
int main() {
int n = randomNum(); /* What the heck is this? */
int i;
for (i = 0; i < n; ++i)
printf("This is not very random\n");
return 0;
}
So you have to "declare" it -- tell the compiler that this function exists, and what its arguments and return values are, so that you can use it. Then the compiler will trust you that the function will show up eventually, and let you make calls.
Code:
#include <stdio.h>
int randomNum();
int main() {
int n = randomNum(), i;
for (i = 0; i < n; ++i)
printf("This is not very random\n");
return 0;
}
You could just declare the function this way in every file where you use it, but that would be a hassle. Also, what if you change it, and the return type becomes a long instead of an int? Then you'd have to find every source file where you used the function, and change the declaration. What a nightmare!
So, instead, you make a file "random.h", which just has the declaration.
Code:
int randomNum();
Then
#include "random.h"
in each file where you use it. That way, you can make the changes in just one spot. And from the compiler's perspective, this is exactly the same as if you had manually written the declarations into every source file.
2) The compiler doesn't know or care about header files. It just takes source code and spits out executable code. This executable code is placed in an object file. And it only considers one file at a time!
While you are compiling foo.c, it will see the declaration int randomNum(); and say "okay, this function is somewhere." Then when you use the function, it won't really know what code to generate, because it doesn't know where the function is. Essentially, it puts a note in the executable output (foo.o), saying "HEY, A CALL TO randomNum() GOES HERE."
3) Okay, so you've compiled all your source files, and you have a bunch of .o files lying around. But they are useless - with all those notes about "SOME CALL GOES HERE", they can't actually be run.
That is where the linker comes in. It takes all the object files, and builds a symbol table listing all the names of things, and their addresses. Then it combines all the .o files into your final executable, replacing the notes "SOME CALL GOES HERE" with the actual addresses as it goes.
If you declared some function to use, but never actually gave a definition, it will compile just fine; it is the linker that will complain.
Libraries are just the same thing on a slightly larger scale. The library will provide a header file to #include, in order to declare all the functions and variables you will be using. This is usually at /usr/include/cool/cool.h, or something. After including it, you can write code using it, and the compiler will be happy. However, if the linker can't find the definitions in an object file, it will not be happy at all. Since you didn't write the code, of course you won't have an object file yourself -- but it should be in /usr/lib/libcool.a.
(That's actually an "ar" archive of several object files. Check it out - "ar t /usr/lib/libcool.a" lists the contents, and you can extract them with "ar x /usr/lib/libcool.a".) To make sure the linker knows where to find these, you pass the option -lcool.
GCC handles all three stages, normally. You can use "gcc -E foo.c" to only preprocess, "gcc -c foo.c" to only compile (to foo.o), and "gcc foo.o random.o anotherfile.o -lcool -o executable" to only link.
"gcc -lcool -o executable foo.c random.c anotherfile.c" does the whole thing.
I have been playing around with \n Since it means a new line I wanted to see if I could do something, which is basic. I am done for now playing around with that. I want to sit back and read, reread and re-reread the replies in this thread before I do anything else.
Does this look ok?
[CODE]#include <iostream>
using namespace std;
int main()
{
cout << "This is my first program. It couldn't be anymore easier and fun \n";
cout << "This is the second line? \n";
cout << "This is the third line?! \n";
cout << "And the fourth line, etc, etc, etc..... \n";
return 0;
}[CODE]
Output is,
This is my first program. It couldn't be anymore easier and fun
This is the second line?
This is the third line?!
And the fourth line, etc, etc, etc.....
Which is what I was going for.
I understand a little more about the iostream, which is the input and output libraries. I also am learning that the "using namespace std;" helps split things up a bit when using multiple libraries, at least I think that is what it does, at least in part. I am still reading up on that.
Thanks everyone and thanks for being patient with me.
The *.c files contain the actual code which will be translated to executable instructions.
The *.h files contain declarations of functions and variables which *.c files may need to know to work together. For example, a file 'a.c' has a function:
int blah(char a);
Then you have a file 'b.c' that needs to use that function. Since 'b.c' can be compiled at any time and independently of 'a.c', the compiler needs some extra information so that at a later stage the linker can join the code generated by 'a.c' and 'b.c'; that information goes in the header (*.h). Headers can also be used to hold actual code, but that's a more advanced topic.
The *.o files are the "object code"; it contains information about how to link it with other code; the linker then puts together all your object code to produce the final executable.
The "namespace" just helps to avoid ambiguity. If two libraries had a function "void blah(void)" and you linked to both of them, the compiler would have no idea of which function you wanted to use. If the libraries each have a different namespace then you specify which function you want via:
namespaceA::blah()
namespaceB::blah()
Routines like 'cout' are in the 'std' namespace and people really hate typing:
std::cout << "blah blah blah" << std::endl;
So they put: using namespace std;
Which causes the compiler to use the namespace 'std' when the namespace is omitted as in 'cout'.
A header file can contain anything - functions, declarations, externs, globals, prototypes, etc. The contents of headers are include from a source file and treated as part of the source file by the compiler. You can even place an include within a function to add some temporary test code without making your main code unreadable. However, there is a tradition to put only certain things in headers. Note that the include mechanism also works if the included does not have the .h extension.
The source code (.c) is the only thing that matters to the compiler. Headers are only used if they are really used by any .c source file.
You really should find yourself some easy C tutorial and stick with it until you understand it. Philip Machanick had an easy intro written called "C and C++ in 5 days".
Absolutely. You are right about the namespace std, too.
When using C++, another thing about header files is that (by custom, not by requirement) people avoid "using" statements in them.
For instance, say that you had a function inputString which asks the user for some text.
Then, so that you could use this function in lots of different code, you make a header. You need to include <string> so the compiler knows what "string"s are.
File input.h:
Code:
#include <string>
std::string inputString();
Notice we used the full name, std::string, instead of saying
Code:
#include <string>
using namespace std;
string inputString();
Either way works. But the first is preferred, because otherwise every file including your header will have everything defined in "std" put in their namespace -- we call this "polluting the namespace." Suppose you had made a function called "string". Then if you decided to include input.h and use inputString(), there would be a name conflict!
File foo.cc:
Code:
#include <string>
#include "input.h"
using std::cout; /* You can also import specific names. */
void string() {} /* Not a very interesting function */
int main() {
string(); /* This would be an error with the second input.h above. */
cout << "How are you? ";
std::string fine = inputString();
return 0;
}
I think what I am going to do next, tomorrow, is start to study, learn and understand header files more. For practice I am going to use the hello world and expand it. I want to add .h files to it, etc.
The way the hello world code is currently, I understand a few things now already. So instead of starting new, all the time, with each thing I learn I want to use what I have and add to it as much and as far as I can.
Ok, here is this question in the correct thread. If you don't know don't ask, lol.
Does this look like a good, accurate c++ glossary? It has a brief explanation where I can start and then take it from there. Unless someone knows of a better c++ glossary?
That's should be fine, after all Stroustrup did design the language. But also (if you haven't already) consider the Thinking in C++ book from Bruce Eckel available here
I have not given up on learning this. I just got really busy. I have been studying and reading some of the above recommendations and soon I will be back with questions.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.