views:

234

answers:

6

It's all in the title; super-simple I reckon, but it's so hard to search for syntactical things like things anywhere.

These are two library files I'm copying from the web, and I'm wondering why they're called two different names

From here: CS50.net

+6  A: 

.c : c file (where the real action is, in general)

.h : header file (to be included with a preprocessor #include directive). Contains stuff that is normally deemed to be shared with other parts of your code, like function prototypes, #define'd stuff, extern declaration for global variables (oh, the horror) and the like.

Technically, you could put everything in a single file. A whole C program. million of lines. But we humans tend to organize things. So you create different C files, each one containing particular functions. That's all nice and clean. Then suddenly you realize that a declaration you have into a given C file should exist also in another C file. So you would duplicate them. The best is therefore to extract the declaration and put it into a common file, which is the .h

For example, in the cs50.h you find what are called "forward declarations" of your functions. A forward declaration is a quick way to tell the compiler how a function should be called (e.g. what input params) and what it returns, so it can perform proper checking (for example if you call a function with the wrong number of parameters, it will complain).

Another example. Suppose you write a .c file containing a function performing regular expression matching. You want your function to accept the regular expression, the string to match, and a parameter that tells if the comparison has to be case insensitive.

in the .c you will therefore put

bool matches(string regexp, string s, int flags) { the code }

Now, assume you want to pass the following flags:

0: if the search is case sensitive

1: if the search is case insensitive

And you want to keep yourself open to new flags, so you did not put a boolean. playing with numbers is hard, so you define useful names for these flags

#define MATCH_CASE_SENSITIVE 0
#define MATCH_CASE_INSENSITIVE 1

This info goes into the .h, because if any program wants to use these labels, it has no way of knowing them unless you include the info. Of course you can put them in the .c, but then you would have to include the .c code (whole!) which is a waste of time and a source of trouble.

Stefano Borini
No that's correct. Now I just go look up what a header file does...
Alex Mcp
+1  A: 

The .c is the source file and .h is the header file.

hexium
+1  A: 
.c : 'C' source code
.h : Header file

Usually, the .c files contain the implementation, and .h files contain the "interface" of an implementation.

AraK
+2  A: 

They're not really library files. They're just source files. Like Stefano said, the .c file is the C source file which actually uses/defines the actual source of what it merely outlined in the .h file, the header file. The header file usually outlines all of the function prototypes and structures that will be used in the actual source file. Think of it like a reference/appendix. This is evident upon looking at the header file, as you will see :) So then when you want to use something that was written in these source files, you #include the header file, which contains the information that the compiler will need to know.

Jorge Israel Peña
Good clarification, thanks. So I #include <cs50.h>, but then that in turn calls the actual functions it needs from cs50.c. This is what I assume from reading the files, is this correct?
Alex Mcp
Yeah that's usually how it goes. However, #include <somefile.h> is usually reserved for files that came with the compiler, like #include <iostream.h> What you want is #include "cs50.h", and make sure that it's somewhere accessible by the compiler, preferably where your other source files are.
Jorge Israel Peña
if i remember correctly, the use of "" is discouraged. yu should always use <> and adjust the -I properly.
Stefano Borini
@Stefano Borini see 6.10.2: *A preprocessing directive of the form`# include "q-char-sequence" new-line` causes the replacement of that directive by the entire contents of the source file identifiedby the specified sequence between the `"` delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read `# include <h-char-sequence> new-line`*
Sinan Ünür
+1  A: 

The .c files are source files which will be compiled. The .h files are used to expose the API of a program to either other part of that program or other program is you are creating a library.

For example, the program PizzaDelivery could have 1 .c file with the main program, and 1 .c file with utility functions. Now, for the main part of the program to be able to use the utility functions, you need to expose the API, via function prototype, into a .h file, this .h file being included by the main .c file.

+1  A: 

Of course, there is nothing that says the extension of a header file must be .h and the extension of a C source file must be .c. These are useful conventions.

E:\Temp> type my.interface
#ifndef MY_INTERFACE_INCLUDED
#define MYBUFFERSIZE 8
#endif
E:\Temp> type my.source
#include 

#include "my.interface"

int main(void) {
    char x[MYBUFFERSIZE] = {0};
    x[0] = 'a';
    puts(x);
    return 0;
}
E:\Temp> gcc -x c my.source -o my.exe

E:\Temp> my
a
Sinan Ünür