Many C programmers assume a single flat memory space. Most machines today have that. There's a long history of machines that didn't: Intel 286 in segmented mode, some Pentium variants in segmented mode beyond 4MB (Linux supports this in the kernel), IBM AS/400, Unisys Series B 36-bit word machines, Burroughs 5500/6700/Unisys Series A segmented machines where an address is a file-like path, Motorola CPUs where I/O space and memory space are distinct, and old DEC PDP-11 machines where code and data address spaces are separate. More recently, there are non shared memory multiprocessors where addresses are duplicated across processors - the PS3's Cell and many GPUs, for example.
Most programmers today will never encounter any of those.
There's also the assumption that null is address 0. Notably breaking the purity of C++s type system with magic 0s for 20 odd years before nullptr came along.
That is the point. They went through the process of tightening down the type system by invalidating automatic casts and making void* less promiscuous and then they break that whole philosophy with a magic literal "0" that can work as a normal integer or as an address placeholder for any pointer even though it won't necessarily evaluate to address zero. At that point why can't I assign "0" to a float too and enjoy some more magic there?
Most programmers today will never encounter any of those.