This commit is contained in:
Miloslav Ciz 2023-04-06 22:43:02 +02:00
parent fa845d3bee
commit 40826e0336
7 changed files with 50 additions and 23 deletions

View file

@ -759,6 +759,8 @@ int main(void)
}
```
NOTE: `"library.h"` here is between double quotes, unlike `<stdio.h>`. This just says we specify an absolute path to the file as it's not in the directory where installed libraries go.
Now we will manually compile the library and the final program. First let's compile the library, in command line run:
```
@ -801,7 +803,7 @@ As a bonus, let's see a few useful compiler flags:
Until now we've encountered simple data types such as `int`, `char` or `float`. These identify values which can take single atomic values (e.g. numbers or text characters). Such data types are called **[primitive types](primitive_type.md)**.
Above these there exist **[compound data types](compound_type.md)** (also *complex* or *structured*) which are composed of multiple primitive types. They are necessary any advanced program.
Above these there exist **[compound data types](compound_type.md)** (also *complex* or *structured*) which are composed of multiple primitive types. They are necessary for any advanced program.
The first compound type is a structure, or **[struct](struct.md)**. It is a collection of several values of potentially different data types (primitive or compound). The following code shows how a struc can be created and used.
@ -1178,9 +1180,9 @@ But beware, there may be too much new information in the first read. Don't get s
Pointers allow us to do certain advanced things such as allocate dynamic memory, return multiple values from functions, inspect content of memory or use functions in similar ways in which we use variables.
A **[pointer](pointer.md)** is nothing complicated: it is a **data type that can hold a memory address** (plus the information of what data type should be stored at that address). An address is simply a number. Why can't we simply use an `int` for an address? Because the size of `int` and a pointer may differ, the size of pointer depends on each platform's address width. It is also good when the compiler knows a certain variable is supposed to point to a memory (and to which type) -- this can prevent bugs.
A **[pointer](pointer.md)** is essentially nothing complicated: it is a **data type that can hold a memory address** (plus an information about what data type should be stored at that address). An address is simply a number. Why can't we just use an `int` to store a memory address? Because the size of `int` and a pointer may differ, the size of pointer depends on each platform's address width. Besides this, as said, a pointer actually holds not only an address but also the information about the type it points to, which is a safety mechanism that will become clear later. It is also good when the compiler knows a certain variable is supposed to point to a memory rather than to hold a generic number -- this can all prevent bugs. I.e. pointers and generic integers are distinguished for the same reason other data types are distinguished -- in theory they don't have to be distinguished, but it's safer.
It's important to remember that a pointer is not a pure address but it also knows about the data type it is pointing to, so there are many kinds of pointers: a pointer to `int`, a pointer to `char`, a pointer to a specific struct type etc.
It is important to stress again that a pointer is not a pure address but it also knows about the data type it is pointing to, so there are many kinds of pointers: a pointer to `int`, a pointer to `char`, a pointer to a specific struct type etc.
A variable of pointer type is created similarly to a normal variable, we just add `*` after the data type, for example `int *x;` creates a variable named `x` that is a pointer to `int` (some people would write this as `int* x;`).