diff --git a/clang.md b/clang.md
index d665279866a61304cf46b91fc0ab2704f4f80fb9..4b6ef33f741c0273882688853246cafb53a0ee8a 100644
--- a/clang.md
+++ b/clang.md
@@ -288,8 +288,41 @@ These are common in many codebases, and the first time you see them, you might b
 
 ## Arrays
 
+Array variable is simply a **pointer** to the **0th** element. So `char *string` and `char string[]` are _nearly_ identical declarations. But the subtle difference is that, `char *string` is viewed as a string literal and can not be modified via subscript. In contrast, `char string[]` is just a character array whose elements can be modified via subscript.
+
+So we have `a[i] == *(a + i)`. But unfortunately, when an array is passed to the function, it is passed as a pointer, and the size information is **lost**.
+
+Arrays in C are very primitive:
+
+- An Array in C does not have the information to its own length, not like `arr.length` in other languages
+- Array's bounds are not checked at all
+    - So we can easily access off the end of an array
+    - We muss pass the array and its size together to any function that is going to manipulate it
+
 ## Strings
 
+String in C is just an array of characters: `char string[] = "hello world"`.
+
+String in C is **null-terminated** which means the special character `\0` marks the end of a string.
+
+There are lots of auxiliary functions provided by the standard library in `<string.h>`, but be aware of how they treat the null character.
+
+For example, the `strlen` function returns the length of the string **excluding** the null character.
+
+There are lots of ways to initialize a string:
+
+```c
+char c[] = "abcd";
+
+char c[50] = "abcd";
+
+char c[] = {'a', 'b', 'c', 'd', '\0'};
+
+char c[5] = {'a', 'b', 'c', 'd', '\0'};
+
+char str* = "string literal"; // can not be modified via array subscript
+```
+
 ## C Memory Management
 
 ## C Compilation Process