eolas/zk/Pointers_in_C.md
2026-02-08 19:22:03 +00:00

91 lines
1.9 KiB
Markdown

---
tags:
- C
---
A pointer is a reference to the address of a variable in memory.
```c
int x = 27;
int *ptr = &x;
printf("%i\n", x);
// 27
printf("%p\n", *ptr);
// 0x7ffeb44f7eac
```
The `&` and `*` is frankly confusing.
In the previous example, `int *ptr = &x`, `ptr` is a variable that holds the
memory address of `x`. `*` signals that it is a pointer variable, `&` is what
does the retrieval.
In the following:
```c
int x = 27;
int *ptr = &x;
int value = *ptr;
```
We again set `ptr` to the memory address of `x`, but we use `*` on the last line
to **de-reference** the pointer and get the original value back. Thus `value`
becomes equal to `27`.
Pointers are necessary because C uses a [call by value](./C_is_call_by_value.md)
system for function arguments.
## To use a pointer you don't have to declare the value first (confusing)
It is totally legitimate to declare a pointer in one go, especially with
strings:
```c
char *name = "Thomas";
```
Then to reference the value (_not_ the address, the actual value) you just use
`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:
```c
*name = 'Tom';
```
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";
name[0] = "t";
```
Here is a real example of me doing this:
```c
void mqtt_publish(esp_mqtt_client_handle_t client, char *topic,
const char *payload)
{
if (MQTT_CONNECTED) {
esp_mqtt_client_publish(client, topic, payload, strlen(payload), 0, 0);
}
}
```
And then when calling the function:
```c
mqtt_publish(mqtt_client, "test_topic", "Test message");
```
Or, using a variable:
```c
static char *topic = "test_topic";
mqtt_publish(mqtt_client, topic, "Test message");
```