In fact in the for loop statement each part of the sstatement is a separate expression statement. So it is naturally that they are separated by semicolons.
Its parts are defined as
for-init-statement
condition;
expression
Even the condition is considered as a statement because there apart from all there can be a declaration. Moreover each part can contain either a list of expressions (separated by comma) or the comma operator. So the only way to distinguish each part is to use the semicolon.
Consider the following for loop
for ( size_t i = 0, j = std::strlen( s ); i < j; i++, j-- ) std::swap( s[i], s[j] );
if do not use the semicolon it would be difficult to write the similar statement that to understant where each part ends or starts.
As for function parameters then you deal with a list. In the C++ grammar items of a list are separated by commas that to distinguish them from statements.