more C notes
This commit is contained in:
parent
eb086f064b
commit
1f2c365a35
2 changed files with 95 additions and 1 deletions
|
|
@ -67,7 +67,6 @@ already used which is string literal notation:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
char word[] = "Hello";
|
char word[] = "Hello";
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The null terminator is implied in this form, you do not need to add it manually.
|
The null terminator is implied in this form, you do not need to add it manually.
|
||||||
|
|
|
||||||
95
zk/Functions_in_C.md
Normal file
95
zk/Functions_in_C.md
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- C
|
||||||
|
---
|
||||||
|
|
||||||
|
## What type is a function?
|
||||||
|
|
||||||
|
A function does not have to a dedicated primitive type. It is a **derived**
|
||||||
|
type, meaning that its type-signature comes from the primitive types that it
|
||||||
|
uses.
|
||||||
|
|
||||||
|
On this basis, a function type is derived from its return type and the number
|
||||||
|
and types of its parameters.
|
||||||
|
|
||||||
|
E.g. for the function:
|
||||||
|
|
||||||
|
```c
|
||||||
|
int mimic_number(int num) {
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
It's type is a product of:
|
||||||
|
|
||||||
|
- its return type (`int`)
|
||||||
|
- the number of parameters (`1`)
|
||||||
|
- the type of its parameter (`int`)
|
||||||
|
|
||||||
|
## Function declarators and function definitions
|
||||||
|
|
||||||
|
In C, it is possible to declare a function without specifying the body, e.g:
|
||||||
|
|
||||||
|
```c
|
||||||
|
int f(void);
|
||||||
|
void g(int i, int j);
|
||||||
|
```
|
||||||
|
|
||||||
|
Are all examples of function declarators.
|
||||||
|
|
||||||
|
Later then you can go back and provide the definition. Note that this is just
|
||||||
|
the same as a normal full function declaration, it's just you've previously
|
||||||
|
declared its existence:
|
||||||
|
|
||||||
|
```c
|
||||||
|
|
||||||
|
int f(void);
|
||||||
|
|
||||||
|
// Some other code
|
||||||
|
|
||||||
|
int f(void) {
|
||||||
|
printf("Here's the definition.")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### What's the point of this?
|
||||||
|
|
||||||
|
The only real utility in distinguishing the declaration from the definition is
|
||||||
|
when creating reusable libraries.
|
||||||
|
|
||||||
|
These follow this sequence:
|
||||||
|
|
||||||
|
- define a `.h` header file with function declaration
|
||||||
|
- define a `.c` file with the function definition
|
||||||
|
- import the function into `main.c` and call function
|
||||||
|
|
||||||
|
Applied example:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// math_utils.h
|
||||||
|
|
||||||
|
int add (int a, int b);
|
||||||
|
```
|
||||||
|
|
||||||
|
```c
|
||||||
|
// math_utils.c
|
||||||
|
int add (int a, int b) {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And then in `main.c`:
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "math_utils.h"
|
||||||
|
|
||||||
|
int main(void):
|
||||||
|
int sum = add(5, 3)
|
||||||
|
```
|
||||||
|
|
||||||
|
> The compiler compiles each .c file separately. The header file tells main.c
|
||||||
|
> that add and multiply exist somewhere, even though they're defined in a
|
||||||
|
> different file. The linker connects everything together at the end.
|
||||||
|
|
||||||
|
In C, the distinction between arguments and parameters is more acute than other
|
||||||
|
languages:
|
||||||
Loading…
Add table
Reference in a new issue