Let's start with the chip and work backwards. I'm simplifying some of this so it may not all be exactly technically correct.
Chip level - Machine Language. Binary numbers that are most frequently expressed by their hexadecimal equivalent.
Each of these numbers is an 'instruction' that tells the chip to do some very simple operation.
Low Level - Assembly Language. Short alphabetical sort-of English instructions that correspond to the machine language instructions. There is a near one for one relationship between the assembly language instructions and the machine language instructions. The programmer uses a text editor to create a list of these assembly language instructions along with some other information which is then saved as a .ASM file. An 'Assembler' program (or human) converts this list of assembly language instructions into a list of the corresponding hex versions of the machine language instructions and saves them as a .HEX file.
High Level - C++. More complex sort-of English functions that correspond roughly with the machine language instructions that the processor understands or with more complex tasks that require many machine language instructions. The programmer uses a text editor to create a list of these functions along with some other information which is then saved as a .CPP file. A 'Compiler' program converts this list of C++ functions into the corresponding hex version of the required machine language instructions. These are usually saved as a .HEX file just like the one created by the assembler.
Arduino - ???. One more magical step similar to that described for C++ which someone else will have to explain. The Arduino functions are expanded into C++ functions which are compiled by a more or less standard C compiler as described above. Remember the phrase "along with some other information" also mentioned above? The Arduino environment (for lack of a better term) takes care of most of this as well.
Don