When C has added structures, which did not exist in B, it has taken the keyword "struct" and also both "." and "->" from the IBM PL/I language, from which C has also taken some other features.
In general, almost any feature added by C to B was taken either from PL/I or from Algol 68. The exceptions are "continue" and the generalized "for", which did not exist in any previous language.
(However the generalized "for" of C was a mistake, because it complicates the frequent use cases in order to simplify seldom encountered use cases. The right way to generalize "for", i.e. with iterators, was introduced by Alphard in the same year with C, i.e. in 1974.) (Compare "for (I=0;I<N;I+=5) {" of C with "for I from 0 to N by 5 do" or "for I in 0:N:5 do" of previous languages. C requires typing a lot of redundant characters in the most frequent cases.)
The oldest symbol for indirection through a pointer (in the language Euler, in January 1966) was a raised middle dot (i.e. a point). This was before ASCII and ASCII did not include the raised middle dot (U+00B7), so it was replaced by the most similar ASCII character, "*".
Euler had used "@" for "address of" and indirection was a postfix operator, as it should. Making "*" a prefix operator in B and C was a mistake, which forced the importing of "->" from PL/I, to avoid an excessive number of parentheses. Otherwise "(*x).y" would have been needed, instead of "x->y". With a postfix "*", that would have been "x*.y", and "->", would not have been needed.
In CPL, the ancestor of BCPL and B, indirection was implicit, like with the C++ references. Instead of having an "address of" operator, CPL had a distinct symbol for an assignment variant that assigns the address of a variable, instead of assigning its value.