In the optimized version I changed the way I read my data from the buffers like this :
....[example with pointer instead of index snipped]....
this is typically the sort of micro-optimisation that is a waste of time unless you
know that you need to shave a processor cycle or a byte of code,
know that playing games like this with the high level code yields better assembler.
This latter point will depend on the compiler - once optimisation is on the output from your two examples might be similar or even identical. It will also be dependent upon the platform which you need to know well.
For example the AVR instruction set* has lousy indexing so I'd expect the code from your first example to be along the lines of your pseudo-code. Except that you ignore operand size issues so that is likely to introduce more actual assembler.
* slight disclaimer, I've never hand coded AVR, just had a quick look at the instruction set a minute ago so might be wrong but you get the point, I'm sure.
Arm, however has decent indexing so the whole "something_fft = samples[i ];" statement should be a single instruction and it might be that version will be better on that platform.
AVR does have pre-decrement and post-increment so the compiler should be able to shange
something_fft = *(samples);
++samples;
into a single instruction which does the assembler equivalent of
something_fft = *(samples++);
Now, you wrote that the other way round. That would be OK** if the initialisation of "samples" (outside the loop) was correct starting one before the data, then incrementing, then dereferencing but if you wrote it that way you'd probably deny the compiler an optimisation.
** Apart from being invalid C - you're not supposed to generate addresses before the start of an array because on some segmented architectures address arithmetic might go AWOL at that boundary. You are allowed to generate the address one past the end of an array for comparison but not to dereference it.
Even if you do "win" by playing these games move platforms and the rules change. It's much better to write code in as clear and un-convoluted way as possible and let the compiler take care of the rest at this level. If you really (after measuring) want to shave a cycle, or shave a byte then actually write the assembler code.