tweaks to C notes

This commit is contained in:
Thomas Bishop 2026-02-08 19:22:03 +00:00
parent 9dcae3ac16
commit f471f891e0
3 changed files with 52 additions and 35 deletions

View file

@ -60,30 +60,17 @@ In memory this would actually be:
With each char corresponding to an ASCII number apart from the null which would
just be `0000 0000`.
### String literals
The easiest way to declare a string as a `char` array is to use the format we've
already used which is string literal notation:
```c
char word[] = "Hello";
```
The null terminator is implied in this form, you do not need to add it manually.
Also the length is fixed to the length of the string (in this case `6` for the
five actual characters plus the null).
### Non-literal string declaration
The more formal way of doing this would be:
```c
char word[6] = {'H', 'e', 'l', 'l', 'o', '\0'}
```
However, in practice, if you just want quick access to a string, where you don't
need to modify the individual characters later, you can just use a direct
pointer definition:
### String literals
In practice, if you just want quick access to a string, where you don't need to
modify the individual characters later, you can just use a direct pointer
definition:
```c
char *name = "Thomas";
@ -94,3 +81,15 @@ is a string literal and is stored as read-only. It can be redefined (the pointer
can point to something else) but it's not mutable itself.
More info in [Pointers in C](./Pointers_in_C.md).
Note that the `*` in the declaration is part of the type definition, it's
signalling that its a pointer to a string literal, it's not
referencing/dereferencing or doing anything to the bytes.
Technically you could write:
```c
char* name = "Thomas"
```
This would be clearer but it is not the convention.

View file

@ -3,14 +3,35 @@ tags:
- C
---
Think of them as a find and replace that takes place before compilation.
Think of macros as a find and replace that takes place before compilation at the
[pre-processor](./C_compilation_process.md) stage.
They are ephemeral and never make it into the compiled code.
They are ephemeral and never make it into the compiled code in the form they are
defined as.
With a macro, the computation happens "inline" without having to call functions
which make costly alterations to the stack.
When the preprocessor injects the value, the injection happens "inline" without
having to call functions which make costly alterations to the stack, which is
the main benefit - efficiency.
A function and function call such as:
Starting with a simple example:
```c
#define NAME "Thomas"
```
This is not actually a variable because it has no memory address. It never makes
it to memory-assignation because it doesn't exist after pre-processing. By the
compilation stage,j this value has been added to the code as a type
corresponding to the literal you defined; in this case a string literal
(`char *`). To emphasise, the macro itself has no type because it doesn't exist
at the type level (compilation), the data type it represents after injection is
applied by the compiler through parsing.
> The convention is to have macros in `ALL_CAPS` to distinguish them from real
> variables. Don't confuse them for constants, constants are actually written in
> lowercase like other actual variables.
To use a more complex example, a function and function call such as:
```c
int square(int x) { return x * x; }
@ -32,7 +53,3 @@ int a = ((5) * (5));
```
after pre-processing but before compilation.
## Syntax
`#define` always creates a macro but there are different types.

View file

@ -48,13 +48,17 @@ char *name = "Thomas";
```
Then to reference the value (_not_ the address, the actual value) you just use
`name`.
`name`. The `*` is just part of the type definition in the above - it's just
signalling the type. If you later want to change the value, you then use `*` as
an operator:
This is confusing but I just have to accept for now.
```c
*name = 'Tom';
```
Note that if you do this, it creates the string in read-only memory. You can't
modify the individual characters of `"Thomas"`. To do this you would need to
define it as:
Note that if you use a pointer to `char`, it creates the string in read-only
memory. You can't modify the individual characters of `"Thomas"`. To do this you
would need to define it as:
```c
char name[] = "Thomas";
@ -85,6 +89,3 @@ Or, using a variable:
static char *topic = "test_topic";
mqtt_publish(mqtt_client, topic, "Test message");
```
> Note in the above the `*` is part of the type definition, _not_ the variable.
> Even more confusing!