C is most certainly a low-level programming language. There's a reason people call it "portable assembly language".
"Portable assembly language" is an oxymoron. And I have never heard anyone use that phrase to describe C.
Of course, as with almost all programming languages, people build useful abstractions in C to bridge the gap somewhat. But that doesn't make C itself a high-level language, any more so than does the use of functions and macros to increase the expressive power of an assembly language.
Never mind building abstractions. The C language itself is a significant abstraction from the machine level. Only a small handful of operators and constructs in C have a close analogue to assembler statements (e.g., accumulation, shift and bitwise logical operators.) Therefore I maintain that it is not a low-level language.