Yes, parameters passed by value are copied. However, you can also pass variables by reference. A reference is an alias, so this makes the parameter an alias to a variable, rather than a copy. For example:
void foo(int x) {}
void bar(int& x) {}
int i;
foo(i); // copies i, foo works with a copy
bar(i); // aliases i, bar works directly on i
If you mark it as const, you have a read-only alias:
void baz(const int&);
baz(i); // aliases i, baz reads-only i
In general, always pass by const-reference. When you need to modify the alias, remove the const. And lastly, when you need a copy, just pass by value.*
* And as a good rule of thumb, fundamental types (int, char*, etc.) and types with sizeof(T) < sizeof(void*)
should be passed by value instead of const-reference, because their size is small enough that copying will be faster than aliasing.