machine code versus source code
Source code is the program as a human wrote it - text you can read, with names, words, and structure: int main() { return 0; }. Machine code is the same program rewritten as raw numbers the CPU can execute directly - no words, just bytes encoding instructions, like the sequence 0x55 0x48 0x89 0xE5 0x31 0xC0. The two are two faces of one program: one made for people, one made for the chip.
You write source code because numbers are unbearable to think in. But the CPU cannot run text; its fetch-execute cycle only understands its own machine code, where each instruction is a specific pattern of bits. A compiler (or assembler) is the bridge: it reads the readable source and emits the equivalent machine code for a particular kind of CPU. The translation is mostly one-way in practice - going from machine code back to readable source (decompilation) is hard and lossy, because names, comments, and structure are thrown away during compilation.
Why it matters: this distinction underpins much of systems programming. It is why you ship a compiled executable, not your text files, to run fast; why machine code is tied to a specific CPU family while source can often be recompiled for many; why a debugger needs extra 'debug info' to map the running machine code back to your source lines; and why reading the machine code (disassembly) is sometimes the only way to know exactly what the CPU will do, especially after the compiler has optimized your source.
The C source return 0; might compile on a 64-bit machine to the two machine instructions written in assembly as 'xor eax, eax' then 'ret' - whose actual machine-code bytes are 0x31 0xC0 0xC3. Readable on the left, executable on the right.
Same instruction, three views: source, assembly mnemonic, raw bytes.
Assembly language is not the same as machine code: assembly is a thin human-readable text form (mov, add, names) that an assembler translates into the actual machine-code bytes. Assembly is readable; machine code is the numbers themselves.