s1 is a struct, whereas s2 and s3 are pointers to structs.
The difference between a type and a pointer to a type is neither marginal nor just a matter of taste or common use.
For example, if you pass s1 to a function that expects a Square, the function receives a copy of the data. If you pass s2 to a function that expects a *Square, the function receives a copy of the pointer, but this copy still points to the same data as the original s2.
If you are familiar with pointerless languages, you might know the notion of references. The concept is similar - passing data to a function by value copies this data, and passing data by reference creates a new reference to the same data.
Hence the use of pointers depends on your use case. If the receiving function shall modify the original data, you need to pass a pointer. If the function shall only read the data, pass it by value.
So … If I return the result in functions, actually I will get the same results.
If I dont, what I pass to a function may change the original data.
Passing data doesn’t change my original data, but passing pointers do.