81

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

These are two library files that I'm copying from CS50.net, and I'm wondering why they have two different extensions.

Alex Mcp
  • 19,037
  • 12
  • 60
  • 93

6 Answers6

138

.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.

Jed Smith
  • 15,584
  • 8
  • 52
  • 59
Stefano Borini
  • 138,652
  • 96
  • 297
  • 431
  • This may also help: This may also help: http://stackoverflow.com/questions/3482948/any-fundamental-difference-between-source-and-header-files-in-c. A lot of the same, but explained a slightly different way. – spugm1r3 Sep 17 '16 at 20:08
25

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
#define MY_INTERFACE_INCLUDED
#endif

E:\Temp> type my.source
#include <stdio.h>

#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
  • 116,958
  • 15
  • 196
  • 339
  • 4
    Thank you for this! I thought the extensions `.h` and `.c` were compulsory and i never thought otherwise! – KeyC0de Feb 16 '17 at 20:34
6

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
  • 36,800
  • 16
  • 93
  • 123
  • Good clarification, thanks. So I #include , 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 Nov 08 '09 at 03:12
  • 2
    Yeah that's usually how it goes. However, #include is usually reserved for files that came with the compiler, like #include 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 Nov 08 '09 at 03:15
  • if i remember correctly, the use of "" is discouraged. yu should always use <> and adjust the -I properly. – Stefano Borini Nov 08 '09 at 03:33
  • 1
    @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 identified by 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 new-line`* – Sinan Ünür Nov 08 '09 at 04:14
3

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

hexium
  • 733
  • 1
  • 7
  • 12
1

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.

0
.c : 'C' source code
.h : Header file

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

Khaled Alshaya
  • 94,250
  • 39
  • 176
  • 234