more C notes
This commit is contained in:
parent
f55f6f6ad6
commit
eb086f064b
3 changed files with 66 additions and 45 deletions
44
zk/Booleans_in_C.md
Normal file
44
zk/Booleans_in_C.md
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- C
|
||||||
|
---
|
||||||
|
|
||||||
|
Booleans are a bit weird in C. _Oficially_ they don't exist as a core primitive
|
||||||
|
data type. Instead you use integers on the basis that:
|
||||||
|
|
||||||
|
> `0` is false and any non-zero value is true (but typically indicated with `1`)
|
||||||
|
|
||||||
|
Hence why the `int main()` [entrypoint](./Entry_point_to_C_programs.md) returns
|
||||||
|
`int`, because "success" is `1` and "error" is `0`.
|
||||||
|
|
||||||
|
A common example of this approach:
|
||||||
|
|
||||||
|
```c
|
||||||
|
|
||||||
|
int is_running = 1; // true
|
||||||
|
int has_error = 0; // false
|
||||||
|
|
||||||
|
if (is_running) {
|
||||||
|
// Do stuff
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Since the **C99** standard, a dedicated Boolean type has been available.
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
bool is_running = true;
|
||||||
|
bool has_error = false;
|
||||||
|
|
||||||
|
if (is_running) {
|
||||||
|
// Do stuff
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note, you must include the bool header file which is part of the core in order
|
||||||
|
to have access to the `bool`, `true`, and `false` keywords.
|
||||||
|
|
||||||
|
This is just syntactic sugar though, and underneath it is just `int` values for
|
||||||
|
`0` and `1`.
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- C
|
||||||
|
---
|
||||||
|
|
||||||
When you pass a value into a C function as an argument it creates a copy of the
|
When you pass a value into a C function as an argument it creates a copy of the
|
||||||
value that is stored outside of the function (the parameter value). This value
|
value that is stored outside of the function (the parameter value). This value
|
||||||
is modified by the function.
|
is modified by the function.
|
||||||
|
|
@ -59,6 +64,3 @@ Which will cause the main function to return what we expect:
|
||||||
```txt
|
```txt
|
||||||
a = 17, b = 21
|
a = 17, b = 21
|
||||||
```
|
```
|
||||||
|
|
||||||
While the non-pointerized version of the function enshrines **call by value**,
|
|
||||||
the pointerized version enshrines **call by reference**.
|
|
||||||
|
|
|
||||||
|
|
@ -6,59 +6,34 @@ tags:
|
||||||
A pointer is a reference to the address of a variable in memory.
|
A pointer is a reference to the address of a variable in memory.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int num = 27;
|
int x = 27;
|
||||||
int *ptr_to_num = #
|
int *ptr = &x;
|
||||||
|
|
||||||
printf("%i\n", num);
|
printf("%i\n", x);
|
||||||
// 27
|
// 27
|
||||||
|
|
||||||
|
|
||||||
printf("%p\n", ptr_to_num);
|
printf("%p\n", *ptr);
|
||||||
// 0x7ffeb44f7eac
|
// 0x7ffeb44f7eac
|
||||||
```
|
```
|
||||||
|
|
||||||
We indicate that we are creating a pointer with `*`.
|
The `&` and `*` is frankly confusing.
|
||||||
|
|
||||||
We then retrieve the memory address with `&`.
|
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.
|
||||||
|
|
||||||
We can 'de-reference' back to the value with:
|
In the following:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
printf("%i\n", *ptr_to_num);
|
int x = 27;
|
||||||
// 27
|
int *ptr = &x;
|
||||||
|
int value = *ptr;
|
||||||
```
|
```
|
||||||
|
|
||||||
## Why are pointers even necessary?
|
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`.
|
||||||
|
|
||||||
In other languages you can do something like:
|
Pointers are necessary because C uses a [call by value](./C_is_call_by_value.md)
|
||||||
|
system for function arguments.
|
||||||
```js
|
|
||||||
let num = 27;
|
|
||||||
console.log(num);
|
|
||||||
// 27
|
|
||||||
|
|
||||||
function modify(theNumber) {
|
|
||||||
theNumber = 28;
|
|
||||||
return theNumber;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In C, you cannot use functions to modify variables that live outside of them
|
|
||||||
(e.g. in higher scope).
|
|
||||||
|
|
||||||
If you did the above with C, `num` would still be `27` after the function call.
|
|
||||||
This is bcause arguments are passed by value, not by reference to the item in
|
|
||||||
memory that the variable refers to.
|
|
||||||
|
|
||||||
So, to modify the actual value in memory, you invoke pointers.
|
|
||||||
|
|
||||||
The above JavaScript in C would be:
|
|
||||||
|
|
||||||
```c
|
|
||||||
int num = 27
|
|
||||||
|
|
||||||
int modify(int *the_number) {
|
|
||||||
*the_number = 28;
|
|
||||||
return the_number;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue