They may appear the same when you are using echo but this is due to them being treated the same by echo and not being equivalent.
If pass three command-line arguments given to a bash script to a C program using
./my_c $@,
you get the result ARGV[1] == "par1" ARGV[2] == "par2" ARGV[3] == "par3".
If you pass three command-line arguments given to a bash script to a C program using ./my_c $*,
you get the result ARGV[1] == "par1 par2 par3".
(ARGV is the array of supplied arguments in C, the first element is always the command-name the program was invoked with)
It's to allow greater flexibility with what you do with the given parameters later in the script.