This did not exist in B as of 1972, though B did support octal integer literals via a 0 prefix.
True, but B's predecessor, BCPL, had a notation of
# for octal and
#x for hexadecimal. So the idea 'jumped' a generation.
The history of C is one of removing features to be added later on again ... for better or worse.
CPL (Combined Programming Language) was developed in Cambridge and London as a simplified Algol for system programming (*1). It was implemented in 1965/66 for the EDSAC 2, Atlas and IBM 7094.
BCPL (Basic CPL) was, as the name suggests a simplified version of CPL, first implemented 1967 on an IBM 7094 (*2).
B was again a simplified BCPL (*3, *4), made to it fit the PDP-7 in 1969.
C was developed via NB (New B) for the PDP-11 in 1972ff, adding (back in) features.
# to denote octal constants. There was no real need for hex, as all machines it was implemented for had word sizes dividable by 3 and used 6 bit characters for output.
BCPL evolved over (quite short) time. While from start on
# was used to mark an octal number, it got soon supplemented by
#b for binary
#x for hexadecimal and even
#o for octal. These additions were time and implementation specific, but at least
#x became quick a standard.
#x again with the whole
# notation (*5) in favour of a preceding zero, simplifying the parser. Since the PDP-7 was a multiple of 3 word size machine, octal was the only machine specific notation needed (*6,7).
C in turn was developed for the PDP-11, for which, as 16 bit machine, many machine dependent constants come naturally in hex - not to mention the 8 bit byte and ASCII's segmentation in groups of 32. Now reintroducing a hex notation was considered useful - just this time staying with the idea of a preceding zero.
*1 - CPL is really worth a look. While it already has many of the basics of C, like pointers to words as basic element,it also contains several features that seem quite unconventional from today. For example
a = bcdoesn't assign the variable bc to a, but the product of b times c. Multi-character identifiers had to start with capital letters. This might as well be the origin of the much liked camel case.
*2 - And a Model 35 TTY, which, at that time, had no curly or square braces, thus digraphs were added. Similar no back slash, so
*was used for special characters in strings.
*3 - Plus some funny switches. Had Algol
+:= as augmented assignment, so used CPL and BCPL
=+, while B switched back to
*4 - Maybe some PL/I added.
*5 - It similar dropped
#as part of comparison operators as well
*6 - It's always worth to keep in mind that the 8 bit byte and the corresponding hex notation was only introduced shortly before with the IBM /360.
*7 - An interesting side note may be that CTC used as well a preceding zero for octal constants in their Assembler for the 1970 Datapoint 2200. So while I know of no direct relation, it's quite interesting that they came up with the same solution at the same time as Thompson did.