From c538ffece3f814bf1cafca8e1af8f3e463fdd4b1 Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Sat, 16 Aug 2025 12:27:13 -0700 Subject: [PATCH 1/3] Draft concept: Headers and Includes --- concepts/headers-includes/.meta/config.json | 7 ++ concepts/headers-includes/about.md | 92 +++++++++++++++++++++ concepts/headers-includes/introduction.md | 84 +++++++++++++++++++ concepts/headers-includes/links.json | 6 ++ config.json | 5 ++ 5 files changed, 194 insertions(+) create mode 100644 concepts/headers-includes/.meta/config.json create mode 100644 concepts/headers-includes/about.md create mode 100644 concepts/headers-includes/introduction.md create mode 100644 concepts/headers-includes/links.json diff --git a/concepts/headers-includes/.meta/config.json b/concepts/headers-includes/.meta/config.json new file mode 100644 index 00000000..3243112c --- /dev/null +++ b/concepts/headers-includes/.meta/config.json @@ -0,0 +1,7 @@ +{ + "authors": [ + "colinleach" + ], + "contributors": [], + "blurb": "C uses header files (*.h) for various declarations. #include statements incorporate these declarations into the .c file." +} diff --git a/concepts/headers-includes/about.md b/concepts/headers-includes/about.md new file mode 100644 index 00000000..529b0de1 --- /dev/null +++ b/concepts/headers-includes/about.md @@ -0,0 +1,92 @@ +# About + +C requires that all functions are declared _before_ they are defined. +This can be done at the top of the `*.c` file containing the definition, but there are advantages in splitting declarations into a separate header file with a `.h` extension. + +You can think of the header file as an API. +The header will tell you _what_ a codebase has to offer, without going into the details of _how_. + +## Header files + +A header file can range from just a few lines to several hundred. + +For a simple example, we can look at the `Hello World` exercise (which you already completed). This is the [`hello_world.h` file][hello-h] which is part of that exercise: + +```c +// This is called an include guard, which ensures that the header is only +// included once. You could alternatively use '#pragma once'. See +// https://en.wikipedia.org/wiki/Include_guard. +#ifndef HELLO_WORLD_H +#define HELLO_WORLD_H + +// Declare the 'hello()' function, which takes no arguments and returns a +// 'const char *', i.e. a pointer to a character (in this case the first +// character in a string). The function itself is defined in the hello_world.c +// source file. This function is called by the test case(s) in the test source +// file test_hello_world.c. +const char *hello(void); + +#endif +``` + +Most of it is explanatory comments (lines starting with `//`). + +### Declarations + +Towards the bottom is the _declaration_ of the `hello()` function. +This is the same as in the _definition_ in `hello_world.c`, except that the declaration ends with a semicolon `;` instead of the function body. + +This function takes no parameters (indicated by [`void`][void]). + +Most functions have parameters, so these: + +- _Must_ include the parameter type, and the compiler will enforce this. +- _Should_ also include the parameter name, as good style to make the header self-documenting. + +For example: + +```c +int remaining_minutes_in_oven(int actual_minutes_in_oven); +``` + +Many other things can be included in a header file, and you will see examples later in the syllabus. + +### Guards + +Lines beginning with `#` are preprocessor directives, to ensure that the compiler only includes the header file once. + +- `HELLO_WORLD_H` is a constant, conventionally the file name converted to uppercase, with the dot replaced by underscore. +- `#ifndef` is an abbreviation of "if not defined": only continue if the `HELLO_WORLD_H` constant does not already exist. +- `#define` creates the constant. +- `#endif` closes the `#ifndef` block. + +## Includes + +The [`hello_world.c` file][hello-c] starts with an [`#include`][include] as the first line. + +```c +#include "hello_world.h" +``` + +That tells the compiler's preprocessor to insert the contents of `hello_world.h` at the top of `hello_world.c`, as though it had been typed there. +The whole expanded file is then compiled. + +There are two variants of `#include`: + +- Those in double-quotes, as above, tell the compiler to search the project directory for the header file. +- Those in brackets, such as `#include `, are for items in the standard library. The compiler will search for these in a central location, such as `\usr\include` (on Ubuntu systems). + +Including system headers is very common in C code, even simple cases like an Exercism toy exercise. + +Common examples include `stdio.h` (_for printing, etc_), `strings.h`, `math.h`, `stdlib.h` (_for various C99 standard library functions_). + +A typical *nix system probably has a few hundred system header files, available for you to use. + +Future Concepts will note which imports are necessary to use the desired functions. + +It may also be necessary to add a linker directive in the `makefile`, such as `LIBS = -lm` to use the math library, but that is a more advanced topic. + +[hello-h]: https://github.com/exercism/c/blob/main/exercises/practice/hello-world/hello_world.h +[hello-c]: https://github.com/exercism/c/blob/main/exercises/practice/hello-world/hello_world.c +[void]: https://en.wikipedia.org/wiki/Void_type +[include]: https://en.wikipedia.org/wiki/Include_directive diff --git a/concepts/headers-includes/introduction.md b/concepts/headers-includes/introduction.md new file mode 100644 index 00000000..d1ae40ed --- /dev/null +++ b/concepts/headers-includes/introduction.md @@ -0,0 +1,84 @@ +# Introduction + +C requires that all functions are declared _before_ they are defined. +This can be done at the top of the `*.c` file containing the definition, but there are advantages in splitting declarations into a separate header file with a `.h` extension. + +You can think of the header file as an API. +The header will tell you _what_ a codebase has to offer, without going into the details of _how_. + +## Header files + +A header file can range from just a few lines to several hundred. + +For a simple example, we can look at the `Hello World` exercise (which you already completed). This is the `hello_world.h` file that is part of that exercise: + +```c +// This is called an include guard, which ensures that the header is only +// included once. You could alternatively use '#pragma once'. See +// https://en.wikipedia.org/wiki/Include_guard. +#ifndef HELLO_WORLD_H +#define HELLO_WORLD_H + +// Declare the 'hello()' function, which takes no arguments and returns a +// 'const char *', i.e. a pointer to a character (in this case the first +// character in a string). The function itself is defined in the hello_world.c +// source file. This function is called by the test case(s) in the test source +// file test_hello_world.c. +const char *hello(void); + +#endif +``` + +Most of it is explanatory comments (lines starting with `//`). + +### Declarations + +Towards the bottom is the _declaration_ of the `hello()` function. +This is the same as in the _definition_ in `hello_world.c`, except that the declaration ends with a semicolon `;` instead of the function body. + +This function takes no parameters (indicated by `void`). + +Most functions have parameters, so these: + +- _Must_ include the parameter type, and the compiler will enforce this. +- _Should_ also include the parameter name, as good style to make the header self-documenting. + +For example: + +```c +int remaining_minutes_in_oven(int actual_minutes_in_oven); +``` + +Many other things can be included in a header file, and you will see examples later in the syllabus. + +### Guards + +Lines beginning with `#` are to ensure that the compiler only includes the header file once. + +- `HELLO_WORLD_H` is a constant, conventionally the file name converted to uppercase, with the dot replaced by underscore. +- `#ifndef` is an abbreviated of "if not defined": only continue if the `HELLO_WORLD_H` constant does not already exist. +- `#define` creates the constant. +- `#endif` closes the `#ifndef` block. + +## Includes + +The `hello_world.c` file starts with an `#include` as the first line. + +```c +#include "hello_world.h" +``` + +That tells the compiler's preprocessor to insert the contents of `hello_world.h` at the top of `hello_world.c`, as though it had been typed there. +The whole expanded file is then compied. + +There are two variants of `#include`: + +- Those in double-quotes, as above, tell the compiler to search the project directory for the header file. +- Those in brackets, such as `#include `, are for items in the standard library. The compiler will search for these in +a central location, such as `\usr\include` (on Ubuntu systems). + +Including system headers is very common in C code, even simple cases like an Exercism toy exercise. + +Common examples include `stdio.h` (_for printing, etc_), `strings.h`, `math.h`, `stdlib.h` (_for various C99 standard library functions_). + +Future Concepts will note which imports are necessary to use the desired functions. diff --git a/concepts/headers-includes/links.json b/concepts/headers-includes/links.json new file mode 100644 index 00000000..dddff7e8 --- /dev/null +++ b/concepts/headers-includes/links.json @@ -0,0 +1,6 @@ +[ + { + "url": "https://en.wikipedia.org/wiki/Include_directive", + "description": "Include directive (Wikipedia)" + } +] diff --git a/config.json b/config.json index 207ceddd..60f936c7 100644 --- a/config.json +++ b/config.json @@ -1180,6 +1180,11 @@ "slug": "basics", "name": "Basics" }, + { + "uuid": "95d7085c-69fd-4799-ae2a-bdc9306da436", + "slug": "headers-includes", + "name": "Headers and Includes" + }, { "uuid": "20948c69-20f7-498d-b743-fada00e5c79d", "slug": "bits", From c81974a3fc460bcce07443a925bc94b8f1770fc8 Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Sat, 16 Aug 2025 13:57:09 -0700 Subject: [PATCH 2/3] small typo --- concepts/headers-includes/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concepts/headers-includes/introduction.md b/concepts/headers-includes/introduction.md index d1ae40ed..90f99873 100644 --- a/concepts/headers-includes/introduction.md +++ b/concepts/headers-includes/introduction.md @@ -56,7 +56,7 @@ Many other things can be included in a header file, and you will see examples la Lines beginning with `#` are to ensure that the compiler only includes the header file once. - `HELLO_WORLD_H` is a constant, conventionally the file name converted to uppercase, with the dot replaced by underscore. -- `#ifndef` is an abbreviated of "if not defined": only continue if the `HELLO_WORLD_H` constant does not already exist. +- `#ifndef` is an abbreviation of "if not defined": only continue if the `HELLO_WORLD_H` constant does not already exist. - `#define` creates the constant. - `#endif` closes the `#ifndef` block. From 27d6d503ada5b4163df1942db326a551a29158de Mon Sep 17 00:00:00 2001 From: Colin Leach Date: Sat, 16 Aug 2025 14:37:52 -0700 Subject: [PATCH 3/3] more typos --- concepts/headers-includes/about.md | 2 +- concepts/headers-includes/introduction.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/concepts/headers-includes/about.md b/concepts/headers-includes/about.md index 529b0de1..f95f466c 100644 --- a/concepts/headers-includes/about.md +++ b/concepts/headers-includes/about.md @@ -78,7 +78,7 @@ There are two variants of `#include`: Including system headers is very common in C code, even simple cases like an Exercism toy exercise. -Common examples include `stdio.h` (_for printing, etc_), `strings.h`, `math.h`, `stdlib.h` (_for various C99 standard library functions_). +Common examples include `stdio.h` (_for printing, etc_), `string.h`, `math.h`, `stdlib.h` (_for various C99 standard library functions_). A typical *nix system probably has a few hundred system header files, available for you to use. diff --git a/concepts/headers-includes/introduction.md b/concepts/headers-includes/introduction.md index 90f99873..ffc49878 100644 --- a/concepts/headers-includes/introduction.md +++ b/concepts/headers-includes/introduction.md @@ -79,6 +79,6 @@ a central location, such as `\usr\include` (on Ubuntu systems). Including system headers is very common in C code, even simple cases like an Exercism toy exercise. -Common examples include `stdio.h` (_for printing, etc_), `strings.h`, `math.h`, `stdlib.h` (_for various C99 standard library functions_). +Common examples include `stdio.h` (_for printing, etc_), `string.h`, `math.h`, `stdlib.h` (_for various C99 standard library functions_). Future Concepts will note which imports are necessary to use the desired functions.