The "Ctrl" or "Control" key is so called because it is used to send control characters. Control characters are not actual characters, but are rather used to control the terminal that they are "printed" on. This is an example of in-band signaling.

To see some control characters, look at man ascii. All characters have a character code; in ASCII, this is a 7-bit pattern, taking up 7 out of 8 bits in a byte. The characters with codes from 0000 to 0037 are control characters.

To send a control character to the application running in a terminal, hold down Ctrl while pressing another character. This modifies the sent character code by clearing its 7th and 6th bits (indexed starting at 1). For reference, the 7th and 6th bits are the ones set in 0140. This is equivalent to bitwise anding the character code with 0037. Again, whenever you hold down Ctrl and press another character while in a terminal, the 8-bit character code that represents that character is modified according to this scheme.

This scheme maps each ASCII character to a control character. However, this is not an injective mapping. That is, multiple ASCII characters map to the same control character. Looking at man ascii, we can see that lower and upper case alphabetic characters (such as 'g', 0107, and 'G', 0147) differ only by the 6th bit. The 6th bit is cleared by Ctrl, so the same alphabetic characters ('g' and 'G') get mapped to the same control character (BEL, 0007).

This modification is done by your terminal or terminal emulator. A terminal communicates your input to the application running in the terminal (such as bash or emacs) with a stream of bytes. There is no (standard) way to specify in this stream of bytes, "This 'g' byte that I am sending you was entered with the Control key held down". Instead, a terminal will just send the corresponding control-character-byte to the application running in the terminal. When you type "Ctrl-g" on your keyboard, the terminal will send the byte 0007, "BEL". If you typed just "g", the terminal would send 0147.

This mapping could also apply to the non-alphanumeric characters in the lower left column of man ascii, such as ' (single quote). ' is represented by the byte 0047, which differs from 'g', 0107, and 'G', 0147, only by the 6th and 7th bits, which are supposedly cleared by holding down Ctrl. So "Ctrl-'", like "Ctrl-g" and "Ctrl-G", would presumably send BEL, 0007. If that were the case, each control character would be be mapped to by exactly three other characters. Unfortunately, most terminal emulators either pass through the entered character verbatim, or map it to some other seemingly random control character; none of the characters in the lower left get mapped to the control character resulting from clearing the 6th and 7th bits. So pressing "Ctrl-'" will send 0047 to the application running in the terminal, just as if you had pressed '.

Look again at man ascii to see all the mappings. In GNU/Linux, the table is arranged so that the upper case alphabetic character and the control character it is mapped to are on the same row.

As a result, the following triples of keys (among others) are equivalent and indistinguishable to a terminal:

Ctrl+i, Ctrl+Shift+i, Tab

Ctrl+j, Ctrl+Shift+j, Enter

Ctrl+[, Ctrl+Shift+[, Escape

These equivalences are useful. These control characters are heavily used, and the keys that directly send them are placed in unergonomic locations, so sending them with Ctrl can be useful.

The last one in particular is very useful for vi/vim users. It is in fact emulated in gvim and other graphical vi-keybinding-using applications (at least, all the ones I've used), so you should be able to always use Ctrl+[ to go to normal mode.

Some other useful control characters to send are:

Ctrl+d, Ctrl+Shift+d, EOF

Ctrl+g, Ctrl+Shift+g, BEL

Key points: