your language is too sloppy for me, a pointer-to-a-struct contains a value (could say "is" a value), and some struct-members might resolve as values, but a switch from a struct to a pointer-to-a-struct is not a switch between a value and a reference; while you might call a pointer "a reference", a struct is never a value. Or did you mean a "dot" r-value and a "dereference to an" r-value? This all makes a difference because C is a call-by-value language, and you can't pass a struct, so it's an important distinction to maintain.
This kind of change might be something a student or newb might encounter, but an experienced C programmer is going to have a sense from the start whether to go with a static/local struct or a malloc'ed one. Maybe on more common a struct containing a struct might switch to a struct containing a pointer to another struct.
personally, I use hungarian and ps->x vs s.x is a nice reinforcement of what hungarian is trying to reinforce. Using parenthesis to illustrate a sort of precedence, I guess I associate the (pointer->) like that as opposed to the (.member) though I can't defend that as making an inordinate amount of sense :)
In my and others' extensive experience in C, almost everyone is wrong about where their programs are consuming time. Profiling almost always produces surprising results. Being about to easily refactor programs to experiment with different data organizations is a superpower for a language.
C programs are difficult to refactor, and so they tend to persist with their earliest design decisions despite changing requirements and profile results.
I was able to see this only via broader experience with other languages. I never even noticed the issue before.
C++ addressed this not by fixing it, but by introducing the reference type. But the C++ ref type brings along with it all kinds of new problems, which I won't get into here.